> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# API de révision de session : création et KYC manuel

> Soumettez une note ou un changement de statut à une session Didit. Revue de conformité par API et journal d'audit, facturé à l'appel.



Créer une invite d'examen de session
        Copier le prompt dans le presse-papiers



      
      

\<pre>

\``Goal: Push a manual decision (Approve / Decline / mark In Review) onto a Didit verification session and write an immutable audit-trail row. Programmatic equivalent of the Console manual-review buttons.

Endpoint: POST https://verification.didit.me/v3/sessions/{session_id}/reviews/
Auth header: x-api-key: YOUR_API_KEY
Content-Type: application/json

Path param:
\- session_id (UUID, REQUIRED) — verification session UUID. Must belong to the same application as the API key (cross-application writes return 404).

Request body:
\- new_status (string, REQUIRED) — one of "Approved" | "Declined" | "In Review". Workflow-internal statuses ("In Progress", "Awaiting User", "Resubmitted", "Expired", "Kyc Expired", "Abandoned", "Not Started") are NOT accepted (400).
\- comment (string, optional, max 10,000 chars) — reviewer rationale. Supports @email mentions which trigger Console notifications.

curl:
curl -s -X POST 'https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/' \
-H "x-api-key: $DIDIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"new_status": "Approved", "comment": "POA cross-checked against utility bill; matches address on file."}'

Response 201 (compact ReviewSerializer shape — different from the GET response):
\{
"user": "API Client",                       // actor display label
"new_status": "Approved",
"comment": "POA cross-checked...",
"created_at": "2026-04-21T16:42:50.445Z"
}
To fetch the full activity row (uuid, activity_type, previous_status, ...) call GET /v3/sessions/{session_id}/reviews/ afterwards. See /reference/data-models for the full ReviewItem shape.

Side effects:
1\. Inserts a Review row with activity_type=STATUS_UPDATED, actor_type=API_KEY.
2\. Updates Session.status to new_status if it differs from the current status.
3\. Fires the status.updated webhook on configured destinations (see /integration/webhooks).
4\. Notifies previous reviewers and @email-mentioned Console users.
NOT idempotent — every call writes a new audit row. Re-posting the same new_status when it equals the current status is a no-op for Session.status but still writes an audit entry.

Failure modes (envelope {"detail": "..."} unless noted):
\- 400 — { "new_status": ["\\"Expired\\" is not a valid choice."] } (or missing new_status)
\- 401 — missing/invalid `x-api-key` header.
\- 403 — API key valid but wrong app or revoked.
\- 404 — session UUID not found / deleted / wrong app.
\- 429 — rate-limited.

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.``

\</pre>



      
      

Coller dans



## OpenAPI

````yaml fr/openapi-25.json POST /v3/sessions/{session_id}/reviews/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de vérification d'identité. Authentifiez-vous avec l'en-tête x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/sessions/{session_id}/reviews/:
    post:
      tags:
        - Sessions
      summary: Ajouter une note d'examen au journal d'audit d'une session
      description: >-
        Ajoute une note au fil d'activité / d'examen d'une session de
        Vérification des utilisateurs (KYC). **Cet endpoint enregistre
        uniquement une entrée — il ne modifie jamais la session.** Le `status`
        de la session reste intact, aucune validation de transition de statut
        n'est exécutée et aucun webhook n'est déclenché. Pour réellement
        approuver, refuser ou rouvrir une session (ce qui écrit également une
        entrée `STATUS_UPDATED` entièrement attribuée dans ce fil), utilisez
        plutôt `PATCH /v3/session/{session_id}/update-status/`.


        Les deux champs du corps sont facultatifs et un objet JSON vide est
        accepté. `new_status` est enregistré purement comme un libellé sur
        l'entrée et accepte l'une des dix valeurs de statut de session (sensible
        à la casse). Les mentions `@email` à l'intérieur de `comment` sont
        enregistrées sous forme de texte brut uniquement — elles ne déclenchent
        aucune notification sur cet endpoint, et le champ `mentioned_emails` de
        l'entrée reste vide.


        Remarque sur l'attribution : les entrées créées ici ne comportent aucune
        information sur l'acteur. Dans le fil, elles affichent `actor_display:
        "Unknown"`, `actor_type: "CONSOLE_USER"` et `activity_type:
        "STATUS_UPDATED"` (valeurs de stockage par défaut), et le champ `user`
        du corps `201` est `"Unknown"`.
      operationId: create_session_review
      parameters:
        - name: Content-Type
          in: header
          required: false
          description: Définir sur `application/json` lors de l'envoi d'un corps JSON.
          schema:
            type: string
            example: application/json
        - name: session_id
          in: path
          required: true
          description: >-
            UUID de la session de Vérification des utilisateurs (KYC). Doit
            appartenir à la même application que la clé API — les UUID
            inter-applications, les sessions supprimées et les identifiants de
            session de Vérification d'entreprise (KYB) renvoient tous `404`.
          schema:
            type: string
            format: uuid
            example: 8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                new_status:
                  type: string
                  nullable: true
                  enum:
                    - Not Started
                    - In Progress
                    - Approved
                    - Declined
                    - In Review
                    - Expired
                    - Abandoned
                    - Kyc Expired
                    - Resubmitted
                    - Awaiting User
                  description: >-
                    Libellé de statut optionnel à enregistrer sur l'entrée.
                    Accepte toute valeur de statut de session, sensible à la
                    casse (`"approved"` est rejeté avec `400`). Enregistrer un
                    statut ici ne modifie **pas** le statut réel de la session —
                    utilisez l'endpoint de mise à jour du statut pour cela.
                  example: In Review
                comment:
                  type: string
                  nullable: true
                  description: >-
                    Note en texte libre optionnelle (aucune limite de longueur
                    imposée). Stockée textuellement ; les mentions `@email` ne
                    sont pas traitées sur cet endpoint.
                  example: Flagging for manual document re-check.
            examples:
              NoteWithStatusLabel:
                summary: Note portant un label de statut (statut de session inchangé)
                value:
                  new_status: In Review
                  comment: Flagging for manual document re-check.
              CommentOnly:
                summary: Note simple sans étiquette de statut
                value:
                  comment: Customer emailed an updated utility bill; awaiting upload.
      responses:
        '201':
          description: >-
            Entrée enregistrée dans le journal d'audit de la session. La session
            elle-même reste inchangée — son `status` conserve sa valeur
            précédente et aucun webhook n'est envoyé. La nouvelle entrée
            apparaît également en tête de `GET …/reviews/` (avec `actor_display:
            "Unknown"`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    type: string
                    description: >-
                      Nom d'affichage de l'auteur de l'entrée. Toujours
                      `"Unknown"` pour les entrées créées via cet endpoint, car
                      il n'enregistre aucune attribution d'acteur.
                    example: Unknown
                  new_status:
                    type: string
                    nullable: true
                    enum:
                      - Not Started
                      - In Progress
                      - Approved
                      - Declined
                      - In Review
                      - Expired
                      - Abandoned
                      - Kyc Expired
                      - Resubmitted
                      - Awaiting User
                    description: >-
                      Le libellé de statut enregistré sur l'entrée, ou `null` si
                      aucun n'a été transmis. Le statut réel de la session n'est
                      pas affecté.
                    example: In Review
                  comment:
                    type: string
                    nullable: true
                    description: >-
                      La note enregistrée sur l'entrée, ou `null` si aucune n'a
                      été envoyée.
                    example: Flagging for manual document re-check.
                  created_at:
                    type: string
                    format: date-time
                    description: Date et heure d'écriture de l'entrée, ISO 8601 UTC.
                    example: '2026-06-12T00:18:44.466537Z'
              examples:
                NoteWithStatusLabel:
                  summary: Note avec un label de statut
                  value:
                    user: Unknown
                    new_status: In Review
                    comment: Flagging for manual document re-check.
                    created_at: '2026-06-12T00:18:44.466537Z'
                CommentOnly:
                  summary: Note simple
                  value:
                    user: Unknown
                    new_status: null
                    comment: Note without status.
                    created_at: '2026-06-12T00:18:44.504157Z'
        '400':
          description: >-
            Erreur de validation, renvoyée sous la forme d'une table de messages
            par champ. La cause habituelle est une valeur de `new_status` qui ne
            fait pas partie des dix statuts autorisés — la vérification est
            sensible à la casse.
          content:
            application/json:
              schema:
                type: object
                properties:
                  new_status:
                    type: array
                    items:
                      type: string
                    example:
                      - '"approved" is not a valid choice.'
              examples:
                InvalidStatusChoice:
                  summary: Valeur de statut en minuscules / inconnue
                  value:
                    new_status:
                      - '"approved" is not a valid choice.'
        '403':
          description: >-
            `x-api-key` manquant, malformé, expiré ou révoqué.
            L'authentification est vérifiée avant la recherche de la session,
            donc une clé manquante renvoie `403` même lorsque l'UUID de session
            n'existe pas.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: You do not have permission to perform this action.
              examples:
                InvalidKey:
                  summary: En-tête x-api-key manquant ou invalide
                  value:
                    detail: You do not have permission to perform this action.
        '404':
          description: >-
            Aucune session de vérification des utilisateurs (KYC) avec cet UUID
            n'est visible pour votre application : l'UUID n'existe pas, la
            session a été supprimée ou elle appartient à une autre application.
            Les ID de session de vérification d'entreprise (KYB) renvoient
            également `404` ici — le flux des examens n'est accessible que pour
            les sessions KYC.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: Session not found.
              examples:
                NotFound:
                  summary: >-
                    UUID de session inconnu, supprimé ou appartenant à une autre
                    application
                  value:
                    detail: Session not found.
        '429':
          description: >-
            Limite de débit dépassée. Examinez les en-têtes de réponse
            `Retry-After` et `X-RateLimit-*`. Voir [Limitation de
            débit](/fr/integration/rate-limiting).
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: >-
            # Records an audit-trail note only -- the session's status does NOT
            change.

            curl -s -X POST
            https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/
            \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "new_status": "In Review",
                "comment": "Flagging for manual document re-check."
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.sessions.reviews.create(
                "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
                new_status="In Review",
                comment="Flagging for manual document re-check.",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: >-
            import Didit from "@didit-protocol/sdk-node";


            // Reads DIDIT_API_KEY.

            const didit = new Didit();


            const result = await
            didit.sessions.reviews.create("8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
            {
              new_status: "In Review",
              comment: "Flagging for manual document re-check.",
            });

            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Reviews.Create(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsCreateParams{\n\tNewStatus: didit.Some(didit.SessionsReviewsCreateParamsNewStatus(\"In Review\")),\n\tComment:   didit.String(\"Flagging for manual document re-check.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: >-
            import me.didit.Didit;

            import me.didit.types.SessionsReviewsCreateParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.sessions().reviews().create("8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
            SessionsReviewsCreateParams.builder()
                    .newStatus(SessionsReviewsCreateParams.NewStatus.of("In Review"))
                    .comment("Flagging for manual document re-check.")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: >-
            <?php


            require 'vendor/autoload.php';


            use Didit\DiditClient;


            // Reads DIDIT_API_KEY.

            $didit = new DiditClient();


            $result =
            $didit->sessions->reviews->create('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d',
            [
                'new_status' => 'In Review',
                'comment' => 'Flagging for manual document re-check.',
            ]);

            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.sessions.reviews.create(
              "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
              new_status: "In Review",
              comment: "Flagging for manual document re-check."
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: >-
            using System;

            using System.Text.Json;

            using Didit;


            // Reads DIDIT_API_KEY.

            using var client = new DiditClient();


            var result = await
            client.Sessions.Reviews.CreateAsync("8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d",
            new SessionsReviewsCreateParams

            {
                NewStatus = new SessionsReviewsCreateParamsNewStatus("In Review"),
                Comment = "Flagging for manual document re-check.",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clé API de votre application, issue de Développeurs -> Clés API dans
        la Business Console. La clé principale dispose d'un accès complet. Une
        clé nommée peut être restreinte : aucun, lecture ou écriture par
        ressource, limitée à certains workflows ou aux sessions approuvées, à
        une liste d'adresses IP et à une date d'expiration. 401 signifie que la
        clé est incorrecte, révoquée ou expirée ; 403 signifie qu'aucune clé n'a
        été envoyée, que la clé n'a pas accès à cette ressource ou action, ou
        que la requête provient d'une adresse hors de sa liste d'IP ; 404 sur
        une route de session signifie que la session est hors des workflows ou
        des statuts de la clé. Une clé sans accès aux médias reçoit les URL
        d'images, de vidéos et de PDF à null, et une clé sans accès en écriture
        aux sessions reçoit les liens et tokens de session à null. Voir
        https://docs.didit.me/console/api-keys.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.