> ## 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 Atualizar Estado de Funcionalidade: Aprovar/Recusar

> Com a Didit, aprove, recuse ou envie para revisão um único passo (OCR, Prova de vida, Correspondência facial, AML) agora ou após o fluxo.



Prompt de atualização do estado de funcionalidade
        Copiar o prompt para a área de transferência



      
      

\<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>



      
      

Colar em

## O que fazUma sessão de verificação é composta por funcionalidades (passos) individuais: ID/OCR, Prova de vida, Correspondência facial, AML, Comprovativo de morada, Telefone, e assim por diante.
Este endpoint permite definir o estado de **um** desses passos como `Approved`, `Declined` ou `In Review`.Use [update-status](https://docs.didit.me/pt/sessions-api/update-status.md) quando quiser aprovar, recusar ou reabrir a sessão inteira.
Use **este** endpoint quando quiser apenas registar uma decisão sobre um único passo, por exemplo para marcar o passo de Correspondência facial como `Declined` no seu próprio fluxo de revisão.Uma sessão que já tenha uma decisão mantém-na: só o passo muda.
Se a sessão ainda não tiver decisão e o fluxo estiver a aguardar precisamente este passo, a substituição conclui o passo, tal como aconteceria se este fosse concluído normalmente.
O fluxo avança, os passos seguintes são executados, e um nó de estado pode definir a decisão da sessão e disparar um webhook `status.updated`.## Direcionar um passo com `node_id`Nos fluxos baseados em grafo, cada passo tem um `node_id` (por exemplo `feature_ocr_1`, `feature_liveness_1`, `feature_aml_1`). Pode encontrá-los na [decisão da sessão](https://docs.didit.me/pt/sessions-api/retrieve-session.md): cada funcionalidade numa decisão V3 inclui o respetivo `node_id`.Nos fluxos **sem grafo (de passo único)**, a funcionalidade subjacente não tem ID de nó. Passe o valor literal `default` como `nodeId` para a direcionar.
Como nenhum passo deste tipo de fluxo tem ID de nó, passe também `feature_type` (por exemplo `LIVENESS`, `AML` ou `FACE_MATCH`) para indicar o passo pretendido.
Um `feature_type` desconhecido devolve `400`.## Aguardar até a pessoa concluir o fluxoPor defeito, a substituição aplica-se de imediato.
Se a pessoa ainda estiver a percorrer o fluxo, isso altera um passo de um fluxo que ainda está em execução; a substituição fica então registada com `forced: true`.Defina `defer_until_flow_finishes: true` para aguardar.
Enquanto a sessão estiver em `Not Started`, `In Progress` ou `Resubmitted` e a pessoa não tiver concluído o fluxo, a substituição fica guardada como `pending_until_flow_finishes`.
Aplica-se quando a pessoa concluir o fluxo, depois de o fluxo atingir a sua própria decisão.
Numa sessão cujo fluxo já terminou, aplica-se de imediato em qualquer dos casos.Uma substituição em espera é cancelada, em vez de aplicada, quando:- a pessoa refaz o passo antes de concluir o fluxo (`check_changed`),
- uma substituição mais recente no mesmo passo a substitui (`replaced`),
- a sessão sai do fluxo sem o concluir: abandonada, expirada ou decidida a meio do fluxo (`session_closed`),
- cancela a substituição com [Cancelar substituição de funcionalidade](https://docs.didit.me/pt/sessions-api/cancel-feature-override.md) (`cancelled_by_reviewer`).A `override` da resposta indica o que aconteceu: `state` é `applied` ou `pending_until_flow_finishes`, e `applied_at` fica definido quando for aplicada.
O `new_status` de nível superior é o estado guardado do passo, pelo que se mantém inalterado enquanto a substituição aguarda.
Use [Listar substituições de funcionalidades](https://docs.didit.me/pt/sessions-api/list-feature-overrides.md) para ver todas as substituições de uma sessão e se a pessoa ainda está no fluxo.## Suporte a KYC e KYBFunciona de forma idêntica para sessões de **Verificação de utilizadores (KYC)** e de **Verificação de empresas (KYB)**: a Didit resolve o `sessionId` em ambas. Os tipos de passo suportados incluem ID/OCR, Prova de vida, Correspondência facial, NFC, AML, Comprovativo de morada, Telefone, E-mail, Validação de base de dados, Questionário, e as verificações KYB de registo, documentos e pessoas-chave.> [!NOTE]
>
> As sessões de API autónomas (criadas através das APIs de verificação autónomas, `session_type = API`) não permitem alterar os estados individuais das funcionalidades: o endpoint devolve `400`.## Exemplos> [tab] Aprovar um passo
>
> ```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] Recusar o passo de Correspondência 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] Fluxo de passo único (nó predefinido)
>
> ```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] Aguardar que a pessoa conclua o fluxo
>
> ```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
>   }'
> ```## O que acontece após uma atualização- **Webhook**: um evento `data.updated` é disparado quando a substituição é aplicada, de imediato ou quando o fluxo termina. Nada é enviado enquanto aguarda ou quando é cancelada.
- **Atividade**: cada substituição fica registada na atividade da sessão como `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED` ou `FEATURE_OVERRIDE_CANCELLED`, com o autor (chave de API, utilizador ou o sistema, quando uma substituição em espera é aplicada). A entrada do pedido inclui o seu `comment` como motivo. No array `reviews` da [decisão da sessão](https://docs.didit.me/pt/sessions-api/retrieve-session.md) estas entradas aparecem com `new_status: null`, e a entrada do pedido tem o seu motivo em `comment`.
- **Decisão da sessão**: uma sessão que já tenha uma decisão mantém-na. Para alterar a decisão final, chame [update-status](https://docs.didit.me/pt/sessions-api/update-status.md) separadamente.## PermissãoRequer o privilégio `write:sessions`, com uma chave de API de cliente (`x-api-key`) ou um cabeçalho de autorização de utilizador.
Uma chave de API com âmbito limitado precisa de acesso de escrita às decisões.## Relacionados- [Atualizar estado da sessão](https://docs.didit.me/pt/sessions-api/update-status.md): altera a decisão geral da sessão.
- [Atualizar estado de correspondência AML](https://docs.didit.me/pt/sessions-api/update-aml-hit-status.md): revê correspondências AML individuais.
- [Obter sessão](https://docs.didit.me/pt/sessions-api/retrieve-session.md): obtém a decisão (e o `node_id` de cada funcionalidade).
- [Webhooks](https://docs.didit.me/pt/integration/webhooks.md): subscreva `data.updated`.
- [Listar substituições de funcionalidades](https://docs.didit.me/pt/sessions-api/list-feature-overrides.md): todas as substituições de uma sessão e o respetivo estado.
- [Cancelar substituição de funcionalidade](https://docs.didit.me/pt/sessions-api/cancel-feature-override.md): impede uma substituição em espera de ser aplicada.


## OpenAPI

````yaml pt/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 Verificação de identidade. Autentique-se com o cabeçalho x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/session/{sessionId}/features/{nodeId}/update-status/:
    patch:
      tags:
        - Sessions
      summary: Atualizar o estado de uma funcionalidade (passo) individual
      description: >-
        Defina o estado de uma única funcionalidade (passo) de verificação
        dentro de uma sessão. Indique a funcionalidade pelo respetivo `nodeId`
        do grafo de fluxo. Em fluxos sem grafo, cujos passos não têm nó, utilize
        `default` e passe também `feature_type` para indicar a que passo se
        refere.


        Funciona tanto para sessões de Verificação de utilizadores (KYC) como de
        Verificação de empresas (KYB) e para todos os tipos de passos: ID/OCR,
        Prova de vida, Correspondência facial, NFC, Triagem AML, Comprovativo de
        morada, Telefone, E-mail, Validação de base de dados, Questionário e as
        verificações de registo / documentos / pessoas-chave de KYB. Este
        endpoint **não** está disponível para sessões de API autónomas
        (`session_type = API`).


        `new_status` tem de ser `Approved`, `Declined` ou `In Review`, e tem de
        ser diferente do estado atual da funcionalidade.


        **Quando a sobreposição se aplica.** Sem `defer_until_flow_finishes` (ou
        com `false`), a sobreposição aplica-se imediatamente, como sempre
        aconteceu; quando a pessoa ainda se encontra no fluxo, é registada como
        `forced`. Com `defer_until_flow_finishes: true` enquanto a pessoa ainda
        se encontra no fluxo (a sessão está como `Not Started`, `In Progress` ou
        `Resubmitted` e não terminou), a sobreposição é guardada como
        `pending_until_flow_finishes` e aplica-se quando o fluxo terminar, após
        o fluxo atingir a sua própria decisão. Numa sessão cujo fluxo já
        terminou, aplica-se imediatamente de qualquer forma. Uma sobreposição
        pendente é cancelada se a pessoa repetir o respetivo passo antes de
        terminar, quando uma sobreposição mais recente na mesma verificação a
        substituir, quando a sessão deixar o fluxo inacabado (abandonada,
        expirada ou com decisão a meio do fluxo), ou quando a cancelar com `POST
        /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`. Liste
        as sobreposições de uma sessão com `GET
        /v3/session/{sessionId}/features/overrides/`.


        **Efeito na sessão.** Uma sessão que já tem uma decisão mantém-na:
        apenas a verificação é alterada. Quando a sessão ainda não tiver uma
        decisão e o respetivo fluxo estiver a aguardar exatamente por este
        passo, a aplicação da sobreposição conclui o passo: o fluxo avança, os
        passos posteriores são executados e um nó de estado pode definir a
        decisão da sessão e acionar `status.updated`.


        **Webhooks e atividade.** Um webhook `data.updated` é acionado quando a
        sobreposição é aplicada (imediatamente ou quando o fluxo termina), nunca
        enquanto aguarda nem quando é cancelada. Cada sobreposição é registada
        na atividade da sessão como `FEATURE_OVERRIDE_PENDING`,
        `FEATURE_OVERRIDE_APPLIED` ou `FEATURE_OVERRIDE_CANCELLED`, com a
        indicação de quem a realizou; o registo do pedido inclui o seu
        `comment`.


        Autentique-se com a sua chave de API (`x-api-key`) ou com um cabeçalho
        de autorização de utilizador com o privilégio `write:sessions`; uma
        chave de API com âmbito limitado necessita de acesso de escrita a
        decisões.
      operationId: patch_v3_session_update_feature_status
      parameters:
        - in: path
          name: sessionId
          required: true
          description: >-
            UUID da sessão de verificação. Aceita IDs de sessão de utilizador
            (KYC) e de empresa (KYB) — o serviço resolve o ID em ambos os tipos
            de sessão.
          schema:
            type: string
            format: uuid
            example: 11111111-2222-3333-4444-555555555555
        - in: path
          name: nodeId
          required: true
          description: >-
            ID do nó do grafo do fluxo da funcionalidade a atualizar (por
            exemplo, `feature_ocr_1`). Utilize o valor literal `default` para
            fluxos que não utilizem grafos (passo único), onde a funcionalidade
            não tem ID de nó.
          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 funcionalidade. Deve diferir do
                    valor atual.
                  enum:
                    - Approved
                    - Declined
                    - In Review
                  example: Approved
                comment:
                  type: string
                  description: >-
                    Nota de texto livre opcional registada no histórico de
                    revisão da sessão para esta alteração de funcionalidade.
                  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: >-
                    Qual o tipo de passo a definir como alvo. Necessário em
                    fluxos sem grafo (`nodeId` = `default`), onde nenhum passo
                    partilha nós; caso contrário, é opcional. Um valor
                    desconhecido devolve `400`.
                  example: LIVENESS
                defer_until_flow_finishes:
                  type: boolean
                  default: false
                  description: >-
                    Enquanto a pessoa ainda estiver no fluxo, armazene a
                    substituição como `pending_until_flow_finishes` e aplique-a
                    quando o fluxo terminar, em vez de imediatamente. Omitido ou
                    `false`, a substituição é aplicada imediatamente. Numa
                    sessão cujo fluxo já terminou, aplica-se imediatamente de
                    qualquer forma.
                  example: false
            examples:
              Apply Now:
                summary: Aprovar imediatamente o passo de ID
                value:
                  new_status: Approved
                  comment: Document manually verified by compliance.
              Wait For The Flow:
                summary: >-
                  Aprovar o passo de prova de vida assim que a pessoa concluir o
                  fluxo
                value:
                  new_status: Approved
                  comment: Liveness retried with a reviewer present.
                  defer_until_flow_finishes: true
              Non-graph Workflow:
                summary: >-
                  Direcionar para o passo de prova de vida de um fluxo sem nós
                  (nodeId = default)
                value:
                  new_status: In Review
                  feature_type: LIVENESS
      responses:
        '200':
          description: >-
            A substituição foi registada. `new_status` é o estado da verificação
            conforme armazenado: o solicitado assim que a substituição for
            aplicada, ou o estado inalterado enquanto aguarda a conclusão do
            fluxo. `override` indica o que ocorreu.
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_id:
                    type: string
                    format: uuid
                  node_id:
                    type: string
                    nullable: true
                    description: >-
                      O nó de fluxo do passo atualizado, ou `null` para um passo
                      sem nó (o caminho `default` num fluxo sem grafo).
                    example: feature_ocr_1
                  feature_type:
                    type: string
                    description: >-
                      Nome do modelo da funcionalidade atualizada (p. ex.,
                      `KYC`, `Face`, `FaceMatch`, `AML`, `POA`).
                    example: KYC
                  new_status:
                    type: string
                    description: >-
                      O estado armazenado da verificação: o solicitado assim que
                      a substituição for aplicada, e o estado inalterado
                      enquanto a substituição aguarda que o fluxo termine.
                    example: Approved
                  override:
                    $ref: '#/components/schemas/FeatureStatusOverride'
                required:
                  - session_id
                  - node_id
                  - feature_type
                  - new_status
                  - override
              examples:
                Applied:
                  summary: A substituição foi aplicada imediatamente
                  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 enquanto a pessoa ainda se
                    encontra no fluxo
                  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: >-
            Erro de validação. Devolvido quando `new_status` é inválido ou
            inalterado, quando `feature_type` é desconhecido ou quando a sessão
            é uma sessão de API autónoma.
          content:
            application/json:
              examples:
                Same Status:
                  summary: new_status é igual ao estado atual
                  value:
                    new_status:
                      - The new status is the same as the current status.
                API Session:
                  summary: >-
                    O estado da funcionalidade não pode ser alterado em sessões
                    de API autónomas
                  value:
                    - Cannot change feature status for API sessions.
                Unknown feature_type:
                  summary: feature_type não é um tipo de passo conhecido
                  value:
                    feature_type:
                      - Unknown feature_type 'SELFIE'.
        '401':
          description: A chave de API com âmbito expirou.
          content:
            application/json:
              examples:
                Expired API Key:
                  summary: Chave de API com âmbito cuja data de validade já passou
                  value:
                    detail: This API key has expired.
        '403':
          description: Credenciais em falta ou permissões insuficientes.
          content:
            application/json:
              examples:
                Invalid Credentials:
                  summary: x-api-key em falta ou inválido
                  value:
                    detail: >-
                      Authentication credentials were not provided or are
                      invalid.
                Missing Privilege:
                  summary: A chave de API não tem write:sessions
                  value:
                    detail: You do not have permission to perform this action.
                Scoped Key Without Access:
                  summary: Chave de API com âmbito sem acesso de escrita a decisões
                  value:
                    detail: This API key has no write access to decisions.
        '404':
          description: >-
            A sessão não foi encontrada ou não tem nenhuma funcionalidade com o
            `nodeId` indicado.
          content:
            application/json:
              examples:
                Session Not Found:
                  summary: session_id desconhecido
                  value:
                    detail: Session not found.
                Feature Not Found:
                  summary: Nenhuma funcionalidade 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: >-
        Uma sobreposição do estado de uma verificação (funcionalidade) efetuada
        com `PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/`: o
        que altera, se foi aplicada ou se ainda aguarda que a pessoa conclua o
        fluxo, quem solicitou e porquê.
      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 da substituição. Transmita-o para o endpoint de
            cancelamento.
          example: 7c9e6679-7425-40de-944b-e07fc1f90ae7
        node_id:
          type: string
          description: O nó do fluxo indicado pelo pedido (`default` para um passo sem nó).
          example: feature_ocr_1
        feature_type:
          type: string
          description: >-
            O `feature_type` transmitido pelo pedido, ou uma string vazia se
            nenhum tiver sido transmitido.
          example: ''
        feature_model:
          type: string
          description: >-
            O tipo de verificação que foi substituído, por exemplo `KYC`,
            `Face`, `AML` ou `GeolocationCheck`.
          example: KYC
        previous_status:
          type: string
          enum:
            - Not Finished
            - Approved
            - Declined
            - In Review
            - Resub Requested
          description: O estado da verificação quando a substituição foi solicitada.
          example: In Review
        new_status:
          type: string
          enum:
            - Approved
            - Declined
            - In Review
          description: O estado definido pela sobreposição.
          example: Approved
        state:
          type: string
          enum:
            - applied
            - pending_until_flow_finishes
            - cancelled
          description: >-
            `applied`: a verificação tem o novo estado.
            `pending_until_flow_finishes`: a substituição aguarda e é aplicada
            quando a pessoa terminar o fluxo. `cancelled`: aguardou e nunca foi
            aplicada (consulte `cancel_reason`).
          example: applied
        forced:
          type: boolean
          description: >-
            `true` quando a substituição foi aplicada de imediato enquanto a
            pessoa ainda estava no fluxo.
          example: false
        reason:
          type: string
          nullable: true
          description: O `comment` enviado com o pedido, ou `null`.
          example: Document manually verified by compliance.
        requested_by:
          type: object
          nullable: true
          description: Quem solicitou a substituição, ou `null` quando não for conhecido.
          properties:
            email:
              type: string
              format: email
              nullable: true
              description: >-
                E-mail do utilizador da consola, ou `null` para chaves de API e
                para o sistema.
              example: reviewer@example.com
            name:
              type: string
              nullable: true
              description: Nome de apresentação do requerente, ou `null`.
              example: Alex Reviewer
            type:
              type: string
              enum:
                - CONSOLE_USER
                - API_KEY
                - SYSTEM
              description: >-
                Quem fez o pedido: um utilizador da consola, uma chave de API ou
                a própria Didit.
              example: CONSOLE_USER
        requested_at:
          type: string
          format: date-time
          description: Quando a substituição foi solicitada.
          example: '2026-10-13T09:15:00Z'
        applied_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Quando a verificação assumiu o novo estado, ou `null` enquanto
            aguarda ou assim que for cancelada.
          example: '2026-10-13T09:15:00Z'
        cancelled_at:
          type: string
          format: date-time
          nullable: true
          description: Quando uma substituição em espera foi cancelada, ou `null`.
          example: null
        cancel_reason:
          type: string
          nullable: true
          enum:
            - cancelled_by_reviewer
            - replaced
            - check_changed
            - session_closed
            - null
          description: >-
            O motivo pelo qual uma sobreposição pendente nunca foi aplicada, ou
            `null`. `cancelled_by_reviewer`: cancelada com o endpoint de
            cancelamento. `replaced`: uma sobreposição mais recente na mesma
            verificação substituiu-a. `check_changed`: a pessoa repetiu a
            verificação antes de concluir o fluxo. `session_closed`: a sessão
            saiu do fluxo antes de a pessoa o concluir (abandonada, expirada ou
            decidida a meio do fluxo).
          example: null
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        A chave de API da sua aplicação, a partir de Programadores -> Chaves de
        API na Business Console. A chave principal tem acesso total. Uma chave
        nomeada pode ter o âmbito definido: nenhum, leitura ou escrita por
        recurso, limitada a alguns fluxos ou a sessões aprovadas, a uma lista de
        endereços IP e a uma data de validade. 401 significa que a chave está
        incorreta, revogada ou expirada; 403 significa que nenhuma chave foi
        enviada, que a chave não tem acesso a este recurso ou ação, ou que o
        pedido veio de um endereço fora da sua lista de IP; 404 numa rota de
        sessão significa que a sessão está fora dos fluxos ou estados da chave.
        Uma chave sem acesso a multimédia recebe URLs de imagens, vídeos e PDFs
        como nulos, e uma chave sem permissão de escrita em sessões recebe
        ligações de sessão e tokens como nulos. Consulte
        https://docs.didit.me/console/api-keys.

````

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