> ## Documentation Index
> Fetch the complete documentation index at: https://docs-platform.services-valid.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Importação de Documentos

> Guia completo de integração para envio de documentos via API

## Visão Geral

A API de Importação de Documentos do Fleximage permite que sistemas externos enviem lotes de documentos para processamento automático de análise, classificação, validação documental e biometria.

<CardGroup cols={2}>
  <Card title="Fluxo Simples" icon="route">
    Apenas 2 etapas: Autenticação + Importação
  </Card>

  <Card title="Processamento Automático" icon="robot">
    OCR, classificação e validação sem intervenção manual
  </Card>

  <Card title="Resultado via Webhook" icon="webhook">
    Receba os resultados automaticamente em sua URL
  </Card>

  <Card title="Multi-documento" icon="files">
    Envie múltiplos documentos em um único lote
  </Card>
</CardGroup>

***

## Fluxo de Integração

<Steps>
  <Step title="Autenticação OAuth 2.0">
    Obtenha um token de acesso JWT via Keycloak usando suas credenciais
  </Step>

  <Step title="Preparar Metadados">
    Monte o arquivo JSON com informações do lote e documentos
  </Step>

  <Step title="Importar Documentos">
    Envie JSON + arquivos via requisição multipart/form-data
  </Step>

  <Step title="Receber BatchID">
    Armazene o ID do lote retornado para rastreamento
  </Step>

  <Step title="Aguardar Webhook">
    Receba o resultado completo da análise em sua URL de callback
  </Step>
</Steps>

***

## 1. Autenticação OAuth 2.0

### Credenciais de Acesso

Você receberá as credenciais de acesso por email. Exemplo de ambiente de desenvolvimento:

| Parâmetro          | Valor                              |
| ------------------ | ---------------------------------- |
| **CLIENT\_ID**     | `teste-api`                        |
| **CLIENT\_SECRET** | `pwR8GPipQvifGhSIH7cH07OOCXd2C8Hg` |

<Warning>
  As credenciais acima são de **uso exclusivo para ambiente de desenvolvimento (DES)**. Credenciais de produção serão fornecidas separadamente pelo time de integração.
</Warning>

### Endpoint de Autenticação

<CodeGroup>
  ```http Request theme={"theme":"catppuccin-latte"}
  POST https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token
  Content-Type: application/x-www-form-urlencoded

  grant_type=client_credentials&client_id=teste-api&client_secret=vveMLSHnasVxzKWchN0DasdawG4UlXxs
  ```

  ```bash cURL theme={"theme":"catppuccin-latte"}
  curl -X POST "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=client_credentials" \
    -d "client_id=teste-api" \
    -d "client_secret=vveMLSHnasVxzKWchN0DpeEdsafxs"
  ```

  ```javascript JavaScript theme={"theme":"catppuccin-latte"}
  const axios = require('axios');
  const qs = require('qs');

  async function getAccessToken() {
    const response = await axios.post(
      'https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token',
      qs.stringify({
        grant_type: 'client_credentials',
        client_id: 'teste-api',
        client_secret: 'vveMLSHnasVxzKWcEDcspeEawG4UlXxs'
      }),
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
    );

    return response.data.access_token;
  }
  ```

  ```python Python theme={"theme":"catppuccin-latte"}
  import requests

  def get_access_token():
      url = "https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token"

      data = {
          'grant_type': 'client_credentials',
          'client_id': 'trustic-api',
          'client_secret': 'vveMLSHnasVxzKWchN0DpeEawG4UlXxs'
      }

      response = requests.post(url, data=data)
      return response.json()['access_token']
  ```

  ```java Java theme={"theme":"catppuccin-latte"}
  import java.net.http.*;
  import java.net.*;

  public class AuthClient {
      public String getAccessToken() throws Exception {
          HttpClient client = HttpClient.newHttpClient();

          String body = "grant_type=client_credentials" +
                        "&client_id=trustic-api" +
                        "&client_secret=vveMLSHnasVxzKWchN0DpeEawG4UlXxs";

          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://auth-des.flexdoc-apis.com.br/realms/fleximage/protocol/openid-connect/token"))
              .header("Content-Type", "application/x-www-form-urlencoded")
              .POST(HttpRequest.BodyPublishers.ofString(body))
              .build();

          HttpResponse<String> response = client.send(request,
              HttpResponse.BodyHandlers.ofString());

          // Parse JSON e retorna access_token
          return parseAccessToken(response.body());
      }
  }
  ```
</CodeGroup>

### Resposta de Sucesso

```json theme={"theme":"catppuccin-latte"}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "profile email"
}
```

<ResponseField name="access_token" type="string" required>
  Token JWT para autenticação nas APIs. Use no header `Authorization: Bearer <token>`
</ResponseField>

<ResponseField name="token_type" type="string">
  Sempre `"Bearer"`
</ResponseField>

<ResponseField name="expires_in" type="integer">
  Tempo de validade em segundos (padrão: **3600 = 1 hora**)
</ResponseField>

<ResponseField name="scope" type="string">
  Escopos concedidos ao token
</ResponseField>

<Info>
  O token expira em **1 hora (3600 segundos)**. Quando expirar, execute a autenticação novamente para obter um novo token.
</Info>

***

## 2. Importação de Documentos

<Note>
  Use o playground **"Try It"** à direita para testar a API diretamente na documentação! →
</Note>

### Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token obtido via OAuth 2.0

  **Formato:** `Bearer {access_token}`

  **Exemplo:** `Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...`
</ParamField>

### Request Body

<ParamField body="jsonData" type="file" required>
  Arquivo JSON contendo metadados do lote e dos documentos.

  **Tipo:** JSON file

  **Estrutura detalhada:** Ver seção 3 abaixo

  **Content-Type:** `application/json`
</ParamField>

<ParamField body="files" type="file[]" required>
  Array de arquivos (PDF, PNG, JPG, JPEG) dos documentos a serem processados.

  **Formatos aceitos:** PDF, PNG, JPG, JPEG

  **Tamanho máximo:** 5MB por arquivo

  **Validação:** Nomes devem corresponder aos especificados no campo `fileName` do JSON
</ParamField>

### Response

<ResponseField name="batchId" type="integer" required>
  Identificador único do lote criado no sistema. Use este ID para rastrear o processamento.

  **Exemplo:** `4697`
</ResponseField>

<ResponseExample>
  ```json Sucesso (200 OK) theme={"theme":"catppuccin-latte"}
  {
    "batchId": 4697
  }
  ```

  ```json Erro 401 - Token Inválido theme={"theme":"catppuccin-latte"}
  {
    "error": "invalid_token",
    "error_description": "Token is expired or invalid"
  }
  ```

  ```json Erro 400 - Dados Inválidos theme={"theme":"catppuccin-latte"}
  {
    "error": "Invalid request",
    "details": "Missing required field 'workflowAlias' in JSON",
    "field": "jsonData.workflowAlias"
  }
  ```
</ResponseExample>

***

## 3. Estrutura do JSON (jsonData)

### Template Completo

<CodeGroup>
  ```json Exemplo Completo theme={"theme":"catppuccin-latte"}
  {
    "workflowAlias": "poc_onboarding",
    "batchExternalId": "LOTE-2026-001",
    "batchOrigin": "1",
    "keys": [
      {
        "key": "webhook_uri",
        "value": "https://seu-sistema.com/api/webhook/flexdoc"
      },
      {
        "key": "cpf",
        "value": "12345678900"
      },
      {
        "key": "origin_system",
        "value": "portal_cliente"
      }
    ],
    "docs": [
      {
        "fileName": "rg_completo.pdf",
        "contentType": "pdf",
        "typeAlias": "nao_identificado",
        "keys": [
          {
            "key": "cpf",
            "value": "12345678900"
          }
        ]
      },
      {
        "fileName": "selfie_cliente.png",
        "contentType": "png",
        "typeAlias": "selfie",
        "keys": [
          {
            "key": "cpf",
            "value": "12345678900"
          }
        ]
      }
    ]
  }
  ```

  ```json Exemplo Mínimo theme={"theme":"catppuccin-latte"}
  {
    "workflowAlias": "poc_auto_face",
    "batchExternalId": "123456",
    "batchOrigin": "1",
    "keys": [
      {
        "key": "webhook_uri",
        "value": "https://seu-sistema.com/webhook"
      },
      {
        "key": "cpf",
        "value": "12345678900"
      },
      {
        "key": "origin_system",
        "value": "meu_sistema"
      }
    ],
    "docs": [
      {
        "fileName": "documento.pdf",
        "contentType": "pdf",
        "typeAlias": "nao_identificado"
      },
      {
        "fileName": "selfie.png",
        "contentType": "png",
        "typeAlias": "selfie"
      }
    ]
  }
  ```
</CodeGroup>

### Campos do Lote

<ResponseField name="workflowAlias" type="string" required>
  Determina o fluxo de processamento aplicado ao lote:

  | Valor            | Descrição                                                     |
  | ---------------- | ------------------------------------------------------------- |
  | `poc_onboarding` | Fluxo padrão com intervenção manual (análise humana)          |
  | `poc_auto_face`  | Processamento 100% automático com validação biométrica facial |
  | `poc_auto`       | Processamento 100% automático sem validação biométrica        |

  <Tip>
    Use `poc_auto_face` para onboarding digital com selfie.
  </Tip>
</ResponseField>

<ResponseField name="batchExternalId" type="string" required>
  Identificador externo do lote para rastreamento no seu sistema.

  **Exemplo:** `"LOTE-2026-001"`, `"PF-12345-20260414"`
</ResponseField>

<ResponseField name="batchOrigin" type="string" required>
  Código da origem do lote. Geralmente `"1"` (consulte com o time de integração).
</ResponseField>

<ResponseField name="keys" type="array" required>
  Lista de chaves lógicas do lote. **3 chaves obrigatórias:**

  <Accordion title="webhook_uri (obrigatório)">
    URL de callback para receber o resultado da análise após o processamento.

    **Formato:** URL completa (https\://)

    **Exemplo:** `"https://seu-sistema.com/api/webhook/flexdoc"`

    <Warning>
      🔒 Se a URL de webhook exigir autenticação (token, Basic Auth ou header personalizado), informe previamente à equipe Flexdoc para configuração segura no sistema.
    </Warning>
  </Accordion>

  <Accordion title="cpf (obrigatório)">
    CPF do titular do documento (somente números, sem formatação).

    **Formato:** 11 dígitos

    **Exemplo:** `"12345678900"`
  </Accordion>

  <Accordion title="origin_system (obrigatório)">
    Nome do cliente, sistema ou projeto de origem. Utilizado para agrupamento e controle de registros.

    **Exemplo:** `"portal_cliente"`, `"app_mobile"`, `"trustic_web"`
  </Accordion>
</ResponseField>

### Campos dos Documentos

<ResponseField name="docs" type="array" required>
  Lista de documentos a serem importados. Cada documento possui:

  <Accordion title="fileName (obrigatório)" icon="file">
    Nome do arquivo que deve corresponder **exatamente** ao arquivo enviado no campo `files`.

    **Case-sensitive**: `"RG.pdf"` ≠ `"rg.pdf"`

    **Exemplo:** `"rg_completo.pdf"`, `"selfie_cliente.png"`
  </Accordion>

  <Accordion title="contentType (obrigatório)" icon="file-code">
    Formato do arquivo. Valores aceitos:

    * `"pdf"` - Documentos PDF
    * `"jpg"` ou `"jpeg"` - Imagens JPEG
    * `"png"` - Imagens PNG

    **Tamanho máximo recomendado:** 5MB por arquivo
  </Accordion>

  <Accordion title="typeAlias (opcional)" icon="tag">
    Tipo do documento. Se omitido, **classificação automática via deep learning** é aplicada.

    | Valor              | Descrição                                                   |
    | ------------------ | ----------------------------------------------------------- |
    | `nao_identificado` | Documento não identificado → classificação automática       |
    | `selfie`           | Fotografia de rosto (obrigatório para validação biométrica) |
    | `rg`               | RG                                                          |
    | `cnh`              | CNH (carteira de motorista)                                 |

    <Warning>
      ⚠️ **Importante**: Documentos de identidade frente e verso devem ser enviados como **um único arquivo combinado (merge)**. Arquivos separados de frente e verso não são aceitos.
    </Warning>
  </Accordion>

  <Accordion title="keys (opcional)" icon="key">
    Lista de chaves associadas ao documento específico (ex.: CPF do titular).

    **Estrutura:**

    ```json theme={"theme":"catppuccin-latte"}
    [
      {
        "key": "cpf",
        "value": "12345678900"
      }
    ]
    ```
  </Accordion>
</ResponseField>

***

## 4. Exemplo Completo de Requisição

<CodeGroup>
  ```bash cURL theme={"theme":"catppuccin-latte"}
  curl -X POST "https://flex-des.flexdoc-apis.com.br/import/import-doc/create" \
    -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
    -F "jsonData=@lote.json" \
    -F "files=@rg_completo.pdf" \
    -F "files=@selfie_cliente.png"
  ```

  ```javascript JavaScript (Axios) theme={"theme":"catppuccin-latte"}
  const FormData = require('form-data');
  const fs = require('fs');
  const axios = require('axios');

  async function importDocuments(token) {
    const form = new FormData();

    // JSON com metadados
    const metadata = {
      workflowAlias: "poc_auto_face",
      batchExternalId: "LOTE-001",
      batchOrigin: "1",
      keys: [
        { key: "webhook_uri", value: "https://seu-sistema.com/webhook" },
        { key: "cpf", value: "12345678900" },
        { key: "origin_system", value: "portal_web" }
      ],
      docs: [
        { fileName: "rg.pdf", contentType: "pdf", typeAlias: "nao_identificado" },
        { fileName: "selfie.png", contentType: "png", typeAlias: "selfie" }
      ]
    };

    form.append('jsonData', JSON.stringify(metadata), {
      contentType: 'application/json',
      filename: 'lote.json'
    });

    // Arquivos
    form.append('files', fs.createReadStream('./rg.pdf'));
    form.append('files', fs.createReadStream('./selfie.png'));

    const response = await axios.post(
      'https://flex-des.flexdoc-apis.com.br/import/import-doc/create',
      form,
      {
        headers: {
          ...form.getHeaders(),
          'Authorization': `Bearer ${token}`
        }
      }
    );

    console.log('BatchId:', response.data.batchId);
    return response.data.batchId;
  }
  ```

  ```python Python (Requests) theme={"theme":"catppuccin-latte"}
  import requests
  import json

  def import_documents(token):
      url = "https://flex-des.flexdoc-apis.com.br/import/import-doc/create"

      headers = {
          "Authorization": f"Bearer {token}"
      }

      # Metadados
      metadata = {
          "workflowAlias": "poc_auto_face",
          "batchExternalId": "LOTE-001",
          "batchOrigin": "1",
          "keys": [
              {"key": "webhook_uri", "value": "https://seu-sistema.com/webhook"},
              {"key": "cpf", "value": "12345678900"},
              {"key": "origin_system", "value": "portal_web"}
          ],
          "docs": [
              {"fileName": "rg.pdf", "contentType": "pdf", "typeAlias": "nao_identificado"},
              {"fileName": "selfie.png", "contentType": "png", "typeAlias": "selfie"}
          ]
      }

      files = {
          'jsonData': ('lote.json', json.dumps(metadata), 'application/json'),
          'files': [
              ('files', open('rg.pdf', 'rb')),
              ('files', open('selfie.png', 'rb'))
          ]
      }

      response = requests.post(url, headers=headers, files=files)

      if response.status_code in [200, 201]:
          batch_id = response.json()['batchId']
          print(f"BatchId: {batch_id}")
          return batch_id
      else:
          print(f"Erro: {response.text}")
          return None
  ```
</CodeGroup>

***

## 5. Resposta da Importação

### Sucesso (200 OK ou 201 Created)

```json theme={"theme":"catppuccin-latte"}
{
  "batchId": 4697
}
```

<ResponseField name="batchId" type="integer" required>
  Identificador único do lote processado. **Armazene este ID** para rastreamento e consultas futuras.
</ResponseField>

<Check>
  Lote criado com sucesso! O processamento iniciou automaticamente. Aguarde o webhook com o resultado completo da análise.
</Check>

### Códigos de Status HTTP

<AccordionGroup>
  <Accordion title="Sucesso (2xx)" icon="circle-check">
    | Código | Status     | Descrição                      |
    | ------ | ---------- | ------------------------------ |
    | `200`  | OK         | Operação realizada com sucesso |
    | `201`  | Created    | Lote criado com sucesso        |
    | `204`  | No Content | Nenhum registro encontrado     |
  </Accordion>

  <Accordion title="Erro do Cliente (4xx)" icon="triangle-exclamation">
    | Código | Status            | Descrição                                            |
    | ------ | ----------------- | ---------------------------------------------------- |
    | `400`  | Bad Request       | Erro na requisição. Verifique os parâmetros enviados |
    | `401`  | Unauthorized      | Token inválido ou expirado. Solicite um novo token   |
    | `403`  | Forbidden         | Acesso negado. Verifique as permissões da credencial |
    | `404`  | Not Found         | Serviço não encontrado. Verifique a URL              |
    | `413`  | Payload Too Large | Arquivo muito grande (máx 10MB)                      |
  </Accordion>

  <Accordion title="Erro do Servidor (5xx)" icon="xmark">
    | Código | Status                | Descrição                                                |
    | ------ | --------------------- | -------------------------------------------------------- |
    | `500`  | Internal Server Error | Erro interno no servidor. Entre em contato com o suporte |
    | `503`  | Service Unavailable   | Serviço indisponível temporariamente                     |
  </Accordion>
</AccordionGroup>

***

## 6. Webhook - Retorno da Validação

Após o processamento, o sistema envia **automaticamente** um POST para a URL configurada em `webhook_uri` com o resultado completo da análise.

### Estrutura do Response (ResponseDto)

<CodeGroup>
  ```json Exemplo - Aprovado theme={"theme":"catppuccin-latte"}
  {
    "dataInicio": "14/04/2026 10:30:15",
    "dataFinal": "14/04/2026 10:32:47",
    "codigoControle": 145900,
    "result": 0,
    "inconclusivo": false,
    "indiceAvaliacaoAutenticidade": 98,
    "indiceFacematch": 95,
    "tipoDocumento": "CNH",
    "cpf": "12345678900",
    "origin": "document-analysis",
    "originKey": "3116063c-a61f-467a-83e5-5e3b07b66e2d",
    "customerId": "tes",
    "externalId": "LOTE-2026-001te",
    "penalidades": [],
    "codigoRejeicao": [],
    "docs": [
      {
        "docName": "Documento de Identidade",
        "docId": 215170,
        "docType": "doc_identidade",
        "type": "cnh",
        "keys": [
          { "keyAlias": "nome", "keyName": "Nome", "value": "JOÃO DA SILVA" },
          { "keyAlias": "cpf", "keyName": "CPF", "value": "12345678900" },
          { "keyAlias": "data_nascimento", "keyName": "Data Nascimento", "value": "15/03/1990" },
          { "keyAlias": "num_registro", "keyName": "Número Registro", "value": "12345678901" }
        ]
      }
    ]
  }
  ```

  ```json Exemplo - Rejeitado theme={"theme":"catppuccin-latte"}
  {
    "dataInicio": "14/04/2026 11:15:20",
    "dataFinal": "14/04/2026 11:17:33",
    "codigoControle": 145901,
    "result": 2,
    "inconclusivo": false,
    "indiceAvaliacaoAutenticidade": 45,
    "indiceFacematch": null,
    "tipoDocumento": "RG",
    "cpf": "98765432100",
    "origin": "document-analysis",
    "originKey": "abc123-def456",
    "customerId": "trustic",
    "externalId": "LOTE-2026-002",
    "penalidades": [
      {
        "data": "14/04/2026 11:16:45",
        "valor": null,
        "descricao": "(RG_37) Formato do RG divergente",
        "regra": "rg_37",
        "rulesType": 1
      },
      {
        "data": "14/04/2026 11:17:02",
        "valor": "MARIA",
        "descricao": "(OCR_02) Nome obtido no documento divergente do nome na RF",
        "regra": "ocr_02",
        "rulesType": 1
      }
    ],
    "codigoRejeicao": [],
    "docs": [
      {
        "docName": "Documento de Identidade",
        "docId": 215171,
        "docType": "doc_identidade",
        "type": "rg",
        "keys": [
          { "keyAlias": "nome", "keyName": "Nome", "value": "MARIA SILVA" },
          { "keyAlias": "cpf", "keyName": "CPF", "value": "98765432100" }
        ]
      }
    ]
  }
  ```

  ```json Exemplo - Pendente (Qualidade) theme={"theme":"catppuccin-latte"}
  {
    "dataInicio": "14/04/2026 12:00:10",
    "dataFinal": null,
    "codigoControle": 145902,
    "result": 1,
    "inconclusivo": true,
    "indiceAvaliacaoAutenticidade": null,
    "indiceFacematch": null,
    "tipoDocumento": "RG",
    "cpf": "11122233344",
    "origin": "document-analysis",
    "originKey": "xyz789-uvw456",
    "customerId": "trustic",
    "externalId": "LOTE-2026-003",
    "penalidades": [],
    "codigoRejeicao": [
      {
        "tipo": "RG",
        "codigo": "doc001",
        "motivo": "Documento ilegível",
        "docId": 215172
      }
    ],
    "docs": [
      {
        "docName": "Documento de Identidade",
        "docId": 215172,
        "docType": "doc_identidade",
        "type": "rg",
        "keys": []
      }
    ]
  }
  ```
</CodeGroup>

### Campos Principais

<AccordionGroup>
  <Accordion title="Informações de Processamento" defaultOpen icon="clock">
    <ResponseField name="dataInicio" type="string">
      Data e hora de início do processamento (formato: `DD/MM/YYYY HH:MM:SS`)
    </ResponseField>

    <ResponseField name="dataFinal" type="string">
      Data e hora de finalização do processamento
    </ResponseField>

    <ResponseField name="codigoControle" type="integer">
      Código único de controle da transação
    </ResponseField>
  </Accordion>

  <Accordion title="Resultado da Análise" icon="check-circle">
    <ResponseField name="result" type="integer">
      Código do resultado da validação:

      | Código | Status        | Significado                                                                      |
      | ------ | ------------- | -------------------------------------------------------------------------------- |
      | `0`    | **Aprovado**  | Documento validado com sucesso                                                   |
      | `1`    | **Pendente**  | Análise inconclusiva, rejeições por qualidade de imagem                          |
      | `2`    | **Rejeitado** | Documento rejeitado por inconsistências (penalidades) abaixo do mínimo permitido |
    </ResponseField>

    <ResponseField name="inconclusivo" type="boolean">
      Indica se a análise foi inconclusiva
    </ResponseField>
  </Accordion>

  <Accordion title="Índices de Confiança" icon="gauge-high">
    <ResponseField name="indiceAvaliacaoAutenticidade" type="integer">
      Índice percentual de autenticidade do documento (**0-100**)

      * **90-100**: Excelente
      * **70-89**: Bom
      * **50-69**: Regular
      * **0-49**: Baixo
    </ResponseField>

    <ResponseField name="indiceFacematch" type="integer">
      Índice percentual de correspondência facial (**0-100**)

      * **95-100**: Match muito alto
      * **85-94**: Match alto
      * **70-84**: Match moderado
      * **0-69**: Match baixo (rejeitar)

      <Info>
        Disponível apenas quando `workflowAlias = "poc_auto_face"` e selfie foi enviada.
      </Info>
    </ResponseField>
  </Accordion>

  <Accordion title="Dados do Titular" icon="user">
    <ResponseField name="tipoDocumento" type="string">
      Tipo do documento principal analisado (`RG`, `CNH`, `CPF`, etc)
    </ResponseField>

    <ResponseField name="cpf" type="string">
      CPF do titular do documento (apenas números)
    </ResponseField>
  </Accordion>

  <Accordion title="Rastreabilidade" icon="fingerprint">
    <ResponseField name="origin" type="string">
      Origem da análise
    </ResponseField>

    <ResponseField name="originKey" type="string">
      Chave identificadora da origem (UUID)
    </ResponseField>

    <ResponseField name="customerId" type="string">
      Identificador do cliente
    </ResponseField>

    <ResponseField name="externalId" type="string">
      Identificador externo da transação (seu `batchExternalId`)
    </ResponseField>
  </Accordion>
</AccordionGroup>

### Penalidades (PenalidadeDto)

Array de objetos contendo irregularidades encontradas durante a análise formalística.

<ResponseField name="penalidades" type="array">
  Lista de penalidades detectadas (vazio se aprovado sem ressalvas)

  **Estrutura:**

  ```json theme={"theme":"catppuccin-latte"}
  {
    "data": "14/04/2026 11:16:45",
    "valor": "MARIA",
    "descricao": "(OCR_02) Nome obtido no documento divergente do nome na RF",
    "regra": "ocr_02",
    "rulesType": 1
  }
  ```

  **Campos:**

  * `data` (string): Data e hora da detecção
  * `valor` (string): Valor associado (quando aplicável)
  * `descricao` (string): Descrição detalhada da penalidade
  * `regra` (string): Código da regra que gerou a penalidade
  * `rulesType` (integer): Tipo da regra
    * `1` = Automática (crítico - divergências com bases oficiais)
    * `2` = Manual
    * `3` = Híbrido (alerta - características suspeitas)
</ResponseField>

<Accordion title="Códigos de Penalidade Comuns">
  **RG (Registro Geral)**

  | Código  | Descrição                                                  |
  | ------- | ---------------------------------------------------------- |
  | `rg_05` | Existe letra "E" entre a Filiação                          |
  | `rg_11` | Assinatura do Diretor divergente                           |
  | `rg_17` | Doc Origem alinhado incorretamente com 3ª letra do Titular |
  | `rg_37` | Formato do RG divergente                                   |
  | `rg_40` | Nome da Mãe antes do Nome do Pai                           |

  **OCR (Validação de Dados)**

  | Código   | Descrição                                                           |
  | -------- | ------------------------------------------------------------------- |
  | `ocr_02` | Nome obtido no documento divergente do nome na RF (Receita Federal) |
  | `ocr_03` | Data de Nascimento divergente da RF                                 |
  | `ocr_13` | Primeiro nome do titular divergente da RF                           |

  **CNH (Carteira Nacional de Habilitação)**

  | Código   | Descrição                                  |
  | -------- | ------------------------------------------ |
  | `cnh_08` | Campo Data Emissão Divergente no Datavalid |
  | `cnh_15` | CNH vencida                                |
  | `cnh_22` | Número de registro divergente              |
</Accordion>

### Códigos de Rejeição (CodigoRejeicaoDto)

Array de objetos contendo motivos de rejeição automática por problemas de qualidade.

<ResponseField name="codigoRejeicao" type="array">
  Lista de códigos de rejeição (vazio se qualidade OK)

  **Estrutura:**

  ```json theme={"theme":"catppuccin-latte"}
  {
    "tipo": "RG",
    "codigo": "doc001",
    "motivo": "Documento ilegível",
    "docId": 215172
  }
  ```

  **Campos:**

  * `tipo` (string): Tipo do documento rejeitado
  * `codigo` (string): Código do erro
  * `motivo` (string): Descrição do motivo
  * `docId` (integer): ID do documento rejeitado
</ResponseField>

<Accordion title="Códigos de Rejeição Comuns">
  | Código   | Descrição                                       |
  | -------- | ----------------------------------------------- |
  | `doc001` | Documento ilegível (baixa qualidade, desfocado) |
  | `doc002` | Documento incompleto (faltando frente ou verso) |
  | `doc003` | Documento danificado (rasgado, manchado)        |
  | `doc004` | Documento expirado                              |
  | `doc005` | Arquivo corrompido ou inválido                  |
</Accordion>

### Documentos Analisados (DocumentoDto)

<ResponseField name="docs" type="array">
  Lista de documentos analisados com dados extraídos via OCR

  **Estrutura:**

  ```json theme={"theme":"catppuccin-latte"}
  {
    "docName": "Documento de Identidade",
    "docId": 215170,
    "docType": "doc_identidade",
    "type": "cnh",
    "keys": [
      {
        "keyAlias": "nome",
        "keyName": "Nome",
        "value": "JOÃO DA SILVA"
      }
    ]
  }
  ```

  **Campos:**

  * `docName` (string): Nome descritivo do documento
  * `docId` (integer): Identificador único do documento
  * `docType` (string): Tipo técnico do documento
  * `type` (string): Categoria do documento (`rg`, `cnh`, `cpf`, etc)
  * `keys` (array): Campos extraídos pelo OCR
</ResponseField>

### Campos Extraídos (KeyDto)

<Accordion title="CNH - Carteira Nacional de Habilitação" icon="id-card">
  | keyAlias                | keyName               | Descrição                       |
  | ----------------------- | --------------------- | ------------------------------- |
  | `nome`                  | Nome                  | Nome completo do titular        |
  | `cpf`                   | CPF                   | Número do CPF                   |
  | `doc_identidade_numero` | Número RG             | Número do RG                    |
  | `doc_identidade_orgao`  | Órgão Expedidor RG    | Órgão emissor do RG             |
  | `doc_identidade_uf`     | UF Órgão Expedidor RG | UF do órgão emissor             |
  | `data_nascimento`       | Data Nascimento       | Data de nascimento (DD/MM/YYYY) |
  | `filiacao_pai`          | Filiação Pai          | Nome do pai                     |
  | `filiacao_mae`          | Filiação Mãe          | Nome da mãe                     |
  | `num_registro`          | Número Registro       | Número de registro da CNH       |
  | `data_validade`         | Data Validade         | Data de validade da CNH         |
  | `data_habilitacao`      | Data Habilitação      | Data da primeira habilitação    |
  | `data_emissao`          | Data Emissão          | Data de emissão da CNH          |
  | `orgao_emissor`         | Órgão Emissor         | Órgão emissor (DETRAN)          |
  | `detran_uf`             | Detran UF             | UF do DETRAN                    |
  | `security_code_1`       | Número Segurança      | Código de segurança 1           |
  | `security_code_2`       | Renach                | Código Renach                   |
  | `num_espelho`           | Número Espelho        | Número espelho da CNH           |
</Accordion>

<Accordion title="RG - Registro Geral" icon="id-card">
  | keyAlias                | keyName             | Descrição                |
  | ----------------------- | ------------------- | ------------------------ |
  | `nome`                  | Nome                | Nome completo do titular |
  | `cpf`                   | CPF                 | Número do CPF            |
  | `doc_identidade_numero` | Número Documento    | Número do RG             |
  | `doc_identidade_orgao`  | Órgão Expedidor     | Órgão emissor            |
  | `doc_identidade_uf`     | UF Órgão Expedidor  | UF do órgão emissor      |
  | `data_nascimento`       | Data Nascimento     | Data de nascimento       |
  | `data_expedicao`        | Data Expedição      | Data de expedição        |
  | `filiacao_pai`          | Filiação Pai        | Nome do pai              |
  | `filiacao_mae`          | Filiação Mãe        | Nome da mãe              |
  | `naturalidade_cidade`   | Naturalidade Cidade | Cidade de nascimento     |
  | `naturalidade_uf`       | Naturalidade UF     | UF de nascimento         |
</Accordion>

***

## 7. Fluxo de Interpretação do Webhook

<Steps>
  <Step title="1. Verificar result">
    ```javascript theme={"theme":"catppuccin-latte"}
    if (result === 0) {
      // Aprovado - Prosseguir com o processo
    } else if (result === 1) {
      // Pendente - Verificar codigoRejeicao Reenviar documentos com melhor qualidade
    } else if (result === 2) {
      // Rejeitado -  Verificar penalidades
    }
    ```
  </Step>

  <Step title="2. Analisar codigoRejeicao">
    Se não vazio, contém motivos de rejeição automática (documento ilegível, incompleto ou danificado).
  </Step>

  <Step title="3. Examinar penalidades" />

  <Step title="4. Consultar docs">
    Acessar dados extraídos dos documentos via OCR.
  </Step>

  <Step title="5. Verificar índices de confiança">
    * `indiceAvaliacaoAutenticidade`: 0-100 (quanto maior, melhor)
    * `indiceFacematch`: 0-100 (> 70 recomendado)
  </Step>
</Steps>

***

## 8. Boas Práticas

<AccordionGroup>
  <Accordion title="Segurança" icon="shield">
    * **Nunca** exponha `client_secret` em repositórios públicos
    * Use variáveis de ambiente para armazenar credenciais
    * Implemente autenticação no webhook (token, Basic Auth)
    * Use HTTPS em produção
    * Rotacione secrets periodicamente (a cada 90 dias)
    * Valide a origem das requisições do webhook (whitelist de IPs)
  </Accordion>

  <Accordion title="Performance" icon="gauge-high">
    * Limite lotes a **10-20 documentos** por requisição para melhor performance
    * Otimize imagens antes do envio (resolução 300 DPI recomendada)
    * Use compressão de PDFs quando possível
    * Para grandes volumes, processe em lotes paralelos (máx 5 simultâneos)
    * Monitore o tamanho total do request (limite: 50MB recomendado)
    * Cache tokens válidos (expire em 55 minutos para margem de segurança)
  </Accordion>

  <Accordion title="Qualidade de Imagem" icon="image">
    * **Resolução mínima**: 300 DPI
    * **Formato preferencial**: PDF para documentos, PNG para selfies
    * **Iluminação**: Boa iluminação natural ou artificial uniforme
    * **Foco**: Imagens nítidas, sem desfoque
    * **Enquadramento**: Documento completo, sem cortes
    * **Sem reflexos**: Evite flash direto em documentos plastificados
    * **Merge RG**: Combine frente e verso em um único PDF
  </Accordion>

  <Accordion title="Rastreabilidade" icon="timeline">
    * Sempre preencha `batchExternalId` com identificador único
    * Use padrão consistente: `{origem}-{cliente}-{timestamp}`
    * Exemplo: `"PORTAL-12345-20260414103015"`
    * Armazene `batchId` retornado para consultas futuras
    * Mantenha log de todas as importações (request + response)
    * Implemente monitoramento de webhooks (alertas se não receber em X minutos)
  </Accordion>

  <Accordion title="Tratamento de Erros" icon="bug">
    * Implemente retry com **backoff exponencial** para erros 5xx
      * 1ª tentativa: aguardar 1s
      * 2ª tentativa: aguardar 2s
      * 3ª tentativa: aguardar 4s
      * Máximo de 3 tentativas
    * Para erro 400, **não reprocesse** - corrija os dados
    * Para erro 401, renove o token e tente novamente
    * Monitore logs para identificar padrões de falha
    * Configure alertas para taxa de erro > 5%
    * Mantenha auditoria de tentativas de importação
  </Accordion>

  <Accordion title="Webhook - Implementação" icon="webhook">
    * **Responda rapidamente**: Retorne HTTP 200 em \< 3 segundos
    * **Processe assincronamente**: Salve dados e processe em background
    * **Implemente idempotência**: Webhook pode ser reenviado
    * **Valide assinatura**: Se configurado, valide header de autenticação
    * **Log completo**: Registre payload recebido para debugging
    * **Retry do webhook**: Sistema tenta reenviar 3x em caso de falha
  </Accordion>
</AccordionGroup>

***

## 9. Ambientes

<Tabs>
  <Tab title="Desenvolvimento (DEV)">
    ### URLs

    * **API Import**: `https://flex-des.flexdoc-apis.com.br/import`
    * **SSO (Keycloak)**: `https://auth-des.flexdoc-apis.com.br`
    * **Realm**: `fleximage`

    ### Credenciais (Exemplo)

    * **CLIENT\_ID**: `teste-api`
    * **CLIENT\_SECRET**: `vveMLSHnasVxzKWchN0DpeEawG4UlXxs`

    <Warning>
      Credenciais de desenvolvimento são fornecidas no email de boas-vindas.
    </Warning>
  </Tab>

  <Tab title="Produção (PROD)">
    ### URLs

    * **API Import**: `https://fcvs-flexdoc-apis.com.br/import`
    * **SSO (Keycloak)**: `https://auth.flexdoc-apis.com.br`
    * **Realm**: `fleximage`

    ### Credenciais

    <Info>
      🔒 Credenciais de produção são fornecidas separadamente pelo time de integração após homologação completa.
    </Info>

    ### Processo de Go-Live

    <Steps>
      <Step title="Homologação Completa">
        Teste todos os fluxos em ambiente DEV
      </Step>

      <Step title="Solicitar Credenciais PROD">
        Envie email para `integracao@flexdoc.com.br`
      </Step>

      <Step title="Configurar Webhook PROD">
        Forneça URL de produção e método de autenticação
      </Step>

      <Step title="Testes Piloto">
        Execute testes limitados em PROD
      </Step>

      <Step title="Go-Live">
        Libere para uso geral
      </Step>
    </Steps>
  </Tab>
</Tabs>

***
