Postal Code Format
Validate the postcode field without a round trip
Postal codes look nothing alike across countries: five digits in Spain, SW1A 1AA in the UK, K1A 0B1 in Canada. The /v1/places/postal-format endpoint gives you the format, the official regular expression and a sample value per country, so your form can validate the field in the browser and show a placeholder that makes sense.
Endpoint
GET https://api.countrydataapi.com/v1/places/postal-format
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
apikey |
string | Yes | Your API authentication key |
country |
string | No | Internal id, ISO-2, ISO-3 or name. Omit to get every country |
lang |
string | No | Language of the country names. Defaults to en |
Request Example
curl "https://api.countrydataapi.com/v1/places/postal-format?apikey=your-api-key&country=ES"
Fetch every country once and cache it
const response = await fetch(
'https://api.countrydataapi.com/v1/places/postal-format?apikey=your-api-key'
);
const { data } = await response.json();
// Index by ISO-2 for instant lookups in the form
const formats = Object.fromEntries(
data.map(({ country, postal }) => [country.iso2, postal])
);
localStorage.setItem('postal_formats', JSON.stringify(formats));
TypeScript SDK
const { data } = await api.places.postalFormat({ country: 'ES' });
data[0].postal.regex; // "^\\d{5}$"
Response Format
{
"success": true,
"data": [
{
"country": {
"id": "66c7a6c9e4bda21f4ab10ef2",
"name": "Spain",
"iso2": "ES",
"iso3": "ESP",
"phone_code": "+34",
"flag": "🇪🇸"
},
"postal": {
"format": "#####",
"regex": "^\\d{5}$",
"example": "12345"
}
}
],
"count": 1,
"tokens_used": 1,
"remaining_tokens": 4869
}
The format template
| Symbol | Meaning |
|---|---|
# |
A digit |
@ |
A letter |
| anything else | A literal character (space, dash, country prefix...) |
So @@# #@@ describes a UK postcode and produces the example AB1 2CD.
example is generated from format and then checked against regex. If the two disagree, example is null rather than a made-up value you cannot trust. Countries with no postal system return null in all three fields.
Using it in a form
function validatePostcode(value, iso2) {
const postal = formats[iso2];
if (!postal?.regex) return true; // no pattern on record: accept anything
return new RegExp(postal.regex).test(value.trim());
}
// Also useful as a placeholder
input.placeholder = formats[iso2]?.example ?? '';
Validating client-side is a UX improvement, not a guarantee. A well-formed postcode is not necessarily a real one — confirm it with /v1/places/validate before shipping anything to it.
Token Usage
1 token per request, whether you ask for one country or all of them.
This data barely changes. Fetch the full list once, cache it, and you will not need this endpoint again for months. You are free to store it for as long as you want.
Related Endpoints
- GET /v1/places/validate - Check a postcode really exists
- GET /v1/places/autocomplete - Search as the user types
- GET /v1/zipcodes/country - Full list of postal codes for a country