# Reed Jobs Scraper · UK Vacancies, Salaries & Employers (`reapx/reed-jobs-scraper`) Actor

Reed Jobs Scraper to extract UK job listings and vacancies from Reed.co.uk. Filter by keyword, location, salary, contract type, remote work, and date posted. Export clean UK job market data.

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

## Pricing

from $1.30 / 1,000 job returneds

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 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

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## Reed Jobs Scraper · UK Vacancies, Salaries & Employers

**Reed Jobs Scraper** (Reed.co.uk job scraper) extracts UK job listings and vacancies from Reed.co.uk. Search UK jobs by keyword, location, town, county, salary range, contract type, remote status, and posting date.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/reed-jobs-scraper/](https://reapx.dev/data/reed-jobs-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/reed-jobs-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/reed-jobs-scraper). Questions: reapxdev@proton.me

Extract job title, hiring employer, job ID, location, advertised salary, job type, full job description, and application URLs. Ideal for recruitment, hiring analytics, labor market insights, and job board aggregation. Fast HTTP extraction with no login or API key required.

### Reed Jobs Scraper features

- **Reed.co.uk UK Jobs Scraper**: Extract 100,000+ live UK job vacancies with full details.
- **UK Job Search & Salary Filters**: Filter by keyword, town/county, minimum/maximum salary, contract type, and remote status.
- **Structured Recruitment Data**: Returns title, employer, salary breakdown, posting date, full job text, and apply link.

### What this Reed scraper returns

One row per vacancy:

| Field | What it gives you |
| --- | --- |
| `jobId`, `jobTitle`, `jobUrl` | The vacancy and a permanent link to it |
| `employer`, `employerId` | Who is hiring, with a stable advertiser ID |
| `location`, `county` | Where the role sits |
| `salaryFrom`, `salaryTo`, `salaryPeriod`, `hasSalary` | Advertised pay and the period it is quoted in |
| `jobType`, `isFullTime`, `isPartTime` | Permanent, Contract or Temporary, and the working pattern |
| `remoteWorkingOption` | On-Site, Hybrid, Remote or NotSpecified |
| `category`, `subCategory` | Reed's own sector classification |
| `postedAt`, `updatedAt`, `expiresAt` | Freshness and how long the listing stays open |
| `descriptionSnippet`, `isEasyApply`, `isFeatured`, `eligibleUkOnly` | Listing detail |

Five named dataset views ship with it: **Jobs**, **Salaries**, **Employers**,
**Remote & flexible** and **Freshness**.

### How to scrape Reed jobs

1. Put a **job keyword** in - `python developer`, `registered nurse`, `hgv driver`. Leave it empty to search everything.
2. Add a **location** - any UK town, city or county.
3. Narrow by **salary**, **contract type**, **remote working**, **part time** or **posting date**.
4. Set **Max jobs**. You are charged once per job returned, so that is your cost cap.

### Filters

Salary, contract type, remote working, part time, agency exclusion and posting date are applied
**by Reed itself**, so they narrow the search rather than fetching rows and discarding them:

- **Posted within** - today, 3 days, a week or 2 weeks. These are the only four windows Reed
  supports; any other value is silently ignored by the site, so the actor refuses it and says so
  rather than returning unfiltered results that look filtered.
- **Minimum / maximum salary** in £/year - postings quoted hourly, daily or monthly are excluded
  from an annual comparison rather than being converted with a guess.
- **Only jobs that advertise a salary** - Reed marks some postings with a filter band rather than
  real pay, and those are treated as having no salary.
- **Contract type** - Permanent, Contract or Temporary.
- **Part-time only** - independent of contract type, because on Reed it is a separate flag.
- **Remote and hybrid only**, **direct employers only**, **employer name contains**.

### What you can build with it

- **UK salary benchmarking** - advertised pay by role, county and seniority, refreshed daily.
- **Hiring-demand tracking** - vacancy counts per keyword over time show which skills are heating up.
- **Competitor headcount signals** - everything one employer is advertising, by `employerId`.
- **Recruitment market analysis** - agency versus direct-employer share of a sector.
- **Remote-work research** - how the on-site / hybrid / remote split moves by role and region.
- **Job-board aggregation** - clean, deduplicated rows with a stable ID and a permanent URL.
- **Candidate alerting** - a narrow search on a short posting window, scheduled hourly.

### Input configuration

Every field is optional. The prefilled values below are what runs if you press Start without changing anything.

#### What and where

Leave both empty and the run returns the newest vacancies across all of Reed.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `what` | string | free text | Job title or skill, exactly as you would type it into Reed's own search box. Leave empty to search every vacancy on the site. Prefilled with `"python developer"`. |
| `where` | string | free text | UK town, city, county or region. Reed matches its own location vocabulary, so "london", "greater-manchester" and "west-midlands" all work. |

#### How much to fetch

Reed serves 25 vacancies per page, so this decides both the runtime and the price of the run.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `maxJobs` | integer | 1 to 2000 | Hard cap on how many vacancies the run returns. This is also your cost cap: you are charged once per job returned. Prefilled with `100`. |

#### Filters

Salary, contract type, remote working and posting date are applied by Reed itself, so they narrow the search rather than discarding rows afterwards.

| Field | Type | Accepts | What it does |
| --- | --- | --- | --- |
| `postedWithinDays` | string | `1`, `3`, `7`, `14` | How recently the vacancy was posted. Reed supports exactly these four windows; any other value is ignored by the site and would silently return everything, so only these are offered. |
| `minSalaryGbp` | integer | 0 to any | Only vacancies advertising at least this annual salary. Postings quoted hourly, daily or monthly are excluded, because they are not comparable to an annual figure. |
| `maxSalaryGbp` | integer | 0 to any | Only vacancies advertising at most this annual salary. |
| `onlyWithSalary` | true/false | checkbox | Drop vacancies with no published pay. Reed marks some postings with a filter band rather than real pay; those are treated as having no salary. |
| `jobType` | string | `Permanent`, `Contract`, `Temporary` | Limit to one kind of engagement. Part time is not a contract type on Reed; use the part-time filter below instead. |
| `onlyPartTime` | true/false | checkbox | Keep only vacancies Reed marks as part time. This is independent of contract type, so a part-time permanent role and a part-time contract both qualify. |
| `onlyRemote` | true/false | checkbox | Drop vacancies Reed marks as on-site only. |
| `excludeAgencies` | true/false | checkbox | Exclude recruitment agency listings and keep only vacancies posted by the hiring employer. |
| `employer` | string | free text | Keep only vacancies whose employer name contains this text, matched case-insensitively. |

### Pricing

Pay per event. The primary event is **Job returned** (`job-returned`), charged at **$0.002 per event** on the free plan, falling to $0.0008 on the highest tier.

Charged once per complete job vacancy written to the default dataset. A blocked source, a changed page shape and a search that matches nothing are never charged.

Minimum charge cap per run: $0.002.

Tiered discounts apply automatically on every paid Apify plan. Platform usage is absorbed by the Actor, so the per-event price is the whole price.

### Usage examples

#### The prefilled run, which is what Start does with nothing changed

```json
{
  "what": "python developer",
  "maxJobs": 100
}
```

#### Filter by job keyword

```json
{
  "what": "registered nurse",
  "maxJobs": 100
}
```

#### Filter by location

```json
{
  "what": "python developer",
  "maxJobs": 100,
  "where": "manchester"
}
```

#### Filter by posted within

```json
{
  "what": "python developer",
  "maxJobs": 100,
  "postedWithinDays": "7"
}
```

#### Filter by minimum salary (£/year)

```json
{
  "what": "python developer",
  "maxJobs": 100,
  "minSalaryGbp": 50000
}
```

### Output example

One row, exactly as the actor wrote it to the dataset:

```json
{
  "jobId": "56969524",
  "jobTitle": "Sales and Service",
  "employer": "Appcast Enterprise",
  "employerId": "674264",
  "location": "Stretford, Leominster",
  "county": "Herefordshire",
  "hasSalary": false,
  "jobType": "Permanent",
  "isFullTime": true,
  "isPartTime": false,
  "remoteWorkingOption": "NotSpecified",
  "category": "Services",
  "subCategory": "Service Sales",
  "isEasyApply": false,
  "isFeatured": false,
  "eligibleUkOnly": true,
  "postedAt": "2026-06-02T08:10:26",
  "updatedAt": "2026-08-03T05:12:52"
}
```

That row carries 22 fields in total; 18 are shown.

#### Fields on every row

| Field | Type | What it is |
| --- | --- | --- |
| `category` | string | Reed’s top-level sector for the vacancy. |
| `county` | string | County or region the vacancy sits in. |
| `descriptionSnippet` | string | Opening of the job description as shown on the results page. |
| `eligibleUkOnly` | true/false | Whether applicants must already have UK work eligibility. |
| `employer` | string | Hiring employer or, for agency listings, the recruiter. |
| `employerId` | string | Reed’s identifier for the advertiser, stable across their vacancies. |
| `expiresAt` | string | Timestamp the listing closes. |
| `hasSalary` | true/false | Whether the posting advertises real pay rather than a filter band. |
| `isEasyApply` | true/false | Whether the vacancy accepts Reed’s one-click application. |
| `isFeatured` | true/false | Whether the employer paid to feature the listing. |
| `isFullTime` | true/false | Whether the vacancy is full time. |
| `isPartTime` | true/false | Whether the vacancy is part time. |
| `jobId` | string | Reed’s own vacancy identifier. Stable, unique, and how the row is addressed downstream. |
| `jobTitle` | string | Vacancy title as advertised. |
| `jobType` | string | Permanent, Contract or Temporary. Part time is not a contract type on Reed - see isPartTime. |
| `jobUrl` | string | Permanent Reed page for the vacancy. |
| `location` | string | Town or city as Reed displays it. |
| `postedAt` | string | Timestamp the vacancy was first published. |
| `remoteWorkingOption` | string | On-Site, Hybrid, Remote or NotSpecified, as Reed classifies it. Many employers leave it unspecified. |
| `retrievedAt` | string | UTC ISO 8601 timestamp of this run. |
| `salaryFrom` | number | Bottom of the advertised pay range, in the period given by salaryPeriod. Omitted when the posting advertises no real pay. |
| `salaryPeriod` | string | Period the salary figures are quoted in. |
| `salaryTo` | number | Top of the advertised pay range. Omitted when the posting advertises no real pay. |
| `subCategory` | string | Reed’s second-level classification. |
| `updatedAt` | string | Timestamp the vacancy was last edited. |

5 named dataset views ship with it: **Jobs**, **Salaries**, **Employers**, **Remote & flexible**, **Freshness**. They drive the Output tab in Console and the Output block on the Actor's `.md` page.

### FAQ

#### How do I scrape jobs from Reed.co.uk?

Run this actor with a job keyword and optionally a location. It reads Reed's public job-search
pages, which publish their results as structured data in the page itself, so there is no HTML
guesswork and no browser.

#### Do I need a Reed API key?

No. Reed's Jobseeker API needs a registered key, and Reed's `robots.txt` disallows `/api/` to
crawlers, so this actor deliberately does not touch it. It reads the public `/jobs/` pages, which
`robots.txt` allows for every agent, and it never uses the query parameters Reed asks crawlers to
avoid.

#### How recent can I make the results?

Reed offers four posting windows - today, last 3 days, last week and last 2 weeks - and this
actor offers exactly those. Any other number is ignored by Reed's own site and would quietly
return everything, so the actor reports that instead of pretending the filter worked.

#### Why do some jobs have no salary?

Because the employer did not advertise one. Reed also attaches a wide filter band to some
postings that is not real pay - measured over 250 postings, those bands run a median £90,000
wide, with entries like "Night Warehouse Operative £25,000-£100,000". Those are reported as
having no salary rather than published as if they were genuine figures. Turn on **Only jobs that
advertise a salary** to drop them entirely.

#### What is the difference between contract type and part time?

On Reed they are separate. Contract type is Permanent, Contract or Temporary; part time is its
own flag, so a part-time permanent role and a part-time contract both exist. Use **Contract
type** for the first and **Part-time only** for the second.

#### How many jobs can one run return?

Up to 2,000 per search. Reed serves 25 vacancies per page, so a 500-job run is 20 page requests.
Split a bigger job across keywords or locations.

#### How do I track one employer's hiring?

Put their name into **Employer name contains**. Every row also carries `employerId`, Reed's
stable advertiser identifier, so you can group across runs even if the display name changes.

#### How often should I re-run it?

Daily is enough for market research; hourly suits candidate alerting on a narrow search with
**Posted within: Today**. Rows are keyed by `jobId`, so diffing runs is straightforward.

#### Can an AI agent call this actor?

Yes. Every input and output field carries a title, description and example, and every row is
addressed by Reed's `jobId`, so an agent can fill the input and chain the output without extra
prompting.

***

Unofficial - not affiliated with Reed. Collects public data only. reapx.
Contact reapxdev@proton.me.

### The full published archive

- **[reed jobs scraper archive](https://reapx.dev/data/reed-jobs-scraper/)** — every entity this Actor has observed
- **[All reapx datasets](https://reapx.dev/data/)** — 20 sources, tens of thousands of pages
- **[llms.txt](https://reapx.dev/llms.txt)** · **[feed.json](https://reapx.dev/feed.json)** ·
  **[feed.xml](https://reapx.dev/feed.xml)** — the machine-readable index, for agents

Each archive page carries Dataset JSON-LD, a canonical URL and the identifiers used, so an agent
can resolve an entity without running anything. Nothing on those pages is estimated or modelled.

### 🧪 Example input

A real, runnable configuration — this is an actual input this Actor has run with.

```json
{
  "what": "pharmacist",
  "where": "",
  "maxJobs": 250,
  "onlyWithSalary": false,
  "onlyRemote": false,
  "onlyPartTime": false,
  "excludeAgencies": false
}
```

### 📄 Sample output

One real row from a real run of this Actor, unedited.

```json
{
  "jobId": "57043673",
  "jobTitle": "Pharmacist",
  "employer": "ASDA",
  "employerId": "403212",
  "location": "Kirkcaldy",
  "county": "Fife",
  "hasSalary": false,
  "jobType": "Permanent",
  "isFullTime": false,
  "isPartTime": true,
  "remoteWorkingOption": "On-Site",
  "category": "Pharmacist",
  "isEasyApply": false,
  "isFeatured": true,
  "eligibleUkOnly": true,
  "postedAt": "2026-06-22T13:58:43",
  "updatedAt": "2026-08-03T00:12:27",
  "expiresAt": "2026-09-14T23:55:00",
  "descriptionSnippet": "Job Title Pharmacist Location Kirkcaldy Employment Type Part time Contract Type Permanent Shift Pattern Work Shift: Days Hours per Week 27 Salary Competitive salary plus benefits Category Pharmacy, Retail Healthcare Closing Date 4 September 2026 Y...",
  "jobUrl": "https://www.reed.co.uk/jobs/pharmacist/57043673",
  "retrievedAt": "2026-08-03T12:21:08Z"
}
```

### How it works

1. You set the filters below, or none at all.
2. The Actor calls the source's own public endpoint and pages through the results.
3. Every row is pushed to the dataset **as it is built**, not buffered to the end — so a
   run that hits its time limit still returns everything it collected up to that point.
4. You are charged per row returned, so the maximum-results field is also your cost cap.

### 💬 Your feedback

Found a bug, or need a field this does not return yet? Open an issue on the Actor's **Issues**
tab, or write to **reapxdev@proton.me**. Bugs get fixed and reasonable field requests get
added.

# Actor input Schema

## `what` (type: `string`):

Job title or skill, exactly as you would type it into Reed's own search box. Leave empty to search every vacancy on the site.

## `where` (type: `string`):

UK town, city, county or region. Reed matches its own location vocabulary, so "london", "greater-manchester" and "west-midlands" all work.<br><br>Leave this field empty to skip this filter.

## `maxJobs` (type: `integer`):

Hard cap on how many vacancies the run returns. This is also your cost cap: you are charged once per job returned.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `postedWithinDays` (type: `string`):

How recently the vacancy was posted. Reed supports exactly these four windows; any other value is ignored by the site and would silently return everything, so only these are offered.<br><br>Options: <code>1</code>, <code>3</code>, <code>7</code>, <code>14</code>.

## `minSalaryGbp` (type: `integer`):

Only vacancies advertising at least this annual salary. Postings quoted hourly, daily or monthly are excluded, because they are not comparable to an annual figure.

## `maxSalaryGbp` (type: `integer`):

Only vacancies advertising at most this annual salary.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `onlyWithSalary` (type: `boolean`):

Drop vacancies with no published pay. Reed marks some postings with a filter band rather than real pay; those are treated as having no salary.

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

Limit to one kind of engagement. Part time is not a contract type on Reed; use the part-time filter below instead.<br><br>Options: <code>Permanent</code>, <code>Contract</code>, <code>Temporary</code>.

## `onlyPartTime` (type: `boolean`):

Keep only vacancies Reed marks as part time. This is independent of contract type, so a part-time permanent role and a part-time contract both qualify.

## `onlyRemote` (type: `boolean`):

Drop vacancies Reed marks as on-site only.

## `excludeAgencies` (type: `boolean`):

Exclude recruitment agency listings and keep only vacancies posted by the hiring employer.

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

Keep only vacancies whose employer name contains this text, matched case-insensitively.<br><br>Leave this field empty to skip this filter.

## Actor input object example

```json
{
  "what": "registered nurse",
  "where": "manchester",
  "maxJobs": 100,
  "postedWithinDays": "7",
  "minSalaryGbp": 50000,
  "maxSalaryGbp": 90000,
  "onlyWithSalary": true,
  "jobType": "Contract",
  "onlyPartTime": true,
  "onlyRemote": true,
  "excludeAgencies": true,
  "employer": "NHS"
}
```

# Actor output Schema

## `jobs` (type: `string`):

One row per vacancy with employer, location, pay and link.

## `salaries` (type: `string`):

Only the pay data, for benchmarking a role or a market.

## `employers` (type: `string`):

Who is hiring, and how they are advertising.

## `remoteAndFlexible` (type: `string`):

Working pattern per vacancy.

## `freshness` (type: `string`):

Posting, update and expiry dates for tracking how long vacancies stay open.

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

Every record this run produced, with all fields and no view applied. Field-level titles, types, descriptions and examples are declared in the dataset schema.

# 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 = {
    "what": "python developer",
    "maxJobs": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/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 = {
    "what": "python developer",
    "maxJobs": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/reed-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 '{
  "what": "python developer",
  "maxJobs": 100
}' |
apify call reapx/reed-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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