# Códigos de resposta

> Referência dos códigos HTTP usados por toda a API da Rapid.

Página: https://doc.rapidchargeback.com/referencia/codigos-de-resposta/

Referência dos códigos HTTP usados por toda a API da Rapid.

## Códigos de sucesso

| Código | Significado |
|---|---|
| 200 | Sucesso com corpo |
| 201 | Recurso criado |
| 204 | Sucesso sem corpo (ex: `DELETE`) |

## Códigos de erro do cliente

| Código | Significado |
|---|---|
| 400 | Corpo que não é JSON válido (`INVALID_JSON`) |
| 401 | Credenciais ausentes ou inválidas |
| 403 | Empresa bloqueada |
| 404 | Recurso não encontrado |
| 409 | Conflito (duplicata, recurso imutável) |
| 413 | Corpo acima do tamanho máximo (`PAYLOAD_TOO_LARGE`) |
| 422 | Erro de validação |
| 429 | Muitas requisições (rate limit) |

## Códigos de erro do servidor

| Código | Significado |
|---|---|
| 500 | Erro interno (`INTERNAL_ERROR`), retentativa recomendada |

---

## Formato do corpo de erro

Toda resposta de erro tem a estrutura:

```json
{
  "error": {
    "code": "CODIGO_SEMANTICO",
    "message": "Descrição legível do erro"
  }
}
```

## Códigos semânticos mais comuns

| Código | HTTP | Uso |
|---|---|---|
| `INVALID_JSON` | 400 | O corpo não é um JSON válido |
| `UNAUTHORIZED` | 401 | Credenciais ausentes ou inválidas |
| `COMPANY_BLOCKED` | 403 | Empresa bloqueada |
| `VALIDATION_ERROR` | 422 | Um ou mais campos inválidos |
| `NOT_FOUND` | 404 | O endereço não existe na API (caminho com erro de digitação, barra sobrando no fim) |
| `TRANSACTION_NOT_FOUND` | 404 | Transação inexistente |
| `TRANSACTION_DUPLICATE` | 409 | `external_source` + `external_id` já cadastrado |
| `TRANSACTION_IMMUTABLE` | 409 | Transação já utilizada, não pode ser modificada |
| `MERCHANT_NOT_FOUND` | 404 | Merchant inexistente |
| `ALERT_NOT_FOUND` | 404 | Alerta inexistente |
| `ALERT_INVALID_STATUS` | 422 | Status fora do conjunto permitido |
| `PAYLOAD_TOO_LARGE` | 413 | Corpo acima do limite: 1 MB por requisição, 5 MB no [envio em lote](https://doc.rapidchargeback.com/canais/transactions/envio-em-lote/) |
| `RATE_LIMIT_EXCEEDED` | 429 | Limite de requisições excedido (ver abaixo) |
| `INTERNAL_ERROR` | 500 | Erro inesperado no servidor |

## Rate limit

Todas as rotas compartilham um limite de **100 requisições por minuto por IP**, inclusive as que respondem `401` por credencial inválida. A exceção é o [envio de evento pelo navegador](https://doc.rapidchargeback.com/canais/capture/enviar-evento-navegador/), que tem teto próprio de 120 por minuto e não conta nos 100.

Ao ultrapassar, a API retorna:

```
HTTP/1.1 429 Too Many Requests
Retry-After: 15
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 15
```

```json
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded, retry in 15 seconds"
  }
}
```

**Use o `Retry-After`.** Ele diz, em segundos, quanto falta para a janela virar, e a mensagem repete o mesmo número. Esperar exatamente isso é melhor que chutar: espera progressiva cega pode tentar antes da hora (e tomar outro `429`) ou esperar mais que o necessário.

Os headers `X-RateLimit-*` vêm em **todas** as respostas, não só no `429`, então você pode se antecipar: quando `X-RateLimit-Remaining` chegar perto de zero, segure o envio em vez de esperar o erro. Em envio de volume, prefira o [envio em lote](https://doc.rapidchargeback.com/canais/transactions/envio-em-lote/), que manda até 1000 transações numa requisição e gasta uma unidade do limite.

## Retry em erros 5xx

Erros `5xx` geralmente são transitórios. Retente aumentando o intervalo entre as tentativas. Nunca retente `4xx`: eles indicam erro no seu lado e vão falhar de novo.
