—Documentação
Erros.
Toda falha retorna um objeto error consistente com code, message e request_id. Códigos HTTP semânticos. Sem corpo em sucesso de delete.
Formato
exemplo de resposta de erro
{
"error": {
"code": "cpf_invalid",
"message": "O dígito verificador não confere.",
"field": "cpf",
"request_id": "req_01HM9Q2K3N4PXYZ"
}
}Sempre inclua o request_id em tickets de suporte — ele aponta direto para o log da chamada.
Códigos HTTP
| Código | Nome | Quando ocorre |
|---|---|---|
| 200 | OK | Sucesso. Cota foi debitada. |
| 400 | Bad Request | JSON malformado ou campo ausente. |
| 401 | Unauthorized | Chave inválida, ausente ou revogada. |
| 402 | Payment Required | Plano expirado ou cota excedida sem permissão de overage. |
| 403 | Forbidden | Chave válida mas sem permissão (endpoint não incluso, IP fora da allowlist). |
| 404 | Not Found | Recurso não encontrado. |
| 422 | Unprocessable Entity | Validação falhou (CPF inválido, formato incorreto). Não consome cota. |
| 429 | Too Many Requests | Rate limit excedido. Cabeçalho Retry-After indica quando tentar novamente. |
| 500 | Internal Server Error | Falha interna. Idempotente para retry com backoff exponencial. |
| 503 | Service Unavailable | Serviço temporariamente indisponível. Retry recomendado com backoff. Também emitido durante janelas de manutenção (status.cpfhub.com). |
Códigos de erro (campo error.code)
authentication_requiredCabeçalho Authorization ausente.invalid_api_keyChave inválida ou revogada.ip_not_allowedIP da requisição não está na allowlist da chave.quota_exceededCota mensal estourada e overage desabilitado.invalid_cpfCPF não passou na validação de dígito.cpf_not_foundCPF válido mas sem registro na base.rate_limitedLimite de requisições por segundo excedido.service_unavailableServiço temporariamente indisponível. Tente novamente em instantes.
Estratégia de retry
Retentar é seguro para 5xx, 429 e falhas de rede. Use backoff exponencial com jitter:
retry com backoff
async function withRetry(fn, max = 4) {
for (let i = 0; i < max; i++) {
try {
const res = await fn();
if (res.status < 500 && res.status !== 429) return res;
const wait = Math.min(2 ** i * 250 + Math.random() * 250, 5000);
await new Promise(r => setTimeout(r, wait));
} catch (e) {
if (i === max - 1) throw e;
}
}
throw new Error("Todas as tentativas falharam");
}Não retente
4xx (exceto 429). São erros do cliente — retentar pode mascarar bugs e gerar cobrança em loop.