Guide
Keep a copy in sync
Record the release
Record which Atlas release you're loading. Its
releaseIdidentifies exactly the data you have.curl "https://api.ukdataatlas.com/v1/atlas-release"Example response200 { "apiVersion": "v1", "atlasRelease": "sha256:5c4aa4529cbfbd5e4c844c55cddba1ef04a7bf76f3eaa085a357fff401af6d0c", "data": { "schemaVersion": 1, "releaseId": "sha256:5c4aa4529cbfbd5e4c844c55cddba1ef04a7bf76f3eaa085a357fff401af6d0c", "artifacts": [ { "id": "boundary-registry", "path": "boundary-releases.json", "contentHash": "sha256:6516841abb2149d864316bde871efceafbedeb0e6b681bbab588def86e06e0f2" } ], "resources": { "datasets": { "air-quality": "sha256:298235aea52aaa0bfdc40b99b8f4d069f4cc8f149d0c7618100d4798ba17391f", "brexit": "sha256:0ec6e449c5f0b597e464066c65411e507fe5bbde99fa164d0d62babed779337c", "brexit-constituency": "sha256:b9f2a2369e2ebaa243155e16f74fe20662a67972774a7a64c9069fb8d729a931" }, "measures": { "air-quality-grid-cells": "sha256:22b496a24ae5ea228a90ae28834e615610aae3fcab6de60fbd406dde42638b5e", "broadband-full-fibre-availability": "sha256:75c5f4ab3ad7d5bf3a6927c0e89c0f25ba2ccca741558310517186e4e1d5efb3", "broadband-gigabit-availability": "sha256:42403d33b12abf4c70ef7d6ad12141091438e24f23b951ca0e01964ef0937a0f" }, "boundaryReleases": { "combinedAuthority/2025-12-en-bgc": "sha256:562e6613e32c2ab3c9a6fadda26787fe6334e45a90c569743f71b4dc92fad360", "communitySafetyPartnership/2023-12-ew-bgc": "sha256:bfb385ac91c582e9040ba33234a3e7cfb0f7396f12c3a7429e9fcadf205320b9", "constituency/2015-12-gb-bgc": "sha256:9b84fcdd92aeaf87c9b9a87db04297a13399f683e0eca3cf3979270cab5b9f0a" }, "areaIdentities": { "combinedAuthority/2025-12-en-bgc": "sha256:7d92965736e95d7e8a9bb0ec8cfdd1bf522d0958259ca8edc88338b0c2551446", "communitySafetyPartnership/2023-12-ew-bgc": "sha256:252592fe688000dffd235746bd7cb327604ff28a23def38577e3e956e3ef0d12", "constituency/2015-12-gb-bgc": "sha256:c5b97468289a1adb7c4415faa751ac06475931585b2e4f5871f201a1364cd9e3" }, "geometrySources": { "combinedAuthority/2025-12-en-bgc": "sha256:40afe13d45f67a5a67dbf1c8a71e3a0c4d6da175bff3e85ce112d72d49c294e5", "communitySafetyPartnership/2023-12-ew-bgc": "sha256:8c9388ddb1be325fde9e6cad29d00e4d86d1623707e2b784b2af3bf98ee198da", "constituency/2015-12-gb-bgc": "sha256:7ebadb3a6199a789146d4d3919d5d2f26e9417497dc8c77e9fea81757221f936" }, "crosswalks": { "constituency-2010-to-2024-official-lookup-v2": "sha256:cefd706b04545b3a02b75b4d7a88f8240019174412a9444490b09055ece0cc82", "constituency-2024-07-uk-bgc-to-local-authority-2024-05-uk-bgc-area-overlap": "sha256:e989fe1713b8239eb60455db37c25a72915e16950591c46256b815b4fbc3aca7", "local-authority-2025-12-uk-bgc-to-region-2025-12-en-bgc-area-overlap": "sha256:b35db31c062deb9b17061450fdedc1a4f8007ebb75b8e6b6aaf0e7a56a8753a9" }, "validationExceptions": { "crosswalks/constituency-2010-to-2024-official-lookup-v2 source-names-consistent": "sha256:9a3865df66e5a039378327900eddbeeba44c8b2dc782605aed352acbbb36ba42", "exports/house-price-median-observations records-resolve": "sha256:54165bd7f3d2e901e64f5f33f9ae949f51eacb5e4a2c1f3c1905d594fa0df487" }, "namedLocations": { "aberdeen": "sha256:47f33490b901a4fc7f27e09b784369b9a23faa95a8a4e347fbac2d78a8eac3a5", "aberystwyth": "sha256:d04c975edf3c45d63d521e6f2084fc4fcbadff11d758ac95d0af55d2b9088016", "armagh-down-and-newry": "sha256:89a0303432937e9c13bdaa9000f7ec61e486f5e1f21aefa86ef1ba59a97d0ae7" }, "exports": { "air-quality-grid-cells-observations": "sha256:28c7d88c02cc1e686e1a5a74a39daf2b009c89df48f83b233138858857923603", "broadband-full-fibre-availability-observations": "sha256:befe13a38c77c602110ffd824fed7abd96b3157b989b3fb47c5e1b7cf2e05a9b", "broadband-gigabit-availability-observations": "sha256:0ceec568db3d3e9288aa542d5f5a405236ea7f30a2c5a1a4a40f4081be0b2eae" }, "lookups": { "areas-combinedAuthority-2025-12-en-bgc": "sha256:c16596703c7eafca73c9ed4fcf90e5c89f67e5591ba2ac044a2f27de547da50c", "areas-communitySafetyPartnership-2023-12-ew-bgc": "sha256:7ebc8ad95e6e2f99639050ef6e6f2b0c5deeaac929b2242957d8d720c3564bb4", "areas-constituency-2015-12-gb-bgc": "sha256:5f67da9c8ca631f5f59ebad11d33a13dc63b5eebb349a494d3bc9071fb9c9517" } } }, "meta": { "nextCursor": null } }Download a dataset
List the downloads, pick one, and fetch it as a single file. Each entry gives its
id,recordCountandcontentHash.curl "https://api.ukdataatlas.com/v1/exports"Example response200 { "apiVersion": "v1", "atlasRelease": "sha256:dfa67bf7df94ff5b655985b008aec8f28e235746fe0a15f4ca4853d172621eff", "data": { "schemaVersion": 1, "dataCatalogHash": "sha256:708f04397ddcc766ca53f31c43fa806b3e77d9698502932c7dcc19816e200ec4", "fields": { "areaCode": "The official code of the area in the served source partition.", "value": "The numeric value, in the measure's unit.", "status": "`observed` for a value the publisher reported, `derived` for one this API computed." }, "datasets": { "land-area": { "publisher": "Office for National Statistics", "sourceUrl": "https://geoportal.statistics.gov.uk/datasets/standard-area-measurements-for-the-local-authority-districts-december-2024-in-the-uk", "licence": { "name": "Open Government Licence v3.0", "url": "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/" }, "inputs": [ { "path": "geography/land-area/sam-lad-2024-12.csv", "sha256": "a507a632fd3dc616f88e1be9a3af9c22ec26f55d35f0969233abd358bea8c59e" } ], "href": "/v1/datasets/land-area" } }, "exports": [ { "id": "population-density-observations", "measureId": "population-density", "datasetId": "population-uk", "periods": [ "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024" ], "sourceGeography": { "type": "localAuthority", "boundaryYear": 2023 }, "format": "json", "artifact": "population-density-observations", "contentHash": "sha256:1569578cb3bf9272e9e1e9e9dfe79854c2e792d46d35bb85caa0a51fe440e451", "bytes": 356302, "href": "/v1/exports/population-density-observations", "recordCount": 5054, "recordCountByPeriod": { "2011": 361, "2012": 361, "2013": 361, "2014": 361, "2015": 361, "2016": 361, "2017": 361, "2018": 361, "2019": 361, "2020": 361, "2021": 361, "2022": 361, "2023": 361, "2024": 361 }, "schema": { "version": 1, "layout": "periods", "recordType": "numeric", "fields": [ { "name": "areaCode", "type": "string", "required": true }, { "name": "value", "type": "number", "required": true }, { "name": "status", "type": "string", "required": true } ] }, "provenance": { "measure": "/v1/measures/population-density", "datasets": [ { "id": "population-uk", "role": "source" }, { "id": "land-area", "role": "derived-from" } ] } } ], "note": "Each export is the immutable publisher-observation JSON artifact used by the API. Reviewed served corrections, if any, are recorded separately and retain the publisher code on the affected record." }, "meta": { "nextCursor": null } }curl "https://api.ukdataatlas.com/v1/exports/total-jobs-observations"Example response200 { "apiVersion": "v1", "atlasRelease": "sha256:5c4aa4529cbfbd5e4c844c55cddba1ef04a7bf76f3eaa085a357fff401af6d0c", "data": { "id": "total-jobs-observations", "measureId": "total-jobs", "datasetId": "jobs" }, "meta": { "nextCursor": null } }Verify it
Check the file's
contentHashmatches the one in the list. To be certain, recalculate it: it's the SHA-256 of the file without its owncontentHashfield.import { createHash } from "node:crypto"; const response = await fetch("https://api.ukdataatlas.com/v1/exports/total-jobs-observations"); const { contentHash, ...content } = await response.json(); const recomputed = "sha256:" + createHash("sha256") .update(JSON.stringify(content)) .digest("hex"); if (recomputed !== contentHash) { throw new Error("The download doesn't match its published hash"); }Check for changes cheaply
On your next scheduled run, send the download's
ETagback inIf-None-Match. If nothing changed you get a304with no body. Caching has examples.Fetch only what changed
The API only serves the current release, so keep the manifest from your last run. Its
resourcesgive a fingerprint for every dataset, measure, crosswalk, export and lookup, which changes exactly when that resource does. Compare the kept fingerprints with the current ones, fetch what was added or changed, and drop what was removed.import { readFile, writeFile } from "node:fs/promises"; // The manifest you kept from your last run, and the current one. const kept = JSON.parse(await readFile("atlas-release.json", "utf8")); const current = (await (await fetch("https://api.ukdataatlas.com/v1/atlas-release")).json()).data; const before = kept.resources.exports; const after = current.resources.exports; const fetchNow = Object.keys(after).filter((id) => before[id] !== after[id]); const drop = Object.keys(before).filter((id) => !(id in after)); // Fetch fetchNow, delete drop, then keep the current manifest. await writeFile("atlas-release.json", JSON.stringify(current));Add the lookup tables
Finally, take the reference tables you'll join against, such as area codes and names, as CSV or NDJSON.
curl "https://api.ukdataatlas.com/v1/lookups"Example response200 { "apiVersion": "v1", "atlasRelease": "sha256:dfa67bf7df94ff5b655985b008aec8f28e235746fe0a15f4ca4853d172621eff", "data": { "schemaVersion": 1, "contentHash": "sha256:67f2e1de51b89868fc95bac3156b1f1818b364b4db0977e737be475c9f7b69a3", "lookups": [ { "id": "areas-ward-2024-12-uk-bgc", "kind": "area-identities", "title": "Area identities, ward 2024-12-uk-bgc", "source": { "artifact": "areas/ward/2024-12-uk-bgc.json", "contentHash": "sha256:f82398b92702e504d468d6d9e51fe3bc6ccbb3acea467316e783c427cfb0d360" }, "columns": [ { "name": "geography", "type": "string", "required": true, "description": "The geography the release publishes." }, { "name": "boundaryRelease", "type": "string", "required": true, "description": "The boundary release." }, { "name": "code", "type": "string", "required": true, "description": "The official area code." }, { "name": "name", "type": "string", "required": true, "description": "The area's name in the release." }, { "name": "aliases", "type": "string[]", "required": false, "description": "Other names the release gives the area, such as a Welsh name." } ], "rowCount": 8396, "formats": { "csv": { "contentType": "text/csv; charset=utf-8", "bytes": 392763, "contentHash": "sha256:a1b1055efab8ac2b8c04e89a55a4aad87bba6baeca46e27a7b2f658ee4952ea0", "href": "/v1/lookups/areas-ward-2024-12-uk-bgc?format=csv" }, "ndjson": { "contentType": "application/x-ndjson; charset=utf-8", "bytes": 947293, "contentHash": "sha256:162c1889dfbccbc8a75db81e6c05c5a5972333e6bf3342a015fe3dd5400162e5", "href": "/v1/lookups/areas-ward-2024-12-uk-bgc?format=ndjson" } } } ], "note": "Each lookup is rendered from the published artifact its source names, and its bytes match the hash listed for the format." }, "meta": { "nextCursor": null } }