# Erros

Todas as respostas de erro seguem o mesmo formato:


```json
{
  "erro": "CODIGO_DO_ERRO",
  "mensagem": "Descrição legível do problema.",
  "detalhe": "Informação adicional opcional."
}
```

## Códigos HTTP

| Status | Significado geral |
|  --- | --- |
| `400` | Requisição malformada ou campo inválido |
| `401` | Credenciais ausentes ou inválidas |
| `403` | Sem permissão para o recurso |
| `404` | Recurso não encontrado |
| `409` | Conflito de estado (pedido já confirmado, chave duplicada) |
| `422` | Dados válidos sintaticamente, mas inválidos semanticamente |
| `429` | Rate limit atingido |
| `5xx` | Erro interno da plataforma Movvia |


## Catálogo de erros de aplicação

| Código | Status HTTP | Causa | Ação recomendada |
|  --- | --- | --- | --- |
| `PARCEIRO_ID_AUSENTE` | 400 | Header `x-parceiro-id` não enviado | Incluir o header em todas as requisições |
| `PLACA_INVALIDA` | 422 | Formato de placa não reconhecido | Validar formato Mercosul (ABC1D23) ou antigo (ABC1234) |
| `PLACA_JA_CADASTRADA` | 409 | Placa já existe na base do parceiro | Consultar `GET /placas/{placa}` antes de cadastrar |
| `TRANSACAO_NAO_ENCONTRADA` | 404 | `transacaoId` não existe ou não pertence ao parceiro | Verificar o ID; revisar logs de webhook |
| `PEDIDO_JA_CONFIRMADO` | 409 | Tentativa de confirmar pedido já em estado terminal | Verificar estado via `GET /pedidos/{id}` |
| `PEDIDO_EXPIRADO` | 409 | Pedido passou de 48h sem confirmação | Criar novo pedido |
| `IDEMPOTENCY_CONFLICT` | 409 | Mesma `idempotencyKey` com payload diferente | Usar chave diferente para a nova operação |
| `RATE_LIMIT_EXCEEDED` | 429 | Limite de requisições atingido | Aguardar `X-RateLimit-Reset` e retentar |
| `CREDENCIAL_INVALIDA` | 401 | `Authorization` incorreto | Verificar codificação Base64 das credenciais |


## Erros 5xx

Erros de servidor (500, 502, 503, 504) são transitórios. Sempre implemente retry com backoff:

- Aguarde 1s, 5s, 30s entre tentativas.
- Monitore a [status page](https://status.pedagioeletronico.com.br) para incidentes em andamento.
- Erros 5xx não consomem a `idempotencyKey` — reenviar com a mesma chave é seguro.


## Validação de placa

Placas aceitas:


```
Mercosul: [A-Z]{3}[0-9][A-Z][0-9]{2}   → ABC1D23
Antigo:   [A-Z]{3}[0-9]{4}              → ABC1234
```

Validação em Node:


```typescript
function placaValida(placa: string): boolean {
  return /^[A-Z]{3}[0-9][A-Z][0-9]{2}$/.test(placa) ||
         /^[A-Z]{3}[0-9]{4}$/.test(placa);
}
```

Logging
Logue sempre o campo `erro` (não apenas o status HTTP) para facilitar triagem. O código de erro identifica a causa exata sem precisar analisar a mensagem em texto livre.