Developer Docs
LondonIQ API
Three APIs. All London postcodes. Postcode data with 40+ sections (liveability, crime, transport, planning and more), Material Information (Parts A, B & C — Trading Standards compliant), and Planning History (applications within 250m, 1994–present).
Getting started
Email api@londoniq.co.uk to request an API key. We reply within one business day. Pass your key in every request via the X-API-Key header.
curl https://api.londoniq.co.uk/api/v1/postcode/E1%206RF \
-H "X-API-Key: liq_your_key_here"Base URL
https://api.londoniq.co.ukHTTPS only. All responses are JSON. Successful responses are wrapped in a data key. Errors return an error key with a message.
Endpoints
/api/v1/postcode/:postcodeFull data for a single London postcode. URL-encode spaces (e.g. E1%206RF). Returns a single JSON object with the following top-level sections:
curl https://api.londoniq.co.uk/api/v1/postcode/CR2%200QE \
-H "X-API-Key: liq_your_key_here"Key fields reference
| Section | Field | Type | Description |
|---|---|---|---|
| scores | liveability_score | int 0–100 | Composite liveability score, percentile-ranked across London |
| scores | score_percentile | float | Percentile rank vs all London postcodes (100 = best) |
| scores | investment_score | int 0–100 | Price growth potential + demand signal |
| property | median_price | int | null | Median sold price (GBP). Null if fewer than 5 sales in 24 months |
| property | price_1yr_change | float | null | % price change over 12 months |
| property | avg_price_per_sqm | float | null | Average price per m² (GBP) |
| property | market_momentum | string | Rising / Stable / Falling |
| property | price_history | array | Quarterly median prices { quarter, median } |
| property | lha_1bed_rate … 4bed_rate | int | Local Housing Allowance rates (£/month) by bedroom count |
| property | median_construction_age | string | E.g. "1930–1949" |
| property | most_common_walls / heating / roof | string | EPC-derived construction characteristics |
| transport | ptal_numeric | float 1–6 | TfL Public Transport Accessibility Level |
| transport | journey_mins_zone1 | int | Minutes to Zone 1 (peak, public transport) |
| transport | journey_mins_canary_wharf | int | Minutes to Canary Wharf |
| transport | night_tube_accessible | bool | null | Night Tube within walking distance |
| crime | crime_rate_per_1000 | float | Recorded crimes per 1,000 residents/year |
| crime | crime_band | string | LOW / MEDIUM / HIGH / VERY HIGH |
| crime | crime_trend | string | IMPROVING / STABLE / WORSENING |
| crime | crime_vs_borough_pct | float | % difference vs borough average (negative = safer) |
| environment | air_quality_band | string | GOOD / MODERATE / POOR / VERY POOR |
| environment | noise_band | string | LOW / MEDIUM / HIGH / VERY HIGH |
| environment | dominant_noise_source | string | road / rail / air / none |
| environment | in_ulez | bool | Whether postcode is inside the ULEZ boundary |
| environment | radon_risk_band | string | low / moderate / high |
| schools | nearest_primary_ofsted | string | Ofsted rating: Outstanding / Good / Requires Improvement / Inadequate |
| schools | nearest_secondary_progress8 | float | Progress 8 score for nearest secondary |
| schools | ofsted_good_or_outstanding_pct | float | % of schools within 1km rated Good or Outstanding |
| health | nearest_gp_cqc_rating | string | CQC rating: Outstanding / Good / Requires Improvement / Inadequate |
| health | nearest_ae_4hr_compliance_pct | float | % of A&E patients seen within 4 hours |
| health | gp_recommend_pct | float | % of patients who would recommend the GP |
| connectivity | broadband.full_fibre_coverage_pct | float | % of premises with full fibre availability |
| connectivity | broadband.gigabit_coverage_pct | float | % of premises with gigabit broadband |
| connectivity | mobile.coverage.outdoor_5g_pct | float | % 5G outdoor coverage |
| planning | in_conservation_area | bool | Whether postcode is in a conservation area |
| planning | in_article4_area | bool | Article 4 direction applies (restricts permitted development) |
| planning | live_planning_apps_within_800m | int | Active planning applications within 800m |
| planning | cil_rate_residential | int | Community Infrastructure Levy rate (£/m²) |
| planning | housing_pipeline.homes_approved_800m | int | New homes with planning permission within 800m |
| planning | in_opportunity_area | bool | GLA Opportunity Area (regeneration zone) |
| buildings | dominant_type | string | E.g. "Semi-detached", "Purpose-built flat" |
| buildings | street_profile | object | Breakdown of property types on the street (%) |
| property_tax | ct_median_band | string | Most common council tax band (A–H) |
| property_tax | ct_annual_gbp | int | Annual council tax for median band (GBP) |
| property_tax | ct_band_distribution | object | % of local properties in each band |
| ground_stability | shrink_swell_score | int 1–5 | Clay shrink-swell risk (1 = low, 5 = very high) |
| ground_stability | subsidence_risk_score | int 1–5 | Subsidence risk score |
| ground_stability | running_sand_risk | int 1–5 | Running sand risk |
| deprivation | imd_decile | int 1–10 | Index of Multiple Deprivation decile (1 = most deprived) |
| deprivation | median_income | int | Estimated median household income (GBP/year) |
| investment | gross_yield_pct | float | Estimated gross rental yield (%) |
| investment | gentrification_score | int 0–100 | Gentrification trajectory score |
| investment | buyer_demand_band | string | Above Average / Average / Below Average |
| affordability | affordability_ratio | float | House price / median income ratio |
| affordability | stamp_duty_gbp | int | Stamp duty for median-priced property (2025/26 rates) |
| affordability | stamp_duty_ftb_gbp | int | Stamp duty for first-time buyers |
| affordability | mortgage_rate_2yr_fixed_pct | float | Bank of England average 2yr fixed rate |
| insurance_risk | rebuild_cost_estimate_gbp | int | BCIS rebuild cost estimate (for buildings insurance) |
| insurance_risk | insurance_cost_band | string | Standard / Above Standard / High |
| commute_hubs | london_bridge | int | Minutes to London Bridge (public transport) |
| commute_hubs | best_hub | string | Fastest accessible London hub |
| politics | mp_name / mp_party | string | Local MP name and party |
| politics | ward_majority_party | string | Controlling party in the ward |
| energy | solar_kwh_per_kwp_yr | float | Solar energy potential (kWh/kWp/year) |
| energy | heat_pump_suitable | bool | Whether the area is suitable for air/ground source heat pumps |
| climate | sunshine_hours_per_year | int | Annual sunshine hours (Met Office 1991–2020 averages) |
| benchmarks | crime_vs_london_pct | float | % vs London average crime rate (negative = safer) |
| benchmarks | price_vs_london_pct | float | % vs London median house price |
| data_quality | confidence_score | int 0–100 | How complete the data is for this postcode (100 = all sections populated) |
median_price, price_1yr_change, etc.) may be null when fewer than 5 sales occurred in the last 24 months. Always check property.low_sample_warning before using price data./api/v1/postcode/:postcode/material-infoTrading Standards–compliant Material Information for a postcode, structured as Parts A, B and C. Covers council tax, tenure, flood risk, planning restrictions, ground stability, radon, noise, broadband and mobile.
curl https://api.londoniq.co.uk/api/v1/postcode/E1%206AN/material-info \
-H "X-API-Key: liq_your_key_here"Key fields reference
| Part | Field | Type | Description |
|---|---|---|---|
| A — council_tax | band | string | null | Council tax band (A–H) |
| A — council_tax | annual_gbp | int | null | Annual council tax charge (GBP) |
| A — tenure_indicators | leasehold_pct_recent_sales | float | null | % of sales in last 24 months that were leasehold |
| A — tenure_indicators | tenure_confirmation_required | bool | True when exact tenure cannot be confirmed from data — agent must verify |
| A — property_type | dominant_type | string | null | Most common property type on the street |
| A — price_indicators | median_price_24m | int | null | Median sold price over last 24 months |
| A — price_indicators | price_1yr_change_pct | float | null | % price change over 12 months |
| B — flood_risk | zone | string | zone_1 (low) / zone_2 (medium) / zone_3 (high) |
| B — flood_risk | surface_water_risk | string | Low / Medium / High / Very High |
| B — planning_restrictions | in_conservation_area | bool | null | Whether postcode is in a conservation area |
| B — planning_restrictions | in_article4_area | bool | null | Article 4 direction applies (restricts permitted development) |
| B — planning_restrictions | live_planning_apps_800m | int | null | Active planning applications within 800m |
| B — planning_restrictions | planning_apps_approved_pct | float | null | % approval rate for decided applications nearby |
| B — rights_of_way | prow_within_500m | int | null | Public rights of way within 500m |
| C — ground_stability | shrink_swell_risk | string | null | low / moderate / high / very_high |
| C — ground_stability | subsidence_risk_score | int | null | Subsidence risk 1–5 (1 = lowest) |
| C — radon | risk_band | string | null | low / moderate / high |
| C — radon | action_level_exceeded | bool | null | True when radon exceeds the 200 Bq/m³ action level |
| C — noise | band | string | null | LOW / MEDIUM / HIGH / VERY HIGH |
| C — noise | road_lden_db / rail_lden_db / aircraft_lden_db | float | null | Day-evening-night noise level (dB) by source |
| C — broadband | full_fibre_coverage_pct | float | null | % of premises with full fibre availability |
| C — mobile_coverage | outdoor_5g_pct | float | null | % outdoor 5G coverage |
| root | mi_completion_pct | int | Data completeness score (100 = all sections populated) |
| root | limitations | string[] | Fields that require further verification (e.g. title searches) |
/api/v1/postcode/:postcode/planning-historyPlanning applications within a configurable radius of the postcode, sourced from council planning portals, 1994–present. Use the radius_m query parameter to control search radius (default 250m, max 1000m).
curl "https://api.londoniq.co.uk/api/v1/postcode/E1%206AN/planning-history?radius_m=250" \
-H "X-API-Key: liq_your_key_here"Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| radius_m | int | 250 | Search radius in metres (max 1000) |
Key fields reference
| Field | Type | Description |
|---|---|---|
| total_matched | int | Total applications in the database within radius (may exceed returned) |
| returned | int | Number of applications in this response (max 20 per call) |
| applications[].ref | string | null | Council reference number |
| applications[].description | string | null | Proposal description as submitted |
| applications[].decision | string | null | Approved / Refused / Withdrawn / Pending |
| applications[].decision_date | string | null | ISO 8601 date of decision |
| applications[].application_type | string | null | Full / Householder / Prior Approval / etc. |
| applications[].appeal_status | string | null | Present only if an appeal was lodged |
| applications[].url | string | null | Direct link to the application on the council planning portal |
Response format
All responses use a consistent envelope. Errors always include a machine-readable code field for programmatic handling.
| Status | Meaning | Body |
|---|---|---|
| 200 | Success | { "data": { ... } } |
| 401 | Missing or invalid API key | { "error": { "code": "unauthorized", "message": "..." } } |
| 404 | Resource not found | { "error": { "code": "not_found", "message": "..." } } |
| 429 | Rate limit exceeded | { "error": { "code": "rate_limit_exceeded", "message": "..." } } + Retry-After header |
| 502 | Upstream timeout or error | { "error": { "code": "upstream_error", "message": "..." } } |
Error codes
| Code | HTTP status | When it occurs |
|---|---|---|
| unauthorized | 401 | X-API-Key header is missing or does not match any active key |
| not_found | 404 | Postcode, district, or borough not found in our dataset |
| rate_limit_exceeded | 429 | More than 120 requests in the current 60-second window |
| upstream_error | 502 | The LondonIQ data service timed out or returned an error |
When you receive a 429, read the Retry-After header for the number of seconds to wait before retrying.
Rate limits & usage
Limits are applied per API key: 120 requests per 60-second window. Every response includes the following headers:
| Header | Description |
|---|---|
| X-RateLimit-Limit | Max requests allowed per 60-second window (120) |
| X-RateLimit-Remaining | Requests remaining in the current window |
| X-Usage-This-Month | Total calls made this calendar month across all endpoints |
| Retry-After | Seconds to wait before retrying (only present on 429 responses) |
Quickstart
Node.js
const res = await fetch(
'https://api.londoniq.co.uk/api/v1/postcode/CR2%200QE',
{ headers: { 'X-API-Key': process.env.LONDONIQ_API_KEY } }
)
const { data } = await res.json()
// Scores
console.log(data.scores.liveability_score) // 66
console.log(data.scores.safety_score) // 95
console.log(data.scores.transport_score) // 32
// Property
console.log(data.property.median_price) // 592000
console.log(data.property.market_momentum) // "Falling"
// Planning
console.log(data.planning.in_conservation_area) // false
console.log(data.planning.cil_rate_residential) // 110
// Affordability
console.log(data.affordability.stamp_duty_gbp) // 17100
console.log(data.affordability.affordability_band) // "Unaffordable"
// Infrastructure
console.log(data.health.nearest_gp_cqc_rating) // "Good"
console.log(data.connectivity.broadband.gigabit_coverage_pct) // 100Python
import requests, os
r = requests.get(
'https://api.londoniq.co.uk/api/v1/postcode/CR2%200QE',
headers={'X-API-Key': os.environ['LONDONIQ_API_KEY']}
)
data = r.json()['data']
print(data['scores']['liveability_score']) # 66
print(data['planning']['in_conservation_area']) # False
print(data['property_tax']['ct_annual_gbp']) # 2083
print(data['commute_hubs']['best_hub']) # "london_bridge"
print(data['commute_hubs']['best_hub_mins']) # 46PHP
$postcode = urlencode('CR2 0QE');
$ch = curl_init("https://api.londoniq.co.uk/api/v1/postcode/{$postcode}");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('LONDONIQ_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true)['data'];
echo $data['scores']['liveability_score']; // 66
echo $data['planning']['in_conservation_area']; // false
echo $data['property']['median_price']; // 592000Versioning & uptime
The API is versioned in the URL (/api/v1/). We never make breaking changes to an existing version. When a new version is released, the previous version remains supported for a minimum of 12 months with advance notice of deprecation.
Breaking changes include removing fields, changing field types, or changing authentication behaviour. Additive changes (new fields, new endpoints) are non-breaking and may be shipped without notice.
| Topic | Commitment |
|---|---|
| Uptime target | 99.9% monthly |
| Planned maintenance notice | At least 24 hours in advance via api@londoniq.co.uk |
| Incident contact | api@londoniq.co.uk — subject line [URGENT] |
| Deprecation notice | Minimum 12 months before removing a version |
| Status page | status.londoniq.co.uk |
Ready to get started?
Email us to request your key. We reply within one business day.