> ## 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.

# Stato della sessione API: approvare o rifiutare

> Con Didit, usa PATCH /v3/session/{id}/update-status/ per approvare, rifiutare o mettere in revisione sessioni KYC e KYB. Prezzi a consumo.



Prompt per l'aggiornamento dello stato della sessione
        Copia il prompt negli appunti



      
      

\<pre>

\`Manually approve, decline, or re-open a Didit verification session.

Endpoint:
PATCH https://verification.didit.me/v3/session/{session_id}/update-status/

Authentication:
Use the x-api-key header with your Didit API key (or a user-auth token). Privilege: write:sessions.

Path parameter:
\- session_id (UUID) — KYC or KYB; Didit resolves it against both session types.

Request body:
\- new_status (string, required) — One of "Approved", "Declined", "Resubmitted". Any other value is rejected.
\- comment (string, optional) — Free-text note saved on the audit trail (visible in the Console review log).
\- nodes_to_resubmit (array, required when new_status="Resubmitted") — Which feature steps the user must redo. Each entry: { "node_id": "feature_poa_1", "feature": "POA" }. KYB-only nodes "KYB_REGISTRY" and "KYB_KEY_PEOPLE" cannot be resubmitted directly (the parent recomputes from child KYCs).
\- send_email (boolean, optional, default false): if true, email the person. "Approved" and "Declined" send their decision email; "Resubmitted" sends a fresh hosted link with the reasons.
\- email_address (string, required when send_email=true).
\- email_language (string, optional, default "en") — ISO 639-1.
\- email_preview_token (string, optional): the preview_token from Preview Decision Email ("Approved", "Declined") or Preview Resubmission Email ("Resubmitted"). Only valid with send_email=true; without it the request returns 400 { "email_preview_token": ["A preview receipt is only valid when the email is sent."] }. The update then sends exactly the previewed email, or returns 409 before changing anything if the email or the session changed since the preview.

Optional preview step (all three statuses):
1\. Preview the email. Neither call changes the session or sends anything.
\- Approved or Declined: POST https://verification.didit.me/v3/session/{session_id}/decision-email-preview/ with { "new_status": "Approved", "email_language": "en" } (see /sessions-api/preview-decision-email).
\- Resubmitted: POST https://verification.didit.me/v3/session/{session_id}/resubmission-preview/ with { "nodes_to_resubmit": [...], "email_language": "en" } (see /sessions-api/preview-resubmission). email_address is optional there; without it the email goes to the person's own address.
2\. Check subject, html, recipient, will_be_sent and not_sent_reason in the response.
3\. Confirm here with the same new_status (and the same nodes_to_resubmit for Resubmitted), send_email=true, email_address=<recipient>, email_language=<the language you previewed>, email_preview_token=<preview_token>.
The receipt expires after 15 minutes.

Allowed transitions:
Current status must be one of: Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted. Otherwise the API returns 400 { "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: ..." }.
Setting "Approved" or "Declined" on a session that already has that status is a no-op: 200, nothing changes, and no webhook or email goes out. Setting "Resubmitted" on a session that is already Resubmitted returns 400 ["The new status is the same as the current status."].

curl example — approve after manual review:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Approved",
"comment": "Cleared after compliance review."
}'

curl example: approve and send the email you previewed:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Approved",
"send_email": true,
"email_address": "<recipient from the preview>",
"email_language": "en",
"email_preview_token": "<preview_token from the preview>"
}'

curl example — request resubmission of the proof-of-address step:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"new_status": "Resubmitted",
"nodes_to_resubmit": [{ "node_id": "feature_poa_1", "feature": "POA" }],
"comment": "Please upload a clearer proof of address",
"send_email": true,
"email_address": "user@example.com"
}'

Response: { "session_id": "<uuid>" } only. Fetch the refreshed session with GET /v3/session/{session_id}/decision/.

Side effects:
\- Fires a status.updated webhook (plus user.status.updated or business.status.updated alias).
\- Writes an entry to the Console review trail with the actor and your comment.
\- "Approved" or "Declined" with send_email=true emails the decision to email_address. Preview Decision Email tells you beforehand whether it will be sent (for example, not to the contact_details address of a session created without contact_details.send_notification_emails=true).
\- "Resubmitted" sends the user back to the steps in nodes_to_resubmit, resets the session expiration window, and (if send_email=true) emails the user a fresh link. What those steps returned before stays readable: the decision endpoint returns it with include=resubmissions (see Retrieve Session).

Failure modes:
\- 400: invalid new_status (only "Approved", "Declined" and "Resubmitted" are accepted), current status not allowed, nothing to resubmit, send_email=true without email_address, or email_preview_token without send_email=true. Field errors look like { "<field>": ["..."] }.
\- 401: the scoped API key has expired.
\- 403: { "detail": "..." } when credentials are missing or invalid, the caller lacks write:sessions (a scoped API key needs decisions write), or the session belongs to another application.
\- 404: { "detail": "Not found." } when no session with this session_id exists.
\- 409: { "detail": "This email preview changed or expired. Preview the message again before confirming." } when email_preview_token no longer matches the email or the session, or is older than 15 minutes. Nothing changed and no email was sent: preview again.
\- 429 - { "detail": "..." } when a resubmit that only targets backend-only features (AML, DATABASE_VALIDATION, IP_ANALYSIS) repeats within 30 seconds of the previous resubmit. Those features re-run automatically with no user interaction, so an immediate repeat cannot change the outcome; honor the Retry-After header instead of retrying in a loop (e.g. from a webhook handler).

Idempotency:
Repeating "Approved" or "Declined" returns 200 and changes nothing. Repeating "Resubmitted" returns 400.

Next step:
After updating, call GET /v3/session/{session_id}/decision/ to fetch the refreshed payload — see /sessions-api/retrieve-session.

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

\</pre>



      
      

Incolla in

## Supporto KYC e KYBQuesto endpoint funziona in modo identico per le sessioni di **Verifica degli utenti (KYC)** e **Verifica aziendale (KYB)**. Didit associa il `session_id` a entrambi i tipi di sessione; la validazione delle transizioni di stato è la stessa per entrambi (si applica lo stesso enum di stati a entrambi).La risposta contiene solo il `session_id`.
Leggi `session_kind` da [Retrieve Session](https://docs.didit.me/it/sessions-api/retrieve-session.md) quando la tua logica a valle deve distinguere il tipo.## Transizioni consentitePuoi portare una sessione in `Approved`, `Declined` o `Resubmitted`.
Qualsiasi altro `new_status`, incluso `In Review`, restituisce `400`.
Lo stato attuale della sessione deve essere uno tra `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned` o `Resubmitted`; in caso contrario l'API restituisce `400`.Impostare `Approved` o `Declined` su una sessione che ha già quello stato non produce effetti: l'API restituisce `200`, non modifica nulla, non attiva alcun webhook e non invia alcuna email.
Impostare `Resubmitted` su una sessione che è già `Resubmitted` restituisce `400` (`The new status is the same as the current status.`).Una nuova sottomissione i cui `nodes_to_resubmit` contengono solo funzionalità esclusivamente backend (`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`) viene eseguita automaticamente e riporta la sessione a uno stato con decisione senza alcuna interazione con l'utente.
Ripetere una nuova sottomissione di questo tipo entro 30 secondi restituisce `429 Too Many Requests` con un header `Retry-After`, poiché una ripetizione immediata non può produrre un risultato diverso.
Non inviare automaticamente una nuova sottomissione da un gestore di webhook ogni volta che ricevi lo stato `In Review`: prima esamina il risultato o modifica i dati sottostanti.## Visualizza in anteprima l'emailCon `send_email: true`, `Approved` e `Declined` inviano alla persona l'email con la decisione, mentre `Resubmitted` le invia un nuovo link con i motivi.
Puoi visualizzare quell'email prima di modificare qualsiasi cosa:1) Chiama [Preview Decision Email](https://docs.didit.me/it/sessions-api/preview-decision-email.md) per `Approved` o `Declined`, oppure [Preview Resubmission Email](https://docs.didit.me/it/sessions-api/preview-resubmission.md) per `Resubmitted`.
2) Controlla il `subject` e l'`html` renderizzati, il `recipient` e `will_be_sent` / `not_sent_reason`.
3) Chiama questo endpoint con lo stesso `new_status` (e, per una nuova sottomissione, gli stessi `nodes_to_resubmit`), `send_email: true`, `email_address` impostato su `recipient`, la `email_language` che hai visualizzato in anteprima e `email_preview_token` impostato su `preview_token`.Nessuna delle due anteprime modifica la sessione o invia qualcosa.
L'aggiornamento invia poi esattamente l'email che hai visualizzato in anteprima.
La ricevuta scade dopo 15 minuti.
Se il destinatario, la lingua, lo stato della sessione, il mittente o l'email sono cambiati dopo l'anteprima, l'aggiornamento restituisce `409` prima che venga modificato qualsiasi elemento; rigenera l'anteprima e conferma con la nuova ricevuta.
Inviare `email_preview_token` senza `send_email: true` restituisce `400`.
Il passaggio di anteprima è facoltativo: le integrazioni esistenti possono continuare a chiamare questo endpoint senza di esso.## Esempi> [tab] Approvare una sessione di Verifica degli utenti (KYC)
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "comment": "Cleared after manual review by compliance team"
>   }'
> ```> [tab] Rifiutare una sessione di Verifica aziendale (KYB)
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/bs-01HJX1.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Declined",
>     "comment": "Sanctioned subsidiary detected in ownership chain"
>   }'
> ```> [tab] Richiedere una nuova sottomissione
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Resubmitted",
>     "nodes_to_resubmit": [
>       { "node_id": "feature_poa_1", "feature": "POA" }
>     ],
>     "comment": "Please upload a clearer proof of address",
>     "send_email": true,
>     "email_address": "user@example.com"
>   }'
> ```> [tab] Approvare e inviare l'email in anteprima
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/.../update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "send_email": true,
>     "email_address": "user@example.com",
>     "email_language": "en",
>     "email_preview_token": "PREVIEW_TOKEN_FROM_THE_PREVIEW"
>   }'
> ```## AutorizzazioneRichiede il privilegio `write:sessions`. Lo stesso privilegio vale per entrambi i tipi.## Correlati- [Stati di verifica](https://docs.didit.me/it/integration/verification-statuses.md): riferimento della macchina degli stati.
- [Retrieve session](https://docs.didit.me/it/sessions-api/retrieve-session.md): recupera la decisione dopo l'aggiornamento.
- [Panoramica delle sessioni](https://docs.didit.me/it/sessions-api/overview.md): distinzione dei tipi di sessione.
- [Preview Decision Email](https://docs.didit.me/it/sessions-api/preview-decision-email.md): visualizza in anteprima l'email di approvazione o rifiuto prima di inviarla.
- [Preview Resubmission Email](https://docs.didit.me/it/sessions-api/preview-resubmission.md): visualizza in anteprima l'email di nuova sottomissione prima di inviarla.


## OpenAPI

````yaml it/openapi-25.json PATCH /v3/session/{sessionId}/update-status/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API di verifica dell'identità. Autenticati con l'intestazione x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/session/{sessionId}/update-status/:
    patch:
      tags:
        - Sessions
      summary: Approva, rifiuta o richiedi un nuovo invio per una sessione di verifica
      description: >-
        Sovrascrivi manualmente la decisione finale di una sessione di verifica
        KYC o KYB. Imposta `new_status` su `Approved` o `Declined` per
        registrare una decisione manuale, oppure su `Resubmitted` per cancellare
        passaggi di verifica specifici e consentire all'utente di ripeterli
        tramite lo stesso URL di verifica. L'endpoint accetta sia ID di sessione
        utente (KYC) sia aziendali (KYB).


        Chiamalo una volta che la sessione ha raggiunto uno stato revisionabile:
        lo stato attuale deve essere `Approved`, `Declined`, `In Review`, `Kyc
        Expired`, `Abandoned` o `Resubmitted`. Le sessioni che sono ancora `Not
        Started`, `In Progress` o `Awaiting User`, oppure che si sono concluse
        come `Expired`, restituiscono `400`. La tua chiave API deve avere
        l'autorizzazione `write:sessions` (una chiave API con ambito limitato
        necessita dell'accesso in scrittura alle decisioni). Il controllo sullo
        stato idoneo viene eseguito prima della validazione del corpo, quindi
        una sessione non idonea restituisce l'errore `Wrong Current Status`
        anche quando il payload non è valido.


        Per `Resubmitted`, passa `nodes_to_resubmit` per scegliere quali
        passaggi del workflow l'utente deve ripetere, oppure omettilo per
        selezionare automaticamente i tentativi di funzionalità esistenti in uno
        stato che consente il nuovo invio (`Declined`, `In Review`, `Not
        Finished`, `Expired`). Le funzionalità mai tentate non vengono
        selezionate automaticamente: elencale esplicitamente in
        `nodes_to_resubmit`, altrimenti la richiesta restituirà `400` se nessun
        tentativo registrato richiede un nuovo invio. I risultati precedenti dei
        passaggi selezionati vengono spostati nella cronologia del nuovo invio
        (restituita da Get Decision con `include=resubmissions`), i passaggi
        vengono riordinati per corrispondere al grafo del workflow, la finestra
        di scadenza della sessione viene riavviata e l'URL di verifica originale
        torna utilizzabile. I passaggi solo backend (`AML`,
        `DATABASE_VALIDATION`, `IP_ANALYSIS`) in cima all'elenco vengono
        eseguiti immediatamente senza interazione dell'utente; se ogni passaggio
        inviato nuovamente è solo backend, la sessione viene finalizzata
        nuovamente all'interno della stessa richiesta. `KYB_REGISTRY` e
        `KYB_KEY_PEOPLE` non possono essere inviati nuovamente in modo diretto:
        invia nuovamente le sessioni KYC figlie pertinenti e la sessione
        aziendale genitore verrà ricalcolata automaticamente.


        Ogni chiamata che modifica lo stato attiva il
        [webhook](/it/integration/webhooks) `status.updated` una volta
        confermata la modifica e aggiunge una voce di attività (con
        l'attribuzione dell'autore e il tuo `comment`) alle `reviews` della
        sessione, visibile in [Get
        Decision](#get-/v3/session/-sessionId-/decision/) e nella cronologia
        attività della console. Vengono aggiornati anche gli aggregati del
        profilo utente collegati ai `vendor_data` della sessione. Rifiutare
        disabilita il monitoraggio AML continuo per la sessione; riapprovare lo
        riabilita (da `Resubmitted`, `Declined` o `Kyc Expired`) quando il
        monitoraggio è attivato nel workflow. Approvare o rifiutare un KYC
        figlio che appartiene a un controllo delle persone chiave KYB ricalcola
        lo stato della sessione aziendale genitore. Imposta `send_email: true`
        (con `email_address`) per notificare l'utente: un avviso di stato per
        `Approved`/`Declined`, o un'email di nuovo invio contenente il link di
        verifica e i motivi passaggio per passaggio per `Resubmitted`. Per
        verificare prima l'email, visualizzane l'anteprima con [Preview Decision
        Email](/it/sessions-api/preview-decision-email) (`Approved`, `Declined`)
        o [Preview Resubmission Email](/it/sessions-api/preview-resubmission)
        (`Resubmitted`) e passa il suo `preview_token` come
        `email_preview_token`: l'aggiornamento invierà esattamente l'email
        visualizzata in anteprima, oppure restituirà `409` prima di apportare
        qualsiasi modifica se l'email o la sessione sono cambiate rispetto
        all'anteprima o se la ricevuta ha più di 15 minuti.


        Ripetere `Approved` o `Declined` su una sessione che ha già quello stato
        non modifica nulla e restituisce `200`: nessun webhook, nessuna voce di
        attività e nessuna email. Ripetere `Resubmitted` restituisce `400` (`The
        new status is the same as the current status.`). Credenziali mancanti o
        non valide e autorizzazioni mancanti restituiscono `403`; una chiave API
        con ambito limitato scaduta restituisce `401`.
      operationId: patch_v3_session_update_status
      parameters:
        - in: path
          name: sessionId
          required: true
          description: >-
            UUID della sessione di verifica da aggiornare. Accetta sia ID di
            sessione utente (KYC) sia ID di sessione aziendale (KYB): il
            servizio risolve l'ID per entrambi i tipi di sessione.
          schema:
            type: string
            format: uuid
            example: 11111111-2222-3333-4444-555555555555
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - new_status
              properties:
                new_status:
                  type: string
                  description: >-
                    Stato di destinazione. `Approved` e `Declined` registrano
                    una decisione manuale definitiva (ciascuna può anche
                    revocare l'altra). `Resubmitted` azzera i passaggi
                    selezionati e rimanda la sessione all'utente. Qualsiasi
                    altro valore restituisce `400`.
                  enum:
                    - Approved
                    - Declined
                    - Resubmitted
                  example: Approved
                comment:
                  type: string
                  description: >-
                    Motivo della modifica in formato testo libero, memorizzato
                    nella traccia di revisione della sessione e restituito
                    nell'array `reviews` di [Get
                    Decision](#get-/v3/session/-sessionId-/decision/). Ad
                    esempio `Duplicated user`.
                  example: All checks passed manual review
                nodes_to_resubmit:
                  type: array
                  description: >-
                    Passaggi del workflow che l'utente deve ripetere. Viene
                    preso in considerazione solo quando `new_status` è
                    `Resubmitted`. Per `Approved`/`Declined` le voci vengono
                    comunque convalidate a livello di schema (un valore
                    `feature` non valido restituisce `400`), ma le voci conformi
                    allo schema vengono semanticamente ignorate. Se omesso, il
                    server seleziona automaticamente i tentativi esistenti di
                    OCR, Rilevamento della vitalità, Confronto facciale, Prova
                    di residenza, Verifica telefonica, Verifica email, Screening
                    AML, Validazione su database e Questionari il cui stato è
                    `Declined`, `In Review`, `Not Finished` o `Expired` (i
                    tentativi relativi a NFC, analisi IP, stima dell'età,
                    ricerca facciale e documenti KYB non vengono mai selezionati
                    automaticamente; i tentativi sul volto diversi dal confronto
                    facciale vengono selezionati come `LIVENESS`) — le
                    funzionalità che l'utente non ha mai tentato (nessun
                    tentativo registrato) NON vengono selezionate, quindi una
                    sessione con zero tentativi restituisce `400` ("No features
                    found that need resubmission") anche se nulla è stato
                    approvato; in tal caso, passa esplicitamente
                    `nodes_to_resubmit`. I passaggi vengono eseguiti nell'ordine
                    del grafo del workflow indipendentemente dall'ordine con cui
                    li invii. `KYB_REGISTRY`, `KYB_KEY_PEOPLE` e l'alias `KYB`
                    vengono rifiutati con `400` — tali controlli padre vengono
                    ricalcolati a partire dalle relative sessioni KYC figlie.
                  items:
                    type: object
                    required:
                      - node_id
                      - feature
                    properties:
                      node_id:
                        type: string
                        description: >-
                          Identificativo del nodo così come appare nella
                          definizione del workflow della sessione (ad esempio
                          `feature_ocr`, `feature_liveness`).
                        example: feature_ocr
                      feature:
                        type: string
                        description: >-
                          Tipo di funzionalità del nodo. Gli alias
                          `ID_VERIFICATION`, `POA`, `PHONE` ed `EMAIL` vengono
                          normalizzati lato server in `OCR`, `PROOF_OF_ADDRESS`,
                          `PHONE_VERIFICATION` ed `EMAIL_VERIFICATION`.
                          `KYB_REGISTRY`, `KYB_KEY_PEOPLE` e `KYB` superano la
                          convalida dello schema ma vengono sempre rifiutati con
                          l'errore di regola di business `400` mostrato negli
                          esempi.
                        enum:
                          - OCR
                          - OCR_BACK
                          - NFC
                          - AML
                          - FACE
                          - LIVENESS
                          - FACE_MATCH
                          - IP_ANALYSIS
                          - AGE_ESTIMATION
                          - PROOF_OF_ADDRESS
                          - PHONE_VERIFICATION
                          - EMAIL_VERIFICATION
                          - FACE_SEARCH
                          - DATABASE_VALIDATION
                          - QUESTIONNAIRE
                          - DOCUMENT_AI
                          - KYB_DOCUMENTS
                          - ID_VERIFICATION
                          - POA
                          - PHONE
                          - EMAIL
                          - KYB_REGISTRY
                          - KYB_KEY_PEOPLE
                          - KYB
                          - GEOLOCATION
                        example: OCR
                send_email:
                  type: boolean
                  description: >-
                    Indica se inviare un'email all'utente in merito alla
                    modifica. Richiede `email_address`. Per
                    `Approved`/`Declined` l'utente riceve una notifica di stato;
                    per `Resubmitted` l'email include il link di verifica e i
                    motivi del nuovo invio specifici per ciascun passaggio.
                  default: false
                  example: false
                email_address:
                  type: string
                  format: email
                  description: >-
                    Destinatario dell'email di notifica. **Obbligatorio quando
                    `send_email` è `true`**; se omesso restituisce `400`.
                  example: user@example.com
                email_language:
                  type: string
                  description: >-
                    Lingua per l'email di notifica. Accetta qualsiasi stringa a
                    livello di schema; i codici non supportati ripiegano
                    silenziosamente sull'inglese (`en`).
                  default: en
                  example: en
                email_preview_token:
                  type: string
                  writeOnly: true
                  minLength: 1
                  maxLength: 512
                  description: >-
                    Ricevuta opzionale da [Preview Decision
                    Email](/it/sessions-api/preview-decision-email) (per
                    `Approved` e `Declined`) o da [Preview Resubmission
                    Email](/it/sessions-api/preview-resubmission) (per
                    `Resubmitted`): il relativo `preview_token`. Valida solo con
                    `send_email: true`; in sua assenza la richiesta restituisce
                    `400`. Il destinatario, la lingua, lo stato della sessione,
                    il mittente e l'email (e, per un nuovo invio, i passaggi
                    selezionati) devono comunque corrispondere all'anteprima, e
                    la ricevuta scade dopo 15 minuti. In caso contrario, la
                    richiesta restituisce `409` prima che la sessione venga
                    modificata o che venga inviata un'email. Le integrazioni
                    esistenti possono omettere questo campo.
            examples:
              Approve Session:
                summary: Approva una sessione dopo la revisione manuale
                value:
                  new_status: Approved
                  comment: All checks passed manual review
              Decline Session:
                summary: Rifiuta una sessione
                value:
                  new_status: Declined
                  comment: Suspected fraud
              Resubmit Specific Steps:
                summary: Richiedi nuovo invio per i passaggi scelti, con email
                value:
                  new_status: Resubmitted
                  nodes_to_resubmit:
                    - node_id: feature_ocr
                      feature: OCR
                    - node_id: feature_liveness
                      feature: LIVENESS
                  send_email: true
                  email_address: user@example.com
                  email_language: en
              Resubmit Auto-select:
                summary: >-
                  Richiedi nuovo invio (selezione automatica dei passaggi non
                  approvati)
                value:
                  new_status: Resubmitted
              Approve With Previewed Email:
                summary: Approva e invia l'email restituita da Preview Decision Email
                value:
                  new_status: Approved
                  send_email: true
                  email_address: person@example.com
                  email_language: en
                  email_preview_token: >-
                    eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000
      responses:
        '200':
          description: >-
            Stato aggiornato. La risposta contiene solo il `session_id`;
            recupera la sessione aggiornata tramite [Get
            Decision](#get-/v3/session/-sessionId-/decision/). Il webhook
            `status.updated` viene attivato dopo il commit della modifica.
            Ripetere `Approved` o `Declined` restituisce lo stesso corpo e non
            modifica nulla.
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_id:
                    type: string
                    format: uuid
                    description: UUID della sessione aggiornata.
              examples:
                Updated:
                  summary: >-
                    Restituito indistintamente per Approvata, Rifiutata e
                    Reinviata
                  value:
                    session_id: 3472fb7c-8f7c-4d1a-9cf4-cf3d74ce1a60
        '400':
          description: >-
            Errore di validazione. Gli errori di campo arrivano come
            `{"<field>": ["<message>"]}` (alcuni rifiuti delle regole di
            business utilizzano invece un valore stringa: `{"nodes_to_resubmit":
            "<message>"}`), gli errori di transizione tra stati come `{"detail":
            "<message>"}`, e l'errore per lo stesso stato come un semplice array
            JSON.
          content:
            application/json:
              examples:
                Wrong Current Status:
                  summary: La sessione non si trova in uno stato aggiornabile
                  value:
                    detail: >-
                      Only sessions with status Approved, Declined, In Review,
                      Kyc Expired, Abandoned, Resubmitted can be updated.
                      Current status: In Progress
                Invalid Status Value:
                  summary: >-
                    new_status è uno stato di sessione valido ma non è uno tra
                    Approved/Declined/Resubmitted
                  value:
                    new_status:
                      - >-
                        You can only update the status to 'Approved',
                        'Declined', or 'Resubmitted'.
                Missing new_status:
                  summary: Campo obbligatorio omesso
                  value:
                    new_status:
                      - This field is required.
                Same Status:
                  summary: Nuovo invio richiesto su una sessione già reinviata
                  value:
                    - The new status is the same as the current status.
                Email Address Required:
                  summary: send_email true senza email_address
                  value:
                    email_address:
                      - Email address is required when send_email is true.
                Non-resubmittable Feature:
                  summary: Il nuovo invio ha come obiettivo un controllo padre KYB
                  value:
                    nodes_to_resubmit: >-
                      The following features cannot be resubmitted directly:
                      KYB_REGISTRY. Resubmit the relevant child KYC sessions
                      instead; the parent will recompute automatically.
                Nothing To Resubmit:
                  summary: >-
                    La selezione automatica non ha trovato funzionalità non
                    approvate
                  value:
                    nodes_to_resubmit: >-
                      No features found that need resubmission. All features are
                      already approved.
                Invalid Feature Choice:
                  summary: Funzionalità sconosciuta in nodes_to_resubmit
                  value:
                    nodes_to_resubmit:
                      - feature:
                          - >-
                            "BOGUS" is not a valid choice. Valid choices are:
                            OCR, OCR_BACK, NFC, AML, FACE, LIVENESS, FACE_MATCH,
                            IP_ANALYSIS, AGE_ESTIMATION, PROOF_OF_ADDRESS,
                            PHONE_VERIFICATION, EMAIL_VERIFICATION, FACE_SEARCH,
                            DATABASE_VALIDATION, QUESTIONNAIRE, KYB_REGISTRY,
                            KYB_DOCUMENTS, KYB_KEY_PEOPLE, ID_VERIFICATION, POA,
                            PHONE, EMAIL, KYB
                Invalid Status Value (not a status at all):
                  summary: new_status non è un valore valido di StatusChoices
                  value:
                    new_status:
                      - '"Bogus" is not a valid choice.'
                Preview Receipt Without Email:
                  summary: 'email_preview_token inviato senza send_email: true'
                  value:
                    email_preview_token:
                      - A preview receipt is only valid when the email is sent.
        '401':
          description: La chiave API con ambito è scaduta.
          content:
            application/json:
              examples:
                Expired API Key:
                  summary: Chiave API con ambito oltre la sua data di scadenza
                  value:
                    detail: This API key has expired.
        '403':
          description: >-
            Credenziali mancanti o autorizzazioni insufficienti, oppure un
            `session_id` che appartiene a un'altra applicazione.
          content:
            application/json:
              examples:
                Invalid Credentials:
                  summary: x-api-key mancante o non valida
                  value:
                    detail: >-
                      Authentication credentials were not provided or are
                      invalid.
                Missing Privilege:
                  summary: La chiave API non dispone dell'autorizzazione write:sessions
                  value:
                    detail: You do not have permission to perform this action.
        '404':
          description: >-
            Non esiste alcuna sessione KYC o KYB con questo `session_id` (anche
            le sessioni eliminate restituiscono `404`).
          content:
            application/json:
              examples:
                Not Found:
                  summary: session_id sconosciuto
                  value:
                    detail: Not found.
        '409':
          description: >-
            L'anteprima dell'email è cambiata o è scaduta. Genera una nuova
            anteprima prima di confermare; non viene apportata alcuna modifica
            alla sessione né eseguita alcuna consegna dell'email.
          content:
            application/json:
              examples:
                Preview Changed:
                  summary: La ricevuta non corrisponde più o è più vecchia di 15 minuti
                  value:
                    detail: >-
                      This email preview changed or expired. Preview the message
                      again before confirming.
        '429':
          description: >-
            Un nuovo invio mirato esclusivamente a funzionalità solo backend
            (AML, DATABASE_VALIDATION, IP_ANALYSIS) è stato ripetuto entro la
            finestra di cooldown di 30 secondi; una ripetizione immediata non
            può modificare l'esito. Attendi e riprova dopo l'intervallo indicato
            in `Retry-After`.
          content:
            application/json:
              examples:
                Backend-only resubmit throttled:
                  value:
                    detail: >-
                      This session was already resubmitted for backend-only
                      features within the last 30 seconds; repeating it cannot
                      change the outcome. Wait before resubmitting again.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X PATCH \
              https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-status/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "new_status": "Approved",
                "comment": "All checks passed manual review"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.sessions.update_status(
                "11111111-2222-3333-4444-555555555555",
                new_status="Approved",
                comment="All checks passed manual review",
            )
            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.updateStatus("11111111-2222-3333-4444-555555555555",
            {
              new_status: "Approved",
              comment: "All checks passed manual review",
            });

            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"All checks passed manual review\"),\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.SessionsUpdateStatusParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.sessions().updateStatus("11111111-2222-3333-4444-555555555555",
            SessionsUpdateStatusParams.builder()
                    .newStatus(SessionsUpdateStatusParams.NewStatus.of("Approved"))
                    .comment("All checks passed manual review")
                    .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->updateStatus('11111111-2222-3333-4444-555555555555',
            [
                'new_status' => 'Approved',
                'comment' => 'All checks passed manual review',
            ]);

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

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

            result = didit.sessions.update_status(
              "11111111-2222-3333-4444-555555555555",
              new_status: "Approved",
              comment: "All checks passed manual review"
            )
            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.UpdateStatusAsync("11111111-2222-3333-4444-555555555555",
            new SessionsUpdateStatusParams

            {
                NewStatus = "Approved",
                Comment = "All checks passed manual review",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La chiave API della tua applicazione, da Developers -> API keys nella
        Business Console. La chiave primaria ha accesso completo. Una chiave con
        nome può avere un ambito definito: nessuno, lettura o scrittura per
        risorsa, limitata ad alcuni workflow o a sessioni approvate, a un elenco
        di indirizzi IP e a una data di scadenza. 401 indica che la chiave è
        errata, revocata o scaduta; 403 indica che non è stata inviata alcuna
        chiave, che la chiave non ha accesso a questa risorsa o azione, oppure
        che la richiesta proviene da un indirizzo non incluso nel suo elenco IP;
        404 su una route di sessione indica che la sessione non rientra nei
        workflow o negli stati previsti dalla chiave. Una chiave senza accesso
        ai media riceve gli URL di immagini, video e PDF come null, e una chiave
        senza permessi di scrittura sulle sessioni riceve link e token di
        sessione come null. Consulta https://docs.didit.me/console/api-keys.

````

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