Geocoding — entry 075 of 80

ViaCep

Verified Jul 2026

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.

brazilpostal-codecepaddress-lookupfree
AuthenticationNone requiredCall it straight away — no key, no signup.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingFreeNo paid tier — free for the documented use case.
FormatsJSON, XMLResponses can be requested as JSON or XML.

GreatAPIs Score

Score80out of 100
Authentication25/25No authentication required
Pricing20/20Free to use
Docs0/20No docs or spec available
Formats15/15Supports 2 response formats
Freshness20/20Verified within 6 months

Embed this badge

Scored 80 on greatapis.com
<a href="https://greatapis.com/api/viacep/"><img src="https://greatapis.com/badge/viacep.svg" alt="Scored 80 on greatapis.com"></a>

Auth quickstart

  1. 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.
Stored keyNo key stored

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/

200 application/json; charset=utf-8

{"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

Base URLhttps://viacep.com.br/ws

Gotchas & 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): `erro` is a JSON *string* `"true"`, not a boolean, so a naive `if (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 a `text/html; charset=utf-8` body — 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. Only `json` and `xml` are documented ("deve ser `json` ou `xml`"); 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 `json` route, not its own path segment: `GET /ws/{cep}/json/?callback=meuCallback` returned the object wrapped as `meuCallback({...});` 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 **no** `Access-Control-*` headers at all — both confirmed live. So a browser `fetch()` 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."