Usando a API de CPF para pré-preencher nome, data de nascimento e gênero no formulário de cadastro, você elimina entre 15 e 30 segundos de digitação — tempo suficiente para reduzir o abandono em fluxos com mais de 5 campos. O usuário digita apenas o CPF; o restante aparece automaticamente com um debounce de 500ms e a resposta de ~900ms da CPFHub.io. A ANPD orienta que dados pessoais sejam coletados apenas para finalidades declaradas, então use o preenchimento progressivo com transparência: informe ao usuário que os dados foram obtidos via CPF.
Introdução
Cada campo adicional em um formulário de cadastro é um potencial ponto de abandono. Estudos de UX mostram que formulários com mais de 5 campos têm taxas de conclusão significativamente menores do que formulários mais curtos. Mas muitas vezes, os dados que pedimos ao usuário podem ser obtidos automaticamente a partir de informações que ele já forneceu -- como o CPF.
O conceito de preenchimento progressivo
Preenchimento progressivo é a prática de preencher automaticamente campos do formulário a partir de dados já disponíveis. No contexto brasileiro, o CPF é a chave principal que conecta diferentes bases de dados. Ao validar um CPF via API, podemos obter:
- Nome completo: preenche automaticamente o campo de nome.
- Data de nascimento: elimina a necessidade de selecionar dia, mês e ano.
- Gênero: preenche o campo de gênero sem exigir seleção manual.
Esses três campos preenchidos automaticamente economizam entre 15 e 30 segundos de digitação -- tempo suficiente para impactar a conversão.
Fluxo de preenchimento progressivo
O fluxo ideal para preenchimento progressivo com CPF segue estas etapas:
- Usuário digita o CPF.
- O sistema valida automaticamente (com debounce).
- Os campos de nome, nascimento e gênero são preenchidos com os dados da API.
- O usuário pode editar os dados preenchidos se necessário.
- Os campos restantes (e-mail, telefone, endereço) ficam para preenchimento manual.
Implementação completa
HTML do formulário
<form class="registration-form" id="registration-form">
<h2>Cadastro</h2>
<!-- Campo principal: CPF -->
<div class="form-group">
<label for="cpf">CPF</label>
<input
type="text"
id="cpf"
inputmode="numeric"
maxlength="14"
placeholder="000.000.000-00"
required
/>
<div class="form-feedback" id="cpf-feedback" role="status" aria-live="polite"></div>
</div>
<!-- Campos preenchidos automaticamente -->
<div class="auto-fill-section" id="auto-fill-section">
<div class="auto-fill-badge">
Preenchido automaticamente
</div>
<div class="form-group">
<label for="name">Nome completo</label>
<input type="text" id="name" required />
</div>
<div class="form-row">
<div class="form-group form-group--half">
<label for="birthdate">Data de nascimento</label>
<input type="text" id="birthdate" readonly />
</div>
<div class="form-group form-group--half">
<label for="gender">Gênero</label>
<select id="gender">
<option value="">Selecione</option>
<option value="M">Masculino</option>
<option value="F">Feminino</option>
</select>
</div>
</div>
</div>
<!-- Campos manuais -->
<div class="manual-section">
<div class="form-group">
<label for="email">E-mail</label>
<input type="email" id="email" required />
</div>
<div class="form-group">
<label for="phone">Telefone</label>
<input type="tel" id="phone" />
</div>
<div class="form-group">
<label for="cep">CEP</label>
<input
type="text"
id="cep"
inputmode="numeric"
maxlength="9"
placeholder="00000-000"
/>
</div>
<div class="form-group">
<label for="address">Endereço</label>
<input type="text" id="address" />
</div>
</div>
<button type="submit" class="btn-submit" id="btn-submit">
Cadastrar
</button>
</form>
Estilos para feedback de preenchimento
.registration-form {
max-width: 520px;
margin: 0 auto;
}
.form-group {
margin-bottom: 16px;
}
.form-group label {
display: block;
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin-bottom: 4px;
}
.form-group input,
.form-group select {
width: 100%;
padding: 10px 14px;
font-size: 16px;
border: 2px solid #d1d5db;
border-radius: 8px;
outline: none;
transition: all 0.2s ease;
}
.form-group input:focus,
.form-group select:focus {
border-color: #3b82f6;
box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
}
.form-row {
display: flex;
gap: 16px;
}
.form-group--half {
flex: 1;
}
/* Seção de preenchimento automático */
.auto-fill-section {
position: relative;
background: #f0fdf4;
border: 1px solid #bbf7d0;
border-radius: 12px;
padding: 20px 16px 16px;
margin: 16px 0;
opacity: 0;
max-height: 0;
overflow: hidden;
transition: opacity 0.4s ease, max-height 0.5s ease, padding 0.4s ease,
margin 0.4s ease;
}
.auto-fill-section--visible {
opacity: 1;
max-height: 300px;
padding: 20px 16px 16px;
margin: 16px 0;
}
.auto-fill-badge {
position: absolute;
top: -10px;
left: 16px;
background: #059669;
color: #fff;
font-size: 11px;
font-weight: 600;
padding: 2px 10px;
border-radius: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* Animação de preenchimento */
.form-group input.auto-filled {
animation: fill-highlight 0.8s ease;
}
@keyframes fill-highlight {
0% {
background-color: #fff;
}
30% {
background-color: #d1fae5;
}
100% {
background-color: #fff;
}
}
.form-feedback {
font-size: 13px;
margin-top: 4px;
min-height: 18px;
}
JavaScript de preenchimento progressivo
var cpfInput = document.getElementById("cpf");
var feedback = document.getElementById("cpf-feedback");
var autoFillSection = document.getElementById("auto-fill-section");
var debounceTimer = null;
cpfInput.addEventListener("input", function () {
// Formatar
var v = this.value.replace(/\D/g, "").slice(0, 11);
if (v.length > 9)
v = v.replace(/(\d{3})(\d{3})(\d{3})(\d{1,2})/, "$1.$2.$3-$4");
else if (v.length > 6)
v = v.replace(/(\d{3})(\d{3})(\d{1,3})/, "$1.$2.$3");
else if (v.length > 3)
v = v.replace(/(\d{3})(\d{1,3})/, "$1.$2");
this.value = v;
var digits = v.replace(/\D/g, "");
if (digits.length < 11) {
autoFillSection.classList.remove("auto-fill-section--visible");
return;
}
if (debounceTimer) clearTimeout(debounceTimer);
debounceTimer = setTimeout(function () {
fetchAndFill(digits);
}, 500);
});
async function fetchAndFill(cpf) {
feedback.textContent = "Buscando dados...";
feedback.style.color = "#6b7280";
var controller = new AbortController();
var timeoutId = setTimeout(function () {
controller.abort();
}, 10000);
try {
var res = await fetch("https://api.cpfhub.io/cpf/" + cpf, {
headers: {
"x-api-key": "SUA_CHAVE_DE_API",
Accept: "application/json",
},
signal: controller.signal,
});
clearTimeout(timeoutId);
var result = await res.json();
if (result.success) {
feedback.textContent = "CPF válido!";
feedback.style.color = "#059669";
fillFields(result.data);
} else {
feedback.textContent = "CPF não encontrado. Preencha os dados manualmente.";
feedback.style.color = "#f59e0b";
showAutoFillSectionEmpty();
}
} catch (err) {
clearTimeout(timeoutId);
feedback.textContent = "Erro na consulta. Preencha manualmente.";
feedback.style.color = "#dc2626";
showAutoFillSectionEmpty();
}
}
function fillFields(data) {
autoFillSection.classList.add("auto-fill-section--visible");
// Preencher com animação sequencial
setTimeout(function () {
fillWithAnimation("name", data.name);
}, 100);
setTimeout(function () {
fillWithAnimation("birthdate", data.birthDate);
}, 300);
setTimeout(function () {
var genderSelect = document.getElementById("gender");
genderSelect.value = data.gender;
genderSelect.classList.add("auto-filled");
setTimeout(function () {
genderSelect.classList.remove("auto-filled");
}, 800);
}, 500);
}
function fillWithAnimation(fieldId, value) {
var field = document.getElementById(fieldId);
field.value = value;
field.classList.add("auto-filled");
setTimeout(function () {
field.classList.remove("auto-filled");
}, 800);
}
function showAutoFillSectionEmpty() {
autoFillSection.classList.add("auto-fill-section--visible");
document.getElementById("name").value = "";
document.getElementById("birthdate").value = "";
document.getElementById("gender").value = "";
document.getElementById("name").focus();
}
Combinando CPF com API de CEP
Para um preenchimento ainda mais completo, combine a validação de CPF com uma consulta de CEP:
var cepInput = document.getElementById("cep");
var addressInput = document.getElementById("address");
cepInput.addEventListener("input", function () {
var cep = this.value.replace(/\D/g, "");
// Formatação
if (cep.length > 5) {
this.value = cep.slice(0, 5) + "-" + cep.slice(5, 8);
}
if (cep.length === 8) {
fetchAddress(cep);
}
});
async function fetchAddress(cep) {
var controller = new AbortController();
var timeoutId = setTimeout(function () {
controller.abort();
}, 5000);
try {
var res = await fetch("https://viacep.com.br/ws/" + cep + "/json/", {
signal: controller.signal,
});
clearTimeout(timeoutId);
var data = await res.json();
if (!data.erro) {
addressInput.value =
data.logradouro +
", " +
data.bairro +
" - " +
data.localidade +
"/" +
data.uf;
addressInput.classList.add("auto-filled");
setTimeout(function () {
addressInput.classList.remove("auto-filled");
}, 800);
}
} catch (err) {
clearTimeout(timeoutId);
// Silenciar - preenchimento de endereço é opcional
}
}
Permitindo edição dos dados preenchidos
Os campos preenchidos automaticamente devem ser editáveis. Adicione uma indicação visual de que o campo foi preenchido automaticamente mas pode ser alterado:
function fillWithAnimation(fieldId, value) {
var field = document.getElementById(fieldId);
field.value = value;
field.classList.add("auto-filled");
field.removeAttribute("readonly");
// Adicionar tooltip
field.title = "Preenchido automaticamente. Clique para editar.";
setTimeout(function () {
field.classList.remove("auto-filled");
}, 800);
}
Métricas de impacto
Acompanhe o impacto do preenchimento progressivo:
- Tempo de preenchimento: meça o tempo entre o primeiro clique e o envio.
- Taxa de conclusão: compare com a versão sem preenchimento automático.
- Taxa de edição: quantos usuários alteram os dados preenchidos.
- Erros de dados: verifique se o preenchimento automático introduz erros.
// Métricas simples
var formStartTime = null;
document.getElementById("cpf").addEventListener("focus", function () {
if (!formStartTime) formStartTime = Date.now();
});
document
.getElementById("registration-form")
.addEventListener("submit", function () {
var totalTime = Date.now() - formStartTime;
console.log("Tempo de preenchimento:", totalTime, "ms");
// Enviar para analytics
});
Perguntas frequentes
O preenchimento progressivo com CPF funciona para qualquer tipo de formulário?
Funciona melhor em formulários de cadastro onde nome, data de nascimento e gênero são obrigatórios — e-commerce, fintechs, plataformas de saúde e sistemas de RH. Para formulários de contato simples ou checkout de compra rápida, o ganho é menor. O maior impacto é em fluxos com 5 ou mais campos, onde cada campo eliminado aumenta a taxa de conclusão.
Como evitar que a chave de API fique exposta no frontend?
Nunca insira a chave de API diretamente no JavaScript do cliente. Crie um endpoint no seu backend (Node.js, Python, PHP) que receba o CPF do frontend, faça a chamada à CPFHub.io com a chave armazenada em variável de ambiente, e retorne apenas os dados necessários. Isso protege a chave e permite aplicar validações adicionais no servidor.
O que acontece se o usuário digitar um CPF que não existe na base?
A API retorna "success": false. No código do exemplo, o formulário exibe "CPF não encontrado. Preencha os dados manualmente." e abre a seção de campos para preenchimento manual. O fluxo nunca bloqueia o usuário — o preenchimento progressivo é uma conveniência, não um obstáculo.
Como medir se o preenchimento progressivo aumentou a conversão?
Configure um evento de analytics no focus do campo CPF (início) e no submit do formulário (conclusão). Compare o tempo médio de preenchimento e a taxa de abandono antes e depois da implementação. Para um teste mais rigoroso, use A/B test com 50% dos usuários recebendo o formulário com preenchimento automático e 50% sem — compare as taxas de conclusão após 500 envios em cada variação.
Conclusão
O preenchimento progressivo usando CPF como ponto de partida é uma das estratégias mais eficazes para reduzir atrito em formulários de cadastro brasileiros. Com uma única informação — o CPF —, a API do CPFHub.io retorna nome, data de nascimento e gênero em ~900ms, eliminando campos e reduzindo o tempo de preenchimento em até 30 segundos.
A API da CPFHub.io entrega dados em ~900ms, com 99,9% de uptime e conformidade com a LGPD, oferecendo a base para um preenchimento progressivo confiável em qualquer stack.
Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito.
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.



