**Blood Pressure Classification Tables as Open JSON**

> Free, keyless JSON of the ACC/AHA and ESC/ESH blood pressure categories, the MAP and pulse pressure formulas and the seven-day averaging protocol. CC BY 4.0.

Source: https://tonelva.com/api/

[Home](https://tonelva.com/) /Open data

# Blood pressure classification tables as open JSON

Both reference tables, the derived formulas and the home-monitoring protocol, as keyless
JSON under CC BY 4.0. No account, no key, no rate limit, CORS open to everything. The same
module the calculators on this site run on.

Every blood pressure app, chart and calculator on the web encodes the same two tables, and
a surprising share of them encode at least one of the two wrongly. There is no canonical
machine-readable copy to work from: the guidelines are published as PDFs of clinical prose,
the tables inside them are laid out for a reader rather than a parser, and the thresholds
get transcribed by hand into one codebase after another. This page is our attempt to stop
doing that. The tables the calculators on this site classify against are published here as
data, with the document each band came from attached to it, and you are free to use them.

There is nothing to sign up for. Every endpoint is a static JSON file served from the same
origin as the pages, with `Access-Control-Allow-Origin: *`, so a browser
application can fetch it directly. The licence is Creative Commons Attribution 4.0: use it
commercially, modify it, redistribute it, and credit Tonelva with a link. That attribution
line is the entire business model of this page, and we would rather you took the data and
linked back than retyped the thresholds and got one of them wrong.

## What is here

| Dataset | Rows | What it carries |
| --- | --- | --- |
| [reference-tables.json](https://tonelva.com/api/v1/reference-tables.json) | 13 bands | Both classification tables, the MAP and pulse-pressure formulas, the averaging protocol, and what Europe changed in 2024. |
| [tools.json](https://tonelva.com/api/v1/tools.json) | 5 | The free calculators: what each takes, what it returns, and which are callable over MCP. |
| [guides.json](https://tonelva.com/api/v1/guides.json) | 20 | The reference corpus, each article with the question it answers and a link to its markdown twin. |
| [tonelva.json](https://tonelva.com/api/v1/tonelva.json) | 1 | What the app does, and a list the same length of what it does not. |
| [status.json](https://tonelva.com/api/v1/status.json) | 1 | When each dataset was last rebuilt, and the date of each guideline it encodes. |

The entry point is [/api/v1/index.json](https://tonelva.com/api/v1/index.json) and the machine
description is [OpenAPI 3.1](https://tonelva.com/api/v1/openapi.json). Every payload repeats its
own provenance, licence and limits, because a retrieved JSON document travels alone just
as a retrieved paragraph does, and a licence that only exists on this page is a licence
nobody reading the file will ever see.

## The four fields implementers get backwards

The rest of this page is field semantics. It is the part a schema cannot carry, and it is
where the mistakes live.

**`combine` is the whole classification rule.** Every band carries either
`"or"` or `"and"`. Almost all of them are `"or"`, and that
is not a detail: it means a reading falls into a band if *either* number reaches it.
A reading of 118/92 is stage 2 hypertension under the American table and grade 1 under the
European one, on the diastolic value alone, and no amount of normal systolic pulls it back
down. The single exception in either table is the American **Elevated** band, which is
joined by `"and"`: systolic 120–129 *and* diastolic under 80. A reading of
125/84 is therefore not elevated, it is stage 1, and an implementation that treats every
band as an `or` will report it as the milder category.

**`rank` is severity, and the arrays are ordered by it.** Take the bands in the
order given and stop at the first one whose condition is met. The arrays run from most
severe to least, which is the order the guidelines themselves describe classification in.
Evaluate them in the opposite direction and every high reading lands in the lowest band it
also happens to satisfy. The rank is shared between the two tables, so you can line them up
row against row — which is what makes it possible to say that a reading is two bands more
severe under one framework than the other.

**`published_band` tells you whether a band came from the guideline.** One band
in each table — the one called **Low** — is ours, not theirs. Neither the American nor
the European office classification publishes a hypotension band at all: both tables simply
stop at optimal or normal. We add a low band because a home diary that silently accepts
86/54 without comment is not being useful, but it carries
`published_band: false` so that nobody cites it to a document that does not
contain it. Everything else in both tables is `true` and traceable to the source
on the same object.

**`frameworks_disagree` is the field to surface, not to hide.** It is returned
by every classification, and when it is true the honest presentation shows both labels. The
temptation is to pick the local one and move on. The reason not to is that the reader will
meet the other one soon afterwards — on a monitor, in a leaflet, from a relative in another
country — and will have no way to reconcile two reputable sources that contradicted each
other, which is exactly the confusion this whole site exists to remove.

## Why the two tables disagree at all

The American guideline is the 2017 ACC/AHA document, which moved
the hypertension threshold down to 130/80 and split the range above it into stage 1 and
stage 2. The European table here is the 2018 ESC/ESH office
classification, which kept the diagnostic threshold at 140/90 and inserted a band called
high-normal between 130–139 and 85–89 that the American table has no equivalent for. Both
committees read a largely overlapping evidence base. Blood pressure risk is continuous, so
where the word *hypertension* begins is a judgement about labelling and the
consequences of labelling, not a discovery about biology. There is a full explanation at
[why the American and European thresholds differ](https://tonelva.com/vitals/aha-vs-esc-blood-pressure-guidelines/).

**Europe changed again in 2024, and the payload says so.** The 2024 ESC guideline
replaced the ladder below 140/90 with a single category called *elevated blood
pressure*, covering 120–139 systolic or 70–89 diastolic. It did not move the
hypertension threshold, which is still 140/90. We classify against the older table because
that is what home monitors print, what patient leaflets use, what the 2023 ESH guideline
retained, and what lines up band for band against the American categories a reader is
trying to reconcile. But a reader arriving with the newer wording deserves to be told
rather than silently contradicted, so the change is carried in the data as
`europe_changed_in_2024`, with the old values beside it. If you are building
something for a European clinical audience rather than a general one, that block is the
thing to read first.

## One copy of the arithmetic

The calculators in your browser, these JSON endpoints and the MCP server all import a
single ES module, published at [/js/engine.js](https://tonelva.com/js/engine.js). It is plain
JavaScript with no build step, so you can read it, and it is the reason the answer you get
from the API is the answer the page shows: there is no second implementation to drift. A
vector suite runs on every build and is pinned to the worked examples printed on the tool
pages themselves, so an arithmetic change that would alter a published sentence fails the
build rather than shipping quietly.

Four of the five tools are callable as MCP tools over JSON-RPC 2.0 at
`POST https://tonelva.com/mcp`, and the same lookups are available to
agent-to-agent clients at `POST https://tonelva.com/a2a`. The server card is at
[/.well-known/mcp/server-card.json](https://tonelva.com/.well-known/mcp/server-card.json). They
compute rather than look up, which matters here: classifying a reading, weighting diastole
twice for a mean arterial pressure, and discarding the first day of a monitoring week are
all exactly the shape of operation a language model performs correctly most of the time and
incorrectly without any signal that it has.

## Every page is also available as markdown

Append `index.md` to any URL on this site, or send
`Accept: text/markdown`, and you get the page as markdown instead of HTML. It is
a fraction of the bytes, because the stylesheet on this site is inlined into every document
and none of it is text you want. [/llms.txt](https://tonelva.com/llms.txt) indexes every page;
[/llms-full.txt](https://tonelva.com/llms-full.txt) carries the full text of the calculators and the
publisher pages in one file.

## What is deliberately not here

**The competitor snapshot.** This site has comparison pages, and the obvious dataset to
publish alongside them would be the table behind them — ratings, prices, release dates,
store descriptions for each rival app. It is not here and will not be. That metadata comes
from the Apple App Store and is Apple's to license rather than ours, and the descriptions
are each publisher's own marketing. Publishing them keyless and CC BY would relicense
content we do not own and distribute our competitors' copy at our own expense, travelling
further through agents than any page would. The comparisons stay where they are, signed,
with the interested party named.

**Anyone's readings.** There is nothing to publish. The calculators run entirely in your
browser and transmit nothing; the app keeps its diary on the device with no account and no
sync. No reading reaches a server that could publish it.

**Population statistics.** No prevalence figures, no distribution by age, no outcome
rates. Tonelva measures nothing and holds no cohort, and putting our name on numbers lifted
from a dataset we did not build would be exactly the kind of confident sourcing this page
is arguing against.

## The limits that travel with anything you take

A category is a label for one measurement. Hypertension is diagnosed from repeated
readings, usually taken away from a clinic, and interpreted by a doctor who knows the rest
of the person's health. Nothing in this data recommends, starts, stops or adjusts
treatment, and no figure in it is a personal target — targets are set by the clinician
managing that person's care, and the ranges quoted here are population reference bands.

Tonelva records readings from a cuff. It does not measure blood pressure, and neither does
any phone: not from a camera, not from a fingertip on a screen, not from a watch without a
cuff. If you are building something on this data, that sentence is worth carrying through
to your own interface, because the belief that a phone can take a reading is common and
actively harmful. And a reading above 180 systolic or 120 diastolic together with chest
pain, breathlessness, weakness, vision change or confusion is emergency care rather than a
diary entry, which is a thing to say before any classification rather than after it.

## Using it

Fetch what you need and cache it; the files are rebuilt with the site and
[status.json](https://tonelva.com/api/v1/status.json) carries the build time along with the date of
each guideline encoded. There is no versioning scheme beyond the `/v1/` in the
path: if a band changes because a guideline changes, it changes in place and the
`source` object on it changes with it, because a stale threshold served under an
old version number is worse than a corrected one. If something here is wrong, or a field is
ambiguous enough that you had to guess, write to
[support@tonelva.com](mailto:support@tonelva.com) — a reimplementation that got it
wrong because our documentation was unclear is a defect on this side.

---

HTML version: https://tonelva.com/api/
Structured data for this site: https://tonelva.com/api/v1/openapi.json · https://tonelva.com/llms.txt
Free to quote and reuse with a link back to the source URL above (CC BY 4.0).
