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

# Platform Docs Gateway

> Gateway de documentoscopia para importação, acompanhamento e consulta de documentos

## Visão Geral

A API Platform Docs Gateway centraliza a entrada de documentos da plataforma FlexDoc, valida os arquivos enviados, registra auditoria e orquestra o envio ao FlexImage/Backoffice. O gateway também expõe endpoints para acompanhar status, consultar resultados, recuperar arquivos processados, configurar parâmetros por projeto e receber webhooks de processamento.

<CardGroup cols={2}>
  <Card title="Importação de Documentos" icon="file-up">
    Recebe frente, verso e selfie em Base64 via JSON
  </Card>

  <Card title="Orquestração FlexImage" icon="workflow">
    Envia documentos ao Backoffice com workflow e preset configuráveis
  </Card>

  <Card title="Acompanhamento de Status" icon="activity">
    Lista, filtra e consulta documentos por organização e projeto
  </Card>

  <Card title="Auditoria e Webhook" icon="shield-check">
    Persiste eventos e recebe resultados do Backoffice
  </Card>
</CardGroup>

***

## Fluxo de Documentoscopia

<Steps>
  <Step title="Autenticação">
    Envie `x-api-key` ou `Authorization: Bearer` com os headers de organização/projeto.
  </Step>

  <Step title="Preparar Arquivos">
    Converta documentos para Data URI Base64. Frente é obrigatória; verso e selfie são opcionais.
  </Step>

  <Step title="Importar Documentos">
    Faça `POST /api/v1/documents/import`. O gateway valida CPF, tipo de arquivo, tamanho e assinatura do conteúdo.
  </Step>

  <Step title="Enviar ao FlexImage">
    O gateway cria o registro local, resolve parâmetros de workflow e envia multipart/form-data ao FlexImage.
  </Step>

  <Step title="Receber Resultado">
    O Backoffice chama `/api/v1/webhooks/backoffice` e o gateway atualiza status, resultado e auditoria.
  </Step>
</Steps>

***

## Ambientes

| Ambiente        | Base URL                                             |
| --------------- | ---------------------------------------------------- |
| Desenvolvimento | `https://dev-docs-gateway-api.services-valid.com.br` |
| Homologação     | `https://hml-docs-gateway-api.services-valid.com.br` |
| Produção        | `https://docs-gateway-api.services-valid.com.br`     |
| Local           | `http://localhost:3000`                              |
| Proxy Apigee    | `/docs-gateway`                                      |

<Info>
  Em ambiente de desenvolvimento, a documentação OpenAPI fica disponível em `/docs` e o JSON em `/openapi.json`.
</Info>

***

## Authentication

As rotas protegidas de `/api/v1/*` aceitam duas estratégias de autenticação. Webhooks usam `x-secret-token`.

<ParamField header="x-api-key" type="string">
  API key validada na Platform API.

  **Formato:** `x-api-key: {api_key}`

  **Uso recomendado:** integrações server-to-server que já possuem chave do projeto.
</ParamField>

<ParamField header="Authorization" type="string">
  Bearer token validado na Platform API.

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

  Quando usar Bearer, informe também:

  * `x-organization-id`
  * `x-project-id`
</ParamField>

<ParamField header="x-secret-token" type="string">
  Token secreto usado exclusivamente por rotas administrativas/webhooks, como `/api/v1/webhooks/backoffice`.

  **Formato:** `x-secret-token: {secret_token}`
</ParamField>

<Note>
  Todas as respostas incluem ou propagam `requestId` quando disponível, facilitando correlação em logs, auditoria e suporte.
</Note>

***

## Importar Documentos

<ParamField path="POST /api/v1/documents/import" type="endpoint" required>
  Importa documentos para análise de documentoscopia.

  **Content-Type:** `application/json`

  **Tamanho máximo do body:** 25 MB
</ParamField>

### Request Body

<ParamField body="cpf" type="string" required>
  CPF do titular do documento.

  **Formato:** 11 dígitos, com ou sem máscara.

  **Validações:** tamanho de 11 dígitos e dígitos verificadores válidos.

  **Exemplo:** `"12345678909"`
</ParamField>

<ParamField body="documents.identification.front" type="string" required>
  Frente do documento em Data URI Base64.

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

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

  **Exemplo:**

  ```json theme={"theme":"catppuccin-latte"}
  "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
  ```
</ParamField>

<ParamField body="documents.identification.back" type="string">
  Verso do documento em Data URI Base64.

  Quando informado, o gateway une frente e verso em um PDF antes de enviar ao FlexImage.

  **Formatos aceitos:** JPG, JPEG, PNG e PDF
</ParamField>

<ParamField body="selfie" type="string">
  Selfie do titular em Data URI Base64.

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

  <Info>
    Selfie não aceita PDF.
  </Info>
</ParamField>

<ResponseExample>
  ```json Request theme={"theme":"catppuccin-latte"}
  {
    "cpf": "12345678909",
    "documents": {
      "identification.front": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...",
      "identification.back": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
    },
    "selfie": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
  }
  ```
</ResponseExample>

### Response

<ResponseField name="requestId" type="string" required>
  Identificador da requisição gerado pelo gateway.
</ResponseField>

<ResponseField name="documentId" type="string" required>
  UUID do documento criado no gateway.
</ResponseField>

<ResponseField name="batchExternalId" type="string" required>
  Identificador externo enviado ao FlexImage. Por padrão, usa o `requestId`.
</ResponseField>

<ResponseField name="backofficeBatchId" type="string" required>
  Identificador do lote no Backoffice/FlexImage.
</ResponseField>

<ResponseField name="flexImageResponse" type="unknown" required>
  Resposta bruta retornada pelo FlexImage no envio do lote.
</ResponseField>

<ResponseExample>
  ```json Sucesso - 200 OK theme={"theme":"catppuccin-latte"}
  {
    "requestId": "7d7a6f2b-8d9f-4f55-9a2d-ec8e7b4f1d0c",
    "documentId": "123e4567-e89b-12d3-a456-426614174000",
    "batchExternalId": "7d7a6f2b-8d9f-4f55-9a2d-ec8e7b4f1d0c",
    "backofficeBatchId": "229462",
    "flexImageResponse": {
      "id": "229462",
      "status": "created"
    }
  }
  ```

  ```json Erro 400 - Arquivo Inválido theme={"theme":"catppuccin-latte"}
  {
    "error": "FLEXIMAGE_IMPORT_FAILED",
    "message": "Invalid file type for selfie: \"application/pdf\". Allowed types: jpg, jpeg, png",
    "requestId": "7d7a6f2b-8d9f-4f55-9a2d-ec8e7b4f1d0c",
    "timestamp": "2026-06-01T12:00:00.000Z"
  }
  ```

  ```json Erro 401 - Não Autenticado theme={"theme":"catppuccin-latte"}
  {
    "error": "UNAUTHORIZED",
    "message": "Missing x-api-key header or Bearer token authentication headers (Authorization: Bearer, x-organization-id, x-project-id)",
    "requestId": "7d7a6f2b-8d9f-4f55-9a2d-ec8e7b4f1d0c",
    "timestamp": "2026-06-01T12:00:00.000Z"
  }
  ```
</ResponseExample>

***

## Consultar Documentos

<AccordionGroup>
  <Accordion title="GET /api/v1/documents" icon="list">
    Lista documentos do escopo autenticado com filtros, ordenação e paginação.

    **Query params:**

    | Campo                 | Tipo   | Descrição                                                                                        |
    | --------------------- | ------ | ------------------------------------------------------------------------------------------------ |
    | `cpf`                 | string | CPF do titular, com ou sem máscara                                                               |
    | `name`                | string | Busca parcial por nome do titular                                                                |
    | `workflowPresetAlias` | string | Filtro exato por preset de workflow                                                              |
    | `status`              | string | Status técnico do documento                                                                      |
    | `consolidatedStatus`  | string | `processing`, `error`, `approved`, `rejected` ou `pending`                                       |
    | `createdFrom`         | string | Início do intervalo de criação em ISO 8601                                                       |
    | `createdTo`           | string | Fim do intervalo de criação em ISO 8601                                                          |
    | `sortBy`              | string | `createdAt`, `updatedAt`, `sentAt`, `finishedAt`, `status`, `cpf`, `name`, `workflowPresetAlias` |
    | `sortOrder`           | string | `asc` ou `desc`                                                                                  |
    | `limit`               | number | Itens por página, de 1 a 100. Padrão: 20                                                         |
    | `offset`              | number | Itens ignorados na paginação. Padrão: 0                                                          |

    ```json Response theme={"theme":"catppuccin-latte"}
    {
      "items": [
        {
          "id": "123e4567-e89b-12d3-a456-426614174000",
          "organizationId": "org-123",
          "projectId": "project-456",
          "productId": "product-789",
          "cpf": "12345678909",
          "status": "COMPLETED",
          "type": "docs",
          "createdAt": "2026-06-01T12:00:00.000Z",
          "updatedAt": "2026-06-01T12:05:00.000Z",
          "sentAt": "2026-06-01T12:00:01.000Z",
          "sentToBackofficeAt": "2026-06-01T12:00:02.000Z",
          "finishedAt": "2026-06-01T12:05:00.000Z",
          "errorMessage": null,
          "errorCode": null,
          "backofficeBatchId": "229462",
          "requestId": "7d7a6f2b-8d9f-4f55-9a2d-ec8e7b4f1d0c",
          "name": "JOAO DA SILVA",
          "workflow_preset_alias": "documentoscopia_auto_15min",
          "result": {
            "id": "223e4567-e89b-12d3-a456-426614174001",
            "documentId": "123e4567-e89b-12d3-a456-426614174000",
            "status": "APPROVED",
            "confidenceScore": 98.5,
            "raw_response": {},
            "processedBy": "backoffice",
            "createdAt": "2026-06-01T12:05:00.000Z"
          }
        }
      ],
      "pagination": {
        "total": 1,
        "limit": 20,
        "offset": 0
      }
    }
    ```
  </Accordion>

  <Accordion title="GET /api/v1/documents/{id}" icon="file-search">
    Retorna os dados completos de um documento, incluindo o resultado do processamento quando disponível.

    **Path param:**

    | Campo | Tipo | Descrição         |
    | ----- | ---- | ----------------- |
    | `id`  | uuid | UUID do documento |

    <Note>
      A consulta respeita o escopo de organização e projeto associado à autenticação.
    </Note>
  </Accordion>

  <Accordion title="GET /api/v1/documents/{id}/files" icon="files">
    Recupera os arquivos processados em Base64 diretamente no FlexImage.

    **Disponibilidade:** apenas depois que o documento possui `backofficeBatchId`, normalmente após envio/processamento.

    ```json Response theme={"theme":"catppuccin-latte"}
    {
      "files": [
        {
          "docId": 229462,
          "fileName": "doc_229462.jpg",
          "fileType": "jpg",
          "base64Content": "/9j/4AAQSkZJRgABAQAAAQ...",
          "typeAlias": "identification_front",
          "typeName": "identification_front"
        }
      ]
    }
    ```

    **Erros comuns:**

    | Status | Erro                  | Quando ocorre                         |
    | ------ | --------------------- | ------------------------------------- |
    | `404`  | `NOT_FOUND`           | Documento não encontrado              |
    | `422`  | `FILES_NOT_AVAILABLE` | Documento sem `backofficeBatchId`     |
    | `502`  | `FLEXIMAGE_ERROR`     | Falha ao buscar arquivos no FlexImage |
  </Accordion>

  <Accordion title="GET /api/v1/documents/statistics" icon="chart-column">
    Retorna contagens consolidadas por estado.

    ```json Response theme={"theme":"catppuccin-latte"}
    {
      "processing": 12,
      "error": 2,
      "approved": 80,
      "rejected": 5,
      "pending": 3
    }
    ```

    **Regras de consolidação:**

    | Campo        | Critério                                                           |
    | ------------ | ------------------------------------------------------------------ |
    | `processing` | Documentos com status `PENDING`, `SENDING` ou `SENT`               |
    | `error`      | Documentos com status `ERROR`                                      |
    | `approved`   | Documentos `COMPLETED` com resultado `APPROVED`                    |
    | `rejected`   | Documentos `COMPLETED` com resultado `REJECTED` ou `MANUAL_REVIEW` |
    | `pending`    | Documentos `COMPLETED` ainda sem resultado                         |
  </Accordion>
</AccordionGroup>

***

## Status e Resultados

<AccordionGroup>
  <Accordion title="Status do Documento" icon="rotate">
    | Status       | Descrição                       |
    | ------------ | ------------------------------- |
    | `PENDING`    | Documento registrado no gateway |
    | `MERGING`    | Arquivos em etapa de união      |
    | `UPLOADING`  | Arquivos em etapa de upload     |
    | `SENDING`    | Envio ao FlexImage em andamento |
    | `SENT`       | Lote enviado ao FlexImage       |
    | `PROCESSING` | Processamento em andamento      |
    | `COMPLETED`  | Processamento concluído         |
    | `ERROR`      | Erro registrado pelo gateway    |
    | `FAILED`     | Falha de processamento          |
    | `TIMEOUT`    | Tempo limite excedido           |
  </Accordion>

  <Accordion title="Resultado de Análise" icon="badge-check">
    | Status          | Descrição                             |
    | --------------- | ------------------------------------- |
    | `APPROVED`      | Documento aprovado                    |
    | `REJECTED`      | Documento rejeitado                   |
    | `MANUAL_REVIEW` | Documento enviado para revisão manual |
    | `ERROR`         | Resultado com erro                    |
  </Accordion>
</AccordionGroup>

***

## Parâmetros de Projeto

Os parâmetros permitem ajustar workflow, preset e checklist por organização/projeto autenticado. Quando não há parâmetro salvo, o gateway usa os defaults configurados por variável de ambiente.

<ParamField path="GET /api/v1/parameters" type="endpoint">
  Lista parâmetros do projeto autenticado.
</ParamField>

<ParamField path="POST /api/v1/parameters" type="endpoint">
  Cria ou atualiza um parâmetro.
</ParamField>

<ParamField body="key" type="string" required>
  Chave do parâmetro.

  **Formato:** letras maiúsculas, números e `_`.

  **Exemplos aceitos:**

  * `PARAMETER_WORKFLOW_ALIAS`
  * `PARAMETER_WORKFLOW_PRESET_ALIAS`
  * `PARAMETER_CHECKLIST_CODE`
  * `PARAMETER_CHECKLIST_GROUP`
  * `PARAMETER_CHECKLIST_VERSION`
</ParamField>

<ParamField body="value" type="string" required>
  Valor do parâmetro.
</ParamField>

<ResponseExample>
  ```json Request theme={"theme":"catppuccin-latte"}
  {
    "key": "PARAMETER_WORKFLOW_PRESET_ALIAS",
    "value": "documentoscopia_auto_15min"
  }
  ```

  ```json Response theme={"theme":"catppuccin-latte"}
  {
    "id": "323e4567-e89b-12d3-a456-426614174002",
    "organizationId": "123e4567-e89b-12d3-a456-426614174000",
    "projectId": "223e4567-e89b-12d3-a456-426614174001",
    "key": "PARAMETER_WORKFLOW_PRESET_ALIAS",
    "value": "documentoscopia_auto_15min",
    "createdAt": "2026-06-01T12:00:00.000Z",
    "updatedAt": "2026-06-01T12:00:00.000Z"
  }
  ```
</ResponseExample>

***

## Presets de Workflow

<ParamField path="GET /api/v1/workflow-presets" type="endpoint">
  Lista os presets aceitos para envio ao FlexImage.
</ParamField>

| Alias                                    | Tipo   | Descrição                              |
| ---------------------------------------- | ------ | -------------------------------------- |
| `documentoscopia_mesa_base_face_15min`   | manual | Documentoscopia Mesa Base Face 15min   |
| `documentoscopia_mesa_base_face_30min`   | manual | Documentoscopia Mesa Base Face 30min   |
| `documentoscopia_mesa_base_face_1hora`   | manual | Documentoscopia Mesa Base Face 1hora   |
| `documentoscopia_mesa_base_face_2horas`  | manual | Documentoscopia Mesa Base Face 2horas  |
| `documentoscopia_mesa_base_face_4horas`  | manual | Documentoscopia Mesa Base Face 4horas  |
| `documentoscopia_mesa_base_face_8horas`  | manual | Documentoscopia Mesa Base Face 8horas  |
| `documentoscopia_mesa_base_face_24horas` | manual | Documentoscopia Mesa Base Face 24horas |
| `documentoscopia_auto_15min`             | auto   | Documentoscopia Auto 15min             |

***

## Webhook do Backoffice

<ParamField path="POST /api/v1/webhooks/backoffice" type="endpoint" required>
  Recebe o resultado do processamento de documentos feito pelo Backoffice.

  **Autenticação:** `x-secret-token`
</ParamField>

<ParamField body="external_id" type="string">
  Identificador externo usado para localizar o documento no gateway. Normalmente corresponde ao `requestId`/`batchExternalId`.
</ParamField>

<ParamField body="result" type="number">
  Código numérico de resultado recebido do Backoffice.
</ParamField>

<ParamField body="inconclusivo" type="boolean">
  Indica se o resultado foi inconclusivo.
</ParamField>

<ParamField body="penalidades" type="array">
  Lista de penalidades/regras aplicadas ao documento.
</ParamField>

<ResponseExample>
  ```json Request theme={"theme":"catppuccin-latte"}
  {
    "external_id": "7d7a6f2b-8d9f-4f55-9a2d-ec8e7b4f1d0c",
    "data_inicio": "2026-06-01T12:00:00.000Z",
    "data_final": "2026-06-01T12:05:00.000Z",
    "indice_avaliacao_autenticidade": 98.5,
    "indice_facematch": "97.0",
    "codigo_controle": 123,
    "penalidades": [],
    "result": 1,
    "inconclusivo": false,
    "tipo_documento": "RG",
    "cpf": "12345678909",
    "origin": "backoffice",
    "customer_id": "customer-123"
  }
  ```

  ```json Response - 200 OK theme={"theme":"catppuccin-latte"}
  {
    "received": true,
    "documentId": "123e4567-e89b-12d3-a456-426614174000"
  }
  ```

  ```json Erro 404 - Documento Não Encontrado theme={"theme":"catppuccin-latte"}
  {
    "error": "DOCUMENT_NOT_FOUND",
    "message": "Document not found"
  }
  ```
</ResponseExample>

***

## Health Checks

<AccordionGroup>
  <Accordion title="GET /health" icon="heart-pulse">
    Retorna status básico da aplicação.

    ```json Response theme={"theme":"catppuccin-latte"}
    {
      "status": "ok",
      "timestamp": "2026-06-01T12:00:00.000Z",
      "uptime": 3600,
      "version": "1.0.0"
    }
    ```
  </Accordion>

  <Accordion title="GET /health/ready" icon="database">
    Valida dependências necessárias para tráfego: PostgreSQL e Redis.

    ```json Response theme={"theme":"catppuccin-latte"}
    {
      "status": "ready",
      "checks": {
        "database": true,
        "redis": true
      },
      "timestamp": "2026-06-01T12:00:00.000Z"
    }
    ```
  </Accordion>

  <Accordion title="GET /health/live" icon="server">
    Retorna se o processo da aplicação está vivo.

    ```json Response theme={"theme":"catppuccin-latte"}
    {
      "status": "alive",
      "timestamp": "2026-06-01T12:00:00.000Z"
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Exemplos de Código

<CodeGroup>
  ```bash cURL theme={"theme":"catppuccin-latte"}
  curl -X POST "https://hml-docs-gateway-api.services-valid.com.br/api/v1/documents/import" \
    -H "x-api-key: ${API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{
      "cpf": "12345678909",
      "documents": {
        "identification.front": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
      },
      "selfie": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
    }'
  ```

  ```javascript JavaScript (Node.js) theme={"theme":"catppuccin-latte"}
  import { readFileSync } from "node:fs";

  function toDataUri(filePath, mimeType) {
    const base64 = readFileSync(filePath).toString("base64");
    return `data:${mimeType};base64,${base64}`;
  }

  async function importDocument() {
    const response = await fetch(
      "https://hml-docs-gateway-api.services-valid.com.br/api/v1/documents/import",
      {
        method: "POST",
        headers: {
          "x-api-key": process.env.API_KEY,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          cpf: "12345678909",
          documents: {
            "identification.front": toDataUri("./frente.jpg", "image/jpeg"),
            "identification.back": toDataUri("./verso.jpg", "image/jpeg"),
          },
          selfie: toDataUri("./selfie.png", "image/png"),
        }),
      }
    );

    const data = await response.json();

    if (!response.ok) {
      throw new Error(`${data.error}: ${data.message}`);
    }

    return data;
  }

  const result = await importDocument();
  console.log(result.documentId, result.backofficeBatchId);
  ```

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

  def to_data_uri(path: str, mime_type: str) -> str:
      with open(path, "rb") as file:
          encoded = base64.b64encode(file.read()).decode("utf-8")
      return f"data:{mime_type};base64,{encoded}"

  response = requests.post(
      "https://hml-docs-gateway-api.services-valid.com.br/api/v1/documents/import",
      headers={
          "x-api-key": os.environ["API_KEY"],
          "Content-Type": "application/json",
      },
      json={
          "cpf": "12345678909",
          "documents": {
              "identification.front": to_data_uri("./frente.jpg", "image/jpeg"),
          },
          "selfie": to_data_uri("./selfie.png", "image/png"),
      },
      timeout=30,
  )

  response.raise_for_status()
  print(response.json())
  ```
</CodeGroup>

***

## Operação Local

<Steps>
  <Step title="Instalar dependências">
    Execute `bun install`.
  </Step>

  <Step title="Subir infraestrutura">
    Execute `docker compose up -d` para PostgreSQL e Redis locais.
  </Step>

  <Step title="Configurar ambiente">
    Crie `.env` a partir dos valores necessários para PostgreSQL, Redis, Platform API, FlexImage e tokens.
  </Step>

  <Step title="Aplicar migrations">
    Execute `bun run migrate`.
  </Step>

  <Step title="Iniciar API">
    Execute `bun run dev` e acesse `http://localhost:3000/docs`.
  </Step>
</Steps>

### Variáveis Principais

| Variável                          | Descrição                                   | Padrão                                                                |
| --------------------------------- | ------------------------------------------- | --------------------------------------------------------------------- |
| `PORT`                            | Porta HTTP                                  | `3000`                                                                |
| `DATABASE_URL`                    | URL de conexão PostgreSQL                   | `postgresql://postgres:postgres@localhost:5432/platform_docs_gateway` |
| `REDIS_URL`                       | URL de conexão Redis                        | `redis://localhost:6379`                                              |
| `PLATFORM_API_BASE_URL`           | Base URL da Platform API                    | ambiente configurado                                                  |
| `PLATFORM_API_CLIENT_SECRET`      | Secret do cliente da Platform API           | obrigatório por ambiente                                              |
| `FLEXDOC_BASE_URL`                | Base URL do Keycloak/FlexDoc                | ambiente configurado                                                  |
| `FLEXDOC_CLIENT_SECRET`           | Secret client credentials do FlexDoc        | obrigatório por ambiente                                              |
| `FLEXIMAGE_API_BASE_URL`          | Base URL da API FlexImage                   | ambiente configurado                                                  |
| `FLEXIMAGE_WEBHOOK_URL`           | URL pública de webhook enviada ao FlexImage | vazio                                                                 |
| `SECRET_TOKEN`                    | Token esperado em webhooks                  | obrigatório para webhook                                              |
| `PARAMETER_WORKFLOW_ALIAS`        | Workflow default                            | `180seguros`                                                          |
| `PARAMETER_WORKFLOW_PRESET_ALIAS` | Preset default                              | `documentoscopia_auto_15min`                                          |

***

## Boas Práticas

<AccordionGroup>
  <Accordion title="Arquivos e Base64" icon="image">
    * Envie sempre Data URI completa: `data:image/jpeg;base64,...`
    * Use JPG/PNG para selfie.
    * Use JPG/PNG/PDF para documentos.
    * Mantenha cada arquivo abaixo de 5 MB.
    * Evite logar payloads com Base64 ou dados pessoais.
  </Accordion>

  <Accordion title="Autenticação" icon="key">
    * Prefira `x-api-key` para integrações server-to-server.
    * Em Bearer, envie também `x-organization-id` e `x-project-id`.
    * Rotacione secrets e tokens periodicamente.
    * Não exponha `x-secret-token` em clientes web ou aplicativos móveis.
  </Accordion>

  <Accordion title="Acompanhamento" icon="clock">
    * Guarde `documentId`, `requestId` e `backofficeBatchId`.
    * Consulte `/api/v1/documents/{id}` para status detalhado.
    * Use `/api/v1/documents/statistics` para dashboards e filas operacionais.
    * Trate `SENT` e `PROCESSING` como estados assíncronos.
  </Accordion>

  <Accordion title="Tratamento de Erros" icon="triangle-alert">
    | Status | Motivo comum                                    | Ação recomendada                          |
    | ------ | ----------------------------------------------- | ----------------------------------------- |
    | `400`  | CPF, Base64, tipo ou tamanho inválido           | Corrigir payload antes de reenviar        |
    | `401`  | Header de autenticação ausente ou inválido      | Renovar credencial/token                  |
    | `409`  | Requisição duplicada ou conflito de chave única | Verificar `requestId`/documento existente |
    | `422`  | Arquivos ainda indisponíveis                    | Aguardar conclusão do processamento       |
    | `502`  | Falha de integração com FlexImage               | Reprocessar com backoff e acompanhar logs |
  </Accordion>
</AccordionGroup>
