Geocoding — entry 066 of 80
Postcodes.io
Postcodes.io is a free, open-source (MIT-licensed) UK postcode lookup and geocoding API: it validates postcodes, reverse-geocodes coordinates to the nearest postcode, and returns administrative geography — ward, constituency, parish, LSOA/MSOA, and more — sourced from the ONS Postcode Directory. It's built and maintained by Ideal Postcodes as a free public service, with a paid Ideal Postcodes product available for teams needing rooftop-level precision or fresher data.
Postcodes.io is a free, open-source (MIT-licensed) lookup and geocoding API for UK postcodes: given a postcode it returns coordinates and administrative geography — ward, constituency, parish, LSOA/MSOA, and more — sourced from the ONS Postcode Directory, with reverse geocoding and bulk variants of both directions.
GreatAPIs Score
Auth quickstart
- No API key required. The docs state plainly: "Postcodes.io does not require authentication." No fixed rate limit is published anywhere in the API reference.
Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.
Look up a single postcode
GEThttps://api.postcodes.io/postcodes/SW1A2AA
{"status":200,"result":{"postcode":"SW1A 2AA","quality":1,"eastings":530047,"northings":179951,"country":"England","longitude":-0.12767,"latitude":51.503541,"admin_district":"Westminster","parliamentary_constituency":"Cities of London and Westminster","admin_ward":"St James's"}}Developer reference
https://api.postcodes.ioGotchas & limits
- The response envelope mirrors the HTTP status rather than always returning 200: a live lookup of a well-formed but unassigned postcode (`GET /postcodes/ZZ999ZZ`) returned HTTP **404** with body `{"status":404,"error":"Postcode not found"}` — code that only inspects the JSON body still needs to branch on `status`/`error`, not just on the transport-level HTTP code (both observed live in this run).
- Bulk lookup is `POST /postcodes` with a JSON body `{"postcodes":[...]}` (`Content-Type: application/json`) — the docs state it "accepts up to 100 postcodes" per request; a live 2-postcode probe (one valid, one malformed) returned `result` as a matching array with `result: null` for the unmatched entry rather than erroring the whole batch.
- Reverse geocoding is a plain GET with query params — `GET /postcodes?lon=<lon>&lat=<lat>` — not a path segment; a live probe returned an array of the nearest matching postcodes each carrying a `distance` field, nearest first (the docs describe the ordering as "closest first" but never state the unit), not a single closest match. The docs state the bulk reverse-geocoding variant (`POST /postcodes` with a `geolocations` array) also caps at 100 locations per request.
- Every response carries `access-control-allow-origin: *` (confirmed on both the success and 404 probes above), so it's safe to call directly from browser JavaScript with no proxy.