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

# Criar Validação KYC

> Iniciar uma sessão de verificação KYC para uma entidade pessoa — na API KYC da gu1 para fluxos de verificação de identidade, com exemplos para create.

## Resumo

Este endpoint cria uma nova sessão de validação KYC para uma entidade pessoa usando um provedor de integração configurado. Após criar a validação, você receberá uma URL de verificação que pode compartilhar com seu cliente para completar a verificação de identidade.

## Diagrama de Fluxo Completo

Sequência desde a criação da entidade até a validação KYC (fluxo de produção; no sandbox com números de documento de teste o passo do provedor é omitido e a API retorna o resultado mock e os webhooks imediatamente—veja [Dados mock no sandbox](/pt/use-cases/kyc/sandbox-mock-data)):

```mermaid theme={null}
sequenceDiagram
    participant Client as Sua Aplicação
    participant API as API gu1
    participant User as Usuário Final
    participant KYC as Provedor KYC

    Note over Client,KYC: Passo 1: Criar Entidade Pessoa
    Client->>API: POST /api/entities
    Note right of Client: type, taxId, name, countryCode
    API-->>Client: 201 Created { entityId }<br/>ou 409 se taxId já existe

    Note over Client,KYC: Passo 2: Criar Validação KYC
    Client->>API: POST /api/kyc/validations
    Note right of Client: entityId, integrationCode
    API->>KYC: Inicializar sessão de verificação
    KYC-->>API: Sessão criada
    API-->>Client: 201 Created<br/>{ id, providerSessionUrl, status: "pending" }

    Note over Client,KYC: Passo 3: Usuário Completa Verificação
    Client->>User: Enviar providerSessionUrl
    User->>KYC: Abre URL, envia documento, selfie
    KYC->>KYC: Documento + liveness + comparação facial
    KYC->>API: Resultado (webhook ou sync do provedor)
    API->>API: Atualizar status da validação

    Note over Client,KYC: Passo 4: Webhook ao Cliente
    API->>Client: POST sua URL de webhook
    Note right of API: event: kyc.validation_approved<br/>ou kyc.validation_rejected<br/>payload: validação completa

    Note over Client,KYC: Passo 5: Opcional – Consultar Status
    Client->>API: GET /api/kyc/validations/:id
    API-->>Client: 200 OK { status, ... }
```

<Accordion title="Pontos-Chave no Fluxo">
  **1. Entidade e taxId duplicado**

  * Crie primeiro a entidade pessoa com `POST /api/entities` (inclua `countryCode`). Se o `taxId` já existir na organização, a API retorna **409** e não cria duplicado; use o ID da entidade existente.
  * Você precisa de um `entityId` existente para criar uma validação KYC.

  **2. Código de integração**

  * `global_gueno_validation_kyc` é o código padrão para KYC completo e funciona no sandbox sem configuração adicional.

  **3. URL de verificação**

  * Em produção, a resposta inclui `providerSessionUrl`. Envie essa URL ao seu usuário; eles completam o fluxo na página do provedor (documento + selfie). A URL é válida até `expiresAt`.
  * No **sandbox**, se o documento da entidade estiver na [lista de teste](/pt/use-cases/kyc/sandbox-mock-data), não há sessão do provedor: a API retorna 201 com status `pending` e **momentos depois** atualiza a validação e envia os webhooks (ex.: `kyc.validation_approved` ou `kyc.validation_rejected`), sem passo do usuário. **Importante:** Você deve ter um endpoint webhook configurado para receber as respostas - veja [Dados mock no sandbox](/pt/use-cases/kyc/sandbox-mock-data).

  **4. Eventos de webhook**

  * Quando a validação termina, a API envia um webhook à sua URL. O **evento** é um de: `kyc.validation_approved`, `kyc.validation_rejected`, `kyc.validation_abandoned`, `kyc.validation_expired`, `kyc.validation_cancelled` (não um único evento “completed”). O payload é o objeto de validação completo.
  * Você também pode fazer polling em `GET /api/kyc/validations/:id` para atualizações de status.
</Accordion>

## Pré-requisitos

Antes de criar uma validação KYC:

1. **A entidade pessoa deve existir**: Crie uma entidade pessoa usando a [API de Entidades](/api-reference/entities/create)
2. **Integração KYC configurada**: Sua organização deve ter um provedor de integração KYC ativado (ex: `global_gueno_validation_kyc`)
3. **API key válida**: Autentique com sua chave API

<Info>
  **Sandbox vs Produção**: Ambientes sandbox NÃO requerem configuração de perfil ou pré-configuração. Você pode testar validações KYC imediatamente no sandbox com dados de teste. Ambientes de produção requerem:

  * Onboarding da organização concluído
  * Provedor de integração KYC ativado pela equipe gu1
  * Saldo de créditos suficiente para operações KYC

  Para começar no sandbox, simplesmente use sua chave de API do sandbox - nenhuma configuração adicional é necessária.
</Info>

### Dados mock (sandbox)

No sandbox, quando o documento da entidade pessoa (`taxId`) coincide com um dos nossos **valores de teste**, a API retorna um **resultado mock imediato** (ex.: aprovado, rejeitado, cancelado) e envia os webhooks correspondentes, sem executar verificação real. O formato do documento não importa (ex.: `99.990.001` e `99990001` funcionam igual).

Para a lista completa de números de documento de teste por formato (Argentina DNI/CUIT, Brasil CPF/CNPJ), resultados esperados e exemplos de resposta, veja **[Dados mock no sandbox](/pt/use-cases/kyc/sandbox-mock-data)**.

## Comportamentos Importantes

### taxId duplicado (POST /entities)

<Warning>
  **O que acontece se você chamar POST /entities com um taxId que já existe?**

  A API **não** cria uma segunda entidade. Retorna **409 Conflict** com código de erro `DUPLICATE_TAX_ID` e inclui nos detalhes o `id`, `name` e `type` da entidade existente.

  **O que fazer:**

  1. **Opção A – Consultar antes**: Use `GET /api/entities?taxId=12345678` (ou o endpoint by-tax-id) antes de criar. Se a entidade existir, use seu `entityId` para KYC.
  2. **Opção B – Tratar o 409**: Se receber 409, leia `error.details.existingEntityId` na resposta e use esse `entityId` para sua validação KYC.
  3. **Reutilizar a mesma entidade**: Use uma entidade por pessoa/empresa e crie várias validações KYC sobre esse mesmo `entityId` se precisar de re-verificação ou novas tentativas.

  **Exemplo – Verificar antes de criar:**

  ```javascript theme={null}
  // Verificar se a entidade existe
  const existing = await fetch('https://api.gu1.ai/api/entities?taxId=12345678', {
    headers: { 'Authorization': 'Bearer SUA_API_KEY' }
  });
  const data = await existing.json();

  let entityId;
  if (data.data && data.data.length > 0) {
    entityId = data.data[0].id; // Usar entidade existente
  } else {
    const createRes = await fetch('https://api.gu1.ai/api/entities', {
      method: 'POST',
      headers: { 'Authorization': 'Bearer SUA_API_KEY', 'Content-Type': 'application/json' },
      body: JSON.stringify({ type: 'person', taxId: '12345678', name: 'João Silva', countryCode: 'AR' })
    });
    const created = await createRes.json();
    entityId = created.entity?.id ?? created.data?.id;
  }

  // Criar validação KYC com o entityId
  ```
</Warning>

### Múltiplas Validações KYC por Entidade

Você **pode** criar múltiplas validações KYC para a mesma entidade:

* Cada validação recebe um ID e sessão únicos
* Apenas a validação **aprovada** mais recente é marcada como `isCurrent: true`
* Casos de uso: Re-verificação, validações expiradas, tentativas falhadas
* Se a entidade já tiver uma validação **aberta** (`pending`, `in_progress` ou `in_review`), o create retorna **`409 VALIDATION_IN_PROGRESS`** com **`activeValidationId`** — cancele essa validação primeiro e só então crie de novo

<Note>
  **Contrato aditivo:** Clientes que leem apenas `error` e `message` não mudam. `activeValidationId` é metadata opcional no 409 para evitar lookup extra antes do cancel.
</Note>

## Solicitação

### Endpoint

```
POST https://api.gu1.ai/api/kyc/validations
```

### Headers

```json theme={null}
{
  "Authorization": "Bearer SUA_API_KEY",
  "Content-Type": "application/json"
}
```

### Parâmetros de Query (opcionais)

<ParamField query="doubleCheckRenaper" type="boolean">
  Em `true`, ativa a dupla verificação RENAPER para entidades da **Argentina**. Em estados **terminais** a API consulta o registro oficial (dados e, quando aplicável, biometria) e armazena o resultado em metadata. **Somente** se a **verificação OCR KYC** retornar o estado **`approved`** uma falha no cruzamento pode rejeitar automaticamente a validação; em `in_review` ou `rejected` o chequeo é informativo (`enforcementApplied: false`). Requer entidade da Argentina e credenciais RENAPER configuradas na organização.
</ParamField>

### Parâmetros do Body

Informe **exatamente um** identificador de entidade:

<ParamField body="entityId" type="string">
  O UUID da entidade pessoa a verificar

  **Tipo**: `string` (uuid)
</ParamField>

<ParamField body="entityExternalId" type="string">
  Seu ID externo da entidade (`entities.externalId` na Gu1).
</ParamField>

<ParamField body="entityTaxId" type="string">
  Documento fiscal (CUIT, CPF, DNI, etc.). A Gu1 resolve com match normalizado em `entities.tax_id`. A entidade **deve existir** (404 se não houver linha).
</ParamField>

<Info>
  No **sandbox**, `GET /api/entities/by-tax-id/{taxId}` pode retornar prévia sintética para números de teste do catálogo (`sandboxMock: true`) sem linha no DB. **POST /validations** ainda exige entidade real persistida.
</Info>

<ParamField body="integrationCode" type="string" required>
  O código do provedor de integração para validação KYC

  **Valor Padrão**: `global_gueno_validation_kyc` (recomendado para a maioria dos casos de uso)

  **Tipo**: `string` (comprimento mínimo: 1)

  <Note>
    **O que é integrationCode?**

    O `integrationCode` identifica qual integração de provedor KYC usar para verificação. Pense nisso como selecionar o serviço de verificação.

    **Códigos de Integração Disponíveis:**

    * `global_gueno_validation_kyc` - **Recomendado** - KYC completo com documento + selfie + comparação facial + liveness
    * Códigos personalizados podem ser configurados para sua organização (contate o suporte)

    **Como encontrar seu código de integração:**

    1. Faça login no [Dashboard gu1](https://app.gu1.ai)
    2. Navegue até Configurações → Integrações → Provedores KYC
    3. Seu código de integração ativo será listado lá

    Em **ambientes sandbox**, `global_gueno_validation_kyc` funciona imediatamente sem configuração.
  </Note>
</ParamField>

<ParamField body="doubleCheckRenaper" type="boolean">
  Igual ao query param. Em `true` ativa a dupla verificação RENAPER para Argentina. Pode ser enviado no body ou como `?doubleCheckRenaper=true`. Se ambos forem enviados, o query prevalece.
</ParamField>

<ParamField body="omitWarnings" type="string[]">
  Lista opcional de [códigos de aviso KYC](/pt/use-cases/kyc/warning-risk-codes) (strings exatos). Fica armazenada na validação como `metadata.omitWarnings`. Ao concluir a sessão, se a validação ficaria em **`in_review`**, **`warnings` não está vazio** e **todos** os códigos em `warnings` aparecem nesta lista, a API define o status como **`approved`** e mantém os avisos para UI e auditoria. Se **algum** aviso **não** estiver em `omitWarnings`, o status permanece **`in_review`**. Se `warnings` estiver vazio com status `in_review`, **não** há autoaprovação. Códigos inválidos no body retornam **400**. Quando a regra se aplica, `metadata.kycOmitWarningsApplied` registra o instante e os avisos correspondentes.

  Códigos **não omitíveis** (ex.: `GUENO_CROSS_ENTITY_DUPLICATED`) são rejeitados neste campo com **400** e sempre impedem autoaprovação por omit mesmo que constem em `warnings`.

  **Tipo**: `string[]` (cada elemento deve ser um código permitido; duplicados são ignorados)
</ParamField>

## Resposta

### Resposta Bem-sucedida (201 Created)

```json theme={null}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "entityId": "123e4567-e89b-12d3-a456-426614174000",
  "organizationId": "org_abc123",
  "sessionId": "session_xyz789",
  "status": "pending",
  "provider": "kyc_provider",
  "providerSessionUrl": "https://verify.example.com/session_xyz789",
  "isCurrent": true,
  "metadata": { "doubleChecks": { "renaper": true } },
  "createdAt": "2025-01-15T10:30:00Z"
}
```

Com dupla verificação RENAPER ativa, em criação é definido `metadata.doubleChecks.renaper: true`. Após aprovação e execução do chequeo, é preenchido `metadata.responseDoubleChecks.renaper` (ver [Dupla verificação RENAPER](#dupla-verificação-renaper-argentina)).

### Campos de Resposta

<ResponseField name="providerSessionUrl" type="string">
  **A URL de verificação para compartilhar com seu cliente**
</ResponseField>

<ResponseField name="status" type="string">
  Status atual da validação. Valores possíveis:

  * `pending` - Validação criada, aguardando o cliente iniciar
  * `in_progress` - Cliente completando a verificação (preenchendo formulário)
  * `in_review` - Verificação completa, requer revisão manual da equipe de compliance
  * `approved` - Verificação bem-sucedida
  * `rejected` - Verificação falhou
  * `expired` - Sessão de verificação expirada (ex. após 7 dias)
  * `abandoned` - Cliente iniciou mas não completou
  * `cancelled` - Validação cancelada manualmente
</ResponseField>

<Info>
  Após a aprovação, as chaves de mídia aparecem em **`decision`**. Para baixar arquivos (imagens, vídeo), use **`GET /api/kyc/validations/:id/media?key=...`** com `Authorization: Bearer`. Detalhes: [Obter mídia da validação KYC](/pt/use-cases/kyc/validation-media).
</Info>

## Exemplo de Solicitação

<CodeGroup>
  ```javascript Node.js theme={null}
  const response = await fetch('https://api.gu1.ai/api/kyc/validations', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer SUA_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      entityId: '123e4567-e89b-12d3-a456-426614174000',
      integrationCode: 'global_gueno_validation_kyc'
    })
  });

  const validation = await response.json();
  console.log('URL de verificação:', validation.providerSessionUrl);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.gu1.ai/api/kyc/validations',
      headers={
          'Authorization': 'Bearer SUA_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'entityId': '123e4567-e89b-12d3-a456-426614174000',
          'integrationCode': 'global_gueno_validation_kyc'
      }
  )

  validation = response.json()
  print('URL de verificação:', validation['providerSessionUrl'])
  ```
</CodeGroup>

## Respostas de erro

### Entidade não encontrada (404)

```json theme={null}
{
  "error": "ENTITY_NOT_FOUND",
  "message": "Entity not found"
}
```

### Tipo de entidade inválido (400)

```json theme={null}
{
  "error": "INVALID_ENTITY_TYPE",
  "message": "KYC validation is only available for person entities"
}
```

### KYC não configurado (400)

```json theme={null}
{
  "error": "KYC_NOT_CONFIGURED",
  "message": "KYC integration is not configured for this organization. Please contact your administrator."
}
```

### Validação em andamento (409)

Quando a entidade já tem uma validação aberta (`pending`, `in_progress` ou `in_review`), a Gu1 sincroniza com a sessão de captura hospedada quando possível e rejeita um segundo create:

```json theme={null}
{
  "error": "VALIDATION_IN_PROGRESS",
  "message": "Cannot create new KYC validation. There is already a pending validation for this entity. Please cancel or complete the existing validation first.",
  "activeValidationId": "7618e10c-b1b1-408b-b361-1901077ced73"
}
```

**Recuperação:** `409` → `DELETE /api/kyc/validations/{activeValidationId}/cancel` → um único `POST /api/kyc/validations` novo.

Validações terminais (`approved`, `rejected`, `cancelled`, `expired`, `abandoned`) **não** bloqueiam criar outra.

## Dupla verificação RENAPER (Argentina)

Com `doubleCheckRenaper: true` e entidade da Argentina, em cada estado **terminal** (`approved`, `rejected`, `in_review`) a API executa verificação cruzada contra o registro oficial (RENAPER) quando há OCR suficiente. Rejeição automática por RENAPER **somente** se a **verificação OCR KYC** retornou o estado **`approved`**.

### Como enviar

* **Body**: `{ "entityId": "...", "integrationCode": "...", "doubleCheckRenaper": true }`
* **Query**: `POST /api/kyc/validations?doubleCheckRenaper=true` com o mesmo body. Se ambos forem enviados, o query prevalece.

### Onde o resultado é armazenado

Em **`metadata.responseDoubleChecks.renaper`**. Códigos de mismatch (ex.: trâmite e vencimento) são **adicionados** a **`metadata.warnings`** sem substituir avisos anteriores da **verificação OCR KYC**. `errorCode` no objeto `renaper` mantém a primeira falha por compatibilidade; a UI pode listar todos os códigos em `comparisonResults` e `warnings`.

**Campos de `metadata.responseDoubleChecks.renaper`:**

| Campo                | Tipo    | Descrição                                                                                           |
| -------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `verified`           | boolean | `true` se o chequeo passou.                                                                         |
| `matchResult`        | string  | `"match"` \| `"mismatch"` \| `"error"`.                                                             |
| `verifiedAt`         | string  | Timestamp ISO do chequeo.                                                                           |
| `personalNumber`     | string  | Número de trâmite do KYC.                                                                           |
| `idTramitePrincipal` | string  | Número de trâmite do RENAPER.                                                                       |
| `renaperData`        | object  | Resposta bruta do RENAPER (ver [forma de `renaperData`](#forma-de-renaperdata)).                    |
| `comparisonResults`  | object  | Comparação campo a campo entre OCR e registro (quando aplicável).                                   |
| `renaperBiometric`   | object  | Resultado biométrico ABIS (`validate-dni`): `matchResult`, `score`, `renaperData` (resposta bruta). |
| `errorCode`          | string  | Presente se falhou; ver códigos abaixo.                                                             |

### Forma de `renaperData`

É o **body sem transformação** retornado pelo registro via ms-providers (`POST …/provider-records/renaper/data`). A Gu1 repassa como está em `metadata.responseDoubleChecks.renaper.renaperData`. Os nomes dos campos estão em **snake\_case**; todos são opcionais conforme o retorno do RENAPER em cada consulta.

**Exemplo (dupla verificação bem-sucedida, `matchResult: "match"`):**

```json theme={null}
{
  "id_tramite_principal": "987654321",
  "id_tramite_tarjeta_reimpresa": "112233445",
  "ejemplar": "A",
  "vencimiento": "2030-05-20",
  "emision": "2015-05-20",
  "apellido": "García",
  "nombres": "Juan",
  "fecha_nacimiento": "1990-01-15",
  "cuil": "20-30123456-9",
  "calle": "Av. Corrientes",
  "numero": "1234",
  "piso": "5",
  "departamento": "B",
  "codigo_postal": "1043",
  "barrio": "San Nicolás",
  "monoblock": "",
  "ciudad": "Ciudad Autónoma de Buenos Aires",
  "municipio": "Comuna 1",
  "provincia": "Buenos Aires",
  "pais": "Argentina",
  "nacionalidad": "Argentina",
  "codigo_fallecido": "",
  "mensaje_fallecido": "",
  "fecha_fallecimiento": "",
  "id_ciudadano": "30123456",
  "codigo": "",
  "mensaje": ""
}
```

**Outros casos comuns:**

| Situação                                                  | `renaperData` típico                                                                           |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Erro antes de obter dados (ex.: `RENAPER_DNI_MISSING`)    | `{}`                                                                                           |
| Serviço indisponível (`RENAPER_VERIFICATION_UNAVAILABLE`) | `{ "error": "…", "code": "SERVICE_UNAVAILABLE" }`                                              |
| Cruzamento falhou com payload parcial do registro         | Subconjunto de campos (ex.: `id_tramite_principal`, `apellido`, `nombres`, `fecha_nacimiento`) |

No sandbox, os mesmos valores mock aparecem em [Dados mock de KYC (sandbox)](/pt/use-cases/kyc/sandbox-mock-data#exemplo-de-resposta-mock-aprovado).

### Forma de `comparisonResults`

Mapa por campo (`dni`, `tramite`, `name`, `ejemplar`, `dateOfBirth`, `expirationDate`). Cada entrada pode incluir:

| Campo               | Tipo    | Descrição                                                                   |
| ------------------- | ------- | --------------------------------------------------------------------------- |
| `compared`          | boolean | `true` se a comparação foi tentada; `false` se omitida por dados faltantes. |
| `passed`            | boolean | Resultado quando `compared` é `true`.                                       |
| `skipReason`        | string  | `ocr_missing`, `renaper_missing` ou `both_missing` quando não comparado.    |
| `ocrValue`          | string  | Valor extraído do OCR (se aplicável).                                       |
| `renaperValue`      | string  | Valor do registro RENAPER (se aplicável).                                   |
| `similarityPercent` | number  | Apenas em `name`: similaridade Levenshtein (0–100).                         |
| `threshold`         | number  | Apenas em `name`: limiar aplicado (ex.: 80).                                |
| `errorCode`         | string  | Código de falha do campo (ex.: `RENAPER_DNI_NOT_MATCH`).                    |

Para **`ejemplar`**, o valor OCR é **`extractedData.ejemplar`** (ver [campos de extractedData](/pt/use-cases/kyc/id-verification#campos-de-extracteddata)). A comparação ocorre quando existem ambos os valores OCR e RENAPER.

**Exemplo — `extractedData` numa validação KYC aprovada (Argentina):**

```json theme={null}
"extractedData": {
  "documentNumber": "38966181",
  "personalNumber": "00460759387",
  "taxNumber": "20389661814",
  "ejemplar": "C",
  "dateOfBirth": "1995-05-22",
  "expirationDate": "2031-10-17",
  "nationality": "ARG"
}
```

### Forma de `renaperBiometric`

Objeto aninhado em `metadata.responseDoubleChecks.renaper.renaperBiometric` quando a org tem credenciais biométricas e a sessão KYC fornece selfie. O Gu1 envia **uma selfie** a `validate-dni`; o RENAPER compara com a foto do documento no registro.

| Campo                       | Tipo    | Descrição                                                                                  |
| --------------------------- | ------- | ------------------------------------------------------------------------------------------ |
| `verified`                  | boolean | `true` quando `resultado.match` do chequeo biométrico ABIS é positivo.                     |
| `matchResult`               | string  | `"match"` \| `"mismatch"` \| `"error"`.                                                    |
| `score`                     | number  | Pontuação do chequeo biométrico (se aplicável).                                            |
| `verifiedAt`                | string  | Timestamp ISO do chequeo biométrico.                                                       |
| `renaperData`               | object  | Resposta bruta de `validate-dni` (inclui `resultado.match`, `resultado.score`, etc.).      |
| `submittedSelfieRef`        | string  | Referência da selfie enviada: caminho de armazenamento (`kyc/...`) ou URL (`https://...`). |
| `submittedSelfieRefKind`    | string  | Formato de `submittedSelfieRef`: `s3_key` (caminho interno) \| `url` (URL pública).        |
| `submittedSelfiePickedFrom` | string  | Origem em `decision`: `liveness_reference_image` ou `face_match_target_image`.             |
| `errorCode`                 | string  | Se falhar (ex.: `RENAPER_BIOMETRIC_NOT_MATCH`).                                            |
| `skipReason`                | string  | Se não executado (ex.: selfie indisponível).                                               |

### Exemplo completo de `responseDoubleChecks.renaper`

```json theme={null}
{
  "verified": true,
  "matchResult": "match",
  "personalNumber": "00123456789",
  "idTramitePrincipal": "987654321",
  "verifiedAt": "2026-06-05T14:30:00.000Z",
  "enforcementApplied": true,
  "renaperData": {
    "id_tramite_principal": "987654321",
    "apellido": "García",
    "nombres": "Juan",
    "fecha_nacimiento": "1990-01-15",
    "ejemplar": "A",
    "vencimiento": "2030-05-20"
  },
  "comparisonResults": {
    "dni": {
      "field": "dni",
      "compared": true,
      "passed": true,
      "ocrValue": "30123456",
      "renaperValue": "30123456"
    },
    "tramite": {
      "field": "tramite",
      "compared": true,
      "passed": true,
      "ocrValue": "00123456789",
      "renaperValue": "987654321"
    },
    "name": {
      "field": "name",
      "compared": true,
      "passed": true,
      "ocrValue": "Juan García",
      "renaperValue": "García Juan",
      "similarityPercent": 92,
      "threshold": 80
    },
    "ejemplar": {
      "field": "ejemplar",
      "compared": true,
      "passed": true,
      "ocrValue": "A",
      "renaperValue": "A"
    },
    "dateOfBirth": {
      "field": "dateOfBirth",
      "compared": true,
      "passed": true,
      "ocrValue": "1990-01-15",
      "renaperValue": "1990-01-15"
    }
  },
  "renaperBiometric": {
    "verified": true,
    "matchResult": "match",
    "score": 0.91,
    "verifiedAt": "2026-06-05T14:30:02.000Z",
    "submittedSelfieRef": "kyc/org-id/entity-id/session-id/selfie.jpg",
    "submittedSelfieRefKind": "s3_key",
    "submittedSelfiePickedFrom": "liveness_reference_image",
    "renaperData": {
      "resultado": {
        "match": true,
        "score": 0.91
      }
    }
  }
}
```

`renaperBiometric` e entradas em `comparisonResults` podem ser omitidos conforme credenciais, dados OCR ou disponibilidade de selfie.

### Códigos de erro (quando RENAPER falha)

O motivo da rejeição é um **código** em `metadata.warnings` e em `metadata.responseDoubleChecks.renaper.errorCode`. A UI deve traduzir esses códigos.

| Código                             | Significado                                                                                                                                                        |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `RENAPER_DNI_MISSING`              | Número de documento (DNI) não obtido na verificação.                                                                                                               |
| `RENAPER_GENDER_MISSING`           | Género (M/F) obrigatório para chamar RENAPER.                                                                                                                      |
| `RENAPER_VERIFICATION_UNAVAILABLE` | Não foi possível completar a verificação cruzada (ex.: rede). Tente novamente.                                                                                     |
| `RENAPER_DNI_NOT_MATCH`            | O número do documento não coincide com o registro oficial.                                                                                                         |
| `RENAPER_TRAMITE_DATA_MISSING`     | Faltam dados para comparar o número de trâmite.                                                                                                                    |
| `RENAPER_TRAMITE_ID_NOT_MATCH`     | O **número de trâmite** do documento não coincide com o registro (exemplar antigo, vencido ou reemitido; a pessoa deve verificar novamente com documento vigente). |
| `RENAPER_NAME_NOT_MATCH`           | O nome do OCR está abaixo do limiar de 80% de similaridade com o registro RENAPER.                                                                                 |
| `RENAPER_EJEMPLAR_NOT_MATCH`       | O exemplar do documento não coincide com o registro RENAPER.                                                                                                       |
| `RENAPER_DOB_NOT_MATCH`            | A data de nascimento do OCR não coincide com o registro RENAPER.                                                                                                   |
| `RENAPER_EXPIRY_NOT_MATCH`         | A data de vencimento do OCR não coincide com o registro RENAPER.                                                                                                   |
| `RENAPER_BIOMETRIC_NOT_MATCH`      | A selfie não coincide com a foto do documento no registro biométrico.                                                                                              |
| `RENAPER_BIOMETRIC_UNAVAILABLE`    | Não foi possível completar o chequeo biométrico (rede, credenciais ou serviço).                                                                                    |

### Quando o RENAPER aplica enforce (rejeição automática)

| Estado da verificação OCR KYC                                                                           | RENAPER executa?                  | Pode rejeitar por RENAPER?                             |
| ------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------ |
| **`approved`** (aprovação direta)                                                                       | Sim                               | **Sim** — falha no cruzamento → `rejected`             |
| **`in_review`**                                                                                         | Sim                               | **Não** — informativo; equipe decide na revisão manual |
| **`rejected`** (verificação OCR ou regras Gu1)                                                          | Sim (se houver OCR)               | **Não** — informativo; dados ficam em metadata         |
| **Aprovação manual** a partir de `in_review` ([`POST …/approve`](/pt/use-cases/kyc/approve-validation)) | **Não** (reutiliza chequeo salvo) | **Não** — decisão humana                               |

Em todos os casos com consulta ativa, **dados** e **biometria** ficam em `metadata.responseDoubleChecks.renaper`. Em `in_review` e `rejected`, códigos RENAPER com mismatch são adicionados a `warnings` junto com avisos da verificação OCR.

## Próximos Passos

Depois que a validação for **approved**, leia as chaves em `decision` e baixe os arquivos — veja [Obter mídia da validação KYC](/pt/use-cases/kyc/validation-media).

<CardGroup cols={2}>
  <Card title="Obter URL de KYC" icon="link" href="/pt/use-cases/kyc/get-kyc-url">
    Aprenda como recuperar a URL
  </Card>

  <Card title="Integração Webhook" icon="webhook" href="/pt/use-cases/kyc/webhook-integration">
    Configure notificações webhook
  </Card>
</CardGroup>
