Idempotência importa ao consultar CPFs via API porque retries automáticos, falhas de rede e processos em lote podem gerar chamadas duplicadas — e sem cache e deduplicação no cliente, cada chamada extra consome cota e gera custo de excedente desnecessário.
Introdução
Idempotência é um conceito fundamental em design de APIs que garante que uma mesma requisição pode ser executada múltiplas vezes sem alterar o resultado além da primeira execução. Em consultas de CPF, esse conceito é especialmente relevante: retries automáticos, falhas de rede e processamentos em lote podem gerar requisições duplicadas que, em integrações sem controle de deduplicação, causam efeitos colaterais indesejados.
O que é idempotência na prática
Uma operação é idempotente quando executá-la uma ou múltiplas vezes produz o mesmo resultado:
| Método HTTP | Idempotente? | Exemplo com CPF |
|---|---|---|
| GET | Sim | Consultar dados de um CPF |
| PUT | Sim | Atualizar cadastro completo |
| DELETE | Sim | Remover um registro |
| POST | Não (por padrão) | Criar um novo registro |
| PATCH | Depende | Atualizar campo específico |
A consulta de CPF via GET é naturalmente idempotente: consultar o mesmo CPF 10 vezes retorna os mesmos dados sem efeitos colaterais no servidor. Porém, existem nuances importantes que veremos a seguir.
Por que idempotência importa em consultas de CPF
Mesmo em operações GET que são idempotentes por natureza, há implicações práticas:
- Custo de excedente -- cada chamada consome cota; ao ultrapassar o plano, cada consulta extra custa R$0,15
- Billing -- em APIs pagas, cada requisição é cobrada independentemente do resultado ser idêntico
- Logs duplicados -- registros de auditoria são gerados para cada chamada, poluindo relatórios
- Latência acumulada -- requisições desnecessárias aumentam o tempo total de processamento
- Cache invalidation -- sem estratégia de cache, dados idênticos são buscados repetidamente
Implementando idempotência no lado do cliente com JavaScript
Garanta que sua aplicação não faça chamadas redundantes à API:
const axios = require('axios');
const crypto = require('crypto');
class IdempotentCPFClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.cache = new Map();
this.pendingRequests = new Map();
}
generateKey(cpf) {
return crypto.createHash('md5').update(cpf).digest('hex');
}
async consultar(cpf) {
const cpfLimpo = cpf.replace(/\D/g, '');
const chave = this.generateKey(cpfLimpo);
// 1. Verificar cache (idempotência via cache)
if (this.cache.has(chave)) {
const cached = this.cache.get(chave);
if (Date.now() - cached.timestamp < 3600000) {
return { ...cached.dados, fonte: 'cache' };
}
}
// 2. Deduplicar requisições em andamento
if (this.pendingRequests.has(chave)) {
return this.pendingRequests.get(chave);
}
// 3. Executar requisição
const promise = this._executarConsulta(cpfLimpo, chave);
this.pendingRequests.set(chave, promise);
try {
const resultado = await promise;
return resultado;
} finally {
this.pendingRequests.delete(chave);
}
}
async _executarConsulta(cpf, chave) {
const response = await axios.get(
`https://api.cpfhub.io/cpf/${cpf}`,
{ headers: { 'x-api-key': this.apiKey } }
);
if (response.data.success) {
const dados = {
cpf: response.data.data.cpf,
nome: response.data.data.name,
genero: response.data.data.gender,
nascimento: response.data.data.birthDate,
dia: response.data.data.day,
mes: response.data.data.month,
ano: response.data.data.year
};
this.cache.set(chave, { dados, timestamp: Date.now() });
return { ...dados, fonte: 'api' };
}
return null;
}
estatisticas() {
return {
itensEmCache: this.cache.size,
requisicoesPendentes: this.pendingRequests.size
};
}
}
// Demonstração de idempotência
async function demonstrar() {
const client = new IdempotentCPFClient('SUA_CHAVE_AQUI');
// Chamada 1: vai à API
const r1 = await client.consultar('12345678909');
console.log(`Chamada 1: ${r1.nome} (fonte: ${r1.fonte})`);
// Chamada 2: retorna do cache (idempotente, sem consumir cota)
const r2 = await client.consultar('12345678909');
console.log(`Chamada 2: ${r2.nome} (fonte: ${r2.fonte})`);
console.log('Estatísticas:', client.estatisticas());
}
demonstrar();
Padrões de idempotência para operações de escrita
Quando sua aplicação armazena resultados de consulta, a idempotência evita duplicação de registros:
- Idempotency key -- gere uma chave única por operação (ex: hash do CPF + timestamp do dia) e rejeite duplicatas
- Upsert no banco -- use INSERT ON CONFLICT UPDATE para garantir que o mesmo CPF nunca gere registros duplicados
- Deduplicação em fila -- antes de enfileirar uma consulta, verifique se o CPF já está na fila ou foi processado recentemente
- Tombstone pattern -- marque registros como processados para evitar reprocessamento em caso de retry
- Versioning -- mantenha um campo de versão que só é incrementado quando os dados realmente mudam
Testando idempotência da sua integração
Valide que sua implementação é realmente idempotente:
- Teste de duplicata -- envie a mesma consulta 10 vezes e verifique que apenas 1 chamada chegou à API
- Teste de concorrência -- dispare 5 consultas simultâneas para o mesmo CPF e confirme que o cache é respeitado
- Teste de retry -- simule falha de rede e verifique que o retry não gera efeitos colaterais
- Teste de consistência -- compare o resultado da primeira chamada com a décima para garantir igualdade
- Teste de cota -- monitore o consumo de cota durante testes repetitivos para confirmar que o cache funciona
Perguntas frequentes
Por que idempotência importa especificamente em consultas de CPF?
Fluxos de onboarding, fila de lotes e sistemas com retry automático podem chamar a mesma consulta mais de uma vez para o mesmo CPF. Cada chamada duplicada que chega à API consome cota — e ao ultrapassar o plano, gera cobrança de R$0,15 por consulta extra. Cache no cliente é a forma mais simples de garantir idempotência e controlar esse custo.
O GET de CPF é idempotente por natureza — por que ainda preciso me preocupar?
O GET é idempotente no servidor (o resultado é sempre o mesmo). O problema está no cliente: sem cache, cada retry ou chamada duplicada consome cota real. A preocupação é financeira e de performance, não de consistência de dados.
Qual TTL (tempo de expiração) usar no cache de CPF?
Depende do caso de uso. Para onboarding em tempo real, 1 hora é suficiente — os dados de CPF raramente mudam durante uma sessão. Para processamento em lote, um TTL de 24 horas é razoável. Evite TTLs muito longos (semanas) pois dados cadastrais podem ser atualizados na Receita Federal.
Como implementar deduplicação em sistemas distribuídos com múltiplos workers?
Use um cache compartilhado (Redis, por exemplo) com TTL configurável. Antes de cada consulta, cada worker verifica se o CPF já foi consultado recentemente. Se sim, usa o resultado cacheado. Se não, executa a chamada à API e salva o resultado no Redis para os demais workers.
Conclusão
Idempotência não é apenas um conceito teórico, mas uma propriedade essencial para integrações robustas e econômicas com APIs de CPF. Ao implementar cache, deduplicação de requisições e tratamento adequado de retries, você economiza cota, reduz latência e garante consistência nos dados. Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e construa uma integração que nunca desperdiça uma consulta sequer.
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.



