# NHS UK Jobs Scraper (`parsebird/nhs-uk-jobs-scraper`) Actor

Scrape NHS jobs from jobs.nhs.uk by keyword and location. Extract job title, NHS trust, location, salary band, contract type, working pattern, closing date, reference, and full job description. Export as JSON, CSV, or Excel.

- **URL**: https://apify.com/parsebird/nhs-uk-jobs-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.79 / 1,000 job scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### NHS UK Jobs Scraper

Scrape job vacancies from **[jobs.nhs.uk](https://www.jobs.nhs.uk)** — the official NHS Jobs board — into clean, structured JSON. The NHS UK Jobs Scraper pulls the job title, NHS trust, location, salary band, contract type, working pattern, closing date, reference number, and the full job description for any search, with no login and no NHS Jobs API.

<table><tr>
<td style="border-left:4px solid #005EB8;padding:12px 16px;font-weight:600">
Search NHS Jobs by keyword and location, or paste a filtered NHS Jobs URL, and get a structured record per vacancy — trust, Agenda-for-Change band, contract type, dates, reference, and the full description as HTML and clean text.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
Actor: parsebird/nhs-uk-jobs-scraper (Apify). Scrapes vacancies from jobs.nhs.uk. Call with ApifyClient.
Input JSON fields:
  keyword: string — job title, skill, or reference number, e.g. "nurse", "paramedic"
  location: string — city, town, or postcode, e.g. "London", "Manchester", "NE1"
  results_wanted: int (default 20) — max vacancies; this is the number of billed rows
  max_pages: int (default 5) — safety limit on search pages (10 vacancies per page)
  collectDetails: bool (default true) — visit each job page for the full description and refined fields
  startUrl: string — a jobs.nhs.uk search URL; overrides keyword/location
  proxyConfiguration: { "useApifyProxy": true }
Output: one dataset item per vacancy — title, company, location, salary, contract_type, working_pattern, date_posted, closing_date, reference, url, pay_scheme, employer_website, description_html, description_text, source, source_page, scraped_at.
Example: { "keyword": "nurse", "location": "London", "results_wanted": 50 }
API: https://api.apify.com/v2/acts/parsebird~nhs-uk-jobs-scraper  ·  Token: https://console.apify.com/account/integrations
```

### What does NHS UK Jobs Scraper do?

[NHS Jobs](https://www.jobs.nhs.uk) is where every NHS trust, foundation trust, and NHS partner organisation in England advertises vacancies — tens of thousands live at any time. There is no public NHS Jobs API — this NHS Jobs scraper reads the public search and job-advert pages instead. It extracts:

- 🏥 **Employer** — the NHS trust or hiring organisation, plus its website.
- 💷 **Pay** — the salary range or Agenda-for-Change band, and the pay scheme.
- 📋 **Terms** — contract type (Permanent, Fixed-Term, Bank, Secondment…) and working pattern (Full-time, Part-time, Flexible).
- 📍 **Location** — site, town, and postcode.
- 📅 **Dates** — when the vacancy was posted and when applications close.
- 🔖 **Reference** — the NHS job reference number and the direct advert URL.
- 📄 **Description** — the full job description as structured HTML and clean plain text (with `collectDetails`).

Common uses: NHS recruitment-market research, building a healthcare jobs board, workforce and pay-band analysis, and monitoring hiring at specific trusts.

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| keyword | string | No | — | Job title, skill, or reference number. |
| location | string | No | — | City, town, or postcode. |
| results\_wanted | integer | No | 20 | Maximum vacancies to collect (billed rows). |
| max\_pages | integer | No | 5 | Safety limit on search pages (10 vacancies per page). |
| collectDetails | boolean | No | true | Visit each job page for the full description. Turn off for a fast listing-only run. |
| startUrl | string | No | — | A jobs.nhs.uk search URL. Overrides keyword and location. |
| proxyConfiguration | object | No | Apify Proxy | Proxy settings. Residential is recommended for large runs. |

#### Example inputs

Nursing jobs in London:

```json
{ "keyword": "nurse", "location": "London", "results_wanted": 50 }
```

Fast listing-only run:

```json
{ "keyword": "administrator", "collectDetails": false, "results_wanted": 100 }
```

Start from a filtered NHS Jobs URL:

```json
{
  "startUrl": "https://www.jobs.nhs.uk/candidate/search/results?keyword=paramedic&location=Manchester",
  "results_wanted": 20
}
```

### What data can you extract from NHS Jobs?

| Field | Description |
|-------|-------------|
| title | Official job title |
| company | NHS trust or hiring organisation |
| location | Site, town, and postcode |
| salary | Salary range or Agenda-for-Change band |
| pay\_scheme | Pay scheme (Agenda for change, Other…) |
| contract\_type | Permanent, Fixed-Term, Bank, Secondment, Locum… |
| working\_pattern | Full-time, Part-time, Flexible… |
| date\_posted / closing\_date | Publication and application-deadline dates |
| reference | NHS job reference number |
| url | Direct link to the job advert |
| employer\_website | The hiring organisation's website |
| description\_html / description\_text | Full job description (with `collectDetails`) |
| source / source\_page / scraped\_at | Source label, search page, and collection timestamp |

### Output example

```json
{
  "title": "Registered Nurse - Emergency Department",
  "company": "Manchester University NHS Foundation Trust",
  "location": "Manchester Royal Infirmary, Manchester, M13 9WL",
  "salary": "£28,407 to £34,581 a year",
  "pay_scheme": "Agenda for change",
  "contract_type": "Permanent",
  "working_pattern": "Full-time",
  "date_posted": "07 May 2026",
  "closing_date": "04 June 2026",
  "reference": "123-ABC-456",
  "url": "https://www.jobs.nhs.uk/candidate/jobadvert/123-ABC-456",
  "description_text": "Job summary\n\nWe are looking for motivated Registered Nurses...",
  "description_html": "<h2>Job summary</h2>\n<p>We are looking for motivated Registered Nurses...</p>",
  "source": "jobs.nhs.uk",
  "source_page": 1,
  "scraped_at": "2026-09-02T12:00:00.000Z"
}
```

Download the dataset as **JSON, CSV, Excel, HTML, or XML** from the Storage tab or the [Apify API](https://docs.apify.com/api/v2).

### Use cases

- **Healthcare jobs board** — feed an aggregator or alert service with live NHS vacancies.
- **Pay-band analysis** — track Agenda-for-Change bands by role, trust, and region.
- **Recruitment-market research** — measure hiring volume and closing-window pressure across the NHS.
- **Trust monitoring** — start from a trust-filtered URL and collect everything it posts.
- **LLM training data** — a large corpus of structured public-sector job descriptions.

### How it works

1. **Search** — the scraper requests the NHS Jobs results page (10 vacancies per page) with your `keyword` and `location`, and reads each result card.
2. **Detail** — when `collectDetails` is on, each job advert page is fetched for the full description and refined employer, salary, and location fields.
3. **Resilience** — requests are paced and the HTTP session rotates on any block, so large runs stay complete.
4. Rows stream to the dataset and stop at `results_wanted`.

### How much does it cost to scrape NHS Jobs?

This actor is **pay per result** — charged once per vacancy saved.

| Plan | Price per 1,000 vacancies |
|------|---------------------------|
| Free | **$0.99** |
| Bronze | **$0.89** |
| Silver | **$0.89** |
| Gold | **$0.79** |

A small platform **Actor start** fee also applies per run. `results_wanted` is the exact number of billed rows. Scraping 1,000 vacancies on the Free plan costs about **$0.99**. Apify's monthly free platform usage covers small runs.

### How to scrape NHS Jobs

1. Click **Try for free** and sign in to Apify.
2. Enter a **keyword** and/or **location**.
3. Set **results wanted** (start low, e.g. 20).
4. Optionally turn off **Collect full descriptions** for a fast run.
5. Click **Start**, then watch rows appear in the **Output** tab.
6. Export from **Storage**, or pull results via the API.

#### Run it via API

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("parsebird/nhs-uk-jobs-scraper").call(run_input={
    "keyword": "nurse",
    "location": "London",
    "results_wanted": 50,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], "-", job["company"], "-", job["salary"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('parsebird/nhs-uk-jobs-scraper').call({
    keyword: 'administrator',
    collectDetails: false,
    results_wanted: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Schedule recurring runs, add webhooks, or push results to Google Sheets, Slack, Zapier, and Make with [Apify integrations](https://docs.apify.com/platform/integrations).

### FAQ

**Do I need an NHS Jobs account or API key?**
No. The scraper reads public NHS Jobs pages only. NHS Jobs has no public API — this actor is the alternative.

**How current is the data?**
Live. Each run reads NHS Jobs at that moment. Use Apify's scheduler to keep a dataset fresh.

**What does turning off `collectDetails` change?**
The scraper skips the per-job page, so you get every listing field except `description_html` / `description_text` — much faster and cheaper for large runs.

**Why does a location search sometimes return fewer results than expected?**
NHS Jobs matches the location loosely to a travel-to-work area; a narrow keyword plus a small town can legitimately return only a handful of vacancies.

**Something's not working.**
Open an issue on the **Issues** tab with your input and the run link — we respond quickly.

### Is it legal to scrape NHS Jobs?

NHS Jobs is a UK public-sector website and its vacancy adverts are public information any visitor can see. Scraping publicly available pages is legal in most jurisdictions, and this actor does not access private data or bypass any login. You are responsible for how you use the data — follow NHS Jobs' Terms and Conditions and the UK GDPR when handling any personal data, and consult a lawyer if you are unsure. See Apify's guide on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Related actors

- [Freshersworld Jobs Scraper](https://apify.com/parsebird/freshersworld-jobs-scraper) — India fresher and entry-level jobs.
- [Indeed Jobs Scraper](https://apify.com/parsebird/indeed-jobs-scraper) — job listings from Indeed worldwide.
- [hh.ru Jobs Scraper](https://apify.com/parsebird/hh-ru-jobs-scraper) — vacancies from HeadHunter (Russia).
- [MyCareersFuture Singapore Jobs Scraper](https://apify.com/parsebird/mycareersfuture-jobs-scraper) — Singapore's national jobs portal.

Browse all [ParseBird actors](https://apify.com/parsebird) on Apify Store.

# Actor input Schema

## `keyword` (type: `string`):

Search by job title, skill, or reference number, e.g. "nurse", "paramedic", "data analyst".

## `location` (type: `string`):

City, town, or postcode to search in, e.g. "London", "Manchester", "NE1".

## `results_wanted` (type: `integer`):

Maximum number of job listings to collect. This is the number of billed rows.

## `max_pages` (type: `integer`):

Safety limit on search result pages processed (10 vacancies per page).

## `collectDetails` (type: `boolean`):

Visit each job page to extract the full job description and refined fields. Turn off for a fast listing-only run.

## `startUrl` (type: `string`):

Start from a specific jobs.nhs.uk search URL (overrides Keyword and Location).

## `proxyConfiguration` (type: `object`):

Proxy settings. jobs.nhs.uk works from datacenter IPs; residential is recommended for large runs.

## Actor input object example

```json
{
  "keyword": "nurse",
  "location": "London",
  "results_wanted": 20,
  "max_pages": 5,
  "collectDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# 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 = {
    "keyword": "nurse",
    "location": "London",
    "results_wanted": 20,
    "max_pages": 5,
    "startUrl": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/nhs-uk-jobs-scraper").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 = {
    "keyword": "nurse",
    "location": "London",
    "results_wanted": 20,
    "max_pages": 5,
    "startUrl": "",
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/nhs-uk-jobs-scraper").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 '{
  "keyword": "nurse",
  "location": "London",
  "results_wanted": 20,
  "max_pages": 5,
  "startUrl": ""
}' |
apify call parsebird/nhs-uk-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/nhs-uk-jobs-scraper"
        }
    }
}

```

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/1i1TM6dp827ZLlS4P/builds/gn7OAS5ZoIhNxLVdn/openapi.json
