Data APIdocs

Environment

Every res-9 H3 cell can carry six government open-data signals: noise, air quality, flood risk, deprivation, broadband and crime. Where the population layer answers "who lives here?", this one answers "what is it like to live here?".

Each signal is its own block on the cell, and each block carries its own source naming the publisher and the vintage — the six datasets are refreshed on six different cycles, so there is no single "environment version" to quote.

Where the numbers come from

LayerPublisherNative unitCovers
deprivationMHCLG Indices of Deprivation 2025LSOAEngland
crimedata.police.uk street-levelLSOAEngland, Wales
broadbandOfcom Connected Nationsoutput areaEngland, Wales (see below)
air_qualityDefra PCM background maps1 km gridUK
noiseDefra strategic noise maps (Round 4)50 m raster gridEngland (road + rail: whole land area; air: airport contours)
floodEnvironment Agency Flood Map for Planningzone polygonsEngland

Every source is coarser than a res-9 hexagon (a 1 km air-quality square covers about nine and a half of them; an LSOA covers five, at the median). Values are therefore inherited downward onto cells, never interpolated: neighbouring cells will often carry identical readings, and an apparent edge is a source boundary rather than a measurement. This is also why the layer is served at resolution 9 only — rolling an inherited value up to a 36 km² hexagon would compound the inheritance into something meaningless.

Coverage is uneven, and deliberately so

Air quality is the only layer reaching all four nations — though it, like noise, is written only for inhabited cells, so an empty stretch of moorland has no air block even where Defra models it. Crime excludes Police Scotland, which does not publish to data.police.uk. Deprivation, flood and noise are England-only.

Broadband is the subtle one: Ofcom publishes it for the whole UK, but it reaches cells by output-area code through the census table, and that covers England and Wales only. So a Scottish or Northern Irish cell carries no broadband block at all — the Ofcom figures exist, we just have nothing to join them onto yet. Scotland's census (NRS 2022) is a tagged follow-up, and broadband there lights up when it lands.

Deprivation is the one to watch: Wales, Scotland and Northern Ireland publish WIMD, SIMD and NIMDM — separate indices on separate scales, so decile 3 in one is not decile 3 in another. They are never merged into decile, and the rollup refuses to average across them (see below).

Querying the environment layer

GET /v1/h3/environment takes the same geographic input as the rest of /v1/h3/* — exactly one of:

  • bbox=south,west,north,east — every indexed cell in a viewport.
  • cells=<csv> — a specific set of res-9 cells, e.g. an isochrone footprint. An unindexed cell is simply absent (no 404).
  • division=<id> — every cell in an admin area, using an id from /v1/divisions.

Add layer= to request a subset. It narrows what the server reads and returns, so asking for one signal is cheaper than asking for six:

# Deprivation across a London viewport
curl -H "Authorization: Bearer $POI_API_KEY" \
  "$POI_BASE/v1/h3/environment?country=GB&layer=deprivation&bbox=51.50,-0.15,51.56,-0.05&limit=2000"

# Three layers over an isochrone footprint (POST — cell lists get long)
curl -X POST -H "Authorization: Bearer $POI_API_KEY" -H "Content-Type: application/json" \
  "$POI_BASE/v1/h3/environment?country=GB" \
  -d '{"cells": ["89194ad3493ffff"], "layer": "deprivation,crime,air-quality"}'

A block you filtered out with layer= is absent from the response, not null — otherwise every filtered response would claim we had assessed nothing else.

{
  "h3": "89194ad3493ffff",
  "population": 907,
  "deprivation": {
    "source": "mhclg_iod_2025_eng",
    "nation": "ENG",
    "kind": "imd_rank",
    "area_code": "E01001839",
    "decile": 2,
    "rank": 5767,
    "score": 36.087
  }
}

GET /v1/h3/environment/cell/{h3} returns one cell with every block and its provenance, or a 404 when that cell carries no environment data at all.

Rolling an area up

POST /v1/h3/environment/aggregate takes a cell set or a division_id and returns one summary. Averages are population-weighted, with three exceptions. gigabit_pct_mean and mean_down_mbps_mean are premises-weighted — a premises figure averaged by people would answer a different question. flood_zone3_area_pct_mean is not population-weighted at all: it is a plain mean over cells carrying a flood block, which equal-area res-9 cells make area-weighted. Exposure is reported as counts (population_in_flood_zone3, population_over_55db) rather than averages.

Every average ships with a cells_with_<layer> denominator, because a mean over a third of an area is a different claim from a mean over all of it.

Attribution

Contains public sector information licensed under the Open Government Licence v3.0.