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

# Autenticação e erros

> Como autenticar suas requisições (API Key, Bearer Token ou sessionToken) e interpretar respostas de erro.

Todas as requisições à API devem incluir autenticação. Este documento descreve os mecanismos suportados e o formato de erros.

## Autenticação

### 1. API Key (`x-api-key`) — Server-to-Server

Use uma chave de API para operações administrativas e de integração (criar envelopes, gerenciar templates, listar signatários).

```bash theme={"theme":"catppuccin-latte"}
curl -X GET "https://signer.vcc-service.com/v1/envelopes" \
  -H "x-api-key: SEU_API_KEY"
```

A chave de API:

* Identifica seu projeto e organização automaticamente.
* Autoriza operações de qualquer scope (projeto).
* Deve ser mantida **segura e privada** — nunca versione-a ou exponha em código frontend.

### 2. Bearer Token (OAuth2/OIDC) — User-Delegated

Use um token Bearer quando a requisição é feita em nome de um usuário específico (ex: login de usuário de backoffice).

```bash theme={"theme":"catppuccin-latte"}
curl -X GET "https://signer.vcc-service.com/v1/envelopes/uuid/signed-document" \
  -H "Authorization: Bearer BEARER_TOKEN" \
  -H "x-project-id: SEU_PROJECT_ID" \
  -H "x-organization-id: SEU_ORGANIZATION_ID"
```

Bearer Token exige **três headers simultâneos**:

* `Authorization: Bearer <token>` — o token OAuth2/OIDC.
* `x-project-id` — UUID do projeto (não extraído do token, deve ser enviado explicitamente).
* `x-organization-id` — UUID da organização (não extraído do token, deve ser enviado explicitamente).

Omitir qualquer um deles resultará em **401 Unauthorized**.

### 3. Session Token (`sessionToken`) — Signer-Only

Endpoints do signatário (ex: `/v1/sign/:sessionToken`) não exigem nenhum header de autenticação — o `sessionToken` é a credencial.

```bash theme={"theme":"catppuccin-latte"}
curl -X GET "https://signer.vcc-service.com/v1/sign/abc123xyz/preview" \
  -H "Content-Type: application/json"
```

O `sessionToken`:

* É único para cada signatário, em cada envelope.
* Retornado na criação do envelope (campo `signers[].sessionToken`).
* Encapsula identidade e autorização — qualquer um que o possuir pode acessar e assinar.
* **Nunca inclua em logs ou transmita de forma não segura.**

### Qual mecanismo usar?

| Endpoint                                  | API Key | Bearer | Session Token |
| :---------------------------------------- | :------ | :----- | :------------ |
| `POST /v1/envelopes` (criar)              | ✓       | ✗      | ✗             |
| `GET /v1/envelopes` (listar)              | ✓       | ✓      | ✗             |
| `GET /v1/envelopes/:uuid` (detalhe)       | ✓       | ✓      | ✗             |
| `GET /v1/envelopes/:uuid/signed-document` | ✓       | ✓      | ✗             |
| `GET /v1/sign/:sessionToken` (sessão)     | ✗       | ✗      | ✓             |
| `POST /v1/sign/:sessionToken/sign`        | ✗       | ✗      | ✓             |
| `GET /v1/templates`                       | ✓       | ✓      | ✗             |

## Formato de respostas de erro

Erros retornam um envelope JSON estruturado:

<ResponseField name="statusCode" type="integer" required>
  Código HTTP da resposta (ex: 400, 401, 404).
</ResponseField>

<ResponseField name="message" type="string" required>
  Descrição legível do erro em português.
</ResponseField>

<ResponseField name="error" type="object" optional>
  Detalhes adicionais do erro (presente apenas em alguns casos).

  <Expandable title="Propriedades de error">
    <ResponseField name="code" type="string">
      Código interno do erro (ex: `ENVELOPE_NOT_FOUND`, `INVALID_CPF`).
    </ResponseField>

    <ResponseField name="details" type="string">
      Informações adicionais sobre o problema.
    </ResponseField>
  </Expandable>
</ResponseField>

### Exemplo de resposta de erro

```json theme={"theme":"catppuccin-latte"}
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "statusCode": 400,
  "message": "Unique constraint violation on field(s): externalCode",
  "error": {
    "code": "DUPLICATE_EXTERNAL_CODE",
    "details": "O código externo 'FAT-2025-001' já existe para este projeto."
  }
}
```

## Códigos de erro comuns

| HTTP    | Significado           | Ação                                                                                                                                                        |
| :------ | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **400** | Bad Request           | Validação falhou (campo obrigatório, formato inválido, valor inválido). Verifique a mensagem de erro e ajuste a requisição.                                 |
| **401** | Unauthorized          | Autenticação falhou (chave de API inválida/expirada, Bearer token ausente/inválido, ou header de projeto/organização faltando). Verifique suas credenciais. |
| **403** | Forbidden             | Autorização falhou (Bearer token válido, mas sem permissão para este recurso). Verifique as permissões do usuário.                                          |
| **404** | Not Found             | Recurso não encontrado (envelope, template, signatário não existe). Verifique o UUID.                                                                       |
| **409** | Conflict              | Conflito de estado ou constraint (ex: envelope já finalizado, campo já preenchido, CPF duplicado). Verifique o estado atual.                                |
| **410** | Gone                  | Recurso expirou ou foi removido (ex: sessionToken expirou, envelope foi excluído). Solicite um novo token ou crie um novo envelope.                         |
| **422** | Unprocessable Entity  | Payload válido em formato, mas inválido em lógica (ex: template com campos obrigatórios sem valores). Verifique a regra de negócio violada.                 |
| **500** | Internal Server Error | Erro no servidor. Tente novamente; se persistir, contate o suporte.                                                                                         |
| **503** | Service Unavailable   | Serviço temporariamente indisponível (ex: Lacuna RestPKI offline, banco de dados inacessível). Aguarde e tente novamente.                                   |

## Tratamento de erros recomendado

```javascript theme={"theme":"catppuccin-latte"}
// Pseudocódigo
try {
  const response = await fetch("https://signer.vcc-service.com/v1/envelopes", {
    method: "POST",
    headers: {
      "x-api-key": "YOUR_API_KEY",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ /* ... */ })
  });

  if (!response.ok) {
    const error = await response.json();
    
    // statusCode 401 → credenciais inválidas
    if (error.statusCode === 401) {
      console.error("Autenticação falhou:", error.message);
      // Tente refrescar a chave de API ou token
    }
    
    // statusCode 400 → validação
    if (error.statusCode === 400) {
      console.error("Entrada inválida:", error.message);
      // Retorne ao usuário para corrigir
    }
    
    // statusCode 5xx → servidor indisponível
    if (error.statusCode >= 500) {
      console.error("Erro no servidor, tente novamente em breve");
      // Implemente retry com backoff exponencial
    }
    
    throw new Error(error.message);
  }
  
  const data = await response.json();
  return data;
} catch (err) {
  console.error("Erro na requisição:", err);
}
```

## Dicas de depuração

* **Verifique os headers**: Certifique-se de que `x-api-key` (ou `Authorization` + `x-project-id` + `x-organization-id`) está presente em toda requisição de administrador.
* **Valide o sessionToken**: Se um signatário vê erro **410**, o token expirou — solicite um novo via `PATCH` no signatário ou crie um novo envelope.
* **Logs de auditoria**: Use `GET /v1/envelopes/:uuid/history` para ver o histórico completo de um envelope (incluindo IPs, timestamps, falhas de verificação).
* **Sandbox/testes**: Use credenciais de desenvolvimento até validar o fluxo completo; só então migre para credenciais de produção.

## Próximas páginas

Veja o contrato de cada operação na seção [API](/plataforma/assinatura-digital/api/post-envelope).
