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

# Estados de verificação: ciclo de vida da sessão e códigos

> Estados de sessão da Didit explicados: aprovada, recusada, em análise, expirada, reenviada, abandonada e KYC expirado. Trate decisões e webhooks.

Cada sessão de verificação passa por uma série de estados. Compreendê-los ajuda-o a acompanhar o progresso do utilizador, automatizar decisões de conformidade e otimizar a conversão.

Este enum é a única fonte de verdade para as strings devolvidas por `GET /v3/session/<id>/decision/` e por todos os webhooks da Didit.

***

## Todos os valores de estado

> [!NOTE]
>
> Cada estado é uma **string exata** devolvida pela API e pelos webhooks da Didit. Use sempre a comparação estrita de strings (por exemplo, `=== "In Review"`) no seu código: estes valores diferenciam maiúsculas de minúsculas e incluem espaços. O valor `Kyc Expired` também usa um `K` maiúsculo único (e não `KYC`).

| Estado | Valor da string | Descrição |
| - | - | - |
| Não iniciada | `"Not Started"` | Sessão criada, o utilizador ainda não abriu a ligação |
| Em curso | `"In Progress"` | O utilizador está ativamente a concluir a verificação |
| Aprovada | `"Approved"` | Todas as verificações foram aprovadas: identidade verificada |
| Recusada | `"Declined"` | Uma ou mais verificações falharam |
| Em análise | `"In Review"` | Sinalizada para revisão manual de conformidade |
| Aguarda utilizador | `"Awaiting User"` | A aguardar que uma ou mais partes concluam a sua verificação (KYB) |
| Reenviada | `"Resubmitted"` | Pediu-se ao utilizador que repetisse passos específicos |
| Expirada | `"Expired"` | A sessão expirou antes de o utilizador abrir a ligação |
| Abandonada | `"Abandoned"` | O utilizador iniciou a sessão mas não a concluiu a tempo |
| KYC expirado | `"Kyc Expired"` | Sessão aprovada anteriormente cujo documento verificado ultrapassou a data de validade |

***

## Estados da sessão

> [accordion] Não iniciada — "Not Started"
>
> **Valor na API:** `"Not Started"`
>
> A sessão foi criada através da API, mas o utilizador **ainda não abriu a ligação de verificação**.
>
> * **O que fazer:** Aguardar que o utilizador comece ou enviar um lembrete se passar demasiado tempo.
> * **Transita para:** `"In Progress"`, `"Expired"`

> [accordion] Em curso — "In Progress"
>
> **Valor na API:** `"In Progress"`
>
> O utilizador abriu a ligação e está **a concluir os passos de verificação do fluxo** (captura do documento, prova de vida, etc.).
>
> * **O que fazer:** Não é necessária qualquer ação — o utilizador está a seguir o fluxo.
> * **Transita para:** `"Approved"`, `"Declined"`, `"In Review"`, `"Abandoned"`

> [accordion] Aprovada — "Approved"
>
> **Valor na API:** `"Approved"`
>
> Todas as verificações foram **concluídas com êxito**. A identidade do utilizador foi verificada.
>
> * **O que fazer:** Conceder acesso ao utilizador, atualizar o respetivo perfil e guardar os dados da decisão.
> * **O webhook inclui:** O objeto `decision` completo com os resultados de todas as funcionalidades.
> * **Transita para:** `"Kyc Expired"` (quando a data de validade do documento verificado é ultrapassada, salvo se o **Expiration mode** estiver definido como **Allow expired** para esse país e tipo de documento; **Reject expired** é o valor predefinido). Um revisor ou o endpoint de atualização de estado também pode defini-la como `"Declined"` ou `"Resubmitted"`.

> [accordion] Recusada — "Declined"
>
> **Valor na API:** `"Declined"`
>
> Uma ou mais verificações **falharam**. O utilizador não passou na verificação.
>
> * **O que fazer:** Notificar o utilizador. Opcionalmente, pedir uma nova submissão se o problema puder ser corrigido.
> * **O webhook inclui:** O objeto `decision` completo com os avisos que explicam a falha.
> * **Transita para:** `"Resubmitted"` (se um revisor o pedir). Um revisor ou o endpoint de atualização de estado também pode defini-la como `"Approved"`.

> [accordion] Em análise — "In Review"
>
> **Valor na API:** `"In Review"`
>
> As verificações automáticas sinalizaram **avisos que precisam de revisão humana**. Um revisor de conformidade tem de tomar a decisão final.
>
> * **O que fazer:** Um revisor deve abrir a sessão na Console e aprovar, recusar ou pedir uma nova submissão.
> * **O webhook inclui:** O objeto `decision` completo com os avisos.
> * **Transita para:** `"Approved"`, `"Declined"`, `"Resubmitted"`

> [accordion] A aguardar utilizador — "Awaiting User"
>
> **Valor na API:** `"Awaiting User"`
>
> Usado em **sessões KYB (verificação de empresas)** quando o passo de pessoas-chave submeteu a lista de partes e criou sessões KYC / KYB filhas. A sessão principal aguarda até que **todas as partes obrigatórias concluam a respetiva verificação individual**.
>
> * **O que fazer:** Acompanhar os estados das sessões KYC filhas. Quando todas as partes obrigatórias terminarem (aprovadas, recusadas ou expiradas), a sessão principal recalcula automaticamente o seu estado final.
> * **O webhook inclui:** A lista atual de partes e os estados das respetivas sessões filhas.
> * **Transita para:** `"Approved"`, `"Declined"`, `"In Review"` (quando todas as sessões filhas estiverem em estado terminal)
> * **Transita de:** `"In Progress"` (depois de submetido o passo de pessoas-chave)
> * **Nota:** Se uma sessão KYC filha for submetida novamente, a sessão principal volta a `"Awaiting User"` até que a sessão submetida novamente seja concluída. Uma KYB Registry Check com estado `"Declined"` tem prioridade sobre `"Awaiting User"`.

> [accordion] Submetida novamente — "Resubmitted"
>
> **Valor na API:** `"Resubmitted"`
>
> Um revisor pediu que o utilizador **refaça passos específicos de verificação** (por exemplo, tirar outra fotografia desfocada do documento).
>
> * **O que fazer:** Aguardar que o utilizador conclua os passos cuja repetição foi solicitada. O sistema reavaliará automaticamente.
> * **O webhook inclui:** O objeto `resubmit_info` com a lista de funcionalidades a repetir e os motivos.
> * **Transita para:** `"Approved"`, `"Declined"`, `"In Review"`, ou `"Abandoned"` quando a janela da sessão terminar antes de a pessoa refazer os passos.

> [accordion] Expirada — "Expired"
>
> **Valor na API:** `"Expired"`
>
> A sessão **expirou antes de o utilizador abrir a ligação de verificação**.
>
> * **O que fazer:** Criar uma nova sessão e enviar ao utilizador uma ligação nova.
> * **Estado terminal**, sem transições seguintes.

> [accordion] Abandonada — "Abandoned"
>
> **Valor na API:** `"Abandoned"`
>
> O utilizador **iniciou mas não concluiu** a verificação dentro do prazo permitido.
>
> * **O que fazer:** Enviar um lembrete ou criar uma nova sessão.
> * **Sem transições automáticas.** Um revisor, ou `PATCH /v3/session/{sessionId}/update-status/`, pode ainda defini-la como `"Approved"`, `"Declined"` ou `"Resubmitted"`.

> [accordion] KYC expirado — "Kyc Expired"
>
> **Valor na API:** `"Kyc Expired"`
>
> O documento verificado durante a sessão **ultrapassou a respetiva data de validade**. O acionador é essa data, e não um prazo contado a partir da aprovação, e não é enviado nenhum aviso prévio.
>
> * **O que fazer:** Pedir ao utilizador que se verifique novamente com uma nova sessão. `status.updated` transmite a transição, e o resultado da verificação de identidade inclui um aviso `DOCUMENT_EXPIRED`.
> * **Controlado por:** o **Expiration mode** desse país e tipo de documento em *ID verification → Additional settings by country & document type*. **Reject expired** (o valor predefinido) monitoriza o documento; **Allow expired** significa que a sessão nunca transita para este estado.
> * **Sem transições automáticas.** Um revisor, ou `PATCH /v3/session/{sessionId}/update-status/`, pode ainda defini-la como `"Approved"`, `"Declined"` ou `"Resubmitted"`.

***

## Transições de estado

| De | Para | Acionador |
| - | - | - |
| `"Not Started"` | `"In Progress"` | O utilizador abre a ligação de verificação |
| `"Not Started"` | `"Expired"` | O TTL da sessão expira antes de o utilizador abrir a ligação |
| `"In Progress"` | `"Approved"` | Todas as verificações automáticas passam |
| `"In Progress"` | `"Declined"` | Uma ou mais verificações falham |
| `"In Progress"` | `"In Review"` | As verificações assinalam avisos que exigem revisão humana |
| `"In Progress"` | `"Awaiting User"` | Passo de pessoas-chave KYB submetido; a sessão principal aguarda as partes KYC filhas |
| `"In Progress"` | `"Abandoned"` | O utilizador não conclui dentro do prazo |
| `"Awaiting User"` | `"Approved"` | Todas as partes KYB obrigatórias concluem e as verificações agregadas são aprovadas |
| `"Awaiting User"` | `"Declined"` | Uma parte obrigatória é recusada ou a verificação no registo de empresas falha |
| `"Awaiting User"` | `"In Review"` | O resultado KYB agregado exige revisão manual |
| `"In Review"` | `"Approved"` | O revisor aprova manualmente |
| `"In Review"` | `"Declined"` | O revisor recusa manualmente |
| `"In Review"` | `"Resubmitted"` | O revisor solicita que determinados passos sejam refeitos |
| `"Declined"` | `"Resubmitted"` | O revisor solicita que determinados passos sejam refeitos |
| `"Approved"` | `"Resubmitted"` | O revisor solicita que determinados passos sejam refeitos |
| `"Approved"` | `"Declined"` | O revisor ou a API define a decisão contrária |
| `"Declined"` | `"Approved"` | O revisor ou a API define a decisão contrária |
| `"Abandoned"`, `"Kyc Expired"` | `"Approved"`, `"Declined"`, `"Resubmitted"` | O revisor ou a API toma uma decisão sobre uma sessão que terminou sem decisão |
| `"Resubmitted"` | `"Abandoned"` | A janela da sessão termina antes de a pessoa refazer os passos |
| `"Resubmitted"` | `"Approved"` | Os passos reenviados são aprovados em todas as verificações |
| `"Resubmitted"` | `"Declined"` | Os passos reenviados falham |
| `"Resubmitted"` | `"In Review"` | Os passos reenviados assinalam novos avisos |
| `"Resubmitted"` (filho KYB) | `"Awaiting User"` (pai KYB) | O pai volta ao estado de espera até o filho concluir |
| `"Approved"` | `"Kyc Expired"` | A data de validade do documento verificado é ultrapassada (o modo de expiração é **Reject expired**) |

### Diagrama do ciclo de vida

```mermaid theme={null}
flowchart LR
    NS["Not Started"] --> IP["In Progress"]
    NS --> EX["Expired"]
    IP --> AP["Approved"]
    IP --> DC["Declined"]
    IP --> IR["In Review"]
    IP --> AU["Awaiting User<br/>(KYB only)"]
    IP --> AB["Abandoned"]
    AU --> AP
    AU --> DC
    AU --> IR
    IR --> AP
    IR --> DC
    IR --> RS["Resubmitted"]
    DC --> RS
    AP --> RS
    AP <--> DC
    AB --> AP
    AB --> DC
    AB --> RS
    KE --> AP
    KE --> DC
    KE --> RS
    RS --> AB
    RS --> AP
    RS --> DC
    RS --> IR
    AP --> KE["Kyc Expired"]
```

***

## Terminal vs. não terminal

| Categoria | Estados | Significado |
| - | - | - |
| **Decidido** | `"Approved"`, `"Declined"`, `"Kyc Expired"` | As verificações produziram uma decisão, e nada a altera por si só, exceto a passagem de `"Approved"` para `"Kyc Expired"` quando a data de validade do documento verificado é ultrapassada. Um revisor ou o endpoint de atualização do estado ainda pode alterar a decisão. |
| **Não terminal** | `"Not Started"`, `"In Progress"`, `"Resubmitted"`, `"Awaiting User"` | Ainda ativo, a aguardar ação do utilizador, sessões filhas ou processamento. |
| **Acionável** | `"In Review"` | Requer intervenção manual da sua equipa. |
| **Inativo** | `"Expired"`, `"Abandoned"` | Terminou sem uma decisão de verificação. `"Expired"` nunca muda; um revisor ainda pode decidir uma sessão `"Abandoned"`. |

***

## Tratamento dos estados no seu código

Use webhooks ou a [API de obtenção de sessão](https://docs.didit.me/pt/sessions-api/retrieve-session.md) para reagir às alterações de estado.

> [!WARNING]
>
> Os estados são **cadeias de caracteres exatas, sensíveis a maiúsculas e minúsculas, com espaços**. Por exemplo, `"In Review"` (e não `"in_review"` ou `"IN_REVIEW"`). Use sempre a igualdade estrita (`===`) ao comparar.

```javascript theme={null}
// All ten possible status string values (StatusChoices, source of truth):
// "Not Started"  | "In Progress" | "Approved"     | "Declined" |
// "In Review"    | "Resubmitted" | "Awaiting User"|
// "Expired"      | "Abandoned"   | "Kyc Expired"

async function handleWebhook(webhook) {
  const { status, vendor_data: vendorData } = webhook;

  switch (status) {
    case "Not Started":
      // Session created but user hasn't opened the link yet
      break;

    case "In Progress":
      // User is actively completing verification steps
      break;

    case "Approved":
      // All checks passed — grant access
      await db.users.update(vendorData, {
        verified: true,
        verifiedAt: new Date(),
        decision: webhook.decision,
      });
      break;

    case "Declined":
      // Verification failed — notify user
      await db.users.update(vendorData, {
        verificationStatus: "declined",
        declineReasons: webhook.decision?.warnings,
      });
      break;

    case "In Review":
      // Needs manual review by compliance team
      await db.users.update(vendorData, {
        verificationStatus: "pending_review",
      });
      break;

    case "Awaiting User":
      // KYB parent waiting for all child KYC parties to finish
      await db.users.update(vendorData, {
        verificationStatus: "awaiting_kyb_parties",
      });
      break;

    case "Resubmitted":
      // User will redo specific steps
      await db.users.update(vendorData, {
        verificationStatus: "resubmission_pending",
        resubmitInfo: webhook.resubmit_info,
      });
      break;

    case "Abandoned":
      // User started but didn't finish — send reminder
      await sendReminderEmail(vendorData);
      break;

    case "Expired":
    case "Kyc Expired":
      // Session expired — create a new one
      await createNewSession(vendorData);
      break;
  }
}
```

***

## Reenvio

O estado **Resubmitted** permite à sua equipa de conformidade dar uma segunda oportunidade aos utilizadores sem criar uma nova sessão.

**1. O revisor inicia o reenvio**

Na Consola, abra uma sessão `In Review` ou `Declined` e clique em **Solicitar Reenvio**. Selecione os passos que devem ser refeitos.

**2. Os dados anteriores são arquivados**

O sistema repõe as funcionalidades selecionadas e marca os dados anteriores como `previous_attempt`, preservando o registo de auditoria completo.

**3. O utilizador é notificado**

Se existir um e-mail, o utilizador recebe um e-mail localizado com uma ligação direta para retomar.

**4. O utilizador refaz passos específicos**

O utilizador repete apenas os passos assinalados, e não toda a verificação.

**5. O sistema reavalia**

Quando concluir, a sessão transita automaticamente para `"Approved"`, `"Declined"` ou `"In Review"`.

### Payload do webhook de reenvio

```json theme={null}
{
  "session_id": "uuid-of-the-session",
  "status": "Resubmitted",
  "resubmit_info": {
    "nodes_to_resubmit": [
      { "node_id": "feature_ocr", "feature": "OCR" },
      { "node_id": "feature_liveness", "feature": "LIVENESS" }
    ],
    "reasons": {
      "feature_ocr": "DOCUMENT_EXPIRED",
      "feature_liveness": "LOW_LIVENESS_SCORE"
    }
  }
}
```

`reasons` associa cada `node_id` reenviado ao código de aviso do registo mais relevante desse passo (os mesmos códigos que a [decisão](https://docs.didit.me/pt/reference/data-models.md) apresenta), para que possa mapeá-lo para o seu próprio texto. É também o código que o ecrã de reenvio do fluxo alojado e o e-mail de reenvio localizam para o utilizador, exceto nos avisos que revelariam um sinal de triagem ou de fraude (duplicados, AML, lista de bloqueio, verificações entre organizações, integridade da localização e similares): nesses casos, a pessoa vê um motivo genérico, e `resubmit_info.reasons` no seu webhook contém sempre o código real. Um passo sem aviso registado não tem entrada.

### Que funcionalidades podem ser reenviadas

Qualquer funcionalidade com um estado não aprovado: **Declined**, **In Review**, **Not Finished**, **Not Started** ou **Expired**.

> [!TIP]
>
> Pode solicitar o reenvio várias vezes na mesma sessão. Cada ciclo arquiva os dados da tentativa anterior, dando-lhe visibilidade completa do histórico de verificação do utilizador.

***

## Melhores práticas

> [card] Monitorizar sessões em análise
>
> Configure alertas (e-mail ou Slack) na sua Didit Console para ser notificado quando as sessões precisarem de revisão manual.

> [card] Preferir o reenvio
>
> Se o problema puder ser corrigido (foto desfocada, lado errado do documento), peça um reenvio em vez de recusar. Isto melhora a taxa de conversão.

> [card] Acompanhar os abandonos
>
> Taxas elevadas de sessões abandonadas ou expiradas podem indicar atrito na experiência do utilizador. Considere ajustar o TTL da sessão ou melhorar as instruções ao utilizador.

> [card] Processadores idempotentes
>
> Os webhooks podem ser reenviados. Use `session_id` como chave única para garantir que processa cada alteração de estado apenas uma vez.

> [!WARNING]
>
> Valide sempre as assinaturas dos webhooks antes de processar os payloads. A Didit disponibiliza três métodos: `X-Signature`, `X-Signature-V2` (recomendado) e o `X-Signature-Simple`, descontinuado, que autentica apenas o envelope e nunca o corpo `decision`. Consulte [Webhooks](https://docs.didit.me/pt/integration/webhooks.md#verificação-da-assinatura) para mais detalhes.


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