# Visão Geral da API

A API Monetarie permite integrar pagamentos PIX ao seu sistema. Todas as operações exigem API Key e IP Whitelist; endpoints `POST` adicionam HMAC-SHA512 sobre o body.

## URL Base

| Ambiente | URL |
|----------|-----|
| Produção | `https://api.monetarie.com` |
| Homologação | `https://api-h.monetarie.com` |

## Autenticação

Camadas de segurança (por tipo de requisição):

1. **IP Whitelist** (todas) -- IP de origem deve estar na whitelist configurada na API Key
2. **API Key** (todas) -- Header `Authorization: ApiKey {client_id}:{client_secret}` em todas as requisições
3. **HMAC-SHA512** (apenas `POST`) -- Assinatura do body da requisição; obrigatório em `POST /pix/cash-in`, `POST /pix/cash-out`, `POST /cpf/validate`, `POST /webhooks`, `POST /pix/refund`. Requisições `GET` e `DELETE` **não** carregam HMAC (não possuem body a assinar).

:::warning Ordem alfabética obrigatória no body HMAC
Requests POST que exigem HMAC devem assinar o body com **chaves em ordem alfabética**. O backend faz `Jason.decode + Jason.encode!` no body para validação, o que reordena as chaves. Se seu client não alfabetizar antes de assinar, o HMAC computado localmente não bate com o do servidor → HTTP 401.

Detalhes completos: [HMAC-SHA512](/hmac).
:::

Veja [Autenticação](/auth-token) e [HMAC-SHA512](/hmac) para detalhes.

## Formato

| Campo | Formato |
|-------|---------|
| Content-Type | `application/json` |
| Valores de entrada (request) | Inteiros em **centavos** (R$ 1,00 = `100`) |
| Valores de resposta | Inteiros em **subcentavos** (unidades base; R$ 1,00 = `10000`, ÷ 10.000 para reais) |
| Datas | ISO 8601 em UTC com sufixo `Z` (`2026-03-09T15:30:00Z`) |
| IDs | UUID v4 ou string alfanumérica |
| E2E ID | `^E\d{8}[a-zA-Z0-9]{22,26}$` (padrão BACEN, 31-35 chars, sufixo pode conter letras) |

::: tip Terminologia
Nesta documentação, **subcentavos** e **unidades base** referem-se à mesma unidade (10.000 = R$ 1,00). O termo "unidades base" aparece em alguns exemplos herdados; considere-o sinônimo de subcentavos. Sempre divida o valor da resposta por 10.000 para obter reais.
:::

::: warning E2E pode conter letras
O sufixo após `E + ISPB + timestamp` é **alfanumérico de 9 a 13 caracteres** (não só dígitos). Bancos como Nubank emitem E2Es com letras no final. Sempre valide com a regex completa. Detalhes em [PIX Cash-In por E2E ID](/pix-cashin-e2e).
:::

::: danger Conversão de valores
**Para enviar**: multiplique reais por 100. R$ 1,00 = `100`.
**Para ler respostas**: divida por 10.000. `10000` ÷ 10.000 = R$ 1,00.
**Nunca use ponto flutuante** -- sempre inteiros.
:::

## Case das chaves (camelCase opcional)

Respostas JSON usam `snake_case` por padrão (ex.: `transaction_id`, `end_to_end_id`). Se o seu cliente preferir `camelCase`, envie o header:

```
X-Key-Case: camelCase
```

O backend converte **todas as chaves do JSON de resposta** (incluindo objetos aninhados) automaticamente. Exemplo: `transaction_id` → `transactionId`, `pix_key_type` → `pixKeyType`. O header não afeta o body de entrada - envie sempre em `snake_case` ao fazer `POST`.

## Padrão de Resposta

### Sucesso

```json
{
  "worked": true,
  "transaction_id": "PIXOUT20260309abcdef123456",
  "status": "processing"
}
```

### Erro

O formato do erro varia conforme a camada que rejeitou a requisição:

```json
// Plug HMAC (401 assinatura inválida)
{ "worked": false, "detail": "Invalid HMAC signature" }

// ApiKeyAuth (401 / 403)
{ "error": { "status": 401, "message": "Invalid API key" } }

// Respostas de erro da API (404 / 400 / 409 / 422 / 500)
{ "errors": { "not_found": "transaction not found" } }
```

Veja a tabela completa em [Autenticação -- Respostas de Erro](/auth-token#respostas-de-erro).

## Códigos HTTP

| Código | Significado |
|--------|------------|
| 200 | Sucesso |
| 201 | Recurso criado (webhook) |
| 400 | Parâmetros inválidos |
| 401 | API Key ausente ou inválida / HMAC inválido |
| 403 | IP não autorizado na whitelist |
| 404 | Recurso não encontrado |
| 422 | Validação falhou (saldo insuficiente, chave inválida) |
| 429 | Rate limit excedido |
| 500 | Erro interno |

## Rate Limiting

| Tipo | Limite |
|------|--------|
| Por IP (autenticado) | 90.000 requisições/minuto (1.500 req/s) |
| Por IP (autenticação / login) | 5 requisições/minuto |
| `GET /balance` | **sem rate limit** (polling alta frequência permitido) |

Headers de resposta:

```
X-RateLimit-Remaining: 59997
Retry-After: 3  (apenas quando 429)
```

## Idempotência

Requisições POST aceitam o header `Idempotency-Key` (máx. **256 caracteres**) para evitar processamento duplicado. Somente respostas **2xx (sucesso)** são cacheadas por 24 horas. Se a mesma chave for reenviada para o mesmo método e endpoint, a API retorna a resposta original com o header `X-Idempotent-Replay: true`.

```
Idempotency-Key: unique-request-id-123
```

::: tip Escopo da chave
A chave é vinculada a `método + path + Idempotency-Key`. A mesma chave pode ser reutilizada em endpoints diferentes sem colidir. Respostas de erro (4xx/5xx) **não** são cacheadas -- o cliente pode retentar após corrigir a falha.
:::

::: info GET/DELETE e Idempotency-Key
Requisições `GET` e `DELETE` **ignoram** silenciosamente o header `Idempotency-Key` -- o plug só atua em `POST`. Enviar a chave nesses métodos não causa erro, mas não gera cache nem replay.
:::

## Políticas de retry e quarentena

- **Quarentena (stage=5)**: PIX Cash-Out preso em `status: "processing"` por mais de 30 minutos é movido para quarentena, onde permanece aguardando resolução manual pela equipe Monetarie. O status continua `"processing"` da perspectiva do cliente até a finalização. Detalhes no fluxo: [PIX Lifecycle](/pix-lifecycle).
- **Retry automático de webhooks**: deliveries com falha (timeout, 5xx, conexão fechada) são reagendadas em até 7 tentativas (intervalos `[0, 30s, 2min, 10min, 30min, 1h, 2h, 4h]`). Veja [Webhooks](/webhooks).
- **Retry do client**: ao receber `429`, respeite `Retry-After`. Ao receber `500` ou timeout, use backoff exponencial + `Idempotency-Key` para evitar duplicação. Veja [Autenticação](/auth-token) para detalhes.
- **Janela anti-replay do webhook**: o header `X-Monetarie-Timestamp` é Unix time em segundos. O servidor **não** rejeita webhooks antigos; cabe ao seu endpoint descartar entregas com `|now - timestamp| > 300s` (± 5 minutos) como defense-in-depth contra replay. Veja [Webhooks -- Validando a Assinatura](/webhooks#validando-a-assinatura).

## External ID

Campo opcional `external_id` (max 128 chars, alfanumérico + `._:-`) aceito em cash-in e cash-out. Retornado em respostas e webhooks. Permite consulta por referência:

```
GET /api/external/transactions/ref/{external_id}
```

Veja [Conceitos](/guide/concepts) para detalhes.

## Endpoints

### PIX Cash-Out (Envio)

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| POST | `/api/external/pix/cash-out` | Enviar PIX por chave ou copia-e-cola |

### PIX Cash-In (Recebimento)

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| POST | `/api/external/pix/cash-in` | Gerar QR Code para recebimento |

### Consultas

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| GET | `/api/external/transactions` | Listar transações |
| GET | `/api/external/transactions/:id` | Consultar transação por ID |
| GET | `/api/external/transactions/e2e/:e2e_id` | Consultar por E2E ID |
| GET | `/api/external/transactions/tag/:tag` | Consultar por tag (prefixo) |
| GET | `/api/external/transactions/ref/:external_id` | Consultar por external_id |
| GET | `/api/external/transactions/:id/receipt` | Comprovante |

### Conta

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| GET | `/api/external/balance` | Saldo da conta |
| GET | `/api/external/statement` | Extrato |

### Chaves PIX

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| GET | `/api/external/pix/keys` | Listar chaves PIX da conta |

### Devolução

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| POST | `/api/external/pix/refund` | Devolução PIX (total ou parcial) |

### MED

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| GET | `/api/external/med` | Listar MEDs |
| GET | `/api/external/med/:id` | Detalhes de um MED |
| POST | `/api/external/med/:id/defense` | Submeter defesa MED com justificativa e evidências |

### Validação

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| POST | `/api/external/cpf/validate` | Validar CPF |

### Webhooks

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| GET | `/api/external/webhooks` | Listar webhooks |
| POST | `/api/external/webhooks` | Cadastrar webhook |
| DELETE | `/api/external/webhooks/:id` | Remover webhook |
