# Como usar API de CPF para pré-preencher endereço e reduzir atrito no cadastro

> Saiba como usar a API de CPF para pré-preencher dados no cadastro, reduzindo atrito e aumentando conversão em formulários.

**Publicado:** 21/07/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-usar-api-de-cpf-para-pre-preencher-endereco-e-reduzir-atrito-no-cadastro

---


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](https://www.gov.br/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:

1. Usuário digita o CPF.
2. O sistema valida automaticamente (com debounce).
3. Os campos de nome, nascimento e gênero são preenchidos com os dados da API.
4. O usuário pode editar os dados preenchidos se necessário.
5. Os campos restantes (e-mail, telefone, endereço) ficam para preenchimento manual.

---

## Implementação completa

### HTML do formulário

```html
<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

```css
.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

```javascript
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:

```javascript
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:

```javascript
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.

```javascript
// 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.

### Leia também

- [Como pedir CPF no checkout sem espantar o cliente](https://cpfhub.io/blog/como-pedir-cpf-no-checkout-sem-espantar-o-cliente)
- [Como validar CPF no frontend com React e API REST](https://cpfhub.io/blog/como-validar-cpf-no-frontend-com-react-e-api-rest)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)

---

## 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](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito.

