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
/api/v1/cep/{cep}
busca o endereço de um CEP
looks up a postal code's address
/api/v1/cep/distance/{origem}/{destino}
distância entre dois CEPs
distance between two CEPs
/api/v1/cep/busca
busca reversa e autocomplete
reverse search and autocomplete
/api/v1/cep/cidades
cidades de uma UF
cities in a state
/api/v1/cep/bairros
bairros de uma cidade
neighborhoods in a city
/api/v1/cep/lote
busca vários CEPs numa chamada
looks up several CEPs in one call
Parâmetros
Parameters
| Nome | Name | Onde | In | Descrição | Description |
|---|---|---|---|---|---|
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
| Status | Motivo | Reason |
|---|---|---|
| 400 | CEP inválido: precisa ser 8 dígitos numéricos | invalid CEP: must be 8 digits |
| 401 | token ausente ou inválido | missing or invalid token |
| 404 | CEP não encontrado na base | CEP not found in the database |
| 429 | limite de taxa excedido | rate limit exceeded |
| 503 | dado indisponível no momento | data 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.
| Nome | Name | Onde | In | Descrição | Description |
|---|---|---|---|---|---|
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.
| Status | Motivo | Reason |
|---|---|---|
| 400 | algum dos dois CEPs tem formato inválido | either CEP has an invalid format |
| 404 | algum dos dois CEPs não foi encontrado | either CEP wasn't found |
| 503 | falha ao geocodificar (ou, com ?rota=true, ao calcular a rota) | failed to geocode (or, with ?rota=true, to compute the route) |
| 503 | geocodificador (ou roteador, com ?rota=true) não configurado nesse ambiente | geocoder (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.
/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": "..." }
}
| Nome | Name | Onde | In | Descrição | Description |
|---|---|---|---|---|---|
uf | query | obrigatório em /busca, /cidades e /bairros: 2 letras | required on /busca, /cidades and /bairros: 2 letters | ||
cidade | query | obrigatório em /bairros; opcional e parcial em /busca | required on /bairros; optional and partial on /busca | ||
logradouro | query | opcional, parcial: só em /busca | optional, partial: /busca only | ||
limit | query | opcional, padrão 20, máximo 50: só em /busca | optional, 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": "..." }
}
| Status | Motivo | Reason |
|---|---|---|
| 400 | corpo inválido, lista vazia, ou mais de 50 CEPs | invalid body, empty list, or more than 50 CEPs |
| 429 | limite de taxa excedido: contado pelo número de CEPs pedidos, não pela chamada | rate 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.