Issue Nº 51 — Oct 3, 2026

A 404 from Postcodes.io can still carry data

Issue fifty-one covers Postcodes.io, a free, keyless UK postcode lookup in the Geocoding category. This session queried it live. A retired postcode returns a 404 with coordinates inside it. Three endpoints report a miss in three different ways. Two limits stop at 100.

A retired postcode is a 404 with data inside

This session sent GET https://api.postcodes.io/postcodes/E1W1UU. The API returned HTTP 404 and the error "Postcode not found". The body also held a terminated object: postcode "E1W 1UU", year_terminated 2015, month_terminated 2, and a longitude and latitude (-0.073706, 51.508009).

A postcode that never existed gets a plain 404. GET /postcodes/ZZ999ZZ returned {"status":404,"error":"Postcode not found"} with no terminated object.

A client that treats every 404 as "unknown postcode" loses the termination date. Check for the terminated key first. GET /terminated_postcodes/E1W1UU returned HTTP 200 with the same year and month, plus eastings and northings.

Three endpoints, three kinds of miss

A single lookup of a bad postcode returns HTTP 404. GET /postcodes/ZZ999ZZ/validate returned HTTP 200 and {"status":200,"result":false}. The same call for SW1A1AA returned {"status":200,"result":true}. The validate endpoint did not return a 404 in this session.

A bulk POST to /postcodes with {"postcodes":["ZZ99 9ZZ","SW1A 1AA"]} returned HTTP 200. The first row was {"query":"ZZ99 9ZZ","result":null}. The second row held the full record for SW1A 1AA.

So a bulk client must test each row for a null result. It cannot rely on the HTTP status.

Bulk lookup and list limits stop at 100

A bulk POST with 100 copies of SW1A 1AA returned HTTP 200 and 100 result rows. A POST with 101 returned HTTP 400. The message was "Too many postcodes submitted. Up to 100 postcodes can be bulk requested at a time".

The reverse lookup, GET /postcodes?lon=-0.141563&lat=51.50101, returned one postcode with the default radius. With radius=2000 it returned 10 postcodes, the farthest 217 m away. Adding limit=100 returned 100 postcodes. limit=101 also returned 100. The API did not return an error for the larger value.

The search call GET /postcodes?q=SW1A returned 10 results. With limit=101 it returned 100.

No key, and CORS is a wildcard

Every response probed in this session carried access-control-allow-origin: *. This includes 200 and 404 responses, the validate call, the bulk POST and GET /random/postcodes. No key or account header was sent.

A full record holds over 40 fields. They include admin_ward, lsoa21, icb, and both parliamentary_constituency and parliamentary_constituency_2024. For SW1A 1AA, the two constituency fields held the same name, Cities of London and Westminster.

Postcodes.io, by the numbers

Rendered live from the atlas entry
AuthenticationNone required
HTTPSSupported
CORSEnabled
PricingFree
FormatsJSON
ukpostcodeopen-sourcegeocodingfree

Sources

Facts checked Oct 2026