CEP

Endereço a partir do CEP

Logradouro, bairro, cidade, UF e código IBGE do município a partir de um CEP, direto da base oficial dos Correios.

Address from postal code

Street, neighborhood, city, state and the municipality's IBGE code from a Brazilian postal code (CEP), sourced from the official postal database.

SYNC resposta na mesma chamada answers in the same call

Endpoints

Endpoints

GET /api/v1/cep/{cep} busca o endereço de um CEP looks up a postal code's address
GET /api/v1/cep/distance/{origem}/{destino} distância entre dois CEPs distance between two CEPs
GET /api/v1/cep/busca busca reversa e autocomplete reverse search and autocomplete
GET /api/v1/cep/cidades cidades de uma UF cities in a state
GET /api/v1/cep/bairros bairros de uma cidade neighborhoods in a city
POST /api/v1/cep/lote busca vários CEPs numa chamada looks up several CEPs in one call

Parâmetros

Parameters

NomeNameOndeInDescriçãoDescription
cep path 8 dígitos numéricos, com ou sem hífen (01310100 ou 01310-100) 8 digits, with or without a hyphen (01310100 or 01310-100)
ddd query opcional: true inclui o código de área telefônico na resposta (campo ddd, omitido se indisponível) optional: true includes the phone area code in the response (ddd field, omitted if unavailable)

Exemplo

Example

curl https://api.alicercelabs.com.br/api/v1/cep/01310100?ddd=true \
          -H "Authorization: Bearer <token>"
{
          "success": true,
          "data": {
            "cep": "01310-100",
            "logradouro": "Avenida Paulista",
            "complemento": "",
            "bairro": "Bela Vista",
            "municipio": "São Paulo",
            "municipio_cod_ibge": 3550308,
            "uf": "SP",
            "ddd": "11"
          },
          "meta": { "elapsed_ms": 2, "request_id": "..." }
        }

O campo ddd só aparece com ?ddd=true na URL. Sem o parâmetro, a resposta é a mesma de sempre.

The ddd field only shows up with ?ddd=true in the URL. Without it, the response is the same as always.

Erros possíveis

Possible errors

StatusMotivoReason
400CEP inválido: precisa ser 8 dígitos numéricosinvalid CEP: must be 8 digits
401token ausente ou inválidomissing or invalid token
404CEP não encontrado na baseCEP not found in the database
429limite de taxa excedidorate limit exceeded
503dado indisponível no momentodata temporarily unavailable

Distância entre CEPs

Distance between CEPs

Distância em linha reta (fórmula de Haversine), não rodoviária. A base de CEP não traz coordenadas, então cada endereço é geocodificado sob demanda. A resposta ainda vem na mesma chamada (SYNC), só que com uma etapa extra na primeira vez que um CEP aparece.

Straight-line distance (Haversine formula), not driving distance. The postal database has no coordinates, so each address gets geocoded on demand. The response still comes back in the same call (SYNC), just with an extra step the first time a given CEP shows up.

NomeNameOndeInDescriçãoDescription
origem, destino path dois CEPs, 8 dígitos cada, com ou sem hífen two CEPs, 8 digits each, with or without a hyphen
rota query opcional: true inclui distância e duração rodoviária (via um serviço de rotas), além da linha reta que já vem sempre optional: true includes driving distance and duration (via a routing service), on top of the straight-line distance that's always included
curl https://api.alicercelabs.com.br/api/v1/cep/distance/01310100/20040020?rota=true \
          -H "Authorization: Bearer <token>"
{
          "success": true,
          "data": {
            "origem": { "cep": "01310100", "municipio": "São Paulo", "uf": "SP", "lat": -23.5613, "lon": -46.6564 },
            "destino": { "cep": "20040020", "municipio": "Rio de Janeiro", "uf": "RJ", "lat": -22.9068, "lon": -43.1729 },
            "distancia_km": 357.66,
            "distancia_rodoviaria_km": 429.5,
            "duracao_rodoviaria_min": 320.2
          },
          "meta": { "elapsed_ms": 210, "request_id": "..." }
        }

Os dois campos rodoviários só aparecem com ?rota=true. Sem ele, a resposta traz só distancia_km (linha reta), como antes.

Both road fields only show up with ?rota=true. Without it, the response only carries distancia_km (straight-line), as before.

StatusMotivoReason
400algum dos dois CEPs tem formato inválidoeither CEP has an invalid format
404algum dos dois CEPs não foi encontradoeither CEP wasn't found
503falha ao geocodificar (ou, com ?rota=true, ao calcular a rota)failed to geocode (or, with ?rota=true, to compute the route)
503geocodificador (ou roteador, com ?rota=true) não configurado nesse ambientegeocoder (or router, with ?rota=true) not configured on this environment

Coordenadas geocodificadas ficam em cache por 6 meses. O endereço de um CEP não muda, então a mesma dupla de CEPs (ou qualquer combinação reaproveitando um deles) fica praticamente instantânea depois da primeira vez. A rota (?rota=true) fica em cache por 30 dias, um pouco menos: estradas mudam mais que endereços.

Geocoded coordinates are cached for 6 months. A CEP's address doesn't change, so the same pair (or any combination reusing one of them) is near-instant after the first time. The road route (?rota=true) is cached for 30 days, a bit less: roads change more than addresses.

Busca reversa, autocomplete e catálogos

Reverse search, autocomplete and catalogs

Três endpoints pra quando você tem o endereço e quer o CEP, não o contrário, todos lendo só do banco local, sem chamada externa. /busca filtra por UF (obrigatória) mais cidade e logradouro opcionais e parciais: o mesmo filtro de logradouro serve tanto pra achar um CEP quanto pra autocompletar conforme o usuário digita. /cidades e /bairros existem pra montar um formulário em duas etapas (escolha a cidade, depois o bairro) sem o cliente ter que adivinhar a grafia exata.

Three endpoints for when you have the address and want the CEP, not the other way around, all reading only from the local database, no outbound call. /busca filters by state (required) plus optional, partial city and street name: the same street-name filter works both for finding a CEP and for autocompleting as someone types. /cidades and /bairros exist to build a two-step form (pick the city, then the neighborhood) without the client having to guess exact spelling.

GET /api/v1/cep/busca?uf=SP&cidade=São+Paulo&logradouro=Paulista&limit=20
{
          "success": true,
          "data": [
            { "cep": "01310-100", "logradouro": "Avenida Paulista", "bairro": "Bela Vista", "municipio": "São Paulo", "uf": "SP", ... },
            { "cep": "01311-000", "logradouro": "Alameda Santos", ... }
          ],
          "meta": { "elapsed_ms": 5, "request_id": "..." }
        }
NomeNameOndeInDescriçãoDescription
ufqueryobrigatório em /busca, /cidades e /bairros: 2 letrasrequired on /busca, /cidades and /bairros: 2 letters
cidadequeryobrigatório em /bairros; opcional e parcial em /buscarequired on /bairros; optional and partial on /busca
logradouroqueryopcional, parcial: só em /buscaoptional, partial: /busca only
limitqueryopcional, padrão 20, máximo 50: só em /buscaoptional, default 20, max 50: /busca only

Zero resultados é 200 com um array vazio, não 404. Uma busca sem match é uma resposta válida, não um erro.

Zero results is a 200 with an empty array, not a 404. A search with no matches is a valid outcome, not an error.

Busca em lote

Bulk lookup

POST /api/v1/cep/lote busca vários CEPs numa chamada só (até 50 por lote). A resposta é um array na mesma ordem, cada item com endereco (sucesso) ou erro (formato inválido / não encontrado), nunca os dois.

POST /api/v1/cep/lote looks up several CEPs in one call (up to 50 per batch). The response is an array in the same order, each item carrying either endereco (success) or erro (invalid format / not found), never both.

curl -X POST https://api.alicercelabs.com.br/api/v1/cep/lote \
          -H "Authorization: Bearer <token>" \
          -d '{"ceps": ["01310100", "20040020", "cep-invalido"]}'
{
          "success": true,
          "data": [
            { "cep": "01310100", "endereco": { "logradouro": "Avenida Paulista", ... } },
            { "cep": "20040020", "endereco": { "logradouro": "Avenida Rio Branco", ... } },
            { "cep": "cep-invalido", "erro": "formato inválido" }
          ],
          "meta": { "elapsed_ms": 9, "request_id": "..." }
        }
StatusMotivoReason
400corpo inválido, lista vazia, ou mais de 50 CEPsinvalid body, empty list, or more than 50 CEPs
429limite de taxa excedido: contado pelo número de CEPs pedidos, não pela chamadarate limit exceeded: counted by the number of CEPs requested, not by the call

Importante: um lote de 50 CEPs custa 50 unidades da cota de cep/lote, o mesmo que 50 chamadas separadas a GET /api/v1/cep/{cep} custariam, não 1. Do contrário, dava pra contornar o limite inteiro simplesmente empacotando tudo num lote gigante que "custa" uma chamada só.

Important: a batch of 50 CEPs costs 50 units of the cep/lote quota, the same as 50 separate calls to GET /api/v1/cep/{cep} would, not 1. Otherwise, the entire limit could be sidestepped just by packing everything into one giant batch that "costs" a single call.

Usando o SDK

Using the SDK

Todo método de leitura abaixo tem equivalente direto nos três SDKs, sem precisar montar a URL/query string à mão.

Every read method below has a direct equivalent in all three SDKs, no need to build the URL/query string by hand.

SDKs oficiais: Go · Python · JavaScript.

Official SDKs: Go · Python · JavaScript.

Buscar endereço por CEP

Look up an address by postal code

com ddd: true a resposta inclui o DDD do município.

with ddd: true the response includes the municipality's phone area code.

import (
	"context"
	"fmt"

	alicercelabs "github.com/alicercelabs/alicercesdk-go"
)

client := alicercelabs.New("alk_...")
ctx := context.Background()

endereco, err := client.CEP.Get(ctx, "01310100", nil)
if err != nil {
	panic(err)
}
fmt.Println(endereco.Logradouro, endereco.Municipio)

// com DDD:
endereco, err = client.CEP.Get(ctx, "01310100", &alicercelabs.CEPGetOptions{DDD: true})
fmt.Println(endereco.DDD)
from alicercelabs import AlicerceLabs

client = AlicerceLabs(api_key="alk_...")

endereco = client.cep.get("01310100")
print(endereco["logradouro"], endereco["municipio"])

# com DDD:
endereco = client.cep.get("01310100", ddd=True)
print(endereco["ddd"])
import { AlicerceLabs } from "alicercesdk-javascript";

const client = new AlicerceLabs("alk_...");

const endereco = await client.cep.get("01310100");
console.log(endereco.logradouro, endereco.municipio);

// com DDD:
const comDDD = await client.cep.get("01310100", { ddd: true });
console.log(comDDD.ddd);

Busca reversa (endereço → CEPs)

Reverse search (address → postal codes)

quando você tem a rua mas não o CEP.

when you have the street but not the postal code.

ceps, err := client.CEP.Search(ctx, "SP", "Sao Paulo", "Avenida Paulista")
ceps = client.cep.search("SP", "Sao Paulo", "Avenida Paulista")
const ceps = await client.cep.search("SP", "Sao Paulo", "Avenida Paulista");

Listar cidades de um estado

List a state's cities

cidades, err := client.CEP.Cities(ctx, "SP")
cidades = client.cep.cities("SP")
const cidades = await client.cep.cities("SP");

Listar bairros de uma cidade

List a city's neighborhoods

bairros, err := client.CEP.Neighborhoods(ctx, "SP", "Sao Paulo")
bairros = client.cep.neighborhoods("SP", "Sao Paulo")
const bairros = await client.cep.neighborhoods("SP", "Sao Paulo");

Distância entre dois CEPs

Distance between two postal codes

com rota: true soma distância/duração de carro, sem isso é só linha reta.

with rota: true adds driving distance/duration; without it, straight-line only.

dist, err := client.CEP.Distance(ctx, "01310100", "04538132", true)
fmt.Println(dist.DistanceKM, dist.DurationMin)
dist = client.cep.distance("01310100", "04538132", rota=True)
print(dist["distance_km"], dist["duration_min"])
const dist = await client.cep.distance("01310100", "04538132", true);
console.log(dist.distance_km, dist.duration_min);

Busca em lote

Bulk lookup

custa uma unidade de cota por CEP pedido, não uma por chamada.

costs one rate-limit unit per requested CEP, not one per call.

resultados, err := client.CEP.Bulk(ctx, []string{"01310100", "04538132", "00000000"})
for _, r := range resultados {
	if r.Erro != "" {
		fmt.Println(r.CEP, "falhou:", r.Erro)
		continue
	}
	fmt.Println(r.CEP, r.Endereco.Logradouro)
}
resultados = client.cep.bulk(["01310100", "04538132", "00000000"])
for r in resultados:
    if r.get("erro"):
        print(r["cep"], "falhou:", r["erro"])
    else:
        print(r["cep"], r["endereco"]["logradouro"])
const resultados = await client.cep.bulk(["01310100", "04538132", "00000000"]);
for (const r of resultados) {
  if (r.erro) { console.log(r.cep, "falhou:", r.erro); continue; }
  console.log(r.cep, r.endereco.logradouro);
}

Limites

Limits

100/dia · 4/hora sem token, por IP chamador; com uma API key (gerada no painel), 1.000/dia · 41/hora. Contado separado por operação: lookup, distance, busca, cidades, bairros e lote têm cotas independentes. A exceção é lote: em vez de 1 unidade por chamada, cada CEP dentro do lote consome 1 unidade da cota (ver "Busca em lote" acima). Lookups de endereço, busca, cidades e bairros vêm de um banco local, sem chamada externa. Distância (com ?rota=true) é a exceção que depende de serviços externos configuráveis (padrão grátis, sem chave), com cache de 6 meses/30 dias.

100/day · 4/hour without a token, per calling IP; with an API key (generated in the panel), 1,000/day · 41/hour. Counted separately per operation: lookup, distance, busca, cidades, bairros and lote have independent quotas. The exception is lote: instead of 1 unit per call, each CEP inside the batch consumes 1 unit of the quota (see "Bulk lookup" above). Address lookups, search, cities and neighborhoods come from a local database, no outbound call. Distance (with ?rota=true) is the exception depending on configurable external services (default is free, no key), cached for 6 months/30 days.