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

# Eventos

> Os sete eventos da jornada: quando cada um dispara e o que carrega.

Sete eventos, na ordem da jornada. Você escolhe quais receber ao
[cadastrar o endpoint](/platform/webhooks).

| Evento                                         | Dispara quando                          | Corpo extra    |
| ---------------------------------------------- | --------------------------------------- | -------------- |
| `verification.created`                         | o seu backend criou a verificação       | não            |
| `verification.started`                         | a pessoa abriu o link e começou         | não            |
| `verification.document_submitted`              | a pessoa enviou uma imagem de documento | não            |
| `verification.document_processed`              | a análise do documento terminou         | não            |
| `verification.liveness_settled`                | a prova de vida chegou a um desfecho    | não            |
| [`verification.decided`](#verificationdecided) | a verificação chegou ao desfecho final  | `verification` |
| [`verification.scored`](#verificationscored)   | o score ficou pronto                    | `score`        |

## Envelope

Todo evento chega na mesma forma. Nenhum dado da pessoa atravessa o webhook.

<CodeGroup>
  ```json title="Corpo" theme={null}
  {
    "id": "019f0000-0000-7000-8000-000000000001",
    "event": "verification.started",
    "occurred_at": "2026-09-14T17:30:00.000Z",
    "tenant_public_id": "019f0000-0000-7000-8000-000000000002",
    "resource": {
      "type": "verification",
      "public_id": "019f0000-0000-7000-8000-000000000000"
    }
  }
  ```

  ```http title="Headers" theme={null}
  Content-Type: application/json
  User-Agent: Legitimuz-Webhooks/1.0
  X-Legitimuz-Event: verification.started
  X-Legitimuz-Delivery: 019f0000-0000-7000-8000-000000000001
  X-Legitimuz-Attempt: 1
  X-Legitimuz-Signature: t=1757865000,v1=5f2c8a1e...
  ```
</CodeGroup>

| Campo                | O que é                                                            |
| -------------------- | ------------------------------------------------------------------ |
| `id`                 | o identificador da entrega, igual ao header `X-Legitimuz-Delivery` |
| `event`              | o nome do evento. Nunca muda; evento novo entra por adição         |
| `occurred_at`        | quando o evento aconteceu, em ISO 8601 UTC                         |
| `tenant_public_id`   | a conta dona do recurso                                            |
| `resource.public_id` | o `public_id` da verificação                                       |

Campos novos podem aparecer. Não valide com schema que rejeita desconhecidos.

## Eventos sem corpo extra

Chegam só com o envelope. Servem para acompanhar o progresso da jornada.

<ResponseField name="verification.created" type="evento">
  O seu backend chamou [`POST /public/verifications`](/api/create-verification) com sucesso. A
  pessoa ainda não abriu nada.
</ResponseField>

<ResponseField name="verification.started" type="evento">
  A pessoa abriu a verificação e a primeira etapa carregou. O status passa a `started`.
</ResponseField>

<ResponseField name="verification.document_submitted" type="evento">
  Uma imagem de documento foi enviada. Frente e verso disparam duas vezes. Não traz resultado: a
  análise é assíncrona e termina em `verification.document_processed`.
</ResponseField>

<ResponseField name="verification.document_processed" type="evento">
  A análise do documento terminou. Fala só do documento: a verificação ainda não foi decidida.
</ResponseField>

<ResponseField name="verification.liveness_settled" type="evento">
  A prova de vida chegou a um desfecho, aprovada ou recusada.
</ResponseField>

## Eventos com corpo extra

### verification.decided

O desfecho da verificação. É o único evento com o veredito no corpo, e o que a maioria das
integrações escuta.

<CodeGroup>
  ```json title="Corpo" theme={null}
  {
    "id": "019f0000-0000-7000-8000-000000000007",
    "event": "verification.decided",
    "occurred_at": "2026-09-14T17:30:00.000Z",
    "tenant_public_id": "019f0000-0000-7000-8000-000000000002",
    "resource": { "type": "verification", "public_id": "019f0000-0000-7000-8000-000000000000" },
    "verification": {
      "status": "approved",
      "ref_id": "pedido-4471",
      "decided_at": "2026-09-14T17:29:58.000Z"
    }
  }
  ```

  ```ts title="Tratar" theme={null}
  switch (evento.verification.status) {
    case "approved":
      await liberarCadastro(evento.verification.ref_id);
      break;
    case "reproved":
      await recusarCadastro(evento.verification.ref_id);
      break;
    case "review":
      await marcarComoEmAnalise(evento.verification.ref_id);
      break;
  }
  ```
</CodeGroup>

| Campo                     | O que é                                                  |
| ------------------------- | -------------------------------------------------------- |
| `verification.status`     | `approved`, `reproved` ou `review`                       |
| `verification.ref_id`     | a chave que você mandou na criação. `null` se não mandou |
| `verification.decided_at` | quando o desfecho aconteceu                              |

<Info>
  `review` não é recusa. Quando um analista decide no dashboard, este evento dispara de novo com o
  status final. O seu handler precisa aceitar `verification.decided` duas vezes para a mesma
  verificação.
</Info>

### verification.scored

<Info>
  Em implementação. O envelope abaixo é o contrato acordado; a entrega do bloco `score` ainda não
  está disponível em produção.
</Info>

Os dois scores e o resultado de cada regra. Independente de `verification.decided`: não assuma
ordem entre os dois.

```json theme={null}
{
  "id": "019f0000-0000-7000-8000-000000000008",
  "event": "verification.scored",
  "occurred_at": "2026-09-14T17:31:04.000Z",
  "tenant_public_id": "019f0000-0000-7000-8000-000000000002",
  "resource": { "type": "verification", "public_id": "019f0000-0000-7000-8000-000000000000" },
  "score": {
    "risk_score": 18,
    "identity_score": 94,
    "updated_at": "2026-09-14T17:31:03.000Z",
    "breakdown": {
      "risk:proxy_or_vpn": {
        "rule_key": "risk:proxy_or_vpn",
        "rule_version": "1.0.0",
        "category": "risk",
        "title": "Proxy or VPN",
        "status": "NOT_MATCHED",
        "reason_code": "no_proxy_or_vpn_detected",
        "score_points": {},
        "evaluated_at": "2026-09-14T17:31:03.000Z",
        "details": {}
      }
    }
  }
}
```

| Campo                  | O que é                                                           |
| ---------------------- | ----------------------------------------------------------------- |
| `score.risk_score`     | 0 a 100. Quanto maior, pior                                       |
| `score.identity_score` | 0 a 100. Quanto maior, melhor                                     |
| `score.breakdown`      | um objeto por regra, com `status`, `reason_code` e `score_points` |

`MATCHED` significa que a regra encontrou um sinal contra a jornada. `INSUFFICIENT_DATA` não é
aprovação: a regra não teve o que avaliar. As catorze regras estão em [score](/platform/score).

## Próximo passo

<Card title="Segurança" icon="shield-check" href="/webhooks/security" horizontal>
  Confira a assinatura antes de confiar em qualquer um destes corpos.
</Card>
