Validar CPF no cadastro com n8n: workflow passo a passo, sem escrever backend
Transparência: sou fundador da CPFHub e mantenho o nó
n8n-nodes-cpfhubusado neste tutorial.
Formulários de cadastro recebem CPFs digitados errado, CPFs de outras pessoas e nomes que não batem com o documento. Se você já usa n8n para automatizar o onboarding, dá para colocar uma consulta de CPF via API no meio do fluxo sem escrever uma linha de backend. Neste tutorial vamos montar um workflow que recebe um cadastro por webhook, consulta o CPF, compara o nome e decide se aprova ou manda para revisão.
O que você vai precisar
- Uma instância n8n (self-hosted ou n8n Cloud, versão 1.0 ou superior).
- Uma chave de API da CPFHub. O plano gratuito inclui 50 créditos por mês, sem cartão. Cada consulta simples de CPF encontrado custa 1 crédito; CPF não encontrado não consome crédito.
- O community node
n8n-nodes-cpfhub(publicado no npm).
Passo 1: instalar o community node
No n8n, vá em Settings → Community Nodes → Install e digite:
n8n-nodes-cpfhub
Em instalações self-hosted também dá para instalar via npm (npm install n8n-nodes-cpfhub) no diretório de nodes customizados.
Passo 2: criar a credencial
Em Credentials → New, procure CPFHub API, cole sua chave no campo API Key e salve. A chave é gerada no painel em app.cpfhub.io. Por baixo, o nó envia a chave no header x-api-key, como na documentação da API — e ela fica guardada nas credenciais do n8n, fora do front-end.
Passo 3: o desenho do workflow
Webhook (recebe nome + CPF)
→ Code (normaliza e valida dígitos)
→ CPFHub (CPF → Lookup)
→ IF (nome confere?)
→ true: aprovar (resposta 200 / CRM / e-mail)
→ false: revisão manual (Slack, planilha, ticket)
Webhook
Crie um nó Webhook com método POST. O formulário (Typeform, Tally, seu front) envia algo como:
{ "nome": "Fulano de Tal", "cpf": "123.456.789-09" }
Code: normalizar e validar dígitos
Não gaste consultas com CPF digitado errado. Um nó Code (JavaScript) resolve:
const item = $input.first().json.body ?? $input.first().json;
const cpf = String(item.cpf || "").replace(/\D/g, "");
function digito(base) {
let soma = 0;
for (let i = 0; i < base.length; i++) soma += Number(base[i]) * (base.length + 1 - i);
const resto = (soma * 10) % 11;
return resto === 10 ? 0 : resto;
}
const valido =
cpf.length === 11 &&
!/^(\d)\1{10}$/.test(cpf) &&
digito(cpf.slice(0, 9)) === Number(cpf[9]) &&
digito(cpf.slice(0, 10)) === Number(cpf[10]);
return [{ json: { nome: item.nome, cpf, valido } }];
Coloque um IF logo depois: se valido for falso, devolva erro ao formulário ("confira o CPF") e encerre. Só os válidos seguem para a consulta.
CPFHub: Lookup
Adicione o nó CPFHub, operação CPF → Lookup, e no campo CPF use a expressão {{ $json.cpf }}. A saída traz:
| Campo | Exemplo |
|---|---|
cpf | 12345678909 |
name | Fulano de Tal |
nameUpper | FULANO DE TAL |
gender | M |
birthDate | 15/06/1990 |
day, month, year | 15, 6, 1990 |
O tempo típico da consulta simples é ~150 ms (tempo típico, não SLA), então o webhook pode responder ao usuário na hora.
IF: o nome confere?
Comparar nomes exatamente é frágil (acentos, abreviações, nome social). Uma comparação razoável: normalizar os dois lados e exigir primeiro e último nome iguais. Num nó Code antes do IF:
const norm = (s) =>
String(s || "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").toUpperCase().trim().split(/\s+/);
const informado = norm($("Code").first().json.nome);
const oficial = norm($json.nameUpper);
const confere =
informado.length > 0 &&
informado[0] === oficial[0] &&
informado.at(-1) === oficial.at(-1);
return [{ json: { ...$json, confere } }];
No IF, use {{ $json.confere }} igual a true. No ramo verdadeiro, crie o contato no CRM ou envie o e-mail de boas-vindas; no falso, mande para revisão manual com o nome informado e o retornado lado a lado.
Passo 4: tratar erros
O nó lança erros descritivos por status HTTP. Os principais:
- 404 — CPF não encontrado na base. É resultado normal, não falha, e não consome crédito: trate como "revisão manual".
- 401 — chave ausente ou inválida: confira a credencial.
- 403 — créditos esgotados ou conta bloqueada.
- 429 — limite por minuto (30/min no padrão da consulta simples): espere e tente de novo.
- 500/503 — falha passageira: repita com espera crescente.
Ative Settings → On Error → Continue (using error output) (ou "Continue On Fail") no nó CPFHub para que um 404 siga por um ramo próprio em vez de derrubar a execução. Para 429 e 503, o n8n tem Retry On Fail nas configurações do nó.
E a situação cadastral na Receita?
O nó atual faz a consulta simples (nome, gênero, data de nascimento). Se o seu fluxo precisa da situação cadastral em tempo real, use o nó HTTP Request chamando POST https://api.cpfhub.io/cpf/realtime:
- header
x-api-keycom sua chave (use uma credencial do tipo Header Auth); - body JSON com
cpfebirthDate(DD/MM/AAAA); - timeout de 60 s nas opções do nó (o tempo típico é cerca de 1 s, mas a Receita pode demorar);
- custo de 1,5 crédito por consulta bem-sucedida.
A resposta traz situation (REGULAR, SUSPENSA, TITULAR FALECIDO etc.) e deathYear. Lembre que deathYear: null significa "nenhum óbito registrado", não prova de vida. E não ligue Retry On Fail nesse nó por timeout: o POST não é idempotente e pode ter sido cobrado.
Boas práticas de dados
- Grave no CRM só o necessário (por exemplo, "CPF verificado em 12/10/2026"), não a resposta inteira.
- Nas execuções salvas do n8n, os dados de entrada e saída ficam armazenados. Ajuste Save Execution Progress / Save Successful Executions ou a retenção para não acumular CPFs indefinidamente.
- Informe na política de privacidade que os dados cadastrais podem ser verificados junto a provedores de validação.
Variações do mesmo fluxo
- Pedido em e-commerce: gatilho do WooCommerce/Shopify → CPFHub → IF → aprovar ou segurar o pedido e avisar no Slack.
- Formulário + CRM: Typeform/Tally → CPFHub → criar ou atualizar contato com o nome verificado.
- Verificação de maioridade: use
year,monthedaynum nó Code para calcular a idade.
Com cinco ou seis nós você tem validação de CPF no cadastro, com tratamento de erro e sem backend próprio. O pacote está no npm como n8n-nodes-cpfhub, e a referência completa da API fica em cpfhub.io.