Ao consumir a API de CPF do CPFHub.io em produção, erros HTTP são inevitáveis — e a diferença entre um sistema confiável e um frágil está em como cada categoria de erro é tratada: 4xx para problemas na requisição, 5xx para falhas do servidor, e retry com backoff exponencial para erros transitórios. A API do CPFHub.io nunca retorna HTTP 429 nem bloqueia requisições: ao ultrapassar o limite do plano, ela simplesmente cobra R$0,15 por consulta adicional.
Introdução
Ao consumir a API de CPF do CPFHub.io em produção, erros HTTP são inevitáveis. Falhas de rede, timeouts e erros de servidor acontecem, e a diferença entre um sistema confiável e um frágil está em como você trata essas situações.
Classificação dos erros HTTP
Os códigos de status HTTP seguem um padrão que indica a natureza do erro e a ação correta a tomar.
| Faixa | Categoria | Ação recomendada | Exemplo |
|---|---|---|---|
| 2xx | Sucesso | Processar normalmente | 200 OK |
| 400 | Requisição inválida | Corrigir o input | CPF malformado |
| 401 | Não autorizado | Verificar API key | Key ausente ou inválida |
| 403 | Proibido | Verificar permissões | Plano sem acesso |
| 404 | Não encontrado | CPF não existe na base | CPF válido mas sem dados |
| 500 | Erro do servidor | Retry com backoff | Falha interna da API |
| 502/503 | Indisponível | Retry com backoff | API temporariamente fora |
- 4xx — erros do cliente, geralmente não devem ser retentados pois a causa está na requisição
- 5xx — erros do servidor, candidatos a retry pois são tipicamente transitórios
- 429 — a API do CPFHub.io não emite este código: ao ultrapassar o limite do plano gratuito, a API continua respondendo normalmente e cobra R$0,15 por consulta adicional, sem bloquear
Implementando tratamento de erros em Python
Crie uma classe que trata cada categoria de erro de forma específica e oferece mensagens úteis.
import requests
import time
import logging
logger = logging.getLogger(__name__)
class CPFApiError(Exception):
def __init__(self, message: str, status_code: int = None, retryable: bool = False):
super().__init__(message)
self.status_code = status_code
self.retryable = retryable
class CPFClient:
def __init__(self, api_key: str):
self.session = requests.Session()
self.session.headers["x-api-key"] = api_key
self.base_url = "https://api.cpfhub.io/cpf"
def consultar(self, cpf: str) -> dict:
cpf_limpo = "".join(c for c in cpf if c.isdigit())
try:
response = self.session.get(
f"{self.base_url}/{cpf_limpo}",
timeout=15
)
except requests.exceptions.Timeout:
raise CPFApiError("Timeout na requisição", retryable=True)
except requests.exceptions.ConnectionError:
raise CPFApiError("Erro de conexão com a API", retryable=True)
return self._tratar_resposta(response)
def _tratar_resposta(self, response: requests.Response) -> dict:
handlers = {
200: self._handle_success,
400: self._handle_bad_request,
401: self._handle_unauthorized,
403: self._handle_forbidden,
404: self._handle_not_found,
}
handler = handlers.get(response.status_code, self._handle_server_error)
return handler(response)
def _handle_success(self, response):
data = response.json()
if not data.get("success"):
raise CPFApiError("CPF não encontrado na base de dados")
return data
def _handle_bad_request(self, response):
raise CPFApiError("CPF inválido ou malformado", status_code=400)
def _handle_unauthorized(self, response):
raise CPFApiError("API key inválida ou ausente", status_code=401)
def _handle_forbidden(self, response):
raise CPFApiError("Sem permissão para este recurso", status_code=403)
def _handle_not_found(self, response):
raise CPFApiError("CPF não encontrado", status_code=404)
def _handle_server_error(self, response):
logger.error(f"Erro do servidor: {response.status_code}")
raise CPFApiError(
f"Erro interno da API ({response.status_code})",
status_code=response.status_code,
retryable=True
)
- retryable — flag que indica se o erro é candidato a retry automático
- Handler map — mapeia cada status code para um método específico de tratamento
- Timeout explícito — sempre defina timeout para evitar requisições penduradas
Implementando tratamento de erros em JavaScript
A mesma abordagem estruturada aplicada em JavaScript com fetch e classes de erro.
class CPFApiError extends Error {
constructor(message, statusCode = null, retryable = false) {
super(message);
this.name = "CPFApiError";
this.statusCode = statusCode;
this.retryable = retryable;
}
}
class CPFClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = "https://api.cpfhub.io/cpf";
}
async consultar(cpf) {
const cpfLimpo = cpf.replace(/\D/g, "");
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000);
try {
const response = await fetch(`${this.baseUrl}/${cpfLimpo}`, {
headers: { "x-api-key": this.apiKey },
signal: controller.signal,
});
clearTimeout(timeoutId);
return this.#tratarResposta(response);
} catch (error) {
clearTimeout(timeoutId);
if (error.name === "AbortError") {
throw new CPFApiError("Timeout na requisição", null, true);
}
if (error instanceof CPFApiError) throw error;
throw new CPFApiError(`Erro de conexão: ${error.message}`, null, true);
}
}
async #tratarResposta(response) {
const handlers = {
400: () => new CPFApiError("CPF inválido ou malformado", 400),
401: () => new CPFApiError("API key inválida ou ausente", 401),
403: () => new CPFApiError("Sem permissão para este recurso", 403),
404: () => new CPFApiError("CPF não encontrado", 404),
};
if (response.ok) {
const data = await response.json();
if (!data.success) {
throw new CPFApiError("CPF não encontrado na base");
}
return data;
}
const handler = handlers[response.status];
if (handler) throw handler();
throw new CPFApiError(
`Erro do servidor (${response.status})`,
response.status,
response.status >= 500
);
}
}
- AbortController — mecanismo nativo do browser e Node.js para cancelar requisições com timeout
- Private method (#) — método privado usando a sintaxe nativa do JavaScript
- Sem 429 — a API do CPFHub.io não bloqueia por volume; consultas além do plano são cobradas automaticamente a R$0,15 cada
Construindo um wrapper com retry automático
Combine o tratamento de erros com retry inteligente que só retenta erros marcados como retryable.
import time
import random
def consultar_com_retry(
client: CPFClient,
cpf: str,
max_tentativas: int = 3,
delay_base: float = 1.0
) -> dict:
for tentativa in range(max_tentativas):
try:
return client.consultar(cpf)
except CPFApiError as e:
if not e.retryable or tentativa == max_tentativas - 1:
raise
delay = delay_base * (2 ** tentativa)
jitter = random.uniform(0, delay * 0.1)
tempo_espera = delay + jitter
logger.warning(
f"Tentativa {tentativa + 1}/{max_tentativas} falhou: {e}. "
f"Retentando em {tempo_espera:.1f}s"
)
time.sleep(tempo_espera)
raise CPFApiError("Todas as tentativas falharam")
async function consultarComRetry(client, cpf, maxTentativas = 3) {
for (let tentativa = 0; tentativa < maxTentativas; tentativa++) {
try {
return await client.consultar(cpf);
} catch (error) {
if (!error.retryable || tentativa === maxTentativas - 1) {
throw error;
}
const delay = Math.pow(2, tentativa) * 1000;
const jitter = Math.random() * delay * 0.1;
console.warn(
`Tentativa ${tentativa + 1}/${maxTentativas} falhou. ` +
`Retentando em ${((delay + jitter) / 1000).toFixed(1)}s`
);
await new Promise((r) => setTimeout(r, delay + jitter));
}
}
}
| Tentativa | Delay base | Com jitter (exemplo) |
|---|---|---|
| 1 | 1s | 1.0 - 1.1s |
| 2 | 2s | 2.0 - 2.2s |
| 3 | 4s | 4.0 - 4.4s |
- Exponential backoff — dobrar o delay a cada tentativa reduz a pressão sobre a API
- Jitter — variação aleatória evita que múltiplos clientes retentem simultaneamente
- Erros não retentáveis — 400 e 401 são lançados imediatamente, sem desperdício de tentativas
Perguntas frequentes
A API do CPFHub.io retorna HTTP 429 quando o limite de consultas é atingido?
Não. A API do CPFHub.io nunca retorna HTTP 429 nem bloqueia requisições por excesso de volume. Ao ultrapassar o limite do plano gratuito (50 consultas/mês), a API continua respondendo normalmente e cobra R$0,15 por consulta adicional. Não é necessário implementar lógica de espera por rate limit — apenas monitore seu consumo em app.cpfhub.io/settings/billing.
Quais erros HTTP devo tratar com retry automático?
Erros de servidor (5xx) e falhas de rede (timeout, connection error) são os candidatos naturais ao retry, pois são transitórios. Erros de cliente (400, 401, 403, 404) não devem ser retentados — a causa está na requisição e repetir a chamada sem corrigir o problema gera desperdício. Use o padrão de backoff exponencial com jitter para evitar sobrecarga em situações de falha.
Como definir um timeout adequado para a API de CPF?
A latência típica da API do CPFHub.io é de aproximadamente 900ms. Recomenda-se configurar o timeout entre 10 e 15 segundos para absorver variações de rede sem bloquear o usuário por tempo excessivo. Use AbortController no JavaScript e o parâmetro timeout do requests no Python. Timeouts devem ser tratados como erros retentáveis.
O que fazer quando todos os retries falham?
Após esgotar as tentativas de retry, lance o erro para o chamador e registre o evento nos logs com o CPF (mascarado), timestamp, status code e número de tentativas. Se a consulta é crítica para um fluxo (como onboarding), enfileire para processamento posterior em vez de bloquear o usuário. Implemente alertas automáticos quando a taxa de falha ultrapassar um limiar — veja mais em developer.mozilla.org/pt-BR/docs/Web/HTTP/Status para referência completa de status codes HTTP.
Conclusão
Tratar erros HTTP corretamente é a diferença entre um sistema que degrada graciosamente e um que falha catastroficamente. Classifique cada erro por natureza, implemente handlers específicos por status code e adicione retry com backoff para erros transitórios. Vale lembrar: a API do CPFHub.io nunca retorna HTTP 429 — consultas além do plano são cobradas automaticamente, sem bloqueio.
Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a construir integrações robustas com tratamento de erros adequado hoje mesmo.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
Sobre a redação
Redação CPFHub.io
Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.



