# Reed.co.uk Jobs Scraper (`axiomworks/reed-jobs-scraper`) Actor

Scrape public Reed.co.uk job listings and return structured records with titles, employers, locations, salary details, contract types, descriptions, and posting and closing dates. The Actor opens each job page to collect the full description and exact posting date, and requires no login or API key.

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

## Pricing

from $1.79 / 1,000 results

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

## Reed Jobs Scraper

**Returns:** one row per Reed job with id, title, employer, location, salaryText, contractType, datePosted and sourceUrl.
**Input:** `{ "keywords": "software engineer", "location": "London", "maxItems": 10 }`
**Best for:** UK job feeds, salary research and recruiter market analysis.

```json
{"id":"57370484","title":"Registered Nurse","employer":"Excelcare Holdings","location":"Greater Manchester","salaryText":"£24.95 per hour","salaryMin":24.95,"sourceUrl":"https://www.reed.co.uk/jobs/registered-nurse/57370484"}
```

### What does Reed Jobs Scraper do?

Reed Jobs Scraper collects public UK job listings from Reed.co.uk and returns them as clean, structured records. You give it a job keyword and a UK location, for example "software engineer" in "London" or "nurse" in "Manchester", and it walks through the search result pages, opens each job page and extracts the details. You can also paste your own Reed search URLs or individual job URLs. Add further keyword searches in one run, with results deduplicated by Reed job ID. Optional salary and job type filters are applied by Reed before the Actor opens matching jobs.

Every record contains the job title, the employer, the location, the salary as displayed plus a numeric minimum, maximum and pay period, the contract type, the full description as plain text, and the dates the job was posted and closes. Optionally, an AI step adds two extra labels: the seniority of the role and the work arrangement (onsite, hybrid, remote).

The Actor needs no login and no API key. It reads only pages that anyone can open in a browser, at a polite pace of one to two requests per second. It is built for recruiters, salary benchmarking, labour-market research, job aggregators, and anyone who wants Reed listings in a spreadsheet, database or AI workflow.

Typical uses include a weekly feed of new jobs for a role and city, salary benchmarking across UK regions and contract types, tracking which employers hire most for a skill, and feeding job descriptions into your own search index or language model pipeline.

### What data can you get?

Each job becomes one dataset item. Items are unique by `id`, and `sourceUrl` points to the Reed job page the data came from.

| Field | Type | Description |
|---|---|---|
| `id` | string | Reed job identifier |
| `sourceUrl` | string | URL of the job page |
| `title` | string | Job title |
| `employer` | string | Hiring company or recruiter |
| `location` | string | Town, city or area of the job |
| `postalCode` | string | Postcode area when the listing provides one |
| `salaryText` | string | Salary exactly as shown, for example "£24.95 per hour" |
| `salaryMin` | number | Lower salary bound |
| `salaryMax` | number | Upper salary bound |
| `salaryPeriod` | string | HOUR, DAY, WEEK, MONTH or YEAR |
| `contractType` | string | Employment type such as FULL_TIME or PART_TIME |
| `description` | string | Full description as plain text |
| `descriptionHtml` | string | Description HTML from the job page, when published |
| `datePosted` | string | ISO 8601 timestamp of posting |
| `validThrough` | string | ISO 8601 timestamp when the listing closes |
| `employerUrl` | string | Reed company profile page of the employer (empty when the listing has no link) |
| `employmentText` | string | Employment type as shown on the page, e.g. Permanent, full-time |
| `workplaceText` | string | Workplace arrangement when stated, e.g. Remote |
| `easyApply` | boolean | Whether the listing has the Easy Apply badge |
| `salaryCurrency` | string | GBP when a numeric salary was parsed |
| `seniority` | string | AI label: entry, mid, senior, lead or executive |
| `remoteType` | string | AI label: onsite, hybrid, remote or unspecified |

Some listings say the salary is negotiable or competitive. For those, `salaryText` may be empty or text only, and the numeric salary fields are null. Fields that a listing does not provide are returned as null rather than guessed.

### How to use Reed Jobs Scraper

1. Open the Actor in Apify Console and go to the Input tab.
2. Enter keywords and a location, or paste Reed search URLs into Start URLs.
3. Set Max items to the number of jobs you want. The run stops as soon as that many records are saved.
4. Enable AI enrichment if you want the seniority and remote labels; it is off by default.
5. Click Start. Results appear in the Output tab and can be downloaded as JSON, CSV, Excel or HTML.

For several related roles, add `additionalKeywords` and the Actor runs each search until `maxItems` unique jobs are saved. Use `salaryFrom`, `salaryTo` and `jobType` to narrow generated searches. Start URLs preserve the filters already set in the pasted Reed URL. For a search with many results, Reed returns 25 jobs per page. The Actor requests each page in turn and then opens every job page, because the job page is where the full description, the exact posting date including the year and the closing date are published.

If your keywords or location match nothing, the run finishes with zero items and a warning in the log. It does not output placeholder records.

### Input

| Field | Type | Description |
|---|---|---|
| `keywords` | string | Job keywords, for example "python developer". Required unless you give Start URLs. |
| `location` | string | UK town or city, for example "Leeds". Empty means the whole UK. |
| `additionalKeywords` | string array | More search phrases to combine with `keywords`; duplicate job IDs are returned once. |
| `salaryFrom` | integer | Minimum Reed salary filter value in GBP in generated searches; 0 means no filter. |
| `salaryTo` | integer | Maximum Reed salary filter value in GBP in generated searches; 0 means no filter. |
| `jobType` | string | One of any, permanent, contract, temporary, fullTime or partTime; default any. |
| `startUrls` | array | Optional Reed search URLs or job URLs. They override keywords and location. |
| `maxItems` | integer | Maximum jobs to return, default 50. |
| `includeDescription` | boolean | Include the full description text, default true. |
| `enableAiEnrichment` | boolean | Add seniority and remoteType labels, default false. |
| `proxyConfiguration` | object | Proxy settings. Direct by default, with automatic retry through Apify datacenter proxy if Reed blocks a request. |

Example input:

```json
{
  "keywords": "software engineer",
  "location": "London",
  "additionalKeywords": ["backend developer"],
  "salaryFrom": 50000,
  "jobType": "permanent",
  "maxItems": 30,
  "includeDescription": true,
  "enableAiEnrichment": false,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output

Here is a real item produced by the Actor (description shortened):

```json
{
  "id": "57370484",
  "sourceUrl": "https://www.reed.co.uk/jobs/registered-nurse/57370484",
  "title": "Registered Nurse",
  "employer": "Excelcare Holdings",
  "location": "Greater Manchester",
  "postalCode": null,
  "salaryText": "£24.95 per hour",
  "salaryMin": 24.95,
  "salaryMax": 24.95,
  "salaryPeriod": "HOUR",
  "contractType": "FULL_TIME, PART_TIME",
  "description": "We are offering a rewarding career as a Registered Nurse at our Park Avenue Care Home in Bromley. ...",
  "datePosted": "2026-09-21T09:17:25.367Z",
  "validThrough": "2026-11-02T23:55:00.000Z",
  "seniority": "mid",
  "remoteType": "onsite"
}
```

Another item shows a salary range:

```json
{
  "id": "57294994",
  "title": "Nursery Nurse",
  "employer": "Reeson Education",
  "location": "Wigan",
  "postalCode": "WN1",
  "salaryText": "£15.87 - £16.24 per hour",
  "salaryMin": 15.87,
  "salaryMax": 16.24,
  "salaryPeriod": "HOUR",
  "descriptionHtml": "<p>We are offering a rewarding career as a Registered Nurse...</p>",
  "contractType": "FULL_TIME"
}
```

The `seniority` and `remoteType` values are null when AI enrichment is turned off or when the AI processor was unavailable for that item.

### How much does it cost?

The Actor uses pay-per-event pricing. You are charged for each result saved to the dataset, and for each result that was successfully enriched with the AI labels. You are not charged for results that were not saved, and the run never saves more than your Max items. See the Pricing tab on the Actor page for the current rates. You can also set a maximum cost per run in the Apify Console to cap spending.

AI enrichment is a third-party step: the title, location and the beginning of the description are sent to an external AI processor to produce the seniority and remote labels. It is off by default; turn it on with `enableAiEnrichment: true` if you want those labels.

### Use with AI agents (MCP)

You can call this Actor from any MCP-compatible assistant through the Apify MCP server. Add the Actor with this URL:

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

Example prompts: "Find 20 recent nursing jobs in Manchester on Reed and list the employer, salary and contract type." or "Get 50 software engineer jobs in London from Reed and summarise the salary range for senior roles." or "Search Reed for data analyst jobs and give me the closing dates."

The input fields keywords, location and maxItems are listed first so agents can fill them directly.

### Integrations and API

You can run the Actor from code and read the dataset with the Apify API.

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("axiomworks/reed-jobs-scraper").call(run_input={
    "keywords": "software engineer",
    "location": "London",
    "maxItems": 30,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["employer"], item["salaryText"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('axiomworks/reed-jobs-scraper').call({
    keywords: 'nurse',
    location: 'Manchester',
    maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
process.stdout.write(`${items.length} jobs\n`);
```

cURL:

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~reed-jobs-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords":"nurse","location":"Manchester","maxItems":20}'
```

You can also connect the Actor to schedules, webhooks, Google Sheets, Make, Zapier or n8n using the standard Apify integrations. A common pattern is a daily scheduled run that sends new jobs to a spreadsheet or a Slack channel.

### FAQ

**How many jobs can I get?**
As many as the search returns, up to the Max items you set. Reed shows up to roughly forty pages of 25 jobs per search, so for broad searches use several narrower keyword or location combinations.

**Why is the salary empty for some jobs?**
Many listings, especially from recruiters, advertise the salary as negotiable or competitive. Reed publishes no numbers for them, so the numeric fields are null.

**Why does the Actor open every job page?**
Search cards show only a day and month for the posting date. The job page holds the full ISO date, the closing date, the postcode area and the complete description.

**Can I scrape a single job?**
Yes. Put the job URL in Start URLs.

**What happens if Reed blocks a request?**
The Actor retries with increasing delays, switching to a fresh Apify datacenter proxy session after the first failure. If a page still cannot be fetched, it is skipped with a warning in the log. For heavy use, choose a proxy group in the proxy settings.

**Does it need a login?**
No. Only public pages are read.

**Is the data fresh?**
Yes, the Actor reads live pages on each run. Expired jobs are removed by Reed and are skipped.

### Is it legal to scrape Reed?

This Actor reads publicly available job listings that anyone can view without logging in. It does not bypass logins or CAPTCHAs, and it keeps to a modest request rate. Job listings can include personal or commercial information, so use the data in line with applicable laws such as the UK GDPR and with the terms of any site you rely on. Respect the rights of employers and recruiters when you republish text. This is not legal advice; if you plan a commercial product built on the data, consult a lawyer. This Actor is an independent tool and is not affiliated with or endorsed by Reed.

### Feedback

Found a bug, a missing field or a listing type that is not parsed correctly? Open an issue from the Actor page in Apify Console, including the input you used and the job URL. Feature requests, including other Reed search filters, are welcome.

# Actor input Schema

## `keywords` (type: `string`):

First job keyword or phrase to search, e.g. software engineer. Add more searches with additionalKeywords; ignored when startUrls is set.

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

UK town, city or area to search in, e.g. 'London' or 'Manchester'. Leave empty to search all of the UK. Ignored when startUrls is set.

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

Optional Reed.co.uk search result URLs or single job URLs (https://www.reed.co.uk/jobs/<slug>/<id>). When set, they override keywords and location.

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

Maximum number of jobs to return, 1-5000, default 50. The run stops as soon as this many records are saved.

## `includeDescription` (type: `boolean`):

Include the full job description as plain text. Default true.

## `enableAiEnrichment` (type: `boolean`):

Add seniority (entry/mid/senior/lead/executive) and remoteType (onsite/hybrid/remote/unspecified) to each job using a third-party AI processor. Default false.

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

Proxy settings. Requests go direct by default; if Reed blocks them the Actor retries through Apify datacenter proxy. Choose a proxy group here to always use one.

## `additionalKeywords` (type: `array`):

More job searches to combine with keywords, e.g. \["data engineer", "backend developer"]. Duplicate job IDs are returned once. Ignored when startUrls is set.

## `salaryFrom` (type: `integer`):

Minimum salary filter value in GBP for Reed search results, e.g. 50000. Reed decides how each listing matches its salary filter; 0 means any.

## `salaryTo` (type: `integer`):

Maximum salary filter value in GBP for Reed search results, e.g. 100000. Reed decides how each listing matches its salary filter; 0 means any.

## `jobType` (type: `string`):

Job type to request from Reed: permanent, contract, temporary, fullTime or partTime. Default any.

## Actor input object example

```json
{
  "keywords": "software engineer",
  "location": "London",
  "maxItems": 10,
  "includeDescription": true,
  "enableAiEnrichment": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "additionalKeywords": [],
  "salaryFrom": 0,
  "salaryTo": 0,
  "jobType": "any"
}
```

# Actor output Schema

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

One record per job listing.

# 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": "software engineer",
    "location": "London",
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/reed-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": "software engineer",
    "location": "London",
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/reed-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 '{
  "keywords": "software engineer",
  "location": "London",
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axiomworks/reed-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axiomworks/reed-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/EuvEbtlR1U9SwYjrT/builds/PLwX50r0Tgy469gaN/openapi.json
