MENU navbar-image

Introduction

A fast, reliable REST API for looking up Mexican postal codes (códigos postales) and address data.

## Quickstart

**1. Get an API key** — run the artisan command on the server:
```bash
php artisan api:generate-key --name="My App" --email="[email protected]"
```

**2. Make your first request** — pass your key as a Bearer token:
```bash
curl https://api.postalkit.mx/v1/postal-codes/06600 \
  -H "Authorization: Bearer {YOUR_API_KEY}"
```

**3. Explore the endpoints** — use the interactive docs below.

<aside class="notice">All v1 endpoints require a valid API key. The <code>/health</code> endpoint is public.</aside>

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Generate an API key by running: php artisan api:generate-key --name="My App". Pass the key as a Bearer token in the Authorization header.

General

GET health

requires authentication

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/health" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/health"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/health';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/health'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-content-type-options: nosniff
x-frame-options: DENY
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=()
 

{
    "status": "ok",
    "service": "CodigoPostal MX API",
    "version": "1.0.0",
    "timestamp": "2026-06-07T03:34:19+00:00"
}
 

Request      

GET health

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Postal Codes

Look up Mexican postal codes and their settlements, municipality, state, and city.

requires authentication

Search for postal codes using geographic filters. Supports both fuzzy (LIKE) and exact matching via the exact parameter. Returns paginated results ordered by code.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/postal-codes/search?state=Jalisco&municipality=Guadalajara&colonia=Centro&exact=1&page=1" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"state\": \"bngzmiyvdljnikhw\",
    \"municipality\": \"aykcmyuwpwlvqwrs\",
    \"colonia\": \"itcpscqldzsnrwtu\",
    \"exact\": true
}"
const url = new URL(
    "https://api.postalkit.mx/v1/postal-codes/search"
);

const params = {
    "state": "Jalisco",
    "municipality": "Guadalajara",
    "colonia": "Centro",
    "exact": "1",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "state": "bngzmiyvdljnikhw",
    "municipality": "aykcmyuwpwlvqwrs",
    "colonia": "itcpscqldzsnrwtu",
    "exact": true
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/postal-codes/search';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'state' => 'Jalisco',
            'municipality' => 'Guadalajara',
            'colonia' => 'Centro',
            'exact' => '1',
            'page' => '1',
        ],
        'json' => [
            'state' => 'bngzmiyvdljnikhw',
            'municipality' => 'aykcmyuwpwlvqwrs',
            'colonia' => 'itcpscqldzsnrwtu',
            'exact' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/postal-codes/search'
payload = {
    "state": "bngzmiyvdljnikhw",
    "municipality": "aykcmyuwpwlvqwrs",
    "colonia": "itcpscqldzsnrwtu",
    "exact": true
}
params = {
  'state': 'Jalisco',
  'municipality': 'Guadalajara',
  'colonia': 'Centro',
  'exact': '1',
  'page': '1',
}
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload, params=params)
response.json()

Example response (200, Results):


{
    "data": [
        {
            "id": 3,
            "code": "44100",
            "state": {
                "id": 1,
                "name": "Jalisco",
                "code": "14"
            },
            "municipality": {
                "id": 2,
                "name": "Guadalajara",
                "code": "039"
            },
            "city": {
                "id": 1,
                "name": "Guadalajara"
            },
            "settlements": [
                {
                    "id": 5,
                    "name": "Centro",
                    "type": "Colonia",
                    "postal_code": "44100"
                }
            ]
        }
    ],
    "links": {
        "first": "...",
        "last": "...",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "total": 1,
        "per_page": 20
    }
}
 

Example response (422, Missing state):


{
    "message": "The given data was invalid.",
    "errors": {
        "state": [
            "The \"state\" query parameter is required."
        ]
    }
}
 

Exact postal code lookup

requires authentication

Retrieve the full record for a specific 5-digit postal code, including state, municipality, city, and all settlements (colonias) that share that code. Responses include Cache-Control: public, max-age=3600 for client-side caching.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/postal-codes/06600" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/postal-codes/06600"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/postal-codes/06600';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/postal-codes/06600'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Found):


{
    "data": {
        "id": 3,
        "code": "06600",
        "state": {
            "id": 1,
            "name": "Ciudad de México",
            "code": "09"
        },
        "municipality": {
            "id": 2,
            "name": "Cuauhtémoc",
            "code": "015"
        },
        "city": {
            "id": 1,
            "name": "Ciudad de México"
        },
        "settlements": [
            {
                "id": 5,
                "name": "Roma Sur",
                "type": "Colonia",
                "postal_code": "06600"
            }
        ]
    }
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required. Pass it as: Authorization: Bearer {token}"
}
 

Example response (404, Not found):


{
    "message": "Postal code '99999' not found."
}
 

Example response (422, Invalid format):


{
    "message": "Postal code must be exactly 5 digits."
}
 

Example response (429, Rate limited):


{
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. You are allowed 1 000 requests per hour.",
    "retry_after": 1800
}
 

Request      

GET v1/postal-codes/{code}

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

The 5-digit postal code. Example: 06600

Settlements for a postal code

requires authentication

Retrieve all settlements (colonias) that belong to a specific 5-digit postal code. Returns a slim payload without full postal code details. Responses include Cache-Control: public, max-age=3600 for client-side caching.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/postal-codes/06600/settlements" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/postal-codes/06600/settlements"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/postal-codes/06600/settlements';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/postal-codes/06600/settlements'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Found):


{
    "data": [
        {
            "id": 5,
            "name": "Roma Sur",
            "zone": "Urbano",
            "settlement_type": {
                "id": 1,
                "name": "Colonia"
            }
        }
    ]
}
 

Example response (404, Not found):


{
    "message": "Postal code '99999' not found."
}
 

Example response (422, Invalid format):


{
    "message": "Postal code must be exactly 5 digits."
}
 

Request      

GET v1/postal-codes/{code}/settlements

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

The 5-digit postal code. Example: 06600

Geocode by postal code

requires authentication

Retrieve the full record for a specific 5-digit postal code with geographic coordinates. Optional street and number query parameters are included in the response for reference but do not affect the returned coordinates. Responses include Cache-Control: public, max-age=3600 for client-side caching.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/postal-codes/06600/geocode?street=Reforma&number=100" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/postal-codes/06600/geocode"
);

const params = {
    "street": "Reforma",
    "number": "100",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/postal-codes/06600/geocode';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'street' => 'Reforma',
            'number' => '100',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/postal-codes/06600/geocode'
params = {
  'street': 'Reforma',
  'number': '100',
}
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200, Found):


{
    "data": {
        "id": 3,
        "code": "06600",
        "state": {
            "id": 1,
            "name": "Ciudad de Mexico",
            "code": "09"
        },
        "municipality": {
            "id": 2,
            "name": "Cuauhtemoc",
            "code": "015"
        },
        "city": null,
        "settlements": [],
        "latitude": "19.4233000",
        "longitude": "-99.1637000",
        "geocoded_street": null,
        "geocoded_number": null
    }
}
 

Example response (404, Not found):


{
    "message": "Postal code '99999' not found."
}
 

Example response (422, Invalid format):


{
    "message": "Postal code must be exactly 5 digits."
}
 

Request      

GET v1/postal-codes/{code}/geocode

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

The 5-digit postal code. Example: 06600

Query Parameters

street   string  optional    

Optional street name for reference. Example: Reforma

number   string  optional    

Optional street number for reference. Example: 100

Search postal codes by prefix

requires authentication

Search for postal codes by numeric prefix (useful for autocomplete). Returns paginated results ordered by code. Query must be at least 2 characters.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/postal-codes?q=066&page=1" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/postal-codes"
);

const params = {
    "q": "066",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/postal-codes';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'q' => '066',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/postal-codes'
params = {
  'q': '066',
  'page': '1',
}
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200, Results):


{
    "data": [
        {
            "id": 3,
            "code": "06600",
            "state": {
                "id": 1,
                "name": "Ciudad de México",
                "code": "09"
            },
            "municipality": {
                "id": 2,
                "name": "Cuauhtémoc",
                "code": "015"
            },
            "city": {
                "id": 1,
                "name": "Ciudad de México"
            }
        }
    ],
    "links": {
        "first": "...",
        "last": "...",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "total": 1,
        "per_page": 20
    }
}
 

Example response (422, Query too short):


{
    "message": "Query parameter \"q\" must be at least 2 characters."
}
 

Request      

GET v1/postal-codes

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

q   string     

Numeric prefix to search. Must be at least 2 characters. Example: 066

page   integer  optional    

Page number (20 results per page). Example: 1

Settlements

Search for Mexican settlements (colonias, fraccionamientos, ejidos, etc.) by name.

Search settlements by name

requires authentication

Full-text partial search across all settlement names. The search is case-insensitive and matches anywhere in the name. Returns paginated results ordered alphabetically. Query must be at least 2 characters.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/settlements?q=Roma&page=1" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/settlements"
);

const params = {
    "q": "Roma",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/settlements';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'q' => 'Roma',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/settlements'
params = {
  'q': 'Roma',
  'page': '1',
}
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200, Results):


{
    "data": [
        {
            "id": 5,
            "name": "Roma Sur",
            "type": "Colonia",
            "postal_code": "06600",
            "municipality": "Cuauhtémoc",
            "state": "Ciudad de México"
        }
    ],
    "links": {
        "first": "...",
        "last": "...",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "total": 2,
        "per_page": 20
    }
}
 

Example response (422, Query too short):


{
    "message": "Query parameter \"q\" must be at least 2 characters."
}
 

Request      

GET v1/settlements

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

q   string     

Partial name of the settlement to search for. Example: Roma

page   integer  optional    

Page number (20 results per page). Example: 1

States & Municipalities

Browse the 32 Mexican states and their municipalities.

List all states

requires authentication

Returns the complete list of the 32 Mexican states (estados) ordered alphabetically. Each state includes its official state code.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/states" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/states"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/states';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/states'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 5,
            "name": "Aguascalientes",
            "code": "01"
        },
        {
            "id": 1,
            "name": "Ciudad de México",
            "code": "09"
        }
    ]
}
 

Request      

GET v1/states

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

List municipalities for a state by INEGI code

requires authentication

Returns all municipalities (municipios) that belong to the state identified by its 2-digit INEGI code, ordered alphabetically.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/states/by-code/09/municipalities" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/states/by-code/09/municipalities"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/states/by-code/09/municipalities';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/states/by-code/09/municipalities'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "name": "Álvaro Obregón",
            "code": "010"
        },
        {
            "id": 2,
            "name": "Cuauhtémoc",
            "code": "015"
        }
    ]
}
 

Example response (404, State not found):


{
    "message": "State with code '99' not found."
}
 

Request      

GET v1/states/by-code/{code}/municipalities

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

The 2-digit INEGI state code (e.g. "09", "14"). Example: 09

List municipalities for a state

requires authentication

Returns all municipalities (municipios) that belong to the given state, ordered alphabetically.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/states/1/municipalities" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/states/1/municipalities"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/states/1/municipalities';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/states/1/municipalities'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "name": "Álvaro Obregón",
            "code": "010"
        },
        {
            "id": 2,
            "name": "Cuauhtémoc",
            "code": "015"
        }
    ]
}
 

Example response (404, State not found):


{
    "message": "State with id 999 not found."
}
 

Request      

GET v1/states/{id}/municipalities

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The numeric ID of the state (use GET /v1/states to find IDs). Example: 1

List cities for a state

requires authentication

Returns all cities (ciudades) that belong to the given state, ordered alphabetically.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/states/1/cities" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/states/1/cities"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/states/1/cities';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/states/1/cities'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "name": "Aguascalientes"
        },
        {
            "id": 2,
            "name": "Calvillo"
        }
    ]
}
 

Example response (404, State not found):


{
    "message": "State with id 999 not found."
}
 

Request      

GET v1/states/{id}/cities

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The numeric ID of the state (use GET /v1/states to find IDs). Example: 1

List postal codes for a state

requires authentication

Returns all postal codes that belong to the given state, ordered by code and paginated.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/states/1/postal-codes" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/states/1/postal-codes"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/states/1/postal-codes';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/states/1/postal-codes'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "code": "01000",
            "state": {
                "id": 1,
                "name": "Aguascalientes"
            },
            "municipality": {
                "id": 1,
                "name": "Aguascalientes"
            },
            "city": {
                "id": 1,
                "name": "Aguascalientes"
            }
        }
    ]
}
 

Example response (404, State not found):


{
    "message": "State with id 999 not found."
}
 

Request      

GET v1/states/{id}/postal-codes

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The numeric ID of the state (use GET /v1/states to find IDs). Example: 1

List settlements for a municipality within a state

requires authentication

Returns all settlements that belong to the given municipality within the given state, ordered alphabetically by name and paginated with 20 results per page.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/states/1/municipalities/1/settlements" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/states/1/municipalities/1/settlements"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/states/1/municipalities/1/settlements';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/states/1/municipalities/1/settlements'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "name": "Centro",
            "zone": "Urbano",
            "settlement_type": {
                "id": 1,
                "name": "Colonia"
            },
            "postal_code": {
                "id": 1,
                "code": "06600"
            }
        }
    ],
    "links": {},
    "meta": {
        "current_page": 1,
        "per_page": 20,
        "total": 1
    }
}
 

Example response (404, State not found):


{
    "message": "State with id 999 not found."
}
 

Example response (404, Municipality not found):


{
    "message": "Municipality with id 999 not found."
}
 

Request      

GET v1/states/{id}/municipalities/{mid}/settlements

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The numeric ID of the state. Example: 1

mid   integer     

The numeric ID of the municipality. Example: 1

Municipalities

Browse municipality data including their postal codes.

List postal codes for a municipality

requires authentication

Returns all postal codes that belong to the given municipality, ordered by code and paginated with 20 results per page.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/municipalities/1/postal-codes" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/municipalities/1/postal-codes"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/municipalities/1/postal-codes';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/municipalities/1/postal-codes'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "code": "06600",
            "state": {
                "id": 1,
                "name": "Ciudad de México",
                "code": "09"
            },
            "municipality": {
                "id": 2,
                "name": "Cuauhtémoc",
                "code": "015"
            },
            "city": {
                "id": 1,
                "name": "Ciudad de México"
            }
        }
    ],
    "links": {},
    "meta": {
        "current_page": 1,
        "per_page": 20,
        "total": 1
    }
}
 

Example response (404, Municipality not found):


{
    "message": "Municipality with id 999 not found."
}
 

Request      

GET v1/municipalities/{id}/postal-codes

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The numeric ID of the municipality. Example: 1

List settlements for a municipality

requires authentication

Returns all settlements that belong to the given municipality (via their postal codes), ordered alphabetically by name and paginated with 20 results per page.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/municipalities/1/settlements" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/municipalities/1/settlements"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/municipalities/1/settlements';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/municipalities/1/settlements'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "name": "Centro",
            "zone": "Urbano",
            "settlement_type": {
                "id": 1,
                "name": "Colonia"
            },
            "postal_code": {
                "id": 1,
                "code": "06600"
            }
        }
    ],
    "links": {},
    "meta": {
        "current_page": 1,
        "per_page": 20,
        "total": 1
    }
}
 

Example response (404, Municipality not found):


{
    "message": "Municipality with id 999 not found."
}
 

Request      

GET v1/municipalities/{id}/settlements

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The numeric ID of the municipality. Example: 1

Localities

Search for localities (populated places) from the official INEGI catalog.

Search localities

requires authentication

Search for localities within a state and municipality. Supports two filter modes: by name (state + municipality) with fuzzy matching, or by INEGI code (state_code + municipality_code) with exact matching. Returns paginated results ordered by name.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/localities?state=Jalisco&municipality=Guadalajara&state_code=14&municipality_code=039&page=1" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"state\": \"bngzmiyvdljnikhw\",
    \"municipality\": \"aykcmyuwpwlvqwrs\",
    \"state_code\": \"itcpscqldzsnrwtu\",
    \"municipality_code\": \"jwvlxjklqppwqbew\"
}"
const url = new URL(
    "https://api.postalkit.mx/v1/localities"
);

const params = {
    "state": "Jalisco",
    "municipality": "Guadalajara",
    "state_code": "14",
    "municipality_code": "039",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "state": "bngzmiyvdljnikhw",
    "municipality": "aykcmyuwpwlvqwrs",
    "state_code": "itcpscqldzsnrwtu",
    "municipality_code": "jwvlxjklqppwqbew"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/localities';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'state' => 'Jalisco',
            'municipality' => 'Guadalajara',
            'state_code' => '14',
            'municipality_code' => '039',
            'page' => '1',
        ],
        'json' => [
            'state' => 'bngzmiyvdljnikhw',
            'municipality' => 'aykcmyuwpwlvqwrs',
            'state_code' => 'itcpscqldzsnrwtu',
            'municipality_code' => 'jwvlxjklqppwqbew',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/localities'
payload = {
    "state": "bngzmiyvdljnikhw",
    "municipality": "aykcmyuwpwlvqwrs",
    "state_code": "itcpscqldzsnrwtu",
    "municipality_code": "jwvlxjklqppwqbew"
}
params = {
  'state': 'Jalisco',
  'municipality': 'Guadalajara',
  'state_code': '14',
  'municipality_code': '039',
  'page': '1',
}
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload, params=params)
response.json()

Example response (200, Results):


{
    "data": [
        {
            "id": 1,
            "locality_code": "0001",
            "name": "Guadalajara",
            "ambito": "Urbano",
            "latitude": "20.6737800",
            "longitude": "-103.3442300",
            "altitude": "1566",
            "state": {
                "id": 1,
                "name": "Jalisco",
                "code": "14"
            },
            "municipality": {
                "id": 2,
                "name": "Guadalajara",
                "code": "039"
            }
        }
    ],
    "links": {
        "first": "...",
        "last": "...",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "total": 1,
        "per_page": 20
    }
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required. Pass it as: Authorization: Bearer {token}"
}
 

Example response (422, Missing filter pair):


{
    "message": "The given data was invalid.",
    "errors": {
        "filter": [
            "You must provide either (state and municipality) or (state_code and municipality_code)."
        ]
    }
}
 

Example response (429, Rate limited):


{
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. You are allowed 1 000 requests per hour.",
    "retry_after": 1800
}
 

Request      

GET v1/localities

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

state   string  optional    

State name (fuzzy match). Required if not using codes. Example: Jalisco

municipality   string  optional    

Municipality name (fuzzy match). Required if not using codes. Example: Guadalajara

state_code   string  optional    

INEGI state code. Required if not using names. Example: 14

municipality_code   string  optional    

INEGI municipality code. Required if not using names. Example: 039

page   integer  optional    

Page number (20 results per page). Example: 1

Body Parameters

state   string  optional    

Must be at least 1 character. Example: bngzmiyvdljnikhw

municipality   string  optional    

Must be at least 1 character. Example: aykcmyuwpwlvqwrs

state_code   string  optional    

Must be at least 1 character. Example: itcpscqldzsnrwtu

municipality_code   string  optional    

Must be at least 1 character. Example: jwvlxjklqppwqbew

Get a locality

requires authentication

Retrieve a single locality by its ID, including state and municipality details.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/localities/1" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/localities/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/localities/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/localities/1'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Found):


{
    "data": {
        "id": 1,
        "locality_code": "0001",
        "name": "Guadalajara",
        "ambito": "Urbano",
        "latitude": "20.6737800",
        "longitude": "-103.3442300",
        "altitude": "1566",
        "state": {
            "id": 1,
            "name": "Jalisco",
            "code": "14"
        },
        "municipality": {
            "id": 2,
            "name": "Guadalajara",
            "code": "039"
        }
    }
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required. Pass it as: Authorization: Bearer {token}"
}
 

Example response (404, Not found):


{
    "message": "Locality with id 99999 not found."
}
 

Example response (429, Rate limited):


{
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. You are allowed 1 000 requests per hour.",
    "retry_after": 1800
}
 

Request      

GET v1/localities/{id}

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The locality ID. Example: 1

Streets

Search for streets and street types from the official INEGI catalog.

Search streets

requires authentication

Search for streets within a state and municipality. Optionally filter by locality and street name. Returns paginated results ordered by name.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/streets?state_code=09&municipality_code=015&locality_code=0001&q=Reforma&limit=20&page=1" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"state_code\": \"bngzmiyvdljnikhw\",
    \"municipality_code\": \"aykcmyuwpwlvqwrs\",
    \"locality_code\": \"itcpscqldzsnrwtu\",
    \"q\": \"jwvlxjklqppwqbew\",
    \"limit\": 6
}"
const url = new URL(
    "https://api.postalkit.mx/v1/streets"
);

const params = {
    "state_code": "09",
    "municipality_code": "015",
    "locality_code": "0001",
    "q": "Reforma",
    "limit": "20",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "state_code": "bngzmiyvdljnikhw",
    "municipality_code": "aykcmyuwpwlvqwrs",
    "locality_code": "itcpscqldzsnrwtu",
    "q": "jwvlxjklqppwqbew",
    "limit": 6
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/streets';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'state_code' => '09',
            'municipality_code' => '015',
            'locality_code' => '0001',
            'q' => 'Reforma',
            'limit' => '20',
            'page' => '1',
        ],
        'json' => [
            'state_code' => 'bngzmiyvdljnikhw',
            'municipality_code' => 'aykcmyuwpwlvqwrs',
            'locality_code' => 'itcpscqldzsnrwtu',
            'q' => 'jwvlxjklqppwqbew',
            'limit' => 6,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/streets'
payload = {
    "state_code": "bngzmiyvdljnikhw",
    "municipality_code": "aykcmyuwpwlvqwrs",
    "locality_code": "itcpscqldzsnrwtu",
    "q": "jwvlxjklqppwqbew",
    "limit": 6
}
params = {
  'state_code': '09',
  'municipality_code': '015',
  'locality_code': '0001',
  'q': 'Reforma',
  'limit': '20',
  'page': '1',
}
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload, params=params)
response.json()

Example response (200, Results):


{
    "data": [
        {
            "id": 1,
            "name": "Reforma",
            "code": "0001",
            "ambito": "Urbano",
            "street_type": {
                "id": 1,
                "name": "Avenida",
                "code": "01"
            },
            "state": {
                "id": 1,
                "name": "Ciudad de México",
                "code": "09"
            },
            "municipality": {
                "id": 2,
                "name": "Cuauhtémoc",
                "code": "015"
            }
        }
    ],
    "links": {
        "first": "...",
        "last": "...",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "total": 1,
        "per_page": 20
    }
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required. Pass it as: Authorization: Bearer {token}"
}
 

Example response (422, Missing required params):


{
    "message": "The given data was invalid.",
    "errors": {
        "state_code": [
            "The \"state_code\" query parameter is required."
        ]
    }
}
 

Example response (429, Rate limited):


{
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. You are allowed 1 000 requests per hour.",
    "retry_after": 1800
}
 

Request      

GET v1/streets

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

state_code   string     

The INEGI state code. Example: 09

municipality_code   string     

The INEGI municipality code. Example: 015

locality_code   string  optional    

Optional INEGI locality code to narrow results. Example: 0001

q   string  optional    

Optional street name search (partial match). Example: Reforma

limit   integer  optional    

Results per page (max 100, default 50). Example: 20

page   integer  optional    

Page number. Example: 1

Body Parameters

state_code   string     

Must be at least 1 character. Example: bngzmiyvdljnikhw

municipality_code   string     

Must be at least 1 character. Example: aykcmyuwpwlvqwrs

locality_code   string  optional    

Must be at least 1 character. Example: itcpscqldzsnrwtu

q   string  optional    

Must be at least 1 character. Example: jwvlxjklqppwqbew

limit   integer  optional    

Must be at least 1. Must not be greater than 100. Example: 6

List street types

requires authentication

Retrieve the full catalog of street types (e.g. Avenida, Calle, Boulevard). Returns all types ordered by name.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/street-types" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/street-types"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/street-types';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/street-types'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": [
        {
            "id": 1,
            "name": "Avenida",
            "code": "01"
        },
        {
            "id": 2,
            "name": "Boulevard",
            "code": "02"
        },
        {
            "id": 3,
            "name": "Calle",
            "code": "03"
        }
    ]
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required. Pass it as: Authorization: Bearer {token}"
}
 

Example response (429, Rate limited):


{
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. You are allowed 1 000 requests per hour.",
    "retry_after": 1800
}
 

Request      

GET v1/street-types

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Geocoding

Reverse geocode coordinates to the nearest postal code.

Reverse geocode

requires authentication

Find the nearest postal code to the given latitude and longitude coordinates.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/geocode/reverse?lat=19.4233&lng=-99.1637" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"lat\": -89,
    \"lng\": -179
}"
const url = new URL(
    "https://api.postalkit.mx/v1/geocode/reverse"
);

const params = {
    "lat": "19.4233",
    "lng": "-99.1637",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "lat": -89,
    "lng": -179
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/geocode/reverse';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'lat' => '19.4233',
            'lng' => '-99.1637',
        ],
        'json' => [
            'lat' => -89,
            'lng' => -179,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/geocode/reverse'
payload = {
    "lat": -89,
    "lng": -179
}
params = {
  'lat': '19.4233',
  'lng': '-99.1637',
}
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload, params=params)
response.json()

Example response (200, Found):


{
    "data": {
        "id": 3,
        "code": "06600",
        "state": {
            "id": 1,
            "name": "Ciudad de Mexico",
            "code": "09"
        },
        "municipality": {
            "id": 2,
            "name": "Cuauhtemoc",
            "code": "015"
        },
        "city": null,
        "settlements": [],
        "latitude": "19.4233000",
        "longitude": "-99.1637000"
    }
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required."
}
 

Example response (404, No results):


{
    "message": "No geocoded postal codes found near the given coordinates."
}
 

Example response (422, Invalid params):


{
    "message": "The given data was invalid.",
    "errors": {
        "lat": [
            "The lat field is required."
        ],
        "lng": [
            "The lng field is required."
        ]
    }
}
 

Request      

GET v1/geocode/reverse

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

lat   number     

Latitude (-90 to 90). Example: 19.4233

lng   number     

Longitude (-180 to 180). Example: -99.1637

Body Parameters

lat   number     

Must be between -90 and 90. Example: -89

lng   number     

Must be between -180 and 180. Example: -179

Account

Inspect your account usage, plan limits, and database version information.

Get account usage

requires authentication

Retrieve the authenticated user's current plan, monthly request limit, usage count, and remaining requests for the current billing period.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/account/usage" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/account/usage"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/account/usage';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/account/usage'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": {
        "plan": "free",
        "monthly_limit": 100,
        "usage_count": 42,
        "remaining": 58,
        "period": "2026-04"
    }
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required. Pass it as: Authorization: Bearer {token}"
}
 

Example response (429, Rate limited):


{
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. You are allowed 1 000 requests per hour.",
    "retry_after": 1800
}
 

Request      

GET v1/account/usage

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Get database version

requires authentication

Retrieve the date of the last database update and the current API version.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/v1/account/db-version" \
    --header "Authorization: Bearer {YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/v1/account/db-version"
);

const headers = {
    "Authorization": "Bearer {YOUR_API_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/v1/account/db-version';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_API_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/v1/account/db-version'
headers = {
  'Authorization': 'Bearer {YOUR_API_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Success):


{
    "data": {
        "last_updated": "2026-03-15T00:00:00.000000Z",
        "version": "1.0.0"
    }
}
 

Example response (401, Unauthenticated):


{
    "error": "Unauthenticated",
    "message": "A valid API key is required. Pass it as: Authorization: Bearer {token}"
}
 

Example response (429, Rate limited):


{
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. You are allowed 1 000 requests per hour.",
    "retry_after": 1800
}
 

Request      

GET v1/account/db-version

Headers

Authorization        

Example: Bearer {YOUR_API_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Try it (no key needed)

A keyless, IP-rate-limited mirror of the production postal code lookup, used by the interactive demo on the marketing site. Behaviour and response shape match GET /v1/postal-codes/{code}; the only differences are no Bearer token, a much tighter rate limit, and no usage metering.

Demo postal code lookup

Retrieve the full record for a 5-digit postal code, including state, municipality, city, and all settlements (colonias). No API key required. Rate limited per IP address.

Example request:
curl --request GET \
    --get "https://api.postalkit.mx/demo/postal-codes/06600" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://api.postalkit.mx/demo/postal-codes/06600"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://api.postalkit.mx/demo/postal-codes/06600';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://api.postalkit.mx/demo/postal-codes/06600'
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200, Found):


{
    "data": {
        "id": 3,
        "code": "06600",
        "state": {
            "id": 1,
            "name": "Ciudad de México",
            "code": "09"
        },
        "municipality": {
            "id": 2,
            "name": "Cuauhtémoc",
            "code": "015"
        },
        "city": {
            "id": 1,
            "name": "Ciudad de México"
        },
        "settlements": [
            {
                "id": 5,
                "name": "Roma Sur",
                "zone": "Urbano",
                "settlement_type": {
                    "id": 1,
                    "name": "Colonia"
                }
            }
        ]
    }
}
 

Example response (404, Not found):


{
    "message": "Postal code '00000' not found."
}
 

Example response (422, Invalid format):


{
    "message": "Postal code must be exactly 5 digits."
}
 

Example response (429, Demo limit reached):


{
    "message": "Demo lookup limit reached. Sign up for a free key for 100 lookups every month."
}
 

Request      

GET demo/postal-codes/{code}

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

code   string     

The 5-digit postal code. Example: 06600