Como fazer fallback automático quando a API de CPF está fora do ar

Aprenda a implementar fallback automático quando a API de CPF está indisponível. Estratégias com cache, fila e degradação graceful.

Redação CPFHub.io
Redação CPFHub.io
··8 min de leitura
Como fazer fallback automático quando a API de CPF está fora do ar

Quando a API de CPF fica fora do ar, a estratégia correta é combinar cache local, validação sintática, fila de reprocessamento e degradação graceful em cascata — garantindo que a aplicação continue operando mesmo durante janelas de indisponibilidade.

Introdução

Mesmo APIs com SLA de 99,9% podem enfrentar momentos de indisponibilidade. O 0,1% restante pode representar até 8 horas de downtime por ano, e se esse tempo coincidir com um momento crítico da sua aplicação — como um pico de cadastros ou uma campanha de vendas —, o impacto pode ser significativo. A solução é implementar estratégias de fallback que mantenham a aplicação funcional mesmo quando a API de CPF não está respondendo.

Estratégias de fallback

Existem diferentes abordagens de fallback, cada uma adequada a um cenário específico. A escolha depende dos requisitos de negócio e do nível de criticidade da validação de CPF no seu fluxo.

EstratégiaDisponibilidadeAtualidade dos dadosComplexidade
Cache localAltaDados recentesBaixa
Validação sintáticaTotalSem dados cadastraisMuito baixa
Fila para reprocessamentoAltaDados futurosMédia
Degradação gracefulTotalSem validaçãoBaixa

Estratégia 1: Fallback com cache

A abordagem mais comum é manter um cache das consultas recentes e retornar o valor cacheado quando a API estiver indisponível:

import requests
import redis
import json

redis_client = redis.Redis(host='localhost', port=6379, db=0)
CACHE_TTL = 86400 # 24 horas

def consultar_cpf_com_fallback(cpf):
    url = f"https://api.cpfhub.io/cpf/{cpf}"
    headers = {
    "x-api-key": "SUA_CHAVE_DE_API",
    "Accept": "application/json"
    }

    # Tentar consulta na API
    try:
    response = requests.get(url, headers=headers, timeout=10)

    if response.status_code == 200:
    dados = response.json()

    # Armazenar no cache para uso futuro como fallback
    if dados.get("success"):
    redis_client.setex(
    f"cpf_fallback:{cpf}",
    CACHE_TTL,
    json.dumps(dados)
    )

    return {"fonte": "api", "dados": dados}

    except (requests.exceptions.Timeout,
    requests.exceptions.ConnectionError):
    pass

    # Fallback: tentar cache
    cached = redis_client.get(f"cpf_fallback:{cpf}")
    if cached:
    dados = json.loads(cached)
    return {"fonte": "cache", "dados": dados, "aviso": "Dados do cache"}

    # Nenhum fallback disponível
    return {
    "fonte": "nenhum",
    "erro": "API indisponível e sem cache para este CPF"
    }

Estratégia 2: Fallback com validação sintática

Quando a API está fora do ar e não há cache disponível, a validação sintática pode servir como verificação mínima. Ela não confirma a existência real do CPF, mas garante que o formato é válido:

function validarCPFSintatico(cpf) {
    cpf = cpf.replace(/\D/g, '');
    if (cpf.length !== 11) return false;
    if (/^(\d)\1{10}$/.test(cpf)) return false;

    let soma = 0;
    for (let i = 0; i < 9; i++) soma += parseInt(cpf[i]) * (10 - i);
    let resto = (soma * 10) % 11;
    if (resto === 10) resto = 0;
    if (resto !== parseInt(cpf[9])) return false;

    soma = 0;
    for (let i = 0; i < 10; i++) soma += parseInt(cpf[i]) * (11 - i);
    resto = (soma * 10) % 11;
    if (resto === 10) resto = 0;
    return resto === parseInt(cpf[10]);
}

async function consultarCPFComFallback(cpf) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 10000);

    try {
    const response = await fetch(
    `https://api.cpfhub.io/cpf/${cpf}`,
    {
    headers: {
    'x-api-key': 'SUA_CHAVE_DE_API',
    'Accept': 'application/json'
    },
    signal: controller.signal
    }
    );

    clearTimeout(timeoutId);

    if (response.ok) {
    return { fonte: 'api', dados: await response.json() };
    }

    throw new Error(`HTTP ${response.status}`);

    } catch (error) {
    clearTimeout(timeoutId);

    // Fallback: validação sintática
    const sintaticamenteValido = validarCPFSintatico(cpf);

    return {
    fonte: 'fallback_sintatico',
    valido: sintaticamenteValido,
    aviso: 'Validação real indisponível. Apenas formato verificado.',
    revalidarDepois: true
    };
    }
}

Estratégia 3: Fila para reprocessamento posterior

Em alguns fluxos, é possível aceitar o cadastro condicionalmente e enfileirar a validação real para quando a API voltar:

import requests
import redis
import json
from datetime import datetime

redis_client = redis.Redis(host='localhost', port=6379, db=0)

def consultar_cpf_ou_enfileirar(cpf, dados_cadastro):
    url = f"https://api.cpfhub.io/cpf/{cpf}"
    headers = {
    "x-api-key": "SUA_CHAVE_DE_API",
    "Accept": "application/json"
    }

    try:
    response = requests.get(url, headers=headers, timeout=10)

    if response.status_code == 200:
    return {
    "status": "validado",
    "dados": response.json()
    }

    except (requests.exceptions.Timeout,
    requests.exceptions.ConnectionError):
    pass

    # API indisponível: enfileirar para revalidação
    item_fila = {
    "cpf": cpf,
    "dados_cadastro": dados_cadastro,
    "enfileirado_em": datetime.now().isoformat(),
    "tentativas": 0
    }

    redis_client.rpush("fila_revalidacao_cpf", json.dumps(item_fila))

    return {
    "status": "pendente",
    "aviso": "CPF será validado assim que o serviço estiver disponível"
    }

def processar_fila_revalidacao():
    """Executar periodicamente (cron job ou worker)"""
    while True:
    item_raw = redis_client.lpop("fila_revalidacao_cpf")
    if not item_raw:
    break

    item = json.loads(item_raw)
    cpf = item["cpf"]

    url = f"https://api.cpfhub.io/cpf/{cpf}"
    headers = {
    "x-api-key": "SUA_CHAVE_DE_API",
    "Accept": "application/json"
    }

    try:
    response = requests.get(url, headers=headers, timeout=10)

    if response.status_code == 200:
    dados = response.json()
    print(f"CPF {cpf} revalidado: {dados}")
    # Atualizar cadastro no banco de dados
    continue

    except Exception:
    pass

    # Falhou novamente: recolocar na fila
    item["tentativas"] += 1
    if item["tentativas"] < 10:
    redis_client.rpush("fila_revalidacao_cpf", json.dumps(item))
    else:
    print(f"CPF {cpf}: máximo de tentativas atingido")

Estratégia 4: Degradação graceful

Em alguns cenários, a validação de CPF é desejável mas não obrigatória. Nesses casos, a aplicação pode prosseguir sem a validação e sinalizar que ela será feita posteriormente:

  • E-commerce — Aceitar a compra sem validação e marcar o pedido para revisão posterior.

  • Formulários informativos — Aceitar o cadastro com uma flag "pendente de validação".

  • Aplicações internas — Registrar a operação e agendar a validação para o próximo ciclo.

Combinando todas as estratégias

A implementação mais robusta combina as estratégias em cascata:

def consultar_cpf_resiliente(cpf, dados_cadastro=None):
    # Tentativa 1: API em tempo real
    try:
    resultado_api = consultar_via_api(cpf)
    if resultado_api:
    return {"fonte": "api", "dados": resultado_api}
    except Exception:
    pass

    # Tentativa 2: Cache local
    resultado_cache = buscar_no_cache(cpf)
    if resultado_cache:
    return {"fonte": "cache", "dados": resultado_cache}

    # Tentativa 3: Validação sintática + fila
    sintaticamente_valido = validar_cpf_sintatico(cpf)
    if sintaticamente_valido and dados_cadastro:
    enfileirar_para_revalidacao(cpf, dados_cadastro)
    return {
    "fonte": "sintatico",
    "valido_formato": True,
    "pendente_validacao_real": True
    }

    # Tentativa 4: Rejeição
    return {
    "fonte": "nenhum",
    "valido": False,
    "motivo": "CPF inválido e serviço indisponível"
    }

Monitorando falhas e recuperação

Para saber quando o fallback está sendo acionado e quando a API volta ao normal, registre métricas:

  • Taxa de fallback — Percentual de consultas que usaram fallback em vez da API.

  • Tipo de fallback — Distribuição entre cache, sintático e fila.

  • Tempo de indisponibilidade — Quanto tempo a API ficou fora do ar.

  • Tamanho da fila de revalidação — Quantos CPFs aguardam reprocessamento.

Essas métricas permitem avaliar se as estratégias de fallback estão funcionando adequadamente e se o SLA contratado está sendo cumprido. O CERT.br recomenda que sistemas críticos implementem monitoramento ativo de disponibilidade de dependências externas, com alertas automáticos quando a taxa de falha superar 1%.

Perguntas frequentes

Como o fallback com cache funciona quando o CPF nunca foi consultado antes?

Quando não existe entrada no cache para um CPF específico, o sistema não tem dados para retornar. Nesse caso, o fluxo deve avançar para a próxima camada: validação sintática local, que verifica apenas o formato e os dígitos verificadores sem confirmar a existência real do CPF na Receita Federal. O resultado deve ser sinalizado como provisório, com a validação real agendada para quando a API voltar.

Qual TTL (tempo de expiração) devo usar no cache de fallback?

Para dados de CPF, um TTL de 24 horas é um equilíbrio razoável entre utilidade do cache e atualidade das informações. Dados cadastrais como nome e data de nascimento mudam raramente, mas manter o cache por períodos muito longos aumenta o risco de servir dados desatualizados. Em contextos de alta criticidade — como fintechs e seguradoras —, prefira TTLs mais curtos (4 a 8 horas) e invalide o cache proativamente após validações bem-sucedidas.

A fila de reprocessamento garante que todos os CPFs serão validados?

A fila garante que a tentativa de revalidação será feita, mas não que terá sucesso. O worker de reprocessamento deve implementar retentativas com backoff exponencial e um limite máximo de tentativas (ex: 10). CPFs que ultrapassem esse limite devem ser encaminhados para revisão manual, com notificação à equipe responsável. Nunca descarte silenciosamente itens da fila sem registro de log.

A CPFHub.io bloqueia consultas quando o limite do plano é atingido?

Não. A CPFHub.io nunca retorna HTTP 429 nem bloqueia consultas ao atingir o limite. O plano Grátis inclui 50 consultas/mês sem cartão de crédito; o plano Pro inclui 1.000 consultas/mês por R$149. Ao exceder qualquer um desses limites, cada consulta adicional é cobrada a R$0,15 — a aplicação continua funcionando normalmente.


Conclusão

Implementar fallback automático é uma prática essencial para garantir que sua aplicação continue funcional mesmo quando a API de CPF apresenta indisponibilidade temporária. A combinação de cache, validação sintática, filas de reprocessamento e degradação graceful cria uma rede de segurança que mantém a experiência do usuário intacta.

Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e tenha uma API com latência de ~900ms e cobrança por excedente em vez de bloqueio, ideal para construir estratégias de fallback sem surpresas.

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