# NHS Jobs Scraper (`automation-lab/nhs-jobs-scraper`) Actor

Extract structured NHS Jobs vacancies with salary, pay band, dates, full descriptions, person specifications, employer details, and public recruiter contacts. Export to JSON, CSV, or Excel; schedule runs or use the API.

- **URL**: https://apify.com/automation-lab/nhs-jobs-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 Jobs Scraper

NHS Jobs Scraper extracts public healthcare vacancies from [NHS Jobs](https://www.jobs.nhs.uk/) into structured, reusable data.

Search by role and location, apply NHS-specific filters, or process a search or vacancy URL directly.

### What does NHS Jobs Scraper do?

NHS Jobs Scraper turns public jobs.nhs.uk vacancy pages into clean records for recruiting, aggregation, monitoring, and workforce analysis.

It supports both discovery and deep extraction:

- 🔎 Search by keyword, location, employer, or job reference.
- 🏥 Filter by pay band, contract type, and working pattern.
- 🔗 Paste NHS Jobs search-result or vacancy-detail URLs.
- 📄 Enrich each result with full descriptions and person specifications.
- 💷 Parse salary ranges, pay schemes, and pay bands.
- 📅 Normalize posting and closing dates.
- 👤 Capture public recruitment contact details when listed.
- 📦 Export JSON, CSV, Excel, XML, RSS, or access data by API.

No NHS Jobs account, login, or private API key is required.

The scraper uses lightweight public HTML rather than a browser, keeping repeat runs fast and predictable.

### Who is NHS Jobs Scraper for?

**Healthcare recruiters and staffing firms**

- Build daily candidate-sourcing and vacancy feeds.
- Identify trusts hiring for specific professions.
- Route public recruiter contacts into compliant outreach workflows.

**Job boards and aggregators**

- Import current NHS vacancies with stable IDs and canonical URLs.
- Deduplicate listings across searches and regions.
- Track closing dates before syndicating opportunities.

**Workforce and labour-market analysts**

- Compare advertised salaries across roles and locations.
- Measure Band 5, Band 6, or consultant hiring demand.
- Study contract and working-pattern trends over time.

**NHS suppliers and sales intelligence teams**

- Detect trusts expanding particular teams.
- Use hiring signals to prioritize account research.
- Monitor employer activity without manually repeating searches.

### Why use this NHS Jobs scraper?

- ✅ Complete search and detail workflow in one Actor.
- ✅ Full narrative fields, not only search-card snippets.
- ✅ NHS-specific pay-band and person-specification fields.
- ✅ Search filters and pasted URL modes can be combined.
- ✅ Pagination and deduplication work across all inputs.
- ✅ Optional proxy routing is available but disabled by default.
- ✅ Runs can be scheduled daily, weekly, or on demand.
- ✅ Dataset data integrates with thousands of Apify-connected tools.

### What NHS vacancy data can you extract?

| Category | Fields |
|---|---|
| Identity | `vacancyId`, `referenceNumber`, `title`, `url` |
| Employer | `employer`, address, town, county, country, website |
| Location | `location`, `postcode` |
| Pay | salary text, minimum, maximum, currency, period, scheme, band |
| Dates | posting date, closing date, normalized ISO dates |
| Employment | contract type, working pattern |
| Narrative | summary, main duties, full job description, employer description |
| Requirements | essential and desirable person-specification criteria |
| Contact | public contact role, name, email, and phone |
| Provenance | source URL, search keyword, page, enrichment status, scrape time |

A single dataset item represents one unique NHS vacancy.

Detail fields are optional only when detail enrichment is disabled or a vacancy does not publish that field.

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

This Actor uses pay-per-event pricing.

You pay a small run-start fee and a per-vacancy fee only for records saved to the dataset.

| Event | Free plan | Starter | Scale | Business |
|---|---:|---:|---:|---:|
| Run start | $0.00030 | $0.00030 | $0.00030 | $0.00030 |
| Vacancy saved | $0.00012067 | $0.00010493 | $0.000081846 | $0.000062958 |

Higher Apify plans receive additional volume discounts down to $0.000029381 per vacancy on the Diamond tier.

A 10-vacancy Free-plan run costs about $0.00151, including the start fee. A 1,000-vacancy Starter-plan run costs about $0.10523.

Start with 10 vacancies to inspect output and estimate the cost of your recurring workflow.

Your Apify free-plan credits can be used to test thousands of vacancies.

### How to scrape NHS Jobs vacancies

1. Open `automation-lab/nhs-jobs-scraper` in the Apify Store.
2. Enter one or more role keywords, such as `nurse` or `radiographer`.
3. Optionally enter a town, city, county, or postcode.
4. Select pay-band, contract, or working-pattern filters.
5. Keep **Enrich vacancy details** enabled for full descriptions and contacts.
6. Set **Maximum vacancies** to the number of records needed.
7. Click **Start**.
8. Open the dataset and export it in your preferred format.

For a precise existing search, paste its jobs.nhs.uk URL under **NHS Jobs URLs**.

For one known vacancy, paste its `/candidate/jobadvert/...` URL and set `maxItems` to `1`.

### Input parameters

| Input | Type | Default | Description |
|---|---|---|---|
| `keywords` | string[] | `["nurse"]` | Job titles, skills, or search terms |
| `location` | string | empty | UK town, city, county, or postcode |
| `distanceMiles` | integer | `10` | Radius around the location |
| `jobReference` | string | empty | NHS Jobs or Trac reference |
| `employer` | string | empty | NHS trust or employer name |
| `contractTypes` | string[] | `[]` | Permanent, fixed-term, bank, locum, and other filters |
| `workingPatterns` | string[] | `[]` | Full-time, part-time, remote, flexible, and other filters |
| `payBands` | string[] | `[]` | Agenda for Change bands or medical grades |
| `startUrls` | request list | sample search URL | NHS Jobs search or vacancy URLs |
| `maxItems` | integer | `10` | Maximum unique vacancies saved |
| `enrichDetails` | boolean | `true` | Fetch full vacancy detail pages |
| `detailConcurrency` | integer | `4` | Simultaneous detail requests, from 1 to 10 |
| `useApifyProxy` | boolean | `false` | Route requests through Apify Proxy |
| `proxyGroups` | string[] | `[]` | Optional proxy groups |

At least one keyword, job reference, employer, search URL, or detail URL is required.

URLs outside jobs.nhs.uk and unrelated paths are rejected.

### Input examples

Search for nurse vacancies around Manchester:

```json
{
  "keywords": ["nurse"],
  "location": "Manchester",
  "distanceMiles": 20,
  "maxItems": 25,
  "enrichDetails": true
}
````

Monitor Band 5 vacancies across two role families:

```json
{
  "keywords": ["nurse", "therapist"],
  "payBands": ["BAND_5"],
  "maxItems": 100,
  "enrichDetails": true,
  "detailConcurrency": 4
}
```

Extract one vacancy URL:

```json
{
  "keywords": [],
  "startUrls": [
    { "url": "https://www.jobs.nhs.uk/candidate/jobadvert/C9262-26-1074?language=en" }
  ],
  "maxItems": 1
}
```

### Output example

```json
{
  "vacancyId": "C9262-26-1074",
  "referenceNumber": "262-A-26-8075087",
  "title": "Community Nurse - Night Nurse",
  "employer": "North Cumbria Integrated Care NHS Foundation Trust",
  "location": "Carlisle CA1 3TP",
  "postcode": "CA1 3TP",
  "salaryText": "£32,073 to £39,043 a year Per Annum Pro Rata",
  "salaryMin": 32073,
  "salaryMax": 39043,
  "salaryCurrency": "GBP",
  "salaryPeriod": "year",
  "payScheme": "Agenda for change",
  "payBand": "Band 5",
  "datePostedIso": "2026-07-08",
  "closingDateIso": "2026-07-26",
  "contractType": "Permanent",
  "workingPattern": "Part-time",
  "detailEnriched": true,
  "url": "https://www.jobs.nhs.uk/candidate/jobadvert/C9262-26-1074"
}
```

Long narrative and criteria fields are included in the real item but shortened here for readability.

### Tips for best results

- 🎯 Use a specific role phrase for focused feeds.
- 📍 Add location and distance when monitoring a regional labour market.
- 🏥 Combine employer and pay-band filters for trust-level analysis.
- 🧪 Start with 10 records before scaling a new search.
- 📄 Keep detail enrichment enabled when you need descriptions or contacts.
- ⚡ Disable detail enrichment for a faster search-card-only discovery pass.
- 🕐 Schedule recurring searches at a respectful interval.
- 🔁 Deduplicate longitudinal exports using `vacancyId`.

### Pagination, deduplication, and reliability

Each search page exposes a server-rendered next-page link.

The Actor follows that link until it reaches `maxItems`, runs out of pages, or finds no new vacancy IDs.

Temporary HTTP failures are retried with conservative limits.

A failed detail request from a search workflow preserves the valid search-card record and marks `detailEnriched` false.

A blocked or malformed top-level page fails the run rather than returning a misleading success.

Direct requests are the default because public NHS Jobs pages are anonymously accessible.

Enable Apify Proxy only when your environment requires it.

### Integrations for NHS recruitment workflows

**NHS Jobs → Google Sheets**

- Append daily vacancy records for recruiter review.
- Build salary and closing-date dashboards by trust.

**NHS Jobs → Slack or Microsoft Teams**

- Send an alert when a target trust posts a new Band 6 role.
- Notify a sourcing team before a vacancy closes.

**NHS Jobs → Make or Zapier**

- Create a CRM hiring-signal record for each new employer vacancy.
- Route relevant vacancies into an internal candidate-matching process.

**Scheduled runs and webhooks**

- Run searches every morning and deliver the dataset by webhook.
- Compare current `vacancyId` values with a previous export to detect additions.

### Using the Apify API with Node.js

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/nhs-jobs-scraper').call({
  keywords: ['radiographer'],
  location: 'Birmingham',
  maxItems: 50,
  enrichDetails: true
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Using the Apify API with Python

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("automation-lab/nhs-jobs-scraper").call(run_input={
    "keywords": ["occupational therapist"],
    "location": "Leeds",
    "maxItems": 50,
    "enrichDetails": True,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Using the Apify API with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~nhs-jobs-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords":["pharmacist"],"location":"London","maxItems":25,"enrichDetails":true}'
```

After the run finishes, download items from its `defaultDatasetId`.

### Use with AI agents via MCP

NHS Jobs Scraper is available to AI assistants through the [Model Context Protocol](https://docs.apify.com/platform/integrations/mcp).

**Claude Code**

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/nhs-jobs-scraper"
```

**Claude Desktop, Cursor, or VS Code**

```json
{
  "mcpServers": {
    "apify-nhs-jobs": {
      "url": "https://mcp.apify.com?tools=automation-lab/nhs-jobs-scraper"
    }
  }
}
```

Your client will ask you to authenticate with Apify.

**Example prompts**

- “Use `automation-lab/nhs-jobs-scraper` to find Band 5 nurse vacancies within 20 miles of Manchester and summarize salary ranges.”
- “Extract this NHS Jobs vacancy URL and compare its essential criteria with my candidate profile.”
- “Monitor radiographer vacancies in London and return new employers, closing dates, and public contact emails.”

### Is it legal to scrape NHS Jobs?

This Actor collects information displayed on public NHS Jobs pages.

Scraping public data can be lawful, but legality depends on your jurisdiction, purpose, and handling of personal data.

Review NHS Jobs terms, applicable employment rules, copyright, database rights, and UK GDPR obligations before use.

Public recruiter contact details should not be used for spam or unlawful profiling.

Use respectful run sizes and frequencies, store only necessary data, and honor deletion or access obligations that apply to your workflow.

This documentation is general information, not legal advice.

### Frequently asked questions

**Do I need an NHS Jobs account?**

No. The Actor uses anonymously available search and vacancy pages.

**Does it fetch full job descriptions?**

Yes. Detail enrichment is enabled by default and captures summary, duties, responsibilities, person specifications, employer context, and public contact fields.

**How fast is it?**

Search pages are lightweight. Detail-enriched runs make one additional request per vacancy with bounded concurrency, so run time grows with `maxItems`.

**Can I scrape a saved NHS Jobs search URL?**

Yes. Paste a `/candidate/search/results` URL into `startUrls`.

**Can I extract one vacancy?**

Yes. Paste its `/candidate/jobadvert/...` URL and set `maxItems` to 1.

**Why are some fields empty?**

Employers do not publish every optional field on every vacancy. Inspect `detailEnriched`; if it is true, empty optional values were not present on the page.

**Why did my search return no vacancies?**

The combination of keyword, location, pay band, and contract filters may have no current matches. Broaden one filter and run a small test.

**What happens if NHS Jobs changes its markup?**

The Actor checks for recognizable result/detail structures and fails clearly on total parser failure instead of silently producing misleading records.

**How does pricing compare with an official API?**

No private NHS Jobs API key is required. Pay-per-event pricing includes Actor operation and Apify platform features such as storage, schedules, API access, and integrations.

### Data quality and responsible use

Vacancy content is captured as published by the employer.

Normalized numeric salaries and ISO dates are convenience fields; retain the raw salary and date text for auditability.

A closing date may be brought forward by an employer, so refresh time-sensitive feeds.

Person specifications can contain sensitive employment criteria; use them for legitimate matching and analysis, not unlawful discrimination.

Validate critical decisions against the canonical vacancy URL.

### Other recruitment and jobs scrapers

Combine NHS Jobs data with other public hiring sources from automation-lab:

- [LinkedIn Jobs Scraper](https://apify.com/automation-lab/linkedin-jobs-scraper)
- [Glassdoor Jobs Scraper](https://apify.com/automation-lab/glassdoor-jobs-scraper)
- [Google Jobs Scraper](https://apify.com/automation-lab/google-jobs-scraper)
- [Greenhouse Jobs Scraper](https://apify.com/automation-lab/greenhouse-jobs-scraper)
- [Jobsite UK Jobs Scraper](https://apify.com/automation-lab/jobsite-uk-jobs-scraper)
- [Indeed Scraper](https://apify.com/automation-lab/indeed-scraper)
- [Dice Tech Jobs Scraper](https://apify.com/automation-lab/dicecom-tech-jobs-scraper)

Use stable vacancy IDs and canonical URLs when joining or deduplicating sources.

### Support

If a valid NHS Jobs page fails, open an Actor issue with the input and run URL.

Do not include private candidate data or credentials.

For best diagnostics, identify whether the failure affected search extraction, detail enrichment, or a specific filter combination.

# Actor input Schema

## `keywords` (type: `array`):

Enter job titles, skills, or terms to search on jobs.nhs.uk, such as nurse, radiographer, or data analyst.

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

Enter a UK town, city, county, or postcode. Leave blank to search nationally.

## `distanceMiles` (type: `integer`):

Set the search radius around the location.

## `jobReference` (type: `string`):

Find a vacancy by its NHS Jobs or Trac reference number.

## `employer` (type: `string`):

Filter by NHS trust or other healthcare employer name.

## `contractTypes` (type: `array`):

Select one or more NHS Jobs contract filters.

## `workingPatterns` (type: `array`):

Select one or more working-pattern filters.

## `payBands` (type: `array`):

Select Agenda for Change pay bands or common medical grades.

## `startUrls` (type: `array`):

Add jobs.nhs.uk search-result or vacancy-detail URLs. Other domains and unrelated NHS Jobs paths are rejected.

## `maxItems` (type: `integer`):

Limit the number of unique NHS vacancy records saved across all searches and URLs.

## `enrichDetails` (type: `boolean`):

Fetch each vacancy page to add full description, pay band, person specification, employer, and contact fields.

## `detailConcurrency` (type: `integer`):

Set simultaneous detail requests. Keep this conservative to reduce pressure on NHS Jobs.

## `useApifyProxy` (type: `boolean`):

Enable proxy routing only if direct public NHS Jobs requests are blocked in your execution environment.

## `proxyGroups` (type: `array`):

Optional Apify Proxy groups. Leave empty for automatic selection.

## Actor input object example

```json
{
  "keywords": [
    "nurse"
  ],
  "location": "Carlisle",
  "distanceMiles": 10,
  "contractTypes": [],
  "workingPatterns": [],
  "payBands": [],
  "startUrls": [
    {
      "url": "https://www.jobs.nhs.uk/candidate/search/results?keyword=nurse&location=Carlisle&distance=10&language=en"
    }
  ],
  "maxItems": 10,
  "enrichDetails": true,
  "detailConcurrency": 4,
  "useApifyProxy": false,
  "proxyGroups": []
}
```

# Actor output Schema

## `overview` (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 = {
    "keywords": [
        "nurse"
    ],
    "location": "Carlisle",
    "distanceMiles": 10,
    "contractTypes": [],
    "workingPatterns": [],
    "payBands": [],
    "startUrls": [
        {
            "url": "https://www.jobs.nhs.uk/candidate/search/results?keyword=nurse&location=Carlisle&distance=10&language=en"
        }
    ],
    "maxItems": 10,
    "enrichDetails": true,
    "detailConcurrency": 4,
    "useApifyProxy": false,
    "proxyGroups": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/nhs-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 = {
    "keywords": ["nurse"],
    "location": "Carlisle",
    "distanceMiles": 10,
    "contractTypes": [],
    "workingPatterns": [],
    "payBands": [],
    "startUrls": [{ "url": "https://www.jobs.nhs.uk/candidate/search/results?keyword=nurse&location=Carlisle&distance=10&language=en" }],
    "maxItems": 10,
    "enrichDetails": True,
    "detailConcurrency": 4,
    "useApifyProxy": False,
    "proxyGroups": [],
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/nhs-jobs-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "keywords": [
    "nurse"
  ],
  "location": "Carlisle",
  "distanceMiles": 10,
  "contractTypes": [],
  "workingPatterns": [],
  "payBands": [],
  "startUrls": [
    {
      "url": "https://www.jobs.nhs.uk/candidate/search/results?keyword=nurse&location=Carlisle&distance=10&language=en"
    }
  ],
  "maxItems": 10,
  "enrichDetails": true,
  "detailConcurrency": 4,
  "useApifyProxy": false,
  "proxyGroups": []
}' |
apify call automation-lab/nhs-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/nhs-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "NHS Jobs Scraper",
        "description": "Extract structured NHS Jobs vacancies with salary, pay band, dates, full descriptions, person specifications, employer details, and public recruiter contacts. Export to JSON, CSV, or Excel; schedule runs or use the API.",
        "version": "0.1",
        "x-build-id": "zO2IHP2unp3aTzDt5"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~nhs-jobs-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-nhs-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/automation-lab~nhs-jobs-scraper/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-nhs-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/automation-lab~nhs-jobs-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-nhs-jobs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "keywords": {
                        "title": "Keywords",
                        "type": "array",
                        "description": "Enter job titles, skills, or terms to search on jobs.nhs.uk, such as nurse, radiographer, or data analyst.",
                        "default": [
                            "nurse"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "Enter a UK town, city, county, or postcode. Leave blank to search nationally."
                    },
                    "distanceMiles": {
                        "title": "Distance in miles",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Set the search radius around the location.",
                        "default": 10
                    },
                    "jobReference": {
                        "title": "Job reference",
                        "type": "string",
                        "description": "Find a vacancy by its NHS Jobs or Trac reference number."
                    },
                    "employer": {
                        "title": "Employer",
                        "type": "string",
                        "description": "Filter by NHS trust or other healthcare employer name."
                    },
                    "contractTypes": {
                        "title": "Contract types",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Select one or more NHS Jobs contract filters.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Permanent",
                                "Fixed-Term",
                                "Apprenticeship",
                                "Bank",
                                "Locum",
                                "Secondment",
                                "Training",
                                "Voluntary"
                            ]
                        }
                    },
                    "workingPatterns": {
                        "title": "Working patterns",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Select one or more working-pattern filters.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "full-time",
                                "part-time",
                                "job-share",
                                "flexible-working",
                                "remote-working",
                                "compressed-hours",
                                "term-time-hours",
                                "annualised-hours"
                            ]
                        }
                    },
                    "payBands": {
                        "title": "Pay bands",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Select Agenda for Change pay bands or common medical grades.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "BAND_2",
                                "BAND_3",
                                "BAND_4",
                                "BAND_5",
                                "BAND_6",
                                "BAND_7",
                                "BAND_8A",
                                "BAND_8B",
                                "BAND_8C",
                                "BAND_8D",
                                "BAND_9",
                                "CONSULTANT",
                                "SPECIALTY_DOCTOR",
                                "FOUNDATION_DOCTOR",
                                "SPECIALTY_REGISTRAR"
                            ]
                        }
                    },
                    "startUrls": {
                        "title": "NHS Jobs URLs",
                        "type": "array",
                        "description": "Add jobs.nhs.uk search-result or vacancy-detail URLs. Other domains and unrelated NHS Jobs paths are rejected.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "maxItems": {
                        "title": "Maximum vacancies",
                        "minimum": 1,
                        "maximum": 50000,
                        "type": "integer",
                        "description": "Limit the number of unique NHS vacancy records saved across all searches and URLs.",
                        "default": 10
                    },
                    "enrichDetails": {
                        "title": "Enrich vacancy details",
                        "type": "boolean",
                        "description": "Fetch each vacancy page to add full description, pay band, person specification, employer, and contact fields.",
                        "default": true
                    },
                    "detailConcurrency": {
                        "title": "Detail concurrency",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Set simultaneous detail requests. Keep this conservative to reduce pressure on NHS Jobs.",
                        "default": 4
                    },
                    "useApifyProxy": {
                        "title": "Use Apify Proxy",
                        "type": "boolean",
                        "description": "Enable proxy routing only if direct public NHS Jobs requests are blocked in your execution environment.",
                        "default": false
                    },
                    "proxyGroups": {
                        "title": "Proxy groups",
                        "type": "array",
                        "description": "Optional Apify Proxy groups. Leave empty for automatic selection.",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
