BR CEP Format Validator
Validate Brazilian CEP format (8 digits, with or without hyphen).
The CEP: Brazil's 8-digit postal code and its geographic structure
The CEP (Codigo de Enderecamento Postal) is the Brazilian postal code defined by Correios. Every Brazilian address has one. The format is 8 numeric digits, conventionally displayed with a hyphen between the 5th and 6th positions: XXXXX-XXX. Correios estimate there are roughly one million valid CEPs in active circulation, with ongoing additions as new neighborhoods, streets and large buildings receive their own code.
Unlike the US ZIP+4 (which encodes geographic delivery routes) or the British postcode (which mixes letters and numbers), the CEP is purely numeric and follows a strict hierarchical structure. The first digit identifies a Brazilian macro-region, and as you read left to right the number narrows from region to sub-region to sector to sub-sector to delivery unit. Knowing the first digit alone tells you the rough geography of any address.
First-digit map: the 10 Correios regions
- 0 โ City of Sao Paulo (capital)
- 1 โ Sao Paulo state interior
- 2 โ Rio de Janeiro and Espirito Santo
- 3 โ Minas Gerais
- 4 โ Bahia and Sergipe
- 5 โ Pernambuco, Alagoas, Paraiba, Rio Grande do Norte
- 6 โ Ceara, Piaui, Maranhao, Para, Amazonas, Acre, Amapa, Roraima, Rondonia (North and parts of Northeast)
- 7 โ Distrito Federal, Goias, Tocantins, Mato Grosso, Mato Grosso do Sul
- 8 โ Parana and Santa Catarina
- 9 โ Rio Grande do Sul
A common assertion that "0 = Sao Paulo, 9 = Rio Grande do Sul" is true at the macro level. A purely format-based validator (like this one) can verify the 8-digit shape but cannot guarantee the CEP actually exists โ for that, you need a semantic lookup via the Correios DNE or one of the free public APIs described below.
Regex format validation vs semantic lookup
A pure-format validator inspects the shape, not the existence. The canonical regex is:
// Accepts "01310-100" and "01310100"
const re = /^\d{5}-?\d{3}$/
// Normalize before storing
const normalized = cep.replace(/\D/g, '') // strip non-digits
const masked = normalized.replace(/(\d{5})(\d{3})/, '$1-$2')
The hyphen is optional โ most Brazilian back-ends accept both forms and store the unmasked 8 digits. Front-end masks render the hyphen for readability. This validator accepts the input in either form and reports whether the structure is valid; it does not (and cannot) confirm the CEP corresponds to a real address.
For semantic validation โ does this CEP actually exist? โ you have to query one of the public services:
- ViaCEP (
viacep.com.br/ws/{cep}/json/) โ the most popular free endpoint. No authentication. Practical rate limit around 10,000 requests per day per IP. Returns logradouro, bairro, localidade and UF. - BrasilAPI (
brasilapi.com.br/api/cep/v2/{cep}) โ community-maintained alternative, version 2 of the endpoint adds latitude/longitude when available. - AwesomeAPI (
cep.awesomeapi.com.br/json/{cep}) โ additional fallback if the first two fail. - Correios DNE โ the official Diretorio Nacional de Enderecos. Paid product; required for high-volume integrations and the only source guaranteed to be up to date.
Special CEPs: -000, -899, -900 and how cities allocate codes
CEP suffixes encode the granularity of the address. Small towns typically have a single CEP ending in -000 that covers the entire urban area. Large cities allocate one CEP per logradouro, sometimes one CEP per block face on long avenues. Brazil thus has CEPs at three very different scales coexisting in the same database.
Suffixes -899 and -900 are reserved by Correios for special clients (Grandes Usuarios) โ government offices, large corporations, universities. A CEP like 70150-900 (Palacio do Planalto in Brasilia) routes mail to a specific institution, not a street. Treating these as "address CEPs" in a normal e-commerce flow will break shipping calculators because they accept correspondence but not necessarily home deliveries.
CEPs ending in -970 historically belonged to Correios agencies (caixas postais and customer-facing units). Many of these are still active and behave more like P.O. Boxes than residential addresses.
Practical use cases: checkout auto-fill and shipping
The most common front-end pattern in Brazil is the CEP-first checkout: the user types the CEP, the page asynchronously queries ViaCEP or BrasilAPI and pre-fills logradouro, bairro, cidade and UF. Magazine Luiza, Mercado Livre, Americanas and most Vtex stores follow this pattern. The auto-fill flow combines:
- Format validation (this tool's job) before firing the HTTP request.
- Semantic lookup (ViaCEP or BrasilAPI) to fetch the address.
- Shipping calculation (Correios SIGEP, Frete Rapido, Melhor Envio APIs) using the CEP and weight to estimate cost and ETA.
- Risk scoring against the BIN of the credit card to detect fraud where the CEP and billing UF disagree.
An anti-pattern is to rely on regex format validation only and skip the semantic check. Users routinely type the CEP of a different street or a CEP that does not exist. Without the ViaCEP confirmation, the e-commerce engine may quote shipping to nowhere and only discover the error when the carrier rejects the AWB.
FAQ
Is the hyphen mandatory?
No. Both 01310-100 and 01310100 are valid. The hyphen is presentation only. Most back-ends store the 8 digits without the hyphen.
Is the ViaCEP lookup free?
Yes, free and without authentication. The practical rate limit is around 10,000 requests per day per IP. For higher volumes, use BrasilAPI as a fallback or subscribe to the Correios DNE.
Does every Brazilian address have its own CEP?
No. Small towns share a single CEP for the whole town (suffix -000). Large cities go down to street-level or even block-level granularity. Special suffixes (-899, -900, -970) flag institutional CEPs.
Can a CEP belong to two different cities?
No. Every CEP is uniquely tied to one municipality and UF. If a city is split or merged, Correios reissues the codes.
Why does the test value 01310-100 resolve to Avenida Paulista?
Because 01310-100 is the canonical CEP of MASP and the central stretch of Avenida Paulista in Sao Paulo. The leading 0 marks Sao Paulo capital; the next four digits narrow down to the Bela Vista district.
Related Tools
CPF Validator
Validate Brazilian CPF numbers instantly using the official algorithm. Useful for testing document validation in applications. No data sent to servers.
Batch CPF Validator
Validate a list of CPFs (one per line) and see which are valid and which are not. No data sent to servers.
Batch CNPJ Validator
Validate a list of CNPJs (one per line) with a summary of valid, invalid and total. No data sent to servers.