API
A free JSON and CSV API over the same data as this site. No key is needed. Please keep to a few requests per second.
Basics
- Base URL
https://api.ods-tracker.org. All endpoints are GET and allow cross-origin requests. - Unknown parameters, out-of-range limits and invalid dates return
400with a message, so typos never return the wrong rows. Parameters starting with_are ignored (use them to bust caches). - Lists return
items,total,limit,offset,nextOffset(null on the last page) anddataAsOf, the date the data was last synced. Useoffset, notpage. - The change feed pages with
cursor: passnextCursorfrom the previous response until it is null. Cursors stay stable as new changes arrive. - To follow changes, poll
/api/metaand comparelatestEventId; new events have higher ids. Data syncs every 6 hours, so polling more often gains nothing. - Unknown codes return
404. If the database is briefly busy you get503withRetry-After. - CSVs are UTF-8 with a byte-order mark so Excel opens them correctly, and include a
data_as_oforas_atcolumn.
Endpoints
- /api/metaCached 60 s
Data freshness, totals, per-type counts and latestEventId (a watermark for the change feed).
- /api/scopesCached 1 h
Regions, ICBs and Sub-ICB locations with active counts per type.
- /api/orgsCached 5 min
Search and browse every organisation.
- q
- Name, ODS code or postcode (full, sector like "N19 3" or district like "N19"). Up to 100 characters.
- group
- Organisation type key (see Types below). Comma-separate for several.
- role
- ODS primary role code, e.g. RO182.
- scope
- Region, ICB, Sub-ICB location or PCN code. Includes everything within it.
- parent
- Organisations directly linked to this code.
- status
- active (default), inactive or all.
- sort
- relevance (default with q), name or recent.
- limit
- 1–500, default 50.
- offset
- Rows to skip.
- /api/facetsCached 5 min
Counts per type for the same filters as /api/orgs (without group).
- q
- Name, ODS code or postcode (full, sector like "N19 3" or district like "N19"). Up to 100 characters.
- role
- ODS primary role code, e.g. RO182.
- scope
- Region, ICB, Sub-ICB location or PCN code. Includes everything within it.
- parent
- Organisations directly linked to this code.
- status
- active (default), inactive or all.
- /api/suggestCached 5 min
Up to 8 quick matches for a search box.
- q
- Search text.
- group
- Limit to one type.
- /api/orgs/{code}Cached 5 min
One organisation: hierarchy, relationships, successions, roles, its changes and changes that name it, and linked organisations (first page).
- /api/orgs/{code}/childrenCached 5 min
Organisations linked to this one (members, sites, commissioned organisations).
- group
- Type key.
- status
- current (default), past or all.
- limit
- 1–500, default 50.
- offset
- Rows to skip.
- /api/changesCached 5 min
Change feed, newest first on the chosen date basis.
- scope
- Region, ICB, Sub-ICB location or PCN code.
- code
- Changes to one organisation.
- group
- Organisation type key; comma-separate for several.
- kinds
- Comma-separated change kinds (see below).
- field
- Relationship type code. field=RE8&kinds=rel_added,rel_ended gives PCN joins and leaves.
- since, until
- YYYY-MM-DD, inclusive, on the date basis below.
- date
- detected (default): when the change first appeared in ODS. effective: the date ODS says it took effect; changes without one are left out.
- source
- trud (monthly releases, to August 2026) or ord (ODS API, every 6 hours since).
- limit
- 1–500, default 50.
- cursor
- nextCursor from the previous page.
- before
- Legacy id cursor (nextBefore); detected order only.
- /api/changes.rssCached 5 min
The same feed as RSS, 50 items.
- scope
- Region, ICB, Sub-ICB location or PCN code.
- code
- Changes to one organisation.
- group
- Organisation type key; comma-separate for several.
- kinds
- Comma-separated change kinds (see below).
- field
- Relationship type code. field=RE8&kinds=rel_added,rel_ended gives PCN joins and leaves.
- since, until
- YYYY-MM-DD, inclusive, on the date basis below.
- date
- detected (default): when the change first appeared in ODS. effective: the date ODS says it took effect; changes without one are left out.
- source
- trud (monthly releases, to August 2026) or ord (ODS API, every 6 hours since).
- /api/changes/activityCached 1 h
Openings, closures and other changes per month or year. Empty buckets are returned as zeros.
- scope
- Region, ICB, Sub-ICB location or PCN code.
- code
- Changes to one organisation.
- group
- Organisation type key; comma-separate for several.
- kinds
- Comma-separated change kinds (see below).
- field
- Relationship type code. field=RE8&kinds=rel_added,rel_ended gives PCN joins and leaves.
- date
- detected (default): when the change first appeared in ODS. effective: the date ODS says it took effect; changes without one are left out.
- source
- trud (monthly releases, to August 2026) or ord (ODS API, every 6 hours since).
- interval
- month (default) or year.
- months
- Months back including this one, 1–120, default 24.
- years
- Years back including this one, 1–60, default 10 (interval=year).
- /api/practicesCached 5 min; 6 h with asAt
GP practices with PCN, Sub-ICB, ICB and region, today or on a past date.
- scope
- Area code.
- q
- Search text.
- asAt
- YYYY-MM-DD. Practices open that day, with the links that applied then.
- status
- active (default) or all; today only.
- limit
- 1–1000, default 100.
- offset
- Rows to skip.
- /api/pcnsCached 5 min
PCNs with member counts.
- scope
- Area code.
- q
- Search text.
- status
- active (default) or all.
- limit
- 1–2000, default 100.
- offset
- Rows to skip.
- /api/export/orgs.csvCached 5 min
Directory CSV, streamed with no row cap. X-Total-Count gives the row count.
- q
- Name, ODS code or postcode (full, sector like "N19 3" or district like "N19"). Up to 100 characters.
- group
- Organisation type key (see Types below). Comma-separate for several.
- role
- ODS primary role code, e.g. RO182.
- scope
- Region, ICB, Sub-ICB location or PCN code. Includes everything within it.
- parent
- Organisations directly linked to this code.
- status
- active (default), inactive or all.
- /api/export/changes.csvCached 5 min
Change feed CSV, up to 20,000 rows. X-Truncated: true means more matched; narrow the filters.
- scope
- Region, ICB, Sub-ICB location or PCN code.
- code
- Changes to one organisation.
- group
- Organisation type key; comma-separate for several.
- kinds
- Comma-separated change kinds (see below).
- field
- Relationship type code. field=RE8&kinds=rel_added,rel_ended gives PCN joins and leaves.
- since, until
- YYYY-MM-DD, inclusive, on the date basis below.
- date
- detected (default): when the change first appeared in ODS. effective: the date ODS says it took effect; changes without one are left out.
- source
- trud (monthly releases, to August 2026) or ord (ODS API, every 6 hours since).
- /api/export/practices.csvCached 1 h
GP practice mapping CSV, current or as at a date.
- scope
- Area code.
- q
- Search text.
- asAt
- YYYY-MM-DD.
- status
- active or all; today only.
Types
Each organisation gets one type from its ODS primary role. GP practices are those holding the GP practice role (RO76), since their primary role is the generic prescribing cost centre (RO177).
| group | Type | Primary roles |
|---|---|---|
| gp | GP practices | holds RO76 |
| pcn | Primary care networks | RO272 |
| branch | Branch surgeries | RO96 |
| prescribing | Other prescribing settings | RO177, RO88 |
| pharmacy | Pharmacies | RO182, RO181, RO280, RO94 |
| dental | Dental practices | RO110, RO65 |
| optical | Opticians | RO167, RO166 |
| trust | NHS trusts | RO197, RO57, RO107 |
| trust_site | Trust sites | RO198, RO108, RO173 |
| independent | Independent providers | RO172, RO176, RO150 |
| social_care | Social care | RO104, RO101 |
| commissioner | Commissioners | RO98, RO261, RO209, RO210, RO99, RO212, RO213, RO214, RO216, RO217, RO185 |
| local_authority | Local authorities | RO141, RO222, RO119, RO122, RO123 |
| school | Schools and education | RO221, RO288, RO289, RO117 |
| justice | Justice and custody | RO175, RO228, RO230, RO231, RO232, RO233, RO234, RO235, RO236 |
| devolved | Wales, Scotland and NI | RO227, RO315, RO148, RO142, RO144, RO149, RO190, RO155, RO153, RO154, RO322, RO328, RO200 |
| legacy | Legacy NHS bodies | RO179, RO180, RO171, RO111, RO114, RO109, RO132, RO136, RO106 |
| other | Other organisations | anything else |
Change kinds
- created
- Opened
- removed
- Removed
- name
- Renamed
- status
- Status
- closed
- Closed
- reopened
- Reopened
- dates
- Dates
- record_class
- Record class
- address
- Address
- contact
- Contact
- primary_role
- Primary role
- role_added
- Role added
- role_ended
- Role ended
- role_changed
- Role changed
- role_removed
- Role removed
- rel_added
- Joined
- rel_ended
- Left
- rel_changed
- Relationship
- rel_removed
- Relationship removed
- succ_added
- Succession
- succ_removed
- Succession removed
Relationship types (field)
- RE2
- Part of
- RE3
- Directed by
- RE4
- Commissioned by
- RE5
- In the geography of
- RE6
- Operated by
- RE8
- Partner of (practice to PCN)
- RE9
- Nominated payee for
- RE11
- Constituent of
Succession changes use Predecessor or Successor as the field.
Dates and history
- History starts with the June 2018 TRUD release. Changes up to August 2026 are dated to the monthly release that first showed them, so a reorganisation such as April 2020 appears as one spike.
- From September 2026 the ODS API is checked every 6 hours, so detected dates are within hours of ODS publishing.
effectiveDateis the date ODS records for the change (a relationship start or end, an organisation's open or close). It can be earlier than detection when ODS back-dates a record.