API

v1

Every figure on Open Index, with its source, period, publication date and licence, as JSON. Free to use, with no key and no sign-up. Any website can call it.

Base address
https://openindex.co.uk/v1
Format
JSON, UTF-8. Every answer has the same envelope.
Key
None needed
Fair use
About 60 requests a minute per IP address
Updates
Monthly snapshots. This one is 2026.10.4
OpenAPI 3.1
/v1/openapi.json

Quick start

Ask for an area by its official code. Hackney is E09000012; search finds any other.
curl
curl https://openindex.co.uk/v1/places/E09000012
JavaScript
const res = await fetch("https://openindex.co.uk/v1/places/E09000012");
const { data, meta } = await res.json();

const price = data.headline["house-price-average"];
console.log(price.value, price.period); // 605729 "2026-07"
console.log(meta.sources.map((s) => s.credit)); // the credit lines to show

Every answer is {data, meta}. meta.sources lists the sources behind the data, each with its licence and the credit line you must show next to it. meta.snapshot says which monthly snapshot answered.

meta, from the example
{
  "snapshot": "2026.10.4",
  "sources": [
    {
      "id": "ons-geography",
      "name": "ONS boundaries, lookups and code history (Open Geography Portal)",
      "publisher": "Office for National Statistics",
      "licence": "OGL-3.0",
      "licence_url": "https://www.ons.gov.uk/methodology/geography/licences",
      "credit": "Source: Office for National Statistics licensed under the Open Government Licence v.3.0. Contains OS data © Crown copyright and database right 2026.",
      "edition": null,
      "published_at": null,
      "retrieved_at": "2026-10-15T18:40:35Z"
    },
    {
      "id": "ons-mye",
      "name": "Mid-year population estimates",
      "publisher": "Office for National Statistics, National Records of Scotland and the Northern Ireland Statistics and Research Agency",
      "licence": "OGL-3.0",
      "licence_url": "https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
      "credit": "Source: Office for National Statistics licensed under the Open Government Licence v.3.0.",
      "edition": "mid-2025",
      "published_at": "2026-10-01",
      "retrieved_at": "2026-10-15T17:37:24Z"
    },
    … 20 more
  ],
  "docs": "https://openindex.co.uk/api#places"
}

What the API offers

GET/v1Every endpoint, with links to this guide and the OpenAPI file.

No parameters.

Example

GEThttps://openindex.co.uk/v1
Response: data, shortened
{
  "name": "Open Index API",
  "version": "v1",
  "docs": "https://openindex.co.uk/api",
  "openapi": "https://openindex.co.uk/v1/openapi.json",
  "endpoints": [
    {
      "method": "GET",
      "path": "/v1/places/{code}",
      "summary": "One area",
      "docs": "https://openindex.co.uk/api#places"
    },
    {
      "method": "GET",
      "path": "/v1/places/{code}/data",
      "summary": "Every value for an area",
      "docs": "https://openindex.co.uk/api#place-data"
    },
    … 7 more
  ]
}

Errors: 429, 503. What they mean

One area

GET/v1/places/{code}An area's name, level, type, parents, neighbours and the latest value of every layer published at its level, each with its period, publication date, rank and comparisons. Layers with no value here are listed under gaps with the reason.
ParameterInWhat it does
codeRequiredpathThe area's official code, such as E09000012 (Hackney). Lowercase works too.

Example

GEThttps://openindex.co.uk/v1/places/E09000012
Response: data, shortened
{
  "code": "E09000012",
  "name": "Hackney",
  "level": "council",
  "type": "London borough",
  "boundary_set": "LAD26",
  "parents": [
    {
      "code": "E12000007",
      "name": "London",
      "level": "region",
      "path": "/london",
      "url": "https://openindex.co.uk/london"
    },
    {
      "code": "E92000001",
      "name": "England",
      "level": "nation",
      "path": "/england",
      "url": "https://openindex.co.uk/england"
    },
    … 1 more
  ],
  "headline": {
    "house-price-average": {
      "layer": "house-price-average",
      "name": "Average house price",
      "unit": "gbp",
      "value": 605729,
      "period": "2026-07",
      "published_at": "2026-09-16",
      "flags": [],
      "rank": {
        "position": 13,
        "of": 360,
        "scope": "uk",
        "direction": "highest",
        "position_desc": 13
      },
      "parent": {
        "code": "E12000007",
        "name": "London",
        "value": 550037,
        "period": "2026-07"
      },
      "uk": {
        "code": "K02000001",
        "name": "United Kingdom",
        "value": 272611,
        "period": "2026-07"
      },
      "sources": ["uk-hpi"],
      "derived": null
    },
    "age-15-to-64": {
      "layer": "age-15-to-64",
      "name": "Aged 15 to 64",
      "unit": "percent",
      "value": 74.1,
      "period": "2021",
      "published_at": "2026-07-21",
      "flags": [],
      "rank": {
        "position": 10,
        "of": 361,
        "scope": "uk",
        "direction": "highest",
        "position_desc": 10
      },
      "parent": { "code": "E12000007", "name": "London", "value": 70, "period": "2021" },
      "uk": null,
      "sources": ["ons-census-2021", "nrs-census-2022", "nisra-census-2021"],
      "derived": null
    },
    … 65 more
  },
  "gaps": [
    {
      "layer": "crime-scotland-count",
      "period": "2025/26",
      "flags": ["not-covered"],
      "reasons": ["This layer covers Scotland only. For England, see street-level crime."]
    },
    {
      "layer": "crime-scotland-damage-rate",
      "period": "2025/26",
      "flags": ["not-covered"],
      "reasons": ["This layer covers Scotland only. For England, see street-level crime."]
    },
    … 4 more
  ],
  "links": {
    "data": "https://openindex.co.uk/v1/places/E09000012/data",
    "page": "https://openindex.co.uk/hackney"
  },
  … 14 more fields
}

Errors: 400, 404, 429, 503. What they mean

Every value for an area

GET/v1/places/{code}/dataEvery layer value for the area at its own level, each with its period, publication date, flags in words, sources and licences. A value of null always comes with a reason. Filter to one family with family.
ParameterInWhat it does
codeRequiredpathThe area's official code, such as E09000012 (Hackney). Lowercase works too.
familyOptionalqueryOnly this family of layers, such as housing.housing, crime, people, deprivation, health, education, environment, transport, connectivity, planning, economy

Example

GEThttps://openindex.co.uk/v1/places/E09000012/data?family=housing
Response: data, shortened
{
  "place": {
    "code": "E09000012",
    "name": "Hackney",
    "level": "council",
    "level_name": "Council",
    "type": "London borough",
    "path": "/hackney",
    "url": "https://openindex.co.uk/hackney"
  },
  "family": "housing",
  "values": [
    {
      "layer": "house-price-average",
      "name": "Average house price",
      "family": "housing",
      "unit": "gbp",
      "precision": 0,
      "level": "council",
      "value": 605729,
      "period": "2026-07",
      "published_at": "2026-09-16",
      "flags": [],
      "notes": [],
      "rank": {
        "position": 13,
        "of": 360,
        "scope": "uk",
        "direction": "highest",
        "position_desc": 13
      },
      "parent": {
        "code": "E12000007",
        "name": "London",
        "value": 550037,
        "period": "2026-07"
      },
      "uk": {
        "code": "K02000001",
        "name": "United Kingdom",
        "value": 272611,
        "period": "2026-07"
      },
      "sources": ["uk-hpi"],
      "licences": ["OGL-3.0"],
      "derived": null,
      "links": { "layer": "https://openindex.co.uk/v1/layers/house-price-average" }
    },
    {
      "layer": "house-price-change-1y",
      "name": "Annual price change",
      "family": "housing",
      "unit": "percent",
      "precision": 1,
      "level": "council",
      "value": -2.6,
      "period": "2026-07",
      "published_at": "2026-09-16",
      "flags": [],
      "notes": [],
      "rank": {
        "position": 31,
        "of": 360,
        "scope": "uk",
        "direction": "lowest",
        "position_desc": 328
      },
      "parent": { "code": "E12000007", "name": "London", "value": -3.3, "period": "2026-07" },
      "uk": {
        "code": "K02000001",
        "name": "United Kingdom",
        "value": 1.4,
        "period": "2026-07"
      },
      "sources": ["uk-hpi"],
      "licences": ["OGL-3.0"],
      "derived": null,
      "links": { "layer": "https://openindex.co.uk/v1/layers/house-price-change-1y" }
    },
    … 14 more
  ],
  … 1 more fields
}

Errors: 400, 404, 429, 503. What they mean

Every layer

GET/v1/layersThe catalogue: families, every layer with data in this snapshot (its unit, levels and periods), and every source with its licence and credit line.

No parameters.

Example

GEThttps://openindex.co.uk/v1/layers
Response: data, shortened
{
  "families": [
    { "id": "housing", "name": "Housing", "order": 1, "layers": 17 },
    { "id": "crime", "name": "Crime and justice", "order": 2, "layers": 19 },
    … 9 more
  ],
  "layers": [
    {
      "id": "age-15-to-64",
      "slug": "age-15-to-64",
      "name": "Aged 15 to 64",
      "short_name": "15 to 64",
      "family": "people",
      "description": "The share of residents aged 15 to 64 at the census.",
      "unit": "percent",
      "kind": "share",
      "better": "neutral",
      "precision": 1,
      "period_type": "census",
      "geometry": "area",
      "nations": ["E", "W", "S", "N"],
      "finest_level": "output_area",
      "levels": [
        {
          "level": "nation",
          "level_name": "Nation",
          "areas": 4,
          "first": "2021",
          "latest": "2021",
          "count": 1
        },
        {
          "level": "region",
          "level_name": "Region",
          "areas": 12,
          "first": "2021",
          "latest": "2021",
          "count": 1
        },
        … 6 more
      ],
      "derived": null,
      "sources": ["ons-census-2021", "nrs-census-2022", "nisra-census-2021"],
      "links": {
        "self": "https://openindex.co.uk/v1/layers/age-15-to-64",
        "values": "https://openindex.co.uk/v1/layers/age-15-to-64/values",
        "page": "https://openindex.co.uk/sources/age-15-to-64",
        "map": "https://openindex.co.uk/map/age-15-to-64"
      }
    },
    {
      "id": "age-65-and-over",
      "slug": "age-65-and-over",
      "name": "Aged 65 and over",
      "short_name": "65 and over",
      "family": "people",
      "description": "The share of residents aged 65 and over at the census.",
      "unit": "percent",
      "kind": "share",
      "better": "neutral",
      "precision": 1,
      "period_type": "census",
      "geometry": "area",
      "nations": ["E", "W", "S", "N"],
      "finest_level": "output_area",
      "levels": [
        {
          "level": "nation",
          "level_name": "Nation",
          "areas": 4,
          "first": "2021",
          "latest": "2021",
          "count": 1
        },
        {
          "level": "region",
          "level_name": "Region",
          "areas": 12,
          "first": "2021",
          "latest": "2021",
          "count": 1
        },
        … 6 more
      ],
      "derived": null,
      "sources": ["ons-census-2021", "nrs-census-2022", "nisra-census-2021"],
      "links": {
        "self": "https://openindex.co.uk/v1/layers/age-65-and-over",
        "values": "https://openindex.co.uk/v1/layers/age-65-and-over/values",
        "page": "https://openindex.co.uk/sources/age-65-and-over",
        "map": "https://openindex.co.uk/map/age-65-and-over"
      }
    },
    … 95 more
  ],
  "sources": [
    {
      "id": "defra-air-maps",
      "name": "Modelled background air pollution maps (1 km grid)",
      "publisher": "Department for Environment, Food & Rural Affairs",
      "licence": "OGL-3.0",
      "licence_url": "https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
      "credit": "Source: Defra, modelled background air pollution maps. Contains public sector information licensed under the Open Government Licence v3.0.",
      "landing_url": "https://www.gov.uk/government/publications/air-quality-compliance-assessment-2025-modelled-data-and-reports",
      "cadence": "annual",
      "nations": ["E", "W", "S", "N"]
    },
    {
      "id": "dfe-gias",
      "name": "Get Information About Schools",
      "publisher": "Department for Education",
      "licence": "OGL-3.0",
      "licence_url": "https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/",
      "credit": "Contains public sector information licensed under the Open Government Licence v3.0. Source: Department for Education, Get Information About Schools.",
      "landing_url": "https://get-information-schools.service.gov.uk/Downloads",
      "cadence": "daily",
      "nations": ["E"]
    },
    … 32 more
  ]
}

Errors: 429, 503. What they mean

One layer

GET/v1/layers/{id}One layer: its description and caveats, every level with every period, colour breaks, coverage by nation, gaps with reasons, flags in words and its sources.
ParameterInWhat it does
idRequiredpathA layer id from /v1/layers, such as house-price-average. Its slug (house-prices) works too.Any id from /v1/layers

Example

GEThttps://openindex.co.uk/v1/layers/house-price-average
Response: data, shortened
{
  "id": "house-price-average",
  "name": "Average house price",
  "unit": "gbp",
  "precision": 0,
  "levels": [
    {
      "level": "uk",
      "level_name": "United Kingdom",
      "areas": 1,
      "first": "1968-04",
      "latest": "2026-07",
      "count": 700,
      "periods": ["1968-04", "1968-05", "1968-06", "1968-07", "1968-08", "1968-09", … 694 more],
      "breaks": [175000, 225000, 275000, 350000, 450000, 600000],
      "stats": {
        "period": "2026-07",
        "n": 1,
        "min": 272611,
        "median": 272611,
        "max": 272611
      },
      "coverage": {}
    },
    {
      "level": "nation",
      "level_name": "Nation",
      "areas": 4,
      "first": "1968-04",
      "latest": "2026-07",
      "count": 700,
      "periods": ["1968-04", "1968-05", "1968-06", "1968-07", "1968-08", "1968-09", … 694 more],
      "breaks": [175000, 225000, 275000, 350000, 450000, 600000],
      "stats": {
        "period": "2026-07",
        "n": 4,
        "min": 196349,
        "median": 208762,
        "max": 293479
      },
      "coverage": {
        "E": { "areas": 1, "with_value": 1 },
        "W": { "areas": 1, "with_value": 1 },
        "S": { "areas": 1, "with_value": 1 },
        "N": { "areas": 1, "with_value": 1 }
      }
    },
    … 2 more
  ],
  "flag_labels": {
    "no-data": "No figure for this area in this period.",
    "not-covered": "Not published here.",
    "former-code": "The publisher gives this figure under the area's former code. Open Index has matched it to today's area, whose boundary may differ slightly.",
    "summed-from-neighbourhoods": "Worked out by Open Index by adding up the neighbourhood estimates inside this area.",
    "shared-from-neighbourhoods": "Worked out by Open Index from neighbourhood estimates, shared out by where people lived at the census (by area in Northern Ireland). This area's edges do not follow neighbourhood edges, so the figure is close but not exact.",
    "provisional": "HM Land Registry revises sales volumes for the latest 12 months as more sales are registered, so this figure may change.",
    "no-type-price": "The UK House Price Index publishes no price for this type of home in this area.",
    "no-type-price-ni": "The UK House Price Index publishes prices by property type for Northern Ireland as a whole, not for its councils.",
    "series-starts-later": "Council figures start in January 2004 in Scotland and January 2005 in Northern Ireland.",
    "excluded-low-sales": "The UK House Price Index leaves out the Isles of Scilly because it has very few sales each month."
  },
  "gaps": {
    "level": "council",
    "period": "2026-07",
    "total": 1,
    "by_flag": { "excluded-low-sales": 1 },
    "areas": [
      {
        "code": "E06000053",
        "name": "Isles of Scilly",
        "flags": ["excluded-low-sales"],
        "reason": "The UK House Price Index leaves out the Isles of Scilly because it has very few sales each month."
      }
    ]
  },
  "links": {
    "self": "https://openindex.co.uk/v1/layers/house-price-average",
    "values": "https://openindex.co.uk/v1/layers/house-price-average/values",
    "page": "https://openindex.co.uk/sources/house-prices",
    "map": "https://openindex.co.uk/map/house-prices",
    "download": "https://data.openindex.co.uk/s/2026.10.4/downloads/layers/house-price-average/council.csv"
  },
  … 19 more fields
}

Errors: 400, 404, 429, 503. What they mean

Every area's value

GET/v1/layers/{id}/valuesEvery area's value at one level and period, in code order. Pages hold up to 1,000 rows; follow page.next for the rest. Values are only ever given for the levels a source published (no level is split down to finer areas).
ParameterInWhat it does
idRequiredpathA layer id from /v1/layers, such as house-price-average. Its slug (house-prices) works too.Any id from /v1/layers
levelOptionalqueryThe level, such as council. Defaults to the finest level the layer has.uk, nation, region, council, constituency, ward, middle_area, neighbourhood, output_area, postcode, point
periodOptionalqueryThe period, such as 2026-07, 2025 or 2025/26. Defaults to the latest.2026-07, 2025, 2025/26 or latest
limitOptionalqueryRows per page, 1 to 1,000.1 to 1000
cursorOptionalqueryFrom page.next. Treat it as opaque.

Example

GEThttps://openindex.co.uk/v1/layers/house-price-average/values?level=council&period=2026-07
Response: data, shortened
{
  "layer": "house-price-average",
  "level": "council",
  "period": "2026-07",
  "unit": "gbp",
  "published_at": "2026-09-16",
  "values": [
    { "code": "E06000001", "name": "Hartlepool", "value": 136894, "flags": [] },
    { "code": "E06000002", "name": "Middlesbrough", "value": 140909, "flags": [] },
    … 359 more
  ],
  "page": { "limit": 1000, "count": 361, "total": 361, "next": null },
  … 5 more fields
}

Errors: 400, 404, 429, 503. What they mean

The areas a postcode sits in

GET/v1/postcodes/{postcode}Every area a live postcode sits in, from the UK down, and its location to about 10 metres. Great Britain only: Northern Ireland (BT) postcodes answer 404 because their licence allows internal use only.
ParameterInWhat it does
postcodeRequiredpathA full postcode. Spaces and case do not matter: E81AA, e8-1aa and E8%201AA all work.

Example

GEThttps://openindex.co.uk/v1/postcodes/E81AA
Response: data, shortened
{
  "postcode": "E8 1AA",
  "district": "E8",
  "sector": "E8 1",
  "location": { "lon": -0.0617, "lat": 51.548 },
  "areas": {
    "council": {
      "code": "E09000012",
      "name": "Hackney",
      "path": "/hackney",
      "url": "https://openindex.co.uk/hackney",
      "api": "https://openindex.co.uk/v1/places/E09000012"
    },
    "uk": {
      "code": "K02000001",
      "name": "United Kingdom",
      "path": "/",
      "url": "https://openindex.co.uk/",
      "api": "https://openindex.co.uk/v1/places/K02000001"
    },
    … 7 more
  },
  "links": { "page": "https://openindex.co.uk/postcode/e8-1aa" }
}

Errors: 400, 404, 429, 503. What they mean

The snapshot answering

GET/v1/snapshotWhich snapshot is live, when it was built, its levels and boundary sets, every source edition in it, its check results and where its downloads are.

No parameters.

Example

GEThttps://openindex.co.uk/v1/snapshot
Response: data, shortened
{
  "snapshot": "2026.10.4",
  "created_at": "2026-10-18T05:19:35Z",
  "levels": ["uk", "nation", "region", "council", "constituency", "ward", … 3 more],
  "boundary_sets": {
    "uk": ["K02000001"],
    "nation": ["CTRY25"],
    "region": ["CTRY25", "RGN25"],
    "council": ["LAD26"],
    "constituency": ["PCON24"],
    "ward": ["WD26"],
    "middle_area": ["IZ22", "MSOA21", "SDZ21"],
    "neighbourhood": ["DZ21", "DZ22", "LSOA21"],
    "output_area": ["OA21", "OA22"],
    "neighbourhood@DZ11": ["DZ11"],
    "neighbourhood@SOA01": ["SOA01"]
  },
  "areas": {
    "uk": 1,
    "nation": 4,
    "region": 12,
    "council": 361,
    "constituency": 650,
    "ward": 8413,
    "middle_area": 9448,
    "neighbourhood": 46844,
    "output_area": 235243
  },
  "layers": 97,
  "sources": [
    {
      "id": "defra-air-maps",
      "edition": "Background maps 2025 (CMAQ-Urban, 1 km)",
      "published_at": "2026-10-09",
      "retrieved_at": "2026-10-15T18:46:18Z"
    },
    {
      "id": "dfe-gias",
      "edition": "edubasealldata20261015.csv",
      "published_at": "2026-10-15",
      "retrieved_at": "2026-10-15T18:41:55Z"
    },
    … 80 more
  ],
  "checks": { "passed": 1041, "warnings": 56, "failed": 0 },
  "downloads": "https://data.openindex.co.uk/s/2026.10.4/downloads/index.json",
  … 2 more fields
}

Errors: 429, 503. What they mean

This API as OpenAPI 3.1

GET/v1/openapi.jsonGenerated from the route definitions and this snapshot's catalog: layer ids, families, levels and units are enums.

No parameters.

Example

GEThttps://openindex.co.uk/v1/openapi.json

Errors: 429, 503. What they mean

Errors

Errors use one shape, with words that say what would work instead.
404
{
  "error": {
    "code": "not_found",
    "message": "No area with code E09999999 in this snapshot."
  }
}
400bad_requestThe request is malformed: an unknown parameter, a bad code, or a level or period the layer does not have. The message says what would work.
404not_foundNo such area, layer, postcode or endpoint in this snapshot, or a Northern Ireland postcode.
405method_not_allowedAnything but GET, HEAD or OPTIONS. The API only reads.
429rate_limitedToo many requests from one address. Wait a minute and try again.
503unavailableThe data could not be read just now. Try again shortly. Never cached.

Without a key, each IP address can make about 60 requests a minute. Past that the API answers 429 for a short while; wait a minute and try again. Keys with higher limits will come later. For whole layers, the downloads are faster than paging through the API.

Answers can be cached for an hour (Cache-Control: public, max-age=3600). Each has an ETag: send it back in If-None-Match and an unchanged answer is a bodiless 304. The X-Snapshot header names the snapshot, so you can tell when the data moved on.

CORS is open (Access-Control-Allow-Origin: *), so a web page can call the API directly. Only GET, HEAD and OPTIONS are answered.

The data belongs to its publishers. Most is under the Open Government Licence v3.0, which lets you copy, publish and adapt it, including commercially, as long as you credit the source. Show the credit line of every source in meta.sources next to anything you make with it, and check each licence: a few sources use other open licences.

Figures Open Index works out itself, such as house prices against pay, carry a derived label (“Worked out by Open Index from …”). Keep that label with the figure.

Some things are never served, because their licences don’t allow it: address fields from Price Paid Data and energy certificates, and Northern Ireland (BT) postcodes, which are licensed for internal use only.

/v1 never changes shape. Fields may be added, but none is removed or renamed, so ignore fields you don’t know. A change that breaks that promise would go to /v2, announced on the changelog with /v1 kept running alongside.

Numbers do change: each monthly snapshot brings new periods, and publishers revise recent figures. Every value carries its period and publication date, so you can tell which edition you have.

Every layer as CSV and Parquet, boundaries as GeoJSON and GeoParquet, and the register and postcode lookups as Parquet: 1,234 files, listed in downloads/index.json, with every credit line and licence in LICENCE.txt. Each layer’s page under Sources links its own CSV.