Poucas coisas melhoram tanto a experiência de um formulário quanto digitar o CEP e ver o endereço aparecer sozinho. Menos digitação, menos erros de grafia, menos pedidos entregues no lugar errado. Neste tutorial você vai aprender a consultar CEP com JavaScript e preencher automaticamente logradouro, bairro, cidade e UF.
Vamos construir do jeito certo desde o início: um front-end com máscara e fetch, e um pequeno back-end em Node.js que consulta o CEP usando a SDK oficial da APIBrasil. Esse back-end existe por um motivo importante — proteger o seu token — que explicamos logo abaixo.
O que você vai construir
Um formulário de endereço de entrega que:
- Aplica a máscara
00000-000enquanto o usuário digita. - Consulta o CEP automaticamente quando os 8 dígitos são preenchidos.
- Preenche logradouro, bairro, cidade e UF.
- Mostra mensagens claras para CEP inválido ou não encontrado.
- Move o cursor para o campo “Número”, o único que o usuário ainda precisa digitar.
Por que não chamar a API direto do navegador?
APIs profissionais exigem autenticação por token. Tudo o que roda no navegador — HTML, JavaScript, requisições — pode ser visto por qualquer pessoa nas ferramentas de desenvolvedor. Se você colocar o token no JavaScript do front-end, qualquer visitante pode copiá-lo e usar a sua cota ou o seu saldo.
A solução é a arquitetura de proxy no back-end:
| Camada | Responsabilidade | Conhece o token? |
|---|---|---|
Navegador (cep.js) |
Máscara, fetch para o seu servidor, preencher campos |
Não |
Seu back-end (server.js) |
Validar o CEP, chamar a APIBrasil, devolver só o necessário | Sim, via variável de ambiente |
| APIBrasil | Consultar o CEP na base de dados | — |
De quebra, o back-end permite validar a entrada, aplicar cache, limitar requisições e padronizar a resposta. Os mesmos princípios aparecem no tutorial Variáveis de ambiente e arquivo .env.
Pré-requisitos
- Node.js 20.6 ou superior (usamos o
--env-filenativo). - Uma conta na APIBrasil com a API de CEP ativa, e os tokens em mãos: o Bearer token da conta e o DeviceToken do device da API de CEP.
- Conhecimento básico de HTML, JavaScript e Express. Se o Express é novidade, veja antes Minha primeira API em Node.js com Express.
Passo 1: criando o projeto
mkdir consulta-cep && cd consulta-cep
npm init -y
npm pkg set type=module
npm install express apigratis-sdk-nodejs
npm pkg set scripts.dev="node --watch --env-file=.env server.js"

O type=module permite usar import em vez de require. A SDK apigratis-sdk-nodejs não tem dependências de runtime, usa o fetch nativo do Node.js e já traz os tipos para TypeScript.
Crie o arquivo .env com as credenciais (e adicione-o ao .gitignore):
APIBRASIL_BEARER_TOKEN=cole_seu_bearer_token
APIBRASIL_DEVICE_TOKEN=cole_o_device_token_da_api_de_cep
Passo 2: o back-end em Node.js
O server.js faz duas coisas: serve os arquivos da pasta public (nosso front-end) e expõe a rota /api/cep/:cep, que consulta a APIBrasil:

Os detalhes que fazem diferença:
new ApiBrasil()lêAPIBRASIL_BEARER_TOKENeAPIBRASIL_DEVICE_TOKENdo ambiente. O token nunca aparece no código.- Validação antes da chamada: removemos tudo o que não é dígito e exigimos exatamente 8. Assim,
01001-000e01001000funcionam, e entradas inválidas nem chegam à API — economizando requisições. api.cep.cep({ cep })faz oPOST /cep/cepno gateway da APIBrasil, um serviço do tipo device-based (Bearer + DeviceToken).- Resposta normalizada: o back-end devolve sempre o mesmo formato (
logradouro,bairro,cidade,uf). A funçãopegaraceita nomes alternativos de campo, uma técnica usada nos exemplos oficiais da APIBrasil, e o front-end não precisa saber nada sobre o provedor. - Erros tratados: a SDK lança
ApiBrasilErrorcom o status HTTP. Traduzimos 404 para “CEP não encontrado” e demais falhas para uma mensagem genérica, sem vazar detalhes internos para o navegador.
Passo 3: o HTML do formulário
Crie public/index.html:

Pequenos atributos, grande diferença de usabilidade:
inputmode="numeric"abre o teclado numérico no celular.maxlength="9"comporta os 8 dígitos mais o hífen.autocomplete="postal-code"permite que o navegador sugira o CEP salvo do usuário.- O parágrafo com
role="status"faz leitores de tela anunciarem as mensagens de “buscando” e de erro, melhorando a acessibilidade.
O arquivo public/estilo.css com o visual do formulário está no final deste tutorial.
Passo 4: o JavaScript que consulta o CEP
Agora a parte central: public/cep.js.

Como o código funciona:
- Máscara: a cada tecla (
input), removemos o que não é número, limitamos a 8 dígitos e inserimos o hífen após o quinto. Usar o eventoinput, e nãokeyup, cobre também colar com o mouse e o preenchimento automático do navegador. - Disparo automático: quando há 8 dígitos, chamamos
buscarCep. Nada de botão “Buscar”. - Feedback imediato: enquanto a requisição acontece, mostramos “Buscando endereço…” e reticências nos campos, para o usuário não achar que travou.
fetchpara o nosso back-end: a URL é/api/cep/..., no mesmo domínio, então não há problemas de CORS e nenhum token trafega pelo navegador.resposta.ok: ofetchnão lança erro em respostas 400 ou 404; ele só falha em erros de rede. Por isso verificamosresposta.oke lançamos o erro manualmente com a mensagem vinda do servidor.- Foco no número: com o endereço preenchido, levamos o cursor para o campo “Número”.
Passo 5: testando
Suba o servidor com npm run dev e, em outro terminal, teste a rota com cURL antes de ir para o navegador:

Testar o back-end isoladamente ajuda a descobrir se um problema está no servidor ou no front-end. Aprenda mais técnicas em Como testar APIs com cURL e Postman.
Agora abra http://localhost:3000 e digite um CEP:

E veja o comportamento com um CEP inexistente:

Passo 6: o CSS do formulário
Para completar, o public/estilo.css:
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; background: #f1f5f9; display: grid; place-items: center; min-height: 100vh; margin: 0; }
form { background: #fff; padding: 32px; border-radius: 16px; width: min(480px, 92vw); box-shadow: 0 10px 30px rgba(15, 23, 42, .08); }
h1 { font-size: 22px; margin: 0 0 20px; }
label { display: block; font-size: 14px; color: #334155; margin-bottom: 14px; flex: 1; }
input { display: block; width: 100%; margin-top: 6px; padding: 10px 12px; font-size: 16px; border: 1px solid #cbd5e1; border-radius: 8px; }
input:focus { outline: 2px solid #2563eb; border-color: transparent; }
.linha { display: flex; gap: 12px; }
.uf { flex: 0 0 80px; }
#mensagem { font-size: 14px; min-height: 20px; margin: -6px 0 12px; color: #64748b; }
#mensagem.ok { color: #15803d; }
#mensagem.erro { color: #b91c1c; }
O font-size: 16px nos inputs não é à toa: no iPhone, campos com fonte menor que 16px fazem o navegador dar zoom ao focar.
Melhorias para produção
- Cache: CEPs quase nunca mudam. Guarde as consultas em memória, Redis ou banco por alguns dias e economize requisições.
- Rate limiting: limite quantas consultas cada IP pode fazer por minuto na sua rota
/api/cep, para evitar abuso. Veja Como implementar rate limiting em APIs. - Campos editáveis: não bloqueie os campos preenchidos. CEPs de cidades pequenas às vezes não têm logradouro, e o usuário precisa completar.
- Debounce: se mudar o gatilho para cada tecla, aguarde alguns milissegundos sem digitação antes de consultar.
- Mais dados: o serviço de CEP da APIBrasil também oferece rotas para listar estados, cidades e bairros e cidades por DDD. Na SDK, use
api.cep.request('cidadesPorDDD', { ddd: '11' })e similares.
Consultando CEP com PHP ou outras linguagens
A mesma consulta em PHP, com a SDK oficial:
<?php
require 'vendor/autoload.php';
$api = new ApiBrasil\ApiBrasil(); // lê os tokens do ambiente
$resposta = $api->cep->cep(['cep' => '01001000']);
print_r($resposta);
A APIBrasil mantém SDKs para PHP, Node.js, Python, Go, Java, Ruby, Rust, C++ e Flutter. Os exemplos estão no repositório apigratis-exemplos e a referência completa em doc.apibrasil.io.
Erros comuns
403 na consulta — o DeviceToken é de outra API (por exemplo, do WhatsApp) ou seu IP não está na whitelist. Cada serviço device-based tem o próprio device.
401 na consulta — o Bearer token está ausente ou expirou. Confira se o servidor foi iniciado com --env-file=.env.
“Failed to fetch” no navegador — o servidor Node.js não está rodando, ou a página foi aberta direto pelo arquivo (file://) em vez de http://localhost:3000.
Os campos não são preenchidos — abra o DevTools (F12), aba Network, e veja a resposta da rota /api/cep. Se ela estiver correta, o problema está nos id dos inputs.
O import falha no Node.js — faltou "type": "module" no package.json.
Perguntas frequentes
Posso consultar CEP direto do front-end, sem back-end?
Tecnicamente, sim, com APIs públicas sem autenticação. Mas qualquer API que exija token deve ser chamada pelo back-end para não expor a credencial. Além disso, o back-end dá controle sobre cache, limites e formato da resposta.
Como validar se um CEP existe?
Formato você valida localmente (8 dígitos). Existência só é possível consultando uma base de CEPs, como faz a API. Trate o retorno “não encontrado” como uma resposta válida, não como falha do sistema.
Funciona com React, Vue ou Angular?
Sim. A lógica do cep.js (máscara, disparo aos 8 dígitos e fetch para o back-end) é a mesma; muda apenas a forma de atualizar os campos, usando o estado do framework.
A consulta de CEP retorna latitude e longitude?
O serviço de CEP da APIBrasil inclui geolocalização quando disponível para o CEP consultado. Confira os campos retornados na documentação e ajuste a função de normalização do back-end para repassá-los.
Conclusão
Você aprendeu a consultar CEP com JavaScript do jeito certo: máscara e fetch no front-end, um back-end Node.js que valida a entrada e protege o token, consulta pela SDK oficial da APIBrasil, resposta normalizada e tratamento de erros pensado para o usuário. É um recurso pequeno que reduz erros de cadastro e aumenta a conversão em checkouts.
O próximo tutorial da série usa a mesma SDK para outro canal de comunicação: Como enviar mensagens de WhatsApp com Node.js. Crie sua conta na APIBrasil para obter os tokens e testar.
![]()









