Postal codes, the regions around them, and how far apart they are
The Geo & Postal API returns administrative-region and postal reference data as clean JSON.
11 active endpoints, on 1, 2 and 3 credit tiers.
- POST/geo-postal/v1/eu_regions
- POST/geo-postal/v1/tr_regions
- POST/geo-postal/v1/in_postal
- POST/geo-postal/v1/us_regions
- POST/geo-postal/v1/us_census
- POST/geo-postal/v1/admin_boundary
- POST/geo-postal/v1/postal_lookup
- +4 more
What Postal Code & Geocoding endpoints does ReefAPI ship?
11 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Postal Code & Geocoding API
3 of 11 endpoints, ready to run
The places a postal code resolves to, with coordinates, the administrative hierarchy above them, and how confident the match is.
{ "ok": true, "meta": { "api": "geo-postal", "endpoint": "postal_lookup", "mode": "live", "latency_ms": 9, "record_count": 1, "cache_hit": false }, "data": { "normalized_input": { "country": "DE", "postal_code": "10115" }, "match_type": "postal_exact", "confidence": 0.95, "low_confidence": false, "source": "geonames_postal(CC-BY-4.0)", "dataset_version": "nuts2024-01m|lau2024-01m|cgaz-cc-by-4.0|pcode2025-v2.0|geonames-2026-06|turkiyeapi-2025|inpin-godl-2026", "found": true, "country": "DE", "postal_code": "10115", "places": [ { "postal_code": "10115", "name": "Berlin", "admin1": "Berlin", "admin1_code": "BE", "admin2": "", "admin2_code": "00", "admin3": "Berlin, Stadt", "admin3_code": "11000", "lat": 52.5323, "lon": 13.3846, "accuracy": 6 } ], "nuts3": [ "DE300" ] } }
How the Postal Code & Geocoding API works
Postal Code & Geocoding is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 184 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Working out which customers a new depot actually serves
Service areas get drawn as a list of postal codes someone typed by hand. The question underneath is geometric: which codes are within range of this point.
{"country": "DE", "postal_code": "10115", "radius_km": 5}Returns each code in range with its distance from the centre, so the service list is derived rather than maintained.
{"country": "DE", "from": "10115", "to": "80331"}For pricing bands. It works across countries by passing to_country, which is the case a single-country dataset usually cannot answer.
Both answers carry the dataset version and licence they came from, which is what makes a service-area decision reproducible six months later.
curl -X POST https://api.reefapi.com/geo-postal/v1/postal_lookup \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"country":"FR","postal_code":"75001"}'{
"ok": true,
"data": { … },
"meta": {
"api": "geo-postal",
"endpoint": "postal_lookup",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}Which action covers which geography, and what codes it hands back
This is not one global lookup — each region has its own official coding system and its own action. Picking the wrong one is the usual reason a code comes back missing. Every response also carries match_type, confidence, low_confidence, source and dataset_version so you can tell an exact hit from a fuzzy one.
| Action | Geography | Codes it returns |
|---|---|---|
| us_regions | United States — ZIP or lat/lon | state code + 2-digit FIPS, county name + 5-digit FIPS, ZIP centroid |
| us_census | United States — street address, ZIP or lat/lon | census tract GEOID (11 digits), block GEOID (15 digits), ZCTA, county FIPS |
| eu_regions | EU / EFTA / candidate countries | NUTS 0–3 hierarchy, LAU commune with GISCO id |
| tr_regions | Türkiye | il + plaka, ilçe, mahalle/köy, posta kodu, NUTS-TR 1–3 |
| in_postal | India | PIN code, post offices with type and delivery status, district, state |
| admin_boundary | Global — lat/lon only | ADM0 / ADM1 / ADM2 names + ISO3, each with its own confidence |
| postal_lookup | ~100 countries — country + postal code | admin1/admin2/admin3 names and codes, lat/lon, accuracy, NUTS3 for EU |
| postal_search | country + city, or country + state, or country alone | the postal codes for a place, or that country's region list |
| postal_distance / postal_radius | any two postal codes / one code + radius | great-circle distance between postal centroids |
US FIPS lengths are fixed and zero-padded: state is 2 characters ('06' for California), county is 5 ('06037' for Los Angeles, which embeds the state), tract GEOID is 11 and block GEOID is 15. Store them as strings — parsing them as integers destroys the leading zero for every state below 10.
How exact these numbers are, said plainly
Measured across European lookups, radius queries and cross-country distances. The engine states its own limits in the payload; they are repeated here.
Every distance is computed between the centre points of postal areas, not between two doors, and the response says so in its own method note. For a pricing band or a service radius that is the right resolution. For anything that needs the actual address, it is not, and the gap grows with the size of the postal area.
The calculation is great-circle. Two codes on opposite banks of a river are close by this measure and far apart by road. The response labels the method rather than presenting the number as a travel distance, which is the field to read before wiring it into a delivery estimate.
A lookup reports whether it matched the postal code exactly or fell back to something looser, with a confidence number and an explicit low-confidence flag. An approximate answer and an exact one do not arrive looking the same, so you can decide which ones need a human.
Each answer names the source datasets and their versions along with the licence. Postal boundaries are revised; being able to say which vintage produced a number is the difference between a reproducible decision and one you have to re-litigate.
Beyond postal codes, a latitude and longitude resolve to their administrative levels, with dedicated coverage for European, Turkish, Indian and US region systems including census geography. Geometry is optional, so you can ask for the names without paying for the shapes.
What people build with Postal Code & Geocoding
The jobs this data is most often used for.
endpoints
credits per call
Logistics tools call postal_lookup to map a postal code to a region.
Address validation uses eu_regions and us_regions to normalize locations.
Analytics use us_census and admin_boundary to aggregate by area.
What Postal Code & Geocoding data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 184 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/geo-postal/v1/postal_lookup \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"country":"FR","postal_code":"75001"}'import requests
r = requests.post(
"https://api.reefapi.com/geo-postal/v1/postal_lookup",
headers={"x-api-key": REEF_KEY},
json={
"country": "FR",
"postal_code": "75001"
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Postal Code & Geocoding.
Get a free key →Why does us_regions give me census_pending instead of a tract GEOID?▾
Because tract, block and ZCTA polygons come from a different dataset than the ZIP directory us_regions reads. When that extension is not loaded the response returns a census_pending object whose keys are literally marked gov_pending, while state, county, FIPS and centroid come back complete. The fix is not to retry — call us_census, which is the action built for tract and block geoids. A measured us_census lookup on ZIP 02139 returned tract GEOID 25017353101 and block GEOID 250173531012002.
Can found be true while a field inside is null?▾
Yes, and it happens routinely — treat found as 'we resolved the input', not 'every field is populated'. Measured examples: us_census on ZIP 02139 returned found true, a full tract and block, and zcta null. admin_boundary on Paris coordinates returned adm0.id null while adm1.id and adm2.id both carried ids, because the global boundary dataset does not assign ids at country level. Check the specific field, not the flag.
Are the coordinates rooftop-accurate?▾
No, and the response says so. us_regions returns centroid with an explicit centroid_note that it is the ZIP centroid from the postal directory, not a rooftop geocode, and postal_distance reports method 'haversine_centroid' for the same reason: it measures between two postal-code centroids. The one path that can be rooftop-grade is us_census in address mode, which returns matched_address and a match_type of census_geocoder_exact. Distances between two adjacent ZIPs will read as a few kilometres even for neighbouring buildings.
What do match_type and confidence actually mean?▾
match_type names how the input was resolved and confidence scores it from 0 to 1, with low_confidence set as a boolean so you do not have to pick a threshold. Measured values: postal_exact scored 0.95 for a direct ZIP hit, census_geocoder_exact scored 0.97, and a coordinate hit against the global boundary set scored 0.98. A fuzzy place-name match scores materially lower — read low_confidence before you write the result into a customer record.
How do I know the reference data has not gone stale?▾
Every response carries dataset_version listing each underlying dataset and its vintage — NUTS 2024, LAU 2024, the CGAZ boundary composite, the TERCET postcode table, the GeoNames postal snapshot, the Türkiye dataset and the India PIN directory. Log it alongside the result. When a boundary changes, that string is what tells you whether a stored answer was computed before or after the revision.
Can I resolve a batch of postal codes in one call?▾
Yes. batch accepts up to 50 mixed lookups per call and returns each result tagged with the action that produced it, so you can mix a US ZIP, a German postcode and a Turkish il in one request. These are local dataset queries rather than remote fetches — a postal_lookup measured at 7.6 ms against a US ZIP lookup that hits the geocoder at roughly 900 ms — so batching mainly saves round trips, not upstream cost.
Which Turkish fields does tr_regions return that a generic postal lookup misses?▾
The full official hierarchy rather than a flattened place name: province with its id, plaka number, NUTS-TR 1–3 codes, region, population, coordinates, phone area codes and an is_metropolitan flag; district with id and population; and the mahalle/köy matches carrying their own postal_code, population and kind. You can enter it from any direction — coordinates, posta kodu, or il/ilçe/mahalle names — because one Turkish postal code frequently spans several mahalle.
What is the Postal Code & Geocoding API?▾
Postal Code & Geocoding API is a ReefAPI endpoint group for postal code & geocoding It returns live JSON through POST requests under /geo-postal/v1.
Is the Postal Code & Geocoding API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Postal Code & Geocoding calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Postal Code & Geocoding login or account?▾
No login to Postal Code & Geocoding is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Postal Code & Geocoding data?▾
The page example is captured from a live eu_regions call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Postal Code & Geocoding API use?▾
Postal Code & Geocoding actions currently cost 1-3 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Postal Code & Geocoding from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call geo-postal actions with the same key, credit pool and JSON envelope used by normal REST requests.
Is the Postal Code & Geocoding API a Postal Code & Geocoding scraper?▾
It is the managed alternative to a DIY Postal Code & Geocoding scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same postal code & geocoding back as clean JSON.
19 Utilities & AI APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Postal Code & Geocoding, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-30.