Mexico ZIP code API
Mexico does not have ZIP codes. It has códigos postales — five digits, issued by SEPOMEX, and one of them covers a delivery area rather than a neighbourhood. That difference is small enough to miss and large enough to produce an address nobody can deliver to, so it is worth two minutes before you wire anything up.
This is a REST API over the whole national catalog: give it a código postal and it answers with the estado, the municipio and every colonia inside that code.
What each field is called here
Four of these translate cleanly. The fifth is the one that costs a schema migration if you find it late.
| You call it | Mexico calls it | In the API | Worth knowing |
|---|---|---|---|
| ZIP code | Código postal (CP) | code
|
Five digits, leading zero included. There is no ZIP+4 and no extension of any kind. |
| State | Estado | state.name
|
32 of them, each with a two-digit INEGI code returned alongside the name. |
| County | Municipio | municipality.name
|
The level below the estado. Ciudad de México calls its own alcaldías; the API returns them in this same field. |
| City | Ciudad | city.name
|
Optional, frequently null, and not a level of government. Display it; never join on it. |
| Neighborhood | Colonia | settlements[].name
|
Required on every Mexican address, and the field with no equivalent in a US or European form. One postal code usually holds several. |
The colonia is the row to read twice. It is not a free-text neighbourhood label — it is a value from a list, it belongs to a postal code, and a Mexican address without one is incomplete.
One request, start to finish
06600 is a real code in the middle of Mexico City. One GET, a bearer token, no SDK.
Request
curl -s https://api.postalkit.mx/v1/postal-codes/06600 -H "Authorization: Bearer YOUR_API_KEY"
Response
{
"data": {
"id": 384,
"code": "06600",
"state": { "id": 1, "name": "Ciudad de México", "code": "09" },
"municipality": { "id": 6, "name": "Cuauhtémoc", "code": "015" },
"city": { "id": 1, "name": "Ciudad de México" },
"settlements": [
{
"id": 532,
"name": "Juárez",
"zone": "Urbano",
"settlement_type": { "id": 1, "name": "Colonia" }
}
]
}
}
settlements is an array because it has to be. This code happens to hold one colonia; most hold several.
Three things an imported address form gets wrong
-
Treating the postal code as a neighbourhood.
A ZIP+4 narrows to a block. A código postal does not narrow to anything below itself — most of them cover several colonias, and the customer has to pick one. That is the single most expensive assumption to carry into a Mexican checkout. The counted version of that, with the catalog behind it.
-
Storing the code as a number.
Mexican postal codes start at 01000. An integer column drops the leading zero and turns a valid code into a four-digit one, and it fails on Mexico City first — which is exactly where the test data usually is not.
-
Matching estados by name.
The catalog writes some estados out in full — the official name is not always the one on your dropdown. Match on the two-digit INEGI code that comes back beside the name, and the problem disappears.
The endpoints for this job
Four calls cover almost every address form. Parameters, fields and errors are in the reference.
-
GET /v1/postal-codes/{code}
One postal code to its estado, municipio, ciudad and every colonia inside it.
-
GET /v1/postal-codes?q={prefix}
Every code starting with those digits — a type-ahead over the national catalog.
-
GET /v1/postal-codes/{code}/settlements
Just the colonias, for populating the field a form has no other way to fill.
-
GET /v1/settlements?q={name}
The other direction: a colonia name to the postal codes it appears in.
Postal code endpoint reference — every parameter and every error, plus an honest note on the endpoints that have no data behind them yet.
Reading on
- How a Mexican address is structured — the fields your form needs, in the order they are written, and what breaks without each one.
- Glossary of Mexican address terms — colonia, asentamiento, municipio, alcaldía, and which of them is safe to match records on.
- Integration tutorials — working code for Laravel, Node, Python and a React postal-code autocomplete.
- Where the data comes from — the SEPOMEX catalog, what the official file gives you, and what it leaves you to solve.