{"openapi":"3.1.0","info":{"title":"GB Postcodes API","description":"REST API for GB postcodes: lookup, batch search, validate, distance, radius, nearest, matrix, reverse geocode, polygon search, area boundaries, ONSPD geography, and census population data.","version":"1.0.0"},"servers":[{"url":"https:\/\/postcodes-api.co.uk\/api\/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"Postcode":{"type":"object","properties":{"name":{"type":"string","example":"SW1A 1AA"},"type":{"type":"string","enum":["unit","sector","district","area"]},"center":{"$ref":"#\/components\/schemas\/Point"},"geom":{"$ref":"#\/components\/schemas\/Polygon"},"area_sq_km":{"type":"number","format":"float"},"county_code":{"type":"string","nullable":true,"example":"E10000034"},"county_name":{"type":"string","nullable":true,"example":"Worcestershire"},"local_authority_code":{"type":"string","nullable":true,"example":"E07000237"},"local_authority_name":{"type":"string","nullable":true,"example":"Worcester"},"ward_code":{"type":"string","nullable":true},"ward_name":{"type":"string","nullable":true},"parliamentary_constituency_code":{"type":"string","nullable":true},"parliamentary_constituency_name":{"type":"string","nullable":true},"lsoa_code":{"type":"string","nullable":true},"lsoa_name":{"type":"string","nullable":true},"msoa_code":{"type":"string","nullable":true},"msoa_name":{"type":"string","nullable":true},"nhs_icb_code":{"type":"string","nullable":true},"nhs_icb_name":{"type":"string","nullable":true},"nhs_region_code":{"type":"string","nullable":true},"nhs_region_name":{"type":"string","nullable":true},"police_force_area":{"type":"string","nullable":true,"description":"Police force area code (PFA)"},"police_force_area_name":{"type":"string","nullable":true},"rural_urban_classification":{"type":"string","nullable":true,"description":"ONS rural\/urban classification code, e.g. C1"},"census_residents":{"type":"integer","nullable":true,"description":"Census 2021 resident count (unit level; aggregated for sector\/district\/area)"},"census_households":{"type":"integer","nullable":true,"description":"Census 2021 household count"},"census_vintage":{"type":"string","nullable":true,"example":"2021-03","description":"Census reference period for census_residents\/households"},"estimated_residents":{"type":"integer","nullable":true,"description":"ONS mid-year estimate apportioned from LSOA totals (England & Wales units)"},"estimated_residents_vintage":{"type":"string","nullable":true,"example":"mid-2024","description":"Vintage of estimated_residents"}}},"RadiusPopulationResult":{"type":"object","properties":{"code":{"type":"string","example":"SW1A 1AA"},"radius":{"type":"number","format":"float"},"unit":{"type":"string","enum":["km","miles"]},"census_residents":{"type":"integer","nullable":true,"description":"Sum of census_residents across unit postcodes within the radius"},"census_households":{"type":"integer","nullable":true},"estimated_residents":{"type":"integer","nullable":true},"unit_count":{"type":"integer","description":"Number of unit postcodes included in the totals"}}},"Point":{"type":"object","properties":{"type":{"type":"string","const":"Point"},"coordinates":{"type":"array","items":{"type":"number"},"minItems":2,"maxItems":2}}},"Polygon":{"type":"object","properties":{"type":{"type":"string","enum":["Polygon","MultiPolygon"]},"coordinates":{"type":"array"}}},"DistanceResult":{"type":"object","properties":{"distance":{"type":"number","format":"float"},"unit":{"type":"string","enum":["km","miles"]}}},"ValidateResult":{"type":"object","properties":{"valid":{"type":"boolean"},"normalized":{"type":"string","nullable":true},"type":{"type":"string","nullable":true,"enum":["unit","sector","district","area"]}}},"RadiusResult":{"type":"object","properties":{"unit":{"type":"string","enum":["km","miles"]},"results":{"type":"array","items":{"allOf":[{"$ref":"#\/components\/schemas\/Postcode"},{"type":"object","properties":{"distance":{"type":"number","format":"float"}}}]}}}},"MatrixPair":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"distance":{"type":"number","format":"float"},"unit":{"type":"string","enum":["km","miles"]}}},"Area":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","example":"SW"},"center":{"$ref":"#\/components\/schemas\/Point"},"geom":{"$ref":"#\/components\/schemas\/Polygon"},"area_sq_km":{"type":"number","format":"float"}}},"Health":{"type":"object","properties":{"status":{"type":"string","enum":["operational","degraded"]},"checks":{"type":"object"},"timestamp":{"type":"string","format":"date-time"}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"retry_after":{"type":"integer"}}}}},"paths":{"\/api\/health":{"get":{"summary":"Health check","security":[],"servers":[{"url":"https:\/\/postcodes-api.co.uk"}],"responses":{"200":{"description":"All checks passed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Health"}}}},"503":{"description":"One or more checks failed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Health"}}}}}}},"\/postcodes\/{query}":{"get":{"summary":"Postcode search and lookup","description":"Returns a single Postcode object for an exact unit match, or an array of up to 5 matches otherwise.","parameters":[{"name":"query","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","schema":{"type":"string"},"description":"Comma-separated fields. Defaults to name,type,center,geom,area_sq_km plus all ONSPD geography and population fields."},{"name":"detail","in":"query","schema":{"type":"string","enum":["low","medium","high"],"default":"high"},"description":"Geometry simplification level, applied only to a single-object (unit) match"}],"responses":[{"description":"Matching postcode(s)","content":{"application\/json":{"schema":{"oneOf":[{"$ref":"#\/components\/schemas\/Postcode"},{"type":"array","items":{"$ref":"#\/components\/schemas\/Postcode"}}]}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/search":{"get":{"summary":"Batch postcode lookup","parameters":[{"name":"codes","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated postcodes, max 100"},{"name":"fields","in":"query","schema":{"type":"string"},"description":"Comma-separated fields"}],"responses":[{"description":"Batch lookup results keyed by sanitized code"},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/validate":{"get":{"summary":"Validate a postcode","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}}],"responses":[{"description":"Validation result","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidateResult"}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/distance":{"get":{"summary":"Distance between two postcodes","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}},{"name":"compare","in":"query","required":true,"schema":{"type":"string"}},{"name":"unit","in":"query","schema":{"type":"string","enum":["km","miles"],"default":"km"}}],"responses":[{"description":"Distance result","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DistanceResult"}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/radius\/population":{"get":{"summary":"Aggregate population within radius","description":"Sums census and estimated resident counts across all unit postcodes within a radius of an origin code.","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}},{"name":"radius","in":"query","required":true,"schema":{"type":"number"}},{"name":"unit","in":"query","schema":{"type":"string","enum":["km","miles"],"default":"km"}}],"responses":[{"description":"Aggregated population totals","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RadiusPopulationResult"}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/{postcode}\/geography":{"get":{"summary":"ONSPD geography for a postcode","description":"Returns ONSPD-derived admin, census, health, and police geography for the best-matching postcode. Defaults to geography fields only; use fields to request additional columns.","parameters":[{"name":"postcode","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","schema":{"type":"string"},"description":"Comma-separated fields. Defaults to name plus all ONSPD geography fields."}],"responses":[{"description":"Geography data","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Postcode"}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/radius":{"get":{"summary":"Postcodes within radius of a code","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}},{"name":"radius","in":"query","required":true,"schema":{"type":"number"}},{"name":"unit","in":"query","schema":{"type":"string","enum":["km","miles"],"default":"km"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100,"maximum":500}},{"name":"fields","in":"query","schema":{"type":"string"}}],"responses":[{"description":"Nearby postcodes with distance","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RadiusResult"}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/nearest":{"get":{"summary":"Nearest postcodes","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string"}},{"name":"n","in":"query","schema":{"type":"integer","default":10,"maximum":50}},{"name":"unit","in":"query","schema":{"type":"string","enum":["km","miles"],"default":"km"}},{"name":"fields","in":"query","schema":{"type":"string"}}],"responses":[{"description":"Nearest postcodes with distance","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RadiusResult"}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/matrix":{"get":{"summary":"Distance matrix","parameters":[{"name":"codes[]","in":"query","required":true,"schema":{"type":"string"},"description":"Repeat for each postcode (2\u201320 total)"},{"name":"unit","in":"query","schema":{"type":"string","enum":["km","miles"],"default":"km"}}],"responses":[{"description":"Pairwise distances","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/MatrixPair"}}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/reverse":{"get":{"summary":"Reverse geocode","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number"}},{"name":"lng","in":"query","required":true,"schema":{"type":"number"}},{"name":"type","in":"query","schema":{"type":"string","enum":["area","district","sector","unit"],"default":"unit"}},{"name":"fields","in":"query","schema":{"type":"string"}}],"responses":[{"description":"Postcode at coordinates","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Postcode"}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/postcodes\/within":{"post":{"summary":"Postcodes within a polygon","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["polygon"],"properties":{"polygon":{"$ref":"#\/components\/schemas\/Polygon"},"limit":{"type":"integer","default":100,"maximum":500},"fields":{"type":"string"}}}}}},"responses":[{"description":"Postcodes whose centroids fall within the polygon","content":{"application\/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#\/components\/schemas\/Postcode"}}}}}}},{"description":"Bad request","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Unauthorized","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Forbidden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},{"description":"Rate limit or quota exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}]}},"\/areas":{"get":{"summary":"Postcode areas","description":"Public endpoint. Rate limited to 30 requests per minute.","security":[],"parameters":[{"name":"minLng","in":"query","schema":{"type":"number"}},{"name":"minLat","in":"query","schema":{"type":"number"}},{"name":"maxLng","in":"query","schema":{"type":"number"}},{"name":"maxLat","in":"query","schema":{"type":"number"}},{"name":"limit","in":"query","schema":{"type":"integer","default":500,"maximum":1000}},{"name":"fields","in":"query","schema":{"type":"string"},"description":"id, name, geom, center, area_sq_km"}],"responses":{"200":{"description":"Matching areas","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/Area"}}}}},"400":{"description":"Invalid fields parameter","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}}}}