Open data API
6 datasets as JSON or CSV: the statement for every year, every promise card, actors, forecasts and how they scored, contracts and data editions. Free, with no key and no sign-up.
Start at /api/v1, which lists every endpoint with a working example. Add .csv to an address for a spreadsheet.
Try it
curl -s https://ledgergov.uk/api/v1/statement/2025-26curl -s -o promises.csv https://ledgergov.uk/api/v1/promises.csvimport pandas as pd
forecasts = pd.read_csv("https://ledgergov.uk/api/v1/forecasts.csv")
print(forecasts.groupby("result").size())const res = await fetch("https://ledgergov.uk/api/v1/promises");
const { data, licence } = await res.json();
for (const p of data.promises) console.log(p.status_label, p.text);
console.log(licence.attribution);Endpoints
/api/v1/statementEvery year: income, spending, borrowing, debt and GDP, outturn or OBR forecast.JSONCSV/api/v1/statement/{year}One year, line by line: every income and spending line, and borrowing.JSONCSV/api/v1/promisesEvery promise card: the quote, cost range, status and full history.JSONCSV/api/v1/promises/{id}One promise card.JSON/api/v1/actorsPeople, parties and the government, with their cards counted by status.JSONCSV/api/v1/forecastsEvery recorded forecast and, once the outturn is in, how it scored.JSONCSV/api/v1/contractsPublic contracts linked to promise cards, with every change in value or dates.JSONCSV/api/v1/vintagesEvery edition of every source the data holds, newest first.JSONCSV
Every number comes with its source
Each number carries its unit, quality label, source and edition. Here is 2025-26 borrowing as the API gives it:
{
"borrowing": {
"value": 134.286,
"unit": "gbp_bn",
"quality": "sourced",
"source_id": "ons_psf",
"vintage": "PESA-2026 + PSF-2026-09",
"method_note": "Total spending minus receipts (PSF-2026-09). Published borrowing for 2025-26: 134.3bn."
}
}value- The number, in its unit. Money is in £ billion (gbp_bn) unless the unit says otherwise.
unit- gbp_bn, pct_gdp (% of GDP), rate_pct, persons_m, persons_k (thousands), households_m.
quality- sourced: from an official release. approx: worked out from official figures, with the method. modelled: from a model, as a range. training: a working figure not yet checked.
source_id- Which source the number comes from; the response lists every cited source under sources, with its licence.
vintage- The edition the number comes from, for example EFO-2026-03 (the OBR's March 2026 forecast).
method_note- How a number that is not simply copied from a source was made.
low, central, high- A range. Forecasts and model results always have one; a single published number has low = central = high.
Licence and credit
Most figures are Crown copyright under the Open Government Licence v3.0; quotes from Parliament are under the Open Parliament Licence v3.0. Every response carries its licence, and each source lists its own terms.
Please credit the data like this:
Contains public sector information licensed under the Open Government Licence v3.0. Compiled by Public Ledger (https://ledgergov.uk).What else the licence block says
- Every number names its source (sources[].licence gives each one's terms). Most are Crown copyright under the OGL; Bank of England and NATO figures follow their own terms.
- Quotes from Parliament: contains Parliamentary information licensed under the Open Parliament Licence v3.0 (https://www.parliament.uk/site-information/copyright-parliament/open-parliament-licence/). Other quotes are short extracts reproduced for reporting; their rights stay with the speaker and publisher (see each card's quote_licence).
- Notes, summaries and statuses written by Public Ledger are licensed under Creative Commons Attribution 4.0 (CC BY 4.0) (https://creativecommons.org/licenses/by/4.0/): reuse them freely, crediting Public Ledger with a link to the page they come from.
- Official forecasts are the OBR's and the ONS's, labelled by maker; only records with maker "public_ledger" are ours.
Stable, cached, private
- Field names stay the same within
v1. New fields may be added; anything that would break your code comes as a new version, and this one keeps working. - The data changes when the site is updated, after the nightly data job finds a new official release. Responses can be cached for an hour.
- Any website can call it from the browser (open CORS for GET).
- It only serves what the site publishes. Nothing about readers is in it: no follows, no subscriptions, no submissions.
- No key, no account, no tracking.