# UK NHS Provider Reference Records — NHS ODS (`nexgensignal/uk-nhs-provider-reference-records`) Actor

Per-record register of NHS-connected organisations/sites (ODS code, status, role) from NHS England ODS, by role. Keyless, OGL v3, organisation grain only, no person data.

- **URL**: https://apify.com/nexgensignal/uk-nhs-provider-reference-records.md
- **Developed by:** [NexGen Signal](https://apify.com/nexgensignal) (community)
- **Categories:** Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $33.50 / 1,000 nhs organisation records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## UK NHS Provider Reference Records — NHS ODS

**Keyless. Pay per record. The official register of incorporated NHS-connected organisations and sites — ODS code, status, role, change date.**

This actor turns the **NHS England Organisation Data Service (ODS) organisation register** into clean, per-record data — the official register of NHS-connected organisations and sites in the UK, at organisation grain. Each run reads the keyless NHS ODS ORD API (directory.spineservices.nhs.uk) and delivers one row per organisation, structured for reference-data, master-data, and healthcare-organisation analysis, reusable with acknowledgement of the source, with no personal data of any kind.

### What this is, in one paragraph

The NHS England Organisation Data Service (ODS) maintains the authoritative register of organisations connected to NHS systems — trusts and their sites, pharmacies, dental practices, commissioning bodies, and more — each with a unique ODS code. This actor reads the keyless ODS ORD API and delivers one record per ORGANISATION for the role you select: the ODS code, organisation name, status, record class, primary role (id + description), post code, last-change date, and the ODS org link. It is the ORGANISATION register ONLY — a reference/master-data source about incorporated bodies and sites, never a directory of people.

### Who buys this and for what job

- **Master-data and reference-data teams resolving NHS organisations to their ODS codes**
- **Healthcare-analytics teams mapping the NHS organisation landscape by role and status**
- **Integration engineers who need a clean, keyless ODS organisation feed**
- **Data engineers** who want the NHS ODS organisation table as clean rows from a keyless source.

### Open Government Licence v3.0 — reuse with attribution

One licence rider travels on every record. This is public sector information from the **NHS England Organisation Data Service (ODS)**, licensed under the **Open Government Licence v3.0**: you are free to copy, publish, distribute, adapt, and **exploit it commercially and non-commercially**, provided you acknowledge the source with the required attribution. These are reported organisation-register facts as published — not an endorsement or a clinical/quality verdict about any organisation.

### Organisation grain — no person data, by design

The unit of every record is an incorporated organisation or site — a body, never a person. This actor reads ONLY the ODS list endpoint's organisation fields; the single-organisation detail endpoint that carries contact details is NEVER called. No practitioner, contact, email, phone, or named-individual field is read or emitted — the org/person separation is structural, not a filter. A person-key guard runs on every record as a backstop. This is the org register; it is never provider-people.

### Pricing

| Event | Free plan | Bronze | Silver | Gold / Platinum / Diamond |
|-------|-----------|--------|--------|---------------------------|
| `nhs_org_record` | $0.05 | $0.045 | $0.04 | $0.0335 |

Delivered before charged. Blocked runs and empty results cost nothing.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `primaryRoleId` | string | RO198 | **Required.** ODS primary role code to partition the register (e.g. RO198 = NHS TRUST SITE, RO182 = PHARMACY, RO110 = GENERAL DENTAL PRACTICE). |
| `status` | string | Active | Organisation status: Active or Inactive. |
| `maxRecords` | integer | 500 | Ceiling on records delivered and billed. |

### Output

One JSON object per organisation. Real example (values as reported):

```json
{
  "record_id": "RTG",
  "ods_code": "RTG",
  "org_name": "DERBY TEACHING HOSPITALS NHS FOUNDATION TRUST",
  "status": "Active",
  "record_class": "RC1",
  "primary_role_id": "RO198",
  "primary_role_description": "NHS TRUST SITE",
  "post_code": "DE22 3NE",
  "last_change_date": "2021-03-01",
  "org_link": "https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations/RTG",
  "source": "NHS England Organisation Data Service (ODS) \u2014 organisation register",
  "source_url": "https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations",
  "observed_at": "2026-08-25T00:00:00Z"
}
```

An unbilled `RUN_RECEIPT` records the door check, the filters, rows seen and delivered, and whether charged equals delivered.

### Field reference

Each record is one organisation. Identity: `record_id` (= ODS code), `ods_code`, and `org_name`. Register facts: `status`, `record_class`, `primary_role_id`, `primary_role_description`, `post_code`, `last_change_date`, and `org_link`. Provenance travels on every record: `source`, `source_url`, `licence`, `attribution`, `disclaimer`, and `observed_at`.

### How a run works

A run first re-reads the source host's robots posture from your runtime and stops at the door if that ever changes. It pages the NHS ODS organisation source, and flattens each row to one record — carrying every value and label **verbatim**, never anything person-shaped — delivered **before** it is charged, so a blocked or empty run costs you nothing. The actor stops at your `maxRecords` ceiling and records `charge_equals_delivered` in the receipt.

### Coverage and scope

The ODS register holds hundreds of thousands of organisations across all roles (over 217,000 active). Because it is large, this actor **requires a `primaryRoleId` partition** — every run pulls one role (e.g. RO198 = NHS TRUST SITE, ~38k; RO182 = PHARMACY, ~11k), optionally filtered by `status`, up to your `maxRecords` ceiling. Pull one role, or sweep roles to build the full register.

### Working with the data

The register is master data, and the fields make it joinable. Because every record carries the `ods_code` and `primary_role_description`, an analyst can resolve any NHS organisation to its canonical code, filter a role to Active bodies, and track register changes via `last_change_date`. The `record_class` separates incorporated organisations (RC1) from sites (RC2), so the organisational hierarchy stays legible.

### Identifiers and joins

Every record carries the `ods_code` — the UK's canonical identifier for NHS-connected organisations — so this feed keys directly into any dataset that references ODS codes (prescribing, activity, commissioning), acting as the reference/master-data spine.

### An organisation register, never a people directory

The ODS API exposes two very different things: an ORGANISATION list (codes, names, roles, status) and a per-organisation DETAIL record that can include contact points. This actor is built on the organisation list ONLY, and never calls the detail endpoint, so no contact or named-individual data can enter the output. That separation is deliberate and structural: the product is the incorporated-organisation register — the ODS spine other datasets join to — and it is never a directory of practitioners or people.

### Cost guidance

One `nhs_org_record` per delivered row: cost = rows delivered × your plan's per-record price. 1,000 rows is **$50** (Free) / **$33.50** (Gold).

### Honest limitations

- **As reported.** Values, labels, and flags are as filed; this actor reformats, it does not audit or recompute.
- **A label, not a verdict.** These are reported register facts, not an endorsement or a clinical/quality verdict about any organisation.
- **Acknowledge the source.** The acknowledgement travels on every record.
- **No person data** of any kind.

### Differentiation

This is a **net-new** category for the NexGenData fleet. It is distinct from any provider-people or practitioner directory — this cell is the ODS ORGANISATION register (incorporated bodies and sites), delivered at organisation grain with no person data by structural design. Its specific job is the **NHS ODS organisation register, by role**.

### The NexGen Signal family

Part of the NexGen Signal family of pay-per-record data products:

- [EU Plant Desulphurisation Records — EEA IED](https://apify.com/nexgensignal/eu-plant-desulphurisation-records)
- [EU Industrial Secondary Activity Records — EEA IED](https://apify.com/nexgensignal/eu-industrial-secondary-activity-records)
- [UK Company Status Records](https://apify.com/nexgensignal/uk-company-status-records)
- [Higher Education Institution Records](https://apify.com/nexgensignal/higher-education-institution-records)
- [US Hospital Ownership Records](https://apify.com/nexgensignal/us-hospital-ownership-records)

*Source: NHS England Organisation Data Service (ODS), ORD API (directory.spineservices.nhs.uk). Public sector information licensed under the Open Government Licence v3.0; attribution required. Organisation grain only; the detail endpoint with contacts is never called; no practitioner/contact/named-individual field selected or emitted. No natural-person data of any kind. Values and labels as filed, not a verdict.*

# Actor input Schema

## `primaryRoleId` (type: `string`):

REQUIRED ODS primary role code to partition the register (e.g. RO198 = NHS TRUST SITE, RO182 = PHARMACY, RO110 = GENERAL DENTAL PRACTICE).

## `status` (type: `string`):

Organisation status: Active or Inactive.

## `maxRecords` (type: `integer`):

Maximum records delivered and billed.

## Actor input object example

```json
{
  "primaryRoleId": "RO198",
  "status": "Active",
  "maxRecords": 500
}
```

# Actor output Schema

## `results` (type: `string`):

Delivered records.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "primaryRoleId": "RO198",
    "status": "Active",
    "maxRecords": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgensignal/uk-nhs-provider-reference-records").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "primaryRoleId": "RO198",
    "status": "Active",
    "maxRecords": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("nexgensignal/uk-nhs-provider-reference-records").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "primaryRoleId": "RO198",
  "status": "Active",
  "maxRecords": 500
}' |
apify call nexgensignal/uk-nhs-provider-reference-records --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgensignal/uk-nhs-provider-reference-records"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bKGCtN3oX9aJEt40t/builds/CbZDSAyBqfj8pk5r6/openapi.json
