Validação de CPF em AWS Lambda: arquitetura serverless com SmartCPF
Aprenda a integrar validação de CPF em funções Lambda serverless usando a API SmartCPF v2 com autenticação X-API-KEY.

Validar CPF em escala é um problema recorrente em sistemas brasileiros — seja no onboarding de usuários, prevenção de fraude ou compliance regulatório. A abordagem tradicional de manter validadores locais ou bancos de dados de CPF atualizados exige infraestrutura dedicada, monitoramento constante e gestão de atualizações cadastrais. A API SmartCPF resolve isso expondo validação e enriquecimento de dados via endpoint REST simples, eliminando a necessidade de manter réplicas locais de bases oficiais.
Em arquiteturas serverless, onde funções Lambda escalam sob demanda e não mantêm estado, integrar um serviço externo de validação torna-se natural: a função recebe o CPF, chama a API, processa o retorno e devolve o resultado — tudo sem provisionar servidores nem gerenciar conexões de banco de dados persistentes. O modelo de créditos da SmartCPF alinha-se ao pay-per-use do Lambda: você paga apenas pelas consultas executadas, sem custo fixo de infraestrutura.
Como funciona a validação serverless de CPF
A arquitetura segue o padrão request-response assíncrono típico de funções HTTP-triggered no Lambda. O cliente (frontend, API Gateway, fila SQS) envia o CPF para a função. A função monta a requisição HTTPS para https://api.smartcpf.com.br/v2/individuals/{cpf}?package=X, inclui o header obrigatório X-API-KEY, aguarda a resposta, normaliza os campos relevantes (status, consultId, balance, dados cadastrais) e retorna ao chamador. O pacote X no query string define o nível de detalhe do retorno (básico, completo, com score, etc.), permitindo ajustar custo e latência por caso de uso.
Como a SmartCPF exige autenticação exclusivamente via header X-API-KEY — nunca via Authorization Bearer nem query string —, a chave deve ser injetada via variável de ambiente do Lambda (ou AWS Secrets Manager/Parameter Store) e nunca commitada no código. O timeout da função deve considerar a latência da API (tipicamente 50-200ms) mais margem para retries; 5 segundos costuma ser seguro. Erros 4xx (CPF inválido, chave expirada, saldo zerado) são tratados como falhas de negócio; 5xx e timeouts disparam retry com backoff exponencial.
Vantagens da abordagem serverless com SmartCPF
1. Zero infraestrutura de validação
Não há banco de dados de CPF para manter, índices para reconstruir nem jobs de ETL para atualizar bases oficiais. A SmartCPF gerencia a frescura dos dados.
2. Escala automática com custo proporcional
Lambda escala de zero a milhares de invocações paralelas; a API SmartCPF suporta alta concorrência. O custo total é soma de execuções Lambda + créditos consumidos — sem ociosidade.
3. Latência previsível
A API responde em média abaixo de 100ms. Em arquitetura serverless, a latência de cold start do Lambda (100-300ms em Node.js) domina apenas na primeira invocação; warm starts ficam na casa de 10-20ms adicionais.
4. Observabilidade nativa
CloudWatch Logs e Metrics capturam invocações, duração, erros e throttles. O campo executionTimeMs no retorno da SmartCPF permite correlacionar latência da API com a da função.
5. Segregação de responsabilidades
A função Lambda foca em orquestração e transformação; a SmartCPF foca em validação, enriquecimento e compliance. Mudanças na regra de validação não exigem deploy da função.
6. Facilidade de testes e staging
Ambientes dev/staging/prod usam chaves API distintas (configuradas por variável de ambiente), isolando consumo de créditos e dados de teste sem alterar código.
Desafios e considerações reais
1. Cold start em picos repentinos
Se o tráfego é esporádico, cold starts adicionam latência perceptível. Provisioned Concurrency mitiga, mas aumenta custo fixo — avalie se o perfil de tráfego justifica.
2. Dependência de serviço externo
Indisponibilidade da SmartCPF impacta diretamente sua validação. Implemente circuit breaker e fallback (ex.: validação sintática local via algoritmo de dígitos verificadores) para degradar graciosamente.
3. Gestão de créditos e rate limits
O campo balance no retorno indica saldo restante. Monitore via alerta CloudWatch quando cair abaixo de threshold. A API retorna 402/429 quando créditos esgotam ou rate limit é atingido — trate como erro recuperável com retry.
4. Vazamento de chave em logs
Nunca logue o header X-API-KEY ou a URL completa com a chave. Use log redaction no CloudWatch ou masque a chave antes de gravar.
5. LGPD e retenção de dados
O retorno inclui nome, data de nascimento, e-mails, telefones. Sua função deve processar e descartar — não persista dados sensíveis em logs nem em armazenamento temporário sem base legal e criptografia.
Como implementar com a SmartCPF
Abaixo, uma função Lambda em Node.js 20.x pronta para deploy via Serverless Framework, AWS SAM ou CDK. A variável de ambiente SMARTCPF_API_KEY deve conter sua chave; SMARTCPF_PACKAGE define o pacote de consulta (ex.: basic, complete). O handler valida formato do CPF, chama a API com timeout e retry, normaliza a resposta e devolve estrutura padronizada ao API Gateway.
/**
* Lambda handler para validação de CPF via SmartCPF v2
*
* Requisitos:
* - Node.js 20.x runtime
* - Variáveis de ambiente: SMARTCPF_API_KEY, SMARTCPF_PACKAGE (opcional, default: 'basic')
* - Timeout recomendado: 5s
* - Memória: 256 MB+
*/
const https = require('https');
const { URL } = require('url');
const API_BASE = 'https://api.smartcpf.com.br/v2';
const MAX_RETRIES = 2;
const BASE_DELAY_MS = 200;
const REQUEST_TIMEOUT_MS = 4000;
/**
* Remove formatação do CPF (pontos, traço, espaços)
*/
function cleanCpf(cpf) {
return cpf.replace(/[^\d]/g, '');
}
/**
* Valida formato básico: 11 dígitos numéricos
*/
function isValidCpfFormat(cpf) {
const cleaned = cleanCpf(cpf);
return /^\d{11}$/.test(cleaned);
}
/**
* Validação sintática dos dígitos verificadores (fallback local)
* Útil quando API indisponível — não substitui validação oficial
*/
function validateCpfDigits(cpf) {
const digits = cleanCpf(cpf).split('').map(Number);
if (digits.length !== 11 || new Set(digits).size === 1) return false;
const calcDigit = (base) => {
const sum = base.reduce((acc, d, i) => acc + d * (base.length + 1 - i), 0);
const rem = (sum * 10) % 11;
return rem === 10 ? 0 : rem;
};
return digits[9] === calcDigit(digits.slice(0, 9)) &&
digits[10] === calcDigit(digits.slice(0, 10));
}
/**
* Faz requisição HTTP com timeout e retry exponencial
*/
function requestWithRetry(url, apiKey, attempt = 0) {
return new Promise((resolve, reject) => {
const req = https.request(url, {
method: 'GET',
headers: {
'X-API-KEY': apiKey,
'Accept': 'application/json',
'User-Agent': 'smartcpf-lambda-validator/1.0'
},
timeout: REQUEST_TIMEOUT_MS
}, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try { resolve(JSON.parse(data)); }
catch { reject(new Error('Resposta inválida da API')); }
} else if (res.statusCode === 429 || res.statusCode >= 500) {
// Erros recuperáveis: rate limit ou server error
if (attempt < MAX_RETRIES) {
const delay = BASE_DELAY_MS * Math.pow(2, attempt);
setTimeout(() => requestWithRetry(url, apiKey, attempt + 1)
.then(resolve).catch(reject), delay);
} else {
reject(new Error(`API error ${res.statusCode}: ${data}`));
}
} else {
// 4xx exceto 429: erro de negócio, não retry
reject(new Error(`API error ${res.statusCode}: ${data}`));
}
});
});
req.on('error', (err) => {
if (attempt < MAX_RETRIES && (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT')) {
const delay = BASE_DELAY_MS * Math.pow(2, attempt);
setTimeout(() => requestWithRetry(url, apiKey, attempt + 1)
.then(resolve).catch(reject), delay);
} else {
reject(err);
}
});
req.on('timeout', () => {
req.destroy();
if (attempt < MAX_RETRIES) {
const delay = BASE_DELAY_MS * Math.pow(2, attempt);
setTimeout(() => requestWithRetry(url, apiKey, attempt + 1)
.then(resolve).catch(reject), delay);
} else {
reject(new Error('Request timeout'));
}
});
req.end();
});
}
/**
* Normaliza resposta da SmartCPF para formato padronizado da aplicação
*/
function normalizeResponse(apiResponse, originalCpf) {
const { meta, result, success, errors } = apiResponse;
return {
cpf: originalCpf,
valid: success && result?.status === 'Regular',
status: result?.status || 'Não consultado',
consultId: meta?.consultId,
balance: meta?.balance,
executionTimeMs: meta?.executionTimeMs,
data: success && result ? {
name: result.name,
birthDate: result.birthDate,
age: result.age,
motherName: result.motherName,
gender: result.gender,
emails: result.emails || [],
phones: result.phones || [],
addresses: result.addresses || []
} : null,
errors: errors || [],
rawMeta: meta
};
}
exports.handler = async (event) => {
// Extrai CPF do body (API Gateway proxy) ou query string
let cpf = null;
if (event.body) {
try {
const parsed = typeof event.body === 'string' ? JSON.parse(event.body) : event.body;
cpf = parsed.cpf;
} catch { /* ignora parse error */ }
}
if (!cpf && event.queryStringParameters) {
cpf = event.queryStringParameters.cpf;
}
if (!cpf) {
return {
statusCode: 400,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ error: 'CPF é obrigatório', code: 'MISSING_CPF' })
};
}
if (!isValidCpfFormat(cpf)) {
return {
statusCode: 400,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
error: 'CPF inválido: deve conter 11 dígitos numéricos',
code: 'INVALID_CPF_FORMAT',
cpf: cleanCpf(cpf)
})
};
}
const cleanedCpf = cleanCpf(cpf);
const apiKey = process.env.SMARTCPF_API_KEY;
const pkg = process.env.SMARTCPF_PACKAGE || 'basic';
if (!apiKey) {
console.error('SMARTCPF_API_KEY não configurada');
return {
statusCode: 500,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ error: 'Configuração incompleta', code: 'MISSING_API_KEY' })
};
}
const url = new URL(`${API_BASE}/individuals/${cleanedCpf}`);
url.searchParams.set('package', pkg);
try {
const apiResponse = await requestWithRetry(url.toString(), apiKey);
const normalized = normalizeResponse(apiResponse, cleanedCpf);
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(normalized)
};
} catch (err) {
console.error('Erro na consulta SmartCPF:', err.message);
// Fallback: validação sintática local quando API falha
const syntacticValid = validateCpfDigits(cleanedCpf);
return {
statusCode: 502,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
cpf: cleanedCpf,
valid: syntacticValid,
status: syntacticValid ? 'Válido (formato)' : 'Inválido',
consultId: null,
balance: null,
executionTimeMs: null,
data: null,
errors: [{ code: 'API_UNAVAILABLE', message: 'Validação oficial indisponível; usado fallback sintático' }],
fallback: true
})
};
}
};
/**
* Exemplo de uso local (teste manual):
*
* node -e "
* process.env.SMARTCPF_API_KEY='sua-chave-aqui';
* const { handler } = require('./validate-cpf-lambda');
* handler({ body: JSON.stringify({ cpf: '111.111.111-11' }) })
* .then(r => console.log(r.body))
* .catch(console.error);
* "
Resposta da API
{
"meta": {
"searchType": "CPF G",
"consultId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"user": "Fulano de Tal",
"message": "CPF encontrado com sucesso",
"ip": "127.0.0.1",
"success": true,
"apiVersion": "v2",
"date": "2025-01-15T14:30:45.123Z",
"executionTimeMs": 74.1,
"balance": 9.77
},
"result": {
"cpf": "111.111.111-11",
"name": "João da Silva",
"birthDate": "10/09/1992",
"age": 33,
"motherName": "Maria da Silva",
"gender": "M",
"status": "Regular",
"emails": ["[email protected]"],
"phones": [
{
"number": "(55) 99999-9999",
"blockedTelemarketing": false,
"operator": "VIVO",
"type": "CELULAR",
"whatsapp": false
}
],
"addresses": []
},
"success": true,
"errors": []
}
O fluxo demonstrado resolve na prática:
- consultId — identificador único da consulta para auditoria, suporte e idempotência; guarde em logs estruturados para rastreabilidade
- balance — saldo de créditos restante; monitore via alerta (ex.: < 100 créditos) para evitar interrupção silenciosa
- executionTimeMs — latência real da API; use para SLOs internos e detectar degradação de performance
- status — "Regular", "Pendente", "Cancelado", "Nulo" etc.; base para regras de negócio (bloquear cadastro, exigir documento extra)
- data.emails / data.phones — canais de contato enriquecidos; útil para comunicação transacional ou verificação de posse
- fallback (no código) — flag booleana indicando se a validação oficial falhou e o fallback sintático foi usado; trate como sinal de alerta operacional
Por que usar a SmartCPF em produção serverless
- Latência consistente — infraestrutura otimizada para consulta de CPF com SLA público; não há "vizinhos barulhentos" em banco compartilhado
- Integração sem SDK — HTTP puro, sem dependências de cliente oficial; funciona em qualquer runtime Lambda (Node, Python, Go, Java, .NET)
- Modelo de créditos previsível — recarga sob demanda, sem assinatura mensal; custo marginal por validação cai com volume
- Escalabilidade nativa — a API absorve picos de Black Friday, campanhas de marketing ou onboarding em massa sem configuração extra
- Dados enriquecidos além do básico — pacotes opcionais trazem score de risco, óbitos, vínculos empregatícios, veículos, imóveis; ative conforme necessidade sem mudar arquitetura
Conclusão
Validar CPF em Lambda com a SmartCPF elimina a complexidade de manter bases locais, reduz custo de infraestrutura a zero ocioso e entrega latência previsível com observabilidade nativa. O padrão de header X-API-KEY mantém a autenticação simples e segura via variáveis de ambiente, enquanto o fallback sintático garante resiliência mesmo quando o serviço externo oscila. Crie sua conta na SmartCPF e faça sua primeira consulta em minutos.
Sobre a redação
Redação Smart CPF
Autor do blog
Mais artigos

Consumindo a API SmartCPF em Java com Spring Boot
Tutorial prático de integração da API SmartCPF v2 em aplicações Spring Boot com autenticação X-API-KEY e tratamento de erros.

Validação de CPF em Ruby on Rails: guia completo de integração
Como validar e consultar CPF em Rails usando a API SmartCPF v2 com autenticação X-API-KEY, tratamento de erros e exemplos práticos.

SmartCPF vs Consulta Manual na Receita Federal: Tempo e Confiabilidade
Comparativo técnico entre consulta automatizada via API SmartCPF e processo manual no e-CAC: latência, disponibilidade e integração

Validação de CPF em Rust com Axum: exemplo prático com SmartCPF
Aprenda a validar CPF em Rust usando Axum e a API SmartCPF v2. Código completo com autenticação X-API-KEY, tratamento de erros e parsing da resposta.
Pronto para validar CPFs em segundos?
Consultas gratuitas para testar agora. Acesso imediato à documentação.