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

# Actualizar estado de función: aprobar o rechazar un paso

> Aprueba, rechaza o envía a revisión un paso de verificación de Didit (OCR, Liveness, Face Match, AML, POA…) ahora o al terminar el flujo.



Prompt para actualizar el estado de una función
        Copiar el prompt al portapapeles



      
      

\<pre>

\`Approve, decline, or move a SINGLE verification step (feature) of a Didit session to review, now or once the person finishes the flow.

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

Authentication:
x-api-key (client API key) or a user-auth token. Privilege: write:sessions.

Path parameters:
\- session_id (UUID) — KYC or KYB; Didit resolves it against both session types.
\- node_id — the workflow graph node ID of the step (e.g. feature_ocr_1, feature_liveness_1, feature_aml_1). Use the literal "default" for non-graph (single-step) workflows where the step has no node ID.

Request body:
\- new_status (string, required): one of "Approved", "Declined", "In Review". Must differ from the step's current status.
\- comment (string, optional): your reason, saved in the session's activity and returned as the override's reason.
\- feature_type (string, optional): which kind of step to target, for example "LIVENESS", "AML", "FACE_MATCH", "ID_VERIFICATION". Needed when node_id is "default" (non-graph workflows, where steps have no node ID). An unknown value returns 400 { "feature_type": ["Unknown feature_type '...'."] }.
\- defer_until_flow_finishes (boolean, optional, default false): while the person is still in the flow, wait and apply the override when the flow finishes instead of at once.

When the override applies:
\- Omitted or false: it applies at once. If the person is still in the flow it is recorded as forced=true.
\- true while the person is still in the flow (session Not Started, In Progress or Resubmitted, and not finished): it is stored as "pending_until_flow_finishes" and applies when the flow finishes, after the flow reaches its own decision.
\- true after the flow ended: it applies at once.
\- A waiting override is cancelled instead when the person redoes the step before finishing, a newer override on the same step replaces it, the session leaves the flow unfinished (abandoned, expired, decided mid-flow), or you cancel it with POST /v3/session/{session_id}/features/overrides/{override_id}/cancel/.

Which steps this works on:
Every per-step feature record: OCR/ID, Liveness, Face Match, NFC, AML, Proof of Address (POA), Phone, Email, Database Validation, Questionnaire, and the KYB registry / documents / key-people checks.

Difference vs update-status:
\- update-status changes the OVERALL session decision (Approved/Declined/Resubmitted).
\- THIS endpoint changes ONE step's status. A session that already has a decision keeps it. If the session has no decision yet and its workflow is waiting on exactly this step, applying the override completes the step: the workflow moves on and a status node can set the session decision (and fire status.updated).

Not allowed:
\- Standalone API sessions (session_type = API) return 400.

curl example — approve the ID/OCR step:
curl -X PATCH https://verification.didit.me/v3/session/<SESSION_ID>/features/feature_ocr_1/update-status/ \
-H "x-api-key: <API_KEY>" \
-H "Content-Type: application/json" \
-d '{ "new_status": "Approved", "comment": "Document manually verified" }'

Response: { session_id, node_id, feature_type, new_status, override }.
\- node_id is the step's workflow node, or null for a step without a node ("default" in a non-graph workflow).
\- new_status is the step's stored status: the requested one once the override applied, the unchanged one while it waits.
\- override: { id, node_id, feature_type, feature_model, previous_status, new_status, state ("applied" | "pending_until_flow_finishes" | "cancelled"), forced, reason, requested_by { email, name, type }, requested_at, applied_at, cancelled_at, cancel_reason }.

Side effects:
\- Fires a data.updated webhook when the override applies (at once, or when the flow finishes). Nothing is sent while it waits or when it is cancelled.
\- Records the override in the session's activity as FEATURE_OVERRIDE_PENDING, FEATURE_OVERRIDE_APPLIED or FEATURE_OVERRIDE_CANCELLED, with who made it; the request's entry carries your comment. In the decision's reviews array these entries appear with new_status null, and the request's entry has your reason in comment.

Failure modes:
\- 400: new_status invalid or unchanged, unknown feature_type, or the session is a standalone API session.
\- 401: the scoped API key has expired.
\- 403: missing credentials (a wrong, revoked or expired key gets 401), or the caller lacks write:sessions (a scoped key needs decisions write).
\- 404: session not found, or no feature has the given node_id.

Related: list overrides with GET /v3/session/{session_id}/features/overrides/ (see /sessions-api/list-feature-overrides); cancel a waiting one with POST /v3/session/{session_id}/features/overrides/{override_id}/cancel/ (see /sessions-api/cancel-feature-override).

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

\</pre>



      
      

Pegar en

## Qué hace este endpointUna sesión de verificación se compone de **funciones** (pasos) individuales: ID/OCR, prueba de vida, coincidencia facial, análisis AML, prueba de domicilio, teléfono, etc.
Este endpoint te permite establecer el estado de **uno** de esos pasos en `Approved`, `Declined` o `In Review`.Usa [update-status](https://docs.didit.me/es/sessions-api/update-status.md) cuando quieras aprobar, rechazar o reabrir la sesión completa.
Usa **este** endpoint cuando solo quieras registrar una decisión sobre un único paso, por ejemplo, para marcar el paso de coincidencia facial como `Declined` en tu propio flujo de revisión.Una sesión que ya tiene una decisión la conserva: solo cambia el paso.
Si la sesión aún no tiene decisión y su flujo de verificación (workflow) está a la espera de este paso concreto, aplicar la modificación completa el paso, igual que si se hubiera terminado de forma normal.
El flujo avanza, se ejecutan los pasos posteriores, y un nodo de estado puede establecer la decisión de la sesión y disparar un webhook `status.updated`.## Cómo apuntar a un paso con `node_id`En los flujos basados en grafos, cada paso tiene un `node_id` (por ejemplo, `feature_ocr_1`, `feature_liveness_1`, `feature_aml_1`). Puedes encontrarlos en la [decisión de la sesión](https://docs.didit.me/es/sessions-api/retrieve-session.md): cada función de una decisión V3 incluye su `node_id`.En los **flujos que no se basan en grafos (de un solo paso)**, la función subyacente no tiene ID de nodo. Pasa el valor literal `default` como `nodeId` para apuntar a ella.
Como ningún paso de este tipo de flujo tiene ID de nodo, pasa también `feature_type` (por ejemplo, `LIVENESS`, `AML` o `FACE_MATCH`) para indicar a qué paso te refieres.
Un `feature_type` desconocido devuelve `400`.## Esperar a que la persona termine el flujoDe forma predeterminada, la modificación se aplica de inmediato.
Si la persona todavía está recorriendo el flujo, eso cambia un paso de un flujo que sigue en curso; en ese caso, la modificación se registra con `forced: true`.Establece `defer_until_flow_finishes: true` para esperar.
Mientras la sesión esté en `Not Started`, `In Progress` o `Resubmitted` y la persona no haya terminado, la modificación se guarda como `pending_until_flow_finishes`.
Se aplica cuando la persona termina el flujo, después de que el flujo llegue a su propia decisión.
En una sesión cuyo flujo ya terminó, se aplica de inmediato en cualquier caso.Una modificación en espera se cancela en lugar de aplicarse cuando:- la persona repite el paso antes de terminar (`check_changed`),
- una modificación más reciente sobre el mismo paso la sustituye (`replaced`),
- la sesión se cierra sin que el flujo haya terminado: abandonada, expirada o decidida a mitad del flujo (`session_closed`),
- la cancelas con [Cancel Feature Override](https://docs.didit.me/es/sessions-api/cancel-feature-override.md) (`cancelled_by_reviewer`).El campo `override` de la respuesta te indica qué ocurrió: `state` es `applied` o `pending_until_flow_finishes`, y `applied_at` se establece una vez aplicada.
El campo `new_status` de nivel superior es el estado guardado del paso, por lo que no cambia mientras la modificación está en espera.
Usa [List Feature Overrides](https://docs.didit.me/es/sessions-api/list-feature-overrides.md) para ver todas las modificaciones de una sesión y si la persona sigue en el flujo.## Compatibilidad con KYC y KYBFunciona igual para las sesiones de **Verificación de usuario (KYC)** y de **Verificación de empresas (KYB)**: Didit resuelve el `sessionId` en ambos tipos. Los tipos de paso compatibles incluyen ID/OCR, prueba de vida, coincidencia facial, NFC, análisis AML, prueba de domicilio, teléfono, correo electrónico, validación de base de datos, cuestionario y las comprobaciones de registro, documentos y personas clave de KYB.> [!NOTE]
>
> En las sesiones de API independientes (las creadas mediante las API de verificación independientes, `session_type = API`) no se pueden cambiar los estados de funciones individuales: el endpoint devuelve `400`.## Ejemplos> [tab] Aprobar un paso
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/feature_ocr_1/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "comment": "Document manually verified by compliance"
>   }'
> ```> [tab] Rechazar el paso de coincidencia facial
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/feature_face_match/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Declined"
>   }'
> ```> [tab] Flujo de un solo paso (nodo predeterminado)
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/default/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "In Review",
>     "feature_type": "LIVENESS"
>   }'
> ```> [tab] Esperar a que la persona termine el flujo
>
> ```bash theme={null}
> curl -X PATCH https://verification.didit.me/v3/session/4c5c7f3a-.../features/feature_liveness_1/update-status/ \
>   -H "x-api-key: YOUR_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "new_status": "Approved",
>     "comment": "Liveness retried with a reviewer present",
>     "defer_until_flow_finishes": true
>   }'
> ```## Qué ocurre después de una actualización- **Webhook**: se dispara un evento `data.updated` cuando se aplica la modificación, ya sea de inmediato o cuando termina el flujo. No se envía nada mientras está en espera ni cuando se cancela.
- **Actividad**: cada modificación se registra en la actividad de la sesión como `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` o `FEATURE_OVERRIDE_CANCELLED`, junto con quien la realizó (clave de API, usuario o el sistema cuando se aplica una modificación en espera). La entrada de la solicitud incluye tu `comment` como motivo. En el array `reviews` de la [decisión de la sesión](https://docs.didit.me/es/sessions-api/retrieve-session.md), estas entradas aparecen con `new_status: null`, y la entrada de la solicitud tiene tu motivo en `comment`.
- **Decisión de la sesión**: una sesión que ya tiene una decisión la conserva. Para cambiar la decisión final, invoca [update-status](https://docs.didit.me/es/sessions-api/update-status.md) por separado.## PermisoRequiere el privilegio `write:sessions`, con una clave de API de cliente (`x-api-key`) o un encabezado de autorización de usuario.
Una clave de API con alcance limitado necesita acceso de escritura a las decisiones.## Relacionado- [Actualizar el estado de la sesión](https://docs.didit.me/es/sessions-api/update-status.md): cambia la decisión global de la sesión.
- [Actualizar el estado de una coincidencia AML](https://docs.didit.me/es/sessions-api/update-aml-hit-status.md): revisa coincidencias AML individuales.
- [Obtener la sesión](https://docs.didit.me/es/sessions-api/retrieve-session.md): obtén la decisión (y el `node_id` de cada función).
- [Webhooks](https://docs.didit.me/es/integration/webhooks.md): suscríbete a `data.updated`.
- [List Feature Overrides](https://docs.didit.me/es/sessions-api/list-feature-overrides.md): todas las modificaciones de una sesión y su estado.
- [Cancel Feature Override](https://docs.didit.me/es/sessions-api/cancel-feature-override.md): impide que se aplique una modificación en espera.


## OpenAPI

````yaml es/openapi-25.json PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de verificación de identidad. Autentícate con el encabezado x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/session/{sessionId}/features/{nodeId}/update-status/:
    patch:
      tags:
        - Sessions
      summary: Actualizar el estado de una función individual (paso)
      description: >-
        Establece el estado de una única función de verificación (paso) dentro
        de una sesión. Indica la función mediante su `nodeId` del grafo del
        flujo de verificación (workflow). En los flujos que no son de grafo,
        cuyos pasos no tienen nodo, usa `default` y pasa también `feature_type`
        para indicar a qué paso te refieres.


        Funciona tanto para sesiones de Verificación de usuarios (KYC) como de
        Verificación de empresas (KYB) y para todos los tipos de paso: ID/OCR,
        Prueba de vida, Coincidencia facial, NFC, AML, Prueba de domicilio,
        Teléfono, Correo electrónico, Validación de base de datos, Cuestionario
        y las comprobaciones de registro / documentos / personas clave de KYB.
        Este endpoint **no** está disponible para las sesiones de API
        independientes (`session_type = API`).


        `new_status` debe ser `Approved`, `Declined` o `In Review`, y debe ser
        distinto del estado actual de la función.


        **Cuándo se aplica la anulación.** Sin `defer_until_flow_finishes` (o
        con `false`), la anulación se aplica de inmediato, como siempre; si la
        persona sigue en el flujo, se registra como `forced`. Con
        `defer_until_flow_finishes: true` mientras la persona sigue en el flujo
        (la sesión está en `Not Started`, `In Progress` o `Resubmitted` y no ha
        terminado), la anulación se guarda como `pending_until_flow_finishes` y
        se aplica cuando termina el flujo, después de que el flujo llegue a su
        propia decisión. En una sesión cuyo flujo ya terminó, se aplica de
        inmediato en cualquier caso. En cambio, una anulación en espera se
        cancela cuando la persona repite su paso antes de terminar, cuando una
        anulación más reciente sobre la misma comprobación la reemplaza, cuando
        la sesión sale del flujo sin terminarlo (abandonada, expirada o decidida
        a mitad del flujo) o cuando la cancelas con `POST
        /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`.
        Consulta las anulaciones de una sesión con `GET
        /v3/session/{sessionId}/features/overrides/`.


        **Efecto en la sesión.** Una sesión que ya tiene una decisión la
        conserva: solo cambia la comprobación. Cuando la sesión aún no tiene
        decisión y su flujo está esperando exactamente este paso, aplicar la
        anulación completa el paso: el flujo avanza, se ejecutan los pasos
        siguientes y un nodo de estado puede establecer la decisión de la sesión
        y disparar `status.updated`.


        **Webhooks y actividad.** Se dispara un webhook `data.updated` cuando se
        aplica la anulación (de inmediato o cuando termina el flujo), nunca
        mientras está en espera ni cuando se cancela. Cada anulación se registra
        en la actividad de la sesión como `FEATURE_OVERRIDE_PENDING`,
        `FEATURE_OVERRIDE_APPLIED` o `FEATURE_OVERRIDE_CANCELLED`, junto con
        quién la hizo; la entrada de la solicitud incluye tu `comment`.


        Autentícate con tu clave de API (`x-api-key`) o con un encabezado de
        autorización de usuario que tenga el privilegio `write:sessions`; una
        clave de API con alcance limitado necesita acceso de escritura a las
        decisiones.
      operationId: patch_v3_session_update_feature_status
      parameters:
        - in: path
          name: sessionId
          required: true
          description: >-
            UUID de la sesión de verificación. Acepta ID de sesión tanto de
            usuario (KYC) como de empresa (KYB): el servicio resuelve el ID en
            ambos tipos de sesión.
          schema:
            type: string
            format: uuid
            example: 11111111-2222-3333-4444-555555555555
        - in: path
          name: nodeId
          required: true
          description: >-
            ID del nodo del grafo del flujo correspondiente a la función que se
            va a actualizar (por ejemplo, `feature_ocr_1`). Usa el valor literal
            `default` para flujos que no se basan en grafo (de un solo paso), en
            los que la función no tiene ID de nodo.
          schema:
            type: string
            example: feature_ocr_1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - new_status
              properties:
                new_status:
                  type: string
                  description: >-
                    Estado de destino para esta función. Debe ser distinto del
                    valor actual.
                  enum:
                    - Approved
                    - Declined
                    - In Review
                  example: Approved
                comment:
                  type: string
                  description: >-
                    Nota opcional en texto libre que se registra en el historial
                    de revisión de la sesión para este cambio de función.
                  example: Document manually verified by compliance.
                feature_type:
                  type: string
                  enum:
                    - ID_VERIFICATION
                    - OCR
                    - OCR_BACK
                    - NFC
                    - LIVENESS
                    - FACE
                    - AGE_ESTIMATION
                    - AGE_VERIFICATION
                    - FACE_SEARCH
                    - FACE_MATCH
                    - IP_ANALYSIS
                    - AML
                    - PHONE
                    - PHONE_VERIFICATION
                    - EMAIL
                    - EMAIL_VERIFICATION
                    - POA
                    - PROOF_OF_ADDRESS
                    - DATABASE_VALIDATION
                    - DATA_VALIDATION
                    - QUESTIONNAIRE
                    - DOCUMENT_AI
                    - KYB_REGISTRY
                    - KYB_DOCUMENTS
                    - KYB_KEY_PEOPLE
                    - BANK_VERIFICATION
                    - GEOLOCATION
                  description: >-
                    Qué tipo de paso se quiere seleccionar. Es obligatorio en
                    los flujos que no son de grafo (`nodeId` = `default`), donde
                    los pasos no tienen nodo propio; en los demás casos es
                    opcional. Un valor desconocido devuelve `400`.
                  example: LIVENESS
                defer_until_flow_finishes:
                  type: boolean
                  default: false
                  description: >-
                    Mientras la persona sigue en el flujo, guarda la anulación
                    como `pending_until_flow_finishes` y aplícala cuando el
                    flujo termine, en lugar de hacerlo de inmediato. Si se omite
                    o es `false`, la anulación se aplica de inmediato. En una
                    sesión cuyo flujo ya terminó, se aplica de inmediato en
                    ambos casos.
                  example: false
            examples:
              Apply Now:
                summary: Aprobar el paso de ID de inmediato
                value:
                  new_status: Approved
                  comment: Document manually verified by compliance.
              Wait For The Flow:
                summary: >-
                  Aprobar el paso de prueba de vida cuando la persona termine el
                  flujo
                value:
                  new_status: Approved
                  comment: Liveness retried with a reviewer present.
                  defer_until_flow_finishes: true
              Non-graph Workflow:
                summary: >-
                  Apuntar al paso de prueba de vida de un flujo sin nodos
                  (nodeId = default)
                value:
                  new_status: In Review
                  feature_type: LIVENESS
      responses:
        '200':
          description: >-
            Se registró la anulación. `new_status` es el estado de la
            comprobación tal como está almacenado: el solicitado una vez
            aplicada la anulación, o el que no ha cambiado mientras espera a que
            termine el flujo. `override` indica qué ocurrió.
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_id:
                    type: string
                    format: uuid
                  node_id:
                    type: string
                    nullable: true
                    description: >-
                      El nodo del flujo del paso actualizado, o `null` para un
                      paso sin nodo (la ruta `default` en un flujo que no es de
                      grafo).
                    example: feature_ocr_1
                  feature_type:
                    type: string
                    description: >-
                      Nombre del modelo de la función actualizada (p. ej.,
                      `KYC`, `Face`, `FaceMatch`, `AML`, `POA`).
                    example: KYC
                  new_status:
                    type: string
                    description: >-
                      El estado almacenado de la comprobación: el solicitado una
                      vez aplicada la anulación manual, o el original sin
                      cambios mientras la anulación espera a que termine el
                      flujo.
                    example: Approved
                  override:
                    $ref: '#/components/schemas/FeatureStatusOverride'
                required:
                  - session_id
                  - node_id
                  - feature_type
                  - new_status
                  - override
              examples:
                Applied:
                  summary: La anulación se aplicó de inmediato
                  value:
                    session_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                    node_id: feature_ocr_1
                    feature_type: KYC
                    new_status: Approved
                    override:
                      id: 7c9e6679-7425-40de-944b-e07fc1f90ae7
                      node_id: feature_ocr_1
                      feature_type: ''
                      feature_model: KYC
                      previous_status: In Review
                      new_status: Approved
                      state: applied
                      forced: false
                      reason: Document manually verified by compliance.
                      requested_by:
                        email: reviewer@example.com
                        name: Alex Reviewer
                        type: CONSOLE_USER
                      requested_at: '2026-10-13T09:15:00Z'
                      applied_at: '2026-10-13T09:15:00Z'
                      cancelled_at: null
                      cancel_reason: null
                Waiting For The Flow:
                  summary: >-
                    defer_until_flow_finishes mientras la persona sigue en el
                    flujo
                  value:
                    session_id: 3fa85f64-5717-4562-b3fc-2c963f66afa6
                    node_id: feature_liveness_1
                    feature_type: Face
                    new_status: Declined
                    override:
                      id: 9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3
                      node_id: feature_liveness_1
                      feature_type: ''
                      feature_model: Face
                      previous_status: Declined
                      new_status: Approved
                      state: pending_until_flow_finishes
                      forced: false
                      reason: Liveness retried with a reviewer present.
                      requested_by:
                        email: reviewer@example.com
                        name: Alex Reviewer
                        type: CONSOLE_USER
                      requested_at: '2026-10-13T09:15:00Z'
                      applied_at: null
                      cancelled_at: null
                      cancel_reason: null
        '400':
          description: >-
            Error de validación. Se devuelve cuando `new_status` no es válido o
            no cambia, cuando `feature_type` es desconocido o cuando la sesión
            es una sesión de API independiente.
          content:
            application/json:
              examples:
                Same Status:
                  summary: new_status es igual al estado actual
                  value:
                    new_status:
                      - The new status is the same as the current status.
                API Session:
                  summary: >-
                    El estado de la función no se puede cambiar en las sesiones
                    de API independientes
                  value:
                    - Cannot change feature status for API sessions.
                Unknown feature_type:
                  summary: feature_type no es un tipo de paso conocido
                  value:
                    feature_type:
                      - Unknown feature_type 'SELFIE'.
        '401':
          description: La clave de API con alcance limitado ha expirado.
          content:
            application/json:
              examples:
                Expired API Key:
                  summary: >-
                    Clave de API con alcance limitado con la fecha de caducidad
                    vencida
                  value:
                    detail: This API key has expired.
        '403':
          description: Faltan las credenciales o los permisos son insuficientes.
          content:
            application/json:
              examples:
                Invalid Credentials:
                  summary: x-api-key ausente o no válido
                  value:
                    detail: >-
                      Authentication credentials were not provided or are
                      invalid.
                Missing Privilege:
                  summary: La clave de API no tiene el permiso write:sessions
                  value:
                    detail: You do not have permission to perform this action.
                Scoped Key Without Access:
                  summary: >-
                    Clave de API con alcance limitado sin acceso de escritura a
                    las decisiones
                  value:
                    detail: This API key has no write access to decisions.
        '404':
          description: >-
            No se encontró la sesión, o no tiene ninguna función con el `nodeId`
            indicado.
          content:
            application/json:
              examples:
                Session Not Found:
                  summary: session_id desconocido
                  value:
                    detail: Session not found.
                Feature Not Found:
                  summary: No hay ninguna función para este node_id
                  value:
                    detail: >-
                      No feature found with node_id 'feature_ocr_1' in this
                      session.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X PATCH \
              https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/features/feature_ocr_1/update-status/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "new_status": "Approved",
                "comment": "Document manually verified by compliance."
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.sessions.update_feature_status(
                "11111111-2222-3333-4444-555555555555",
                "feature_ocr_1",
                new_status="Approved",
                comment="Document manually verified by compliance.",
            )
            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.updateFeatureStatus(
              "11111111-2222-3333-4444-555555555555",
              "feature_ocr_1",
              {
                new_status: "Approved",
                comment: "Document manually verified by compliance.",
              },
            );
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateFeatureStatus(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", didit.SessionsUpdateFeatureStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"Document manually verified by compliance.\"),\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.SessionsUpdateFeatureStatusParams;


            // Reads DIDIT_API_KEY.

            Didit client = new Didit();


            var result =
            client.sessions().updateFeatureStatus("11111111-2222-3333-4444-555555555555",
            "feature_ocr_1", SessionsUpdateFeatureStatusParams.builder()
                    .newStatus(SessionsUpdateFeatureStatusParams.NewStatus.of("Approved"))
                    .comment("Document manually verified by compliance.")
                    .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->updateFeatureStatus('11111111-2222-3333-4444-555555555555',
            'feature_ocr_1', [
                'new_status' => 'Approved',
                'comment' => 'Document manually verified by compliance.',
            ]);

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

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

            result = didit.sessions.update_feature_status(
              "11111111-2222-3333-4444-555555555555",
              "feature_ocr_1",
              new_status: "Approved",
              comment: "Document manually verified by compliance."
            )
            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.UpdateFeatureStatusAsync("11111111-2222-3333-4444-555555555555",
            "feature_ocr_1", new SessionsUpdateFeatureStatusParams

            {
                NewStatus = "Approved",
                Comment = "Document manually verified by compliance.",
            });

            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    FeatureStatusOverride:
      type: object
      description: >-
        Una modificación manual del estado de una comprobación (función)
        realizada con `PATCH
        /v3/session/{sessionId}/features/{nodeId}/update-status/`: qué cambia,
        si se aplicó o sigue a la espera de que la persona termine el flujo,
        quién la solicitó y por qué.
      required:
        - id
        - node_id
        - feature_type
        - feature_model
        - previous_status
        - new_status
        - state
        - forced
        - reason
        - requested_by
        - requested_at
        - applied_at
        - cancelled_at
        - cancel_reason
      properties:
        id:
          type: string
          format: uuid
          description: Identificador de la anulación. Pásalo al endpoint de cancelación.
          example: 7c9e6679-7425-40de-944b-e07fc1f90ae7
        node_id:
          type: string
          description: >-
            El nodo del flujo que indicó la solicitud (`default` para un paso
            sin nodo).
          example: feature_ocr_1
        feature_type:
          type: string
          description: >-
            El `feature_type` que se pasó en la solicitud, o una cadena vacía si
            no se pasó ninguno.
          example: ''
        feature_model:
          type: string
          description: >-
            El tipo de comprobación que se anuló, por ejemplo `KYC`, `Face`,
            `AML` o `GeolocationCheck`.
          example: KYC
        previous_status:
          type: string
          enum:
            - Not Finished
            - Approved
            - Declined
            - In Review
            - Resub Requested
          description: El estado de la comprobación cuando se solicitó la anulación manual.
          example: In Review
        new_status:
          type: string
          enum:
            - Approved
            - Declined
            - In Review
          description: El estado que establece la anulación.
          example: Approved
        state:
          type: string
          enum:
            - applied
            - pending_until_flow_finishes
            - cancelled
          description: >-
            `applied`: la comprobación tiene el nuevo estado.
            `pending_until_flow_finishes`: la anulación queda en espera y se
            aplica cuando la persona termina el flujo. `cancelled`: quedó en
            espera y nunca se aplicó (consulta `cancel_reason`).
          example: applied
        forced:
          type: boolean
          description: >-
            `true` cuando la anulación se aplicó de inmediato mientras la
            persona seguía en el flujo.
          example: false
        reason:
          type: string
          nullable: true
          description: El `comment` enviado con la solicitud, o `null`.
          example: Document manually verified by compliance.
        requested_by:
          type: object
          nullable: true
          description: Quién solicitó la anulación, o `null` cuando no se conoce.
          properties:
            email:
              type: string
              format: email
              nullable: true
              description: >-
                Correo electrónico del usuario de la consola, o `null` para las
                claves de API y el sistema.
              example: reviewer@example.com
            name:
              type: string
              nullable: true
              description: Nombre visible del solicitante, o `null`.
              example: Alex Reviewer
            type:
              type: string
              enum:
                - CONSOLE_USER
                - API_KEY
                - SYSTEM
              description: >-
                Quién hizo la solicitud: un usuario de la consola, una clave de
                API o la propia Didit.
              example: CONSOLE_USER
        requested_at:
          type: string
          format: date-time
          description: Fecha y hora en que se solicitó la anulación.
          example: '2026-10-13T09:15:00Z'
        applied_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Cuándo la comprobación adoptó el nuevo estado, o `null` mientras
            espera o una vez cancelada.
          example: '2026-10-13T09:15:00Z'
        cancelled_at:
          type: string
          format: date-time
          nullable: true
          description: Cuándo se canceló una anulación en espera, o `null`.
          example: null
        cancel_reason:
          type: string
          nullable: true
          enum:
            - cancelled_by_reviewer
            - replaced
            - check_changed
            - session_closed
            - null
          description: >-
            Por qué nunca se aplicó una anulación en espera, o `null`.
            `cancelled_by_reviewer`: se canceló con el endpoint de cancelación.
            `replaced`: una anulación más reciente sobre la misma comprobación
            la reemplazó. `check_changed`: la persona volvió a hacer la
            comprobación antes de terminar el flujo. `session_closed`: la sesión
            salió del flujo antes de que la persona lo terminara (abandonada,
            expirada o decidida a mitad del flujo).
          example: null
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        La clave de API de tu aplicación, que encontrarás en Developers -> API
        keys en la Business Console. La clave principal tiene acceso completo.
        Una clave con nombre puede tener un alcance limitado: ninguno, lectura o
        escritura por recurso, limitada a algunos flujos o a sesiones aprobadas,
        a una lista de direcciones IP y a una fecha de caducidad. 401 significa
        que la clave es incorrecta, se revocó o expiró; 403 significa que no se
        envió ninguna clave, que la clave no tiene acceso a este recurso o
        acción, o que la solicitud provino de una dirección fuera de su lista de
        IP; 404 en una ruta de sesión significa que la sesión está fuera de los
        flujos o estados de la clave. Una clave sin acceso a contenido
        multimedia recibe las URL de imágenes, videos y PDF como null, y una
        clave sin permiso de escritura en sesiones recibe los enlaces y tokens
        de sesión como null. Consulta https://docs.didit.me/console/api-keys.

````

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