Como Lidar com Erros HTTP ao Consumir APIs de CPF

Aprenda a tratar erros HTTP ao consumir APIs de CPF. Guia completo com status codes, retry, circuit breaker e exemplos em Python e JavaScript.

Redação CPFHub.io
Redação CPFHub.io
··8 min de leitura
Como Lidar com Erros HTTP ao Consumir APIs de CPF

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.

FaixaCategoriaAção recomendadaExemplo
2xxSucessoProcessar normalmente200 OK
400Requisição inválidaCorrigir o inputCPF malformado
401Não autorizadoVerificar API keyKey ausente ou inválida
403ProibidoVerificar permissõesPlano sem acesso
404Não encontradoCPF não existe na baseCPF válido mas sem dados
500Erro do servidorRetry com backoffFalha interna da API
502/503IndisponívelRetry com backoffAPI 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));
    }
    }
}
TentativaDelay baseCom jitter (exemplo)
11s1.0 - 1.1s
22s2.0 - 2.2s
34s4.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.

Redação CPFHub.io

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.

WhatsAppFale conosco via WhatsApp