Geocoding — entry 075 of 80
ViaCep
ViaCEP is a free, high-availability web service for looking up Brazilian postal codes (CEP): given an 8-digit CEP it returns street, neighborhood, city, state, and IBGE/DDD codes, with a reverse address-to-CEP search available too. It's run by WBX and widely embedded across Brazilian dev tooling — its own docs warn that heavy bulk-validation traffic against it can trigger an automatic, indefinite IP block.
ViaCEP is a free, high-performance lookup service for Brazilian postal codes (CEP) — its own docs call it a "webservice gratuito de alto desempenho": given an 8-digit CEP it returns street, neighborhood, city, state, and IBGE/DDD codes, with the response format chosen by URL path segment (json, xml, and the undocumented-but-working piped) rather than an Accept header or query parameter.
GreatAPIs Score
Auth quickstart
- No API key required — requests are public and keyless. ViaCEP's own docs warn that heavy bulk-validation traffic against it can trigger an automatic, indefinite IP block; no fixed requests-per-second number is published.
Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.
Look up a CEP as JSON
GEThttps://viacep.com.br/ws/01310100/json/
{"cep":"01310-100","logradouro":"Avenida Paulista","complemento":"de 612 a 1510 - lado par","unidade":"","bairro":"Bela Vista","localidade":"São Paulo","uf":"SP","estado":"São Paulo","regiao":"Sudeste","ibge":"3550308","gia":"1004","ddd":"11","siafi":"7107"}Developer reference
https://viacep.com.br/wsGotchas & limits
- A well-formed but unassigned CEP returns HTTP 200, not an error status — a live probe of
/ws/99999999/json/returned exactly{"erro":"true"}(confirmed byte-exact in this run):errois a JSON string"true", not a boolean, so a naiveif (response.erro)check works by accident in JavaScript but a typed client expecting a boolean will misparse it. - A malformed CEP (wrong length) fails completely differently: a live probe of
/ws/123/json/returned HTTP 400 with atext/html; charset=utf-8body — a plain HTML error page, not JSON — so callers need to handle three distinct outcomes (200 real address, 200{"erro":"true"}, 400 HTML) rather than a single error path. - The response format is chosen by swapping the last path segment —
/ws/{cep}/json/,/xml/, or/piped/— confirmed live: the same CEP returned a pipe-delimited single line under/piped/(200 text/plain) and a<xmlcep>-rooted document under/xml/(200 application/xhtml+xml), with identical field values to the JSON form. Onlyjsonandxmlare documented ("deve serjsonouxml"); an unrecognised segment 400s with the same HTML error page as a malformed CEP, so don't guess at format names. - JSONP is a query parameter on the
jsonroute, not its own path segment:GET /ws/{cep}/json/?callback=meuCallbackreturned the object wrapped asmeuCallback({...});on a live probe, matching the docs' own JSONP example. - Reverse lookup goes the other direction, by address rather than by coordinates:
GET /ws/{uf}/{cidade}/{logradouro}/json/searches by state, city, and street name and returns an array of matching addresses, each with its own CEP — there's no lat/lon-based reverse geocoding endpoint. - CORS is open on the 200 responses (
Access-Control-Allow-Origin: *, including on the{"erro":"true"}body) but the 400 carries noAccess-Control-*headers at all — both confirmed live. So a browserfetch()of a malformed CEP fails at the CORS layer with an opaque network error rather than a readable 400, which is exactly why ViaCEP's docs tell you to check the 8-digit format client-side before calling: "Antes de acessar o webservice, valide o formato do CEP e certifique-se que o mesmo possua {8} dígitos."