Postcode Intelligence
Enrich any UK postcode with geographic, demographic, environmental, and economic signals from authoritative OGL sources.
Endpoints
GET /v1/postcode/{postcode} GET /v1/postcode/nearest?lat={lat}&lon={lon} GET /v1/postcode/within?lat={lat}&lon={lon} POST /v1/postcode/bulk POST /v1/postcode/bulk/async GET /v1/postcode/bulk/jobs/{jobId} DELETE /v1/postcode/bulk/jobs/{jobId}Input formats
The endpoint accepts four input modes:
| Mode | Example | Returns |
|---|---|---|
| Full postcode | GET /v1/postcode/SW1A+2AA | All signals. Case-insensitive, space optional. |
| Outward code only | GET /v1/postcode/SW1A | District-level signals only — geography, admin areas, constituency. Flood, broadband, property price, crime, and MP data are omitted as they vary too much within a district. |
| Nearest to coordinates | GET /v1/postcode/nearest?lat=51.50&lon=-0.13 | Nearest single postcode centroid with full signal set, plus queryPointDistanceMetres. |
| All postcodes within radius | GET /v1/postcode/within?lat=51.50&lon=-0.13 | Postcode centroids within the radius, ordered by distance, up to your plan's bulk cap (Starter 50, Pro 100, Business 250, Enterprise 500). Each result costs 1 quota unit. Starter and above only. |
Northern Ireland (BT postcodes) return a 422 unsupported_region error on all input modes.
Reverse geocode — nearest postcode
Snap a coordinate to its nearest postcode — useful for resolving GPS coordinates, validating delivery addresses, or snapping device location to a postcode. Returns the full signal set plus a queryPointDistanceMetres field.
| Parameter | Type | Notes |
|---|---|---|
| lat | number | Required. Decimal degrees, WGS84. |
| lon | number | Required. Decimal degrees, WGS84. |
| radius | integer | Optional. Search radius in metres. Default 1000. Returns 404 if no centroid falls within the radius. |
{
"postcode": "SW1A 2AA",
"queryPointDistanceMetres": 87.3,
"latitude": 51.5034,
"longitude": -0.1276,
"country": "England",
"region": "London",
"adminDistrict": "City of Westminster",
/* ... geography, broadband, flood, crime, property,
deprivation, demographics, housing, political ... */
"summary": { "liveabilityLevel": "medium", "propertyRiskLevel": "low" /* ... */ },
"signals": { /* full signal set */ },
"quota": { "remaining": 9999, "limit": 10000, "resetAt": "2026-07-01T00:00:00Z" }
}Same shape as a single postcode lookup, plus queryPointDistanceMetres. See the full response shape and all fields in the Response section below.
Postcodes within a radius
Use this when you need to understand an area rather than a single point — zone risk assessment, delivery catchment analysis, or property research across a neighbourhood. Returns every postcode centroid within the radius, ordered by distance. Each postcode in the result costs one quota unit.
| Parameter | Type | Notes |
|---|---|---|
| lat | number | Required. Decimal degrees, WGS84. |
| lon | number | Required. Decimal degrees, WGS84. |
| radius | integer | Optional. Search radius in metres. Default 1000, max 5000. Returns 404 if no centroids fall within the radius. |
| Tier | Max results per call |
|---|---|
| Free | Not available |
| Micro | Not available |
| Starter | 50 |
| Pro | 100 |
| Business | 250 |
| Enterprise | 500 |
{
"total": 3,
"results": [
{
"postcode": "SW1A 2AA",
"queryPointDistanceMetres": 87.3,
"latitude": 51.5034,
"longitude": -0.1276,
"country": "England",
"region": "London",
"adminDistrict": "City of Westminster",
/* ... geography, broadband, flood, crime, property,
deprivation, demographics, housing, political ... */
"summary": { "propertyRiskLevel": "low", "liveabilityLevel": "medium" /* ... */ },
"signals": { /* full signal set — same shape as single postcode lookup */ }
},
{
"postcode": "SW1A 1AA",
"queryPointDistanceMetres": 142.1
/* ... full signal set ... */
},
{
"postcode": "SW1Y 5AH",
"queryPointDistanceMetres": 198.4
/* ... full signal set ... */
}
],
"quota": { "remaining": 9997, "limit": 10000, "resetAt": "2026-07-01T00:00:00Z" }
}Each result in results[] has the full postcode signal set — identical to a single GET /v1/postcode/{postcode} response, plus queryPointDistanceMetres. See the signal reference for all fields.
Response
Returns a JSON object. See the signal reference for all fields and values. All field names are camelCase.
{
"postcode": "SW1A 2AA",
"adminDistrict": "City of Westminster",
"region": "London",
"summary": {
"propertyRiskLevel": "low",
"liveabilityLevel": "medium",
"insuranceRiskLevel": "low"
},
"signals": {
"flood": { "riversSea": "very_low" },
"deprivation":{ "imdDecile": 8 },
"crime": { "rateBand": "high" },
"property": { "averagePrice": 2847000 },
"broadband": { "gigabit": true },
"political": { "mpName": "Nickie Aiken" }
},
"scores": {
"propertyRiskScore": 0.22,
"liveabilityScore": 0.61
}
}Bulk lookups
Available on Starter and above. Quota is consumed upfront for the full batch.
| Tier | Postcodes per call |
|---|---|
| Free | Not available |
| Micro | Not available |
| Starter | 50 |
| Pro | 100 |
| Business | 250 |
| Enterprise | 500 |
Synchronous bulk
All results returned immediately. Best for batches processed inline.
// Request
{ "postcodes": ["SW1A 2AA", "EC1A 1BB", "M1 1AE"] }
// Response 200
{
"total": 3,
"results": [
{ /* full postcode response */ },
{ "postcode": "EC1A 1BB", "error": "not_found" },
{ "postcode": "BT1 1AA", "error": "unsupported_region" }
]
}Async bulk
Submit a job and poll for results. Useful for large batches or background processing. Jobs expire 24 hours after submission.
// Request
{ "postcodes": ["SW1A 2AA", "EC1A 1BB"] }
// Response 202
{
"jobId": "bulk_4f3a9c1e72b8d5",
"status": "queued",
"total": 2,
"pollUrl": "/v1/postcode/bulk/jobs/bulk_4f3a9c1e72b8d5"
}{
"jobId": "bulk_4f3a9c1e72b8d5",
"status": "complete",
"total": 2,
"done": 2,
"createdAt": "2026-05-18T10:00:00Z",
"completedAt": "2026-05-18T10:00:03Z",
"expiresAt": "2026-05-19T10:00:00Z",
"results": [ /* full postcode responses */ ]
}Status lifecycle: queued → processing → complete | failed → expired
Use DELETE /v1/postcode/bulk/jobs/{jobId} to clean up a job before it expires.