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

\[💰 $0.95 / 1K] Extract UK job listings from Reed.co.uk by keyword, location, salary, contract type, and posted-by source. Get titles, companies, salaries, descriptions, employment types, posted dates, and direct apply URLs — every row a flat job posting.

- **URL**: https://apify.com/solidcode/reed-co-uk-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 6 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.95 / 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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

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

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

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

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

# README

## Reed.co.uk Jobs Scraper

Pull live UK job listings from Reed.co.uk at scale — titles, hiring company, salary parsed into min/max/currency/period, location, employment-type flags, posted date, the full job description, recruiter name, sector, and direct apply URLs. Built for UK recruiters, salary-benchmark analysts, and HR-tech sales teams who need a clean Reed feed without writing scrapers.

### Why This Scraper?

- **Every Reed-native filter wired through** — 5 employment-type toggles (permanent, contract, temp, full-time, part-time), agency vs. direct-employer source filter, 7 distance bands (exact location to 40 miles), 5 date-posted windows (today / last 3 days / last week / last 2 weeks / any), and GBP min/max salary range — none of which the multi-board aggregators expose.
- **Salary parsed into structured fields** — every row carries `salaryMin`, `salaryMax`, `salaryCurrency` as an ISO code, and `salaryPeriod` (annual / hourly / daily / weekly / monthly) alongside the original Reed text. Overseas postings keep their real currency (EUR, USD, AED, INR, CAD, JPY, AUD, PLN, HUF), so a €90,000 role is never mistaken for a £90,000 one. No custom regex on your end to filter "£40-60k" candidates.
- **Up to 5,000 jobs per run** — pagination handled automatically; works equally well at 50 rows for a quick lead pull or 5,000 rows for a region-wide salary survey.
- **Free-form keyword + UK location** — no preset role lists, no fixed locations. Type `"data engineer"` + `"se1"` (postcode) or `"warehouse operative"` + `"manchester"` and Reed's own geocoder handles the rest.
- **The full job description on every row, no toggle required** — `description` carries the complete posting body as plain text on every standard run, not a truncated preview. The optional enrichment pass adds exactly three extras on top: `descriptionHtml` (the same text with its original formatting), `sector` (Reed's own category), and `recruiterReedProfileUrl` for the recruiters Reed publishes a page for.
- **Accepts pasted Reed URLs** — drop in a search-results URL straight from the Reed website (sector picker, graduate, easy-apply, and visa-sponsorship flags all carry through) or an individual job-detail URL — both work side-by-side with free-text queries in the same run.
- **Per-row search echo** — every row records the `searchKeywords` and `searchLocation` that produced it, so multi-query batch runs stay filterable downstream in CSV / Excel / Postgres.
- **No login. No API key. No setup.** Enter a keyword and a UK city and you have a clean dataset in minutes.

### Use Cases

**Recruitment Lead Generation**

- Build target lists of recruitment agencies actively advertising in your sector, named on every row
- Identify direct employers hiring for the same role you place candidates into
- Track which agencies dominate a given UK region or job category
- Turn on detail enrichment to add a Reed company-profile link for the recruiters who publish one, so you can jump straight from a lead to their live vacancy list

**Salary Benchmarking**

- Live UK pay data by role, region, and seniority, refreshed on demand
- Compare permanent vs. contract day-rates for the same job title
- Surface salary-band shifts week-on-week for compensation reviews

**Job-Aggregator & White-Label Boards**

- Backfill a niche or regional jobs board with curated Reed listings
- Power a Slack/email alerting product for new roles in a specific stack
- Build a sector-specific newsletter (FinTech London, NHS healthcare, etc.)

**Workforce & Skills Market Research**

- Track demand for skills like "Python", "AWS", "Salesforce" by region over time
- Map remote vs. hybrid vs. on-site mix in your industry
- Quantify graduate, contract, and permanent supply per UK city

**Competitive Intelligence for HR-Tech Sales**

- Identify recruitment agencies as warm leads for ATS, CRM, or sourcing tools
- Track which competitors of your target customer are hiring (and for what)
- Monitor hiring spikes to time outbound campaigns

### Getting Started

#### Basic Search

A single keyword + city — fastest path to a useful dataset:

```json
{
    "keywords": "python developer",
    "location": "london"
}
```

#### Filtered Search

Narrow to fixed-term contract data engineers in Manchester within 20 miles, paying £60k+:

```json
{
    "keywords": "data engineer",
    "location": "manchester",
    "distance": "20",
    "permanent": false,
    "contract": true,
    "temp": false,
    "minSalary": 60000,
    "maxResults": 200
}
```

#### URL List with Detail Enrichment

Mix two pre-filtered Reed search URLs and add formatted descriptions, sector, and recruiter profile links to both:

```json
{
    "urls": [
        "https://www.reed.co.uk/jobs/python-jobs-in-bristol",
        "https://www.reed.co.uk/jobs/devops-jobs-in-edinburgh"
    ],
    "fetchDescription": true,
    "maxResults": 500
}
```

### Input Reference

#### Search

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `keywords` | string | `"python developer"` | Job title or skill to search, such as `"python developer"` or `"marketing manager"`. Leave empty to scrape Reed's general listing. |
| `location` | string | `"london"` | UK city, region, or postcode (e.g., `"london"`, `"manchester"`, `"se1"`, `"remote"`). Reed accepts full or partial postcodes and town names. |
| `distance` | select | `10 miles` | Search radius from the location: `Exact location only`, `5 miles`, `10 miles`, `15 miles`, `20 miles`, `30 miles`, `40 miles`. Ignored when location is empty. |
| `urls` | string\[] | `[]` | Optional. Paste Reed.co.uk search URLs or individual job URLs. Filters baked into pasted URLs are honored as-is. |

#### Job Type

A single posting can carry multiple flags (e.g., a role can be both contract AND full-time). Each toggle includes any role tagged with that flag.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `permanent` | boolean | `true` | Include permanent contract roles. |
| `contract` | boolean | `true` | Include fixed-term contract roles. |
| `temp` | boolean | `true` | Include temporary roles. |
| `fullTime` | boolean | `true` | Include full-time roles. |
| `partTime` | boolean | `false` | Include part-time roles. |

#### Salary

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `minSalary` | integer | null | Minimum annual salary in GBP. Many Reed listings are tagged `"Competitive"` and may be excluded by Reed's server-side filter when set. |
| `maxSalary` | integer | null | Maximum annual salary in GBP. |

#### Filters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `postedBy` | select | `Any (agency or direct employer)` | Filter by who listed the role: `Any (agency or direct employer)`, `Recruitment agency only`, or `Direct employer only`. |
| `datePosted` | select | `Any time` | Only show roles posted within this window: `Any time`, `Today`, `Last 3 days`, `Last week`, `Last 2 weeks`. |

#### Advanced

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `fetchDescription` | boolean | `false` | Off by default. Adds three fields to every row: `descriptionHtml`, `sector`, and `recruiterReedProfileUrl`. It does **not** control `description` — the full plain-text posting body is already on every row without it. Enrichment opens each posting individually, so runs take substantially longer; the per-result price is the same either way. |
| `maxResults` | integer | `100` | Cap on total job rows across all keywords and URLs. Hard upper bound is 5,000 — set to `0` to use that cap directly. The actor stops requesting new pages once this number is reached but keeps the full final page even if it slightly overshoots (up to ~100 results per page). |

### Output

Every row is a flat job posting. Here is a representative result:

```json
{
    "jobId": "56626200",
    "title": "Python Developer - Insurance Analytics",
    "company": "McGregor Boyall",
    "location": "London",
    "salary": "£40,000 - £60,000 per annum",
    "salaryMin": 40000,
    "salaryMax": 60000,
    "salaryCurrency": "GBP",
    "salaryPeriod": "annual",
    "employmentType": ["Permanent", "Full-time"],
    "postedBy": "agency",
    "postedDate": "2026-04-28T10:27:23",
    "expiryDate": "2026-06-09T23:55:00",
    "applyUrl": "https://www.reed.co.uk/jobs/python-developer-insurance-analytics/56626200/apply",
    "jobUrl": "https://www.reed.co.uk/jobs/python-developer-insurance-analytics/56626200",
    "snippet": "We are looking for a Python developer to join our insurance analytics team...",
    "description": "We are looking for a Python developer to join our insurance analytics team. You will be working on...",
    "descriptionHtml": "<p>We are looking for a <strong>Python</strong> developer...</p><ul><li>5+ years experience</li></ul>",
    "sector": "IT & Telecoms",
    "recruiterName": "McGregor Boyall",
    "recruiterReedProfileUrl": "https://www.reed.co.uk/company-profile/McGregor-Boyall-49265",
    "searchKeywords": "python developer",
    "searchLocation": "london",
    "scrapedAt": "2026-05-09T14:30:00Z"
}
```

#### Core Fields

| Field | Type | Description |
|-------|------|-------------|
| `jobId` | string | Reed's numeric job identifier. |
| `title` | string | Job title as posted. |
| `company` | string | null | Hiring company name. May be null when posted by an agency anonymously. |
| `location` | string | Location as Reed displays it (e.g., `"London"`, `"Manchester · Remote"`). |
| `snippet` | string | Short preview always present from the search results card. |
| `postedDate` | string | When the role was posted (ISO 8601). |
| `expiryDate` | string | null | When the listing closes (ISO 8601). |

#### Salary

| Field | Type | Description |
|-------|------|-------------|
| `salary` | string | null | Salary text as posted (e.g., `"£45,000 - £55,000 per annum"`, `"£18 per hour"`, `"Competitive"`). |
| `salaryMin` | number | null | Parsed minimum salary. Null when not parseable. |
| `salaryMax` | number | null | Parsed maximum salary. Null when not parseable. |
| `salaryCurrency` | string | null | ISO currency code. `"GBP"` on the overwhelming majority of rows; overseas listings return their own code (`EUR`, `USD`, `AED`, `INR`, `CAD`, `JPY`, `AUD`, `PLN`, `HUF`). Null only when Reed reports a currency we cannot identify, in which case `salary` omits the symbol rather than guessing. |
| `salaryPeriod` | string | null | `"annual"`, `"monthly"`, `"weekly"`, `"daily"`, `"hourly"`, or null. |

#### Employment & Source

| Field | Type | Description |
|-------|------|-------------|
| `employmentType` | string\[] | Subset of `["Permanent", "Contract", "Temporary", "Full-time", "Part-time"]`. |
| `postedBy` | string | null | `"agency"` or `"directEmployer"`. |
| `sector` | string | null | Reed's sector category (e.g., `"IT & Telecoms"`, `"Healthcare"`). Enrichment runs only (`fetchDescription: true`); `null` otherwise. |
| `recruiterName` | string | null | Recruiter or company name on the listing page. On every row. |
| `recruiterReedProfileUrl` | string | null | Link to the recruiter's Reed company profile. Enrichment runs only (`fetchDescription: true`), and only for recruiters who have a Reed company profile; `null` otherwise. |

#### Description & Links

| Field | Type | Description |
|-------|------|-------------|
| `description` | string | null | Full job description as plain text. Populated on every row, whether or not `fetchDescription` is on. |
| `descriptionHtml` | string | null | The same description with its original markup preserved (`<p>`, `<ul>`, `<strong>`). Enrichment runs only (`fetchDescription: true`); `null` otherwise. |
| `applyUrl` | string | Direct apply URL — external ATS link when the role redirects, otherwise the Reed apply page. |
| `jobUrl` | string | Reed.co.uk URL for the job detail page. |

#### Search Context

| Field | Type | Description |
|-------|------|-------------|
| `searchKeywords` | string | null | The `keywords` input that produced this row (echoed for batch runs). |
| `searchLocation` | string | null | The `location` input that produced this row. |
| `scrapedAt` | string | ISO 8601 timestamp of the scrape. |

### Tips for Best Results

- **Use `distance` to control noise.** `Exact location only` returns just the postings tagged with that town or postcode; bumping to `40 miles` widens the catchment for commuter-belt or remote-friendly roles. Ignored when `location` is empty.
- **Reed's salary filter overlaps with stated bands.** A posting at `£50,000-£80,000` will appear in a `minSalary: 70000` search because the band crosses your floor — useful for surfacing roles where you're at the top of the range, but expect overlap rather than strict cutoffs.
- **Set `maxResults: 0` to fetch every available row** (capped at the internal 5,000 ceiling). Best paired with a tight keyword + location for a clean salary survey.
- **Paste Reed search URLs to bring filters Reed exposes that this actor doesn't surface as top-level inputs.** Sector picker (`multipleParentSectorIds`), graduate-only, easy-apply, and visa-sponsorship flags are honored when present in the URL — dial in the search on the Reed website, then paste the full URL into the `urls` field.
- **Combine `keywords` + `urls` in one run.** A free-text search and a list of pre-filtered Reed URLs run side-by-side; deduplication by job ID is automatic, so the same posting found twice only counts once.
- **Leave `fetchDescription` off unless you specifically want HTML, sector, or recruiter links.** The full plain-text `description` is on every row either way, so the default setting already gives you readable job bodies for keyword matching, CV parsing, or an LLM pipeline. Switching it on opens every posting one by one and stretches the run out considerably, so keep enriched runs to a few hundred rows to stay inside your run time limit.
- **Use `postedBy: "Recruitment agency only"` for agency lead lists.** Pair it with a sector-filtered URL to surface every agency actively placing into your vertical. Every row names the agency; switch `fetchDescription` on and you also get a Reed company-profile link for the agencies that publish one.

### Pricing

**From $0.95 per 1,000 results.** No compute charges — you only pay per result returned. Apify's loyalty tiers lower the rate as you go, with Gold subscribers paying the least.

| Results | No discount | Bronze | Silver | Gold |
|---------|-------------|--------|--------|------|
| 100 | $0.11 | $0.11 | $0.10 | $0.095 |
| 1,000 | $1.13 | $1.07 | $1.01 | $0.95 |
| 10,000 | $11.30 | $10.70 | $10.10 | $9.50 |
| 100,000 | $113.00 | $107.00 | $101.00 | $95.00 |

Tiered rates take effect on **13 September 2026**. Until that date every run is billed at a flat $0.95 per 1,000 results — the Gold column above. A "result" is any job row in the output dataset. Roughly 4× cheaper than the closest comparable multi-board scraper on the Apify store.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on new results
- **Webhooks** — Trigger custom APIs on run completion
- **Apify API** — Full programmatic access

### Legal & Ethical Use

This actor is designed for legitimate recruitment, salary-benchmarking, market research, and lead-generation work. Users are responsible for complying with applicable laws and Reed.co.uk's terms of service. Do not use extracted data for spam, harassment, or any illegal purpose. Be mindful of UK GDPR when storing or processing personal data appearing in job posts.

# Actor input Schema

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

Job title or skill to search, such as 'python developer' or 'marketing manager'. Leave empty to scrape Reed's general listing.

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

UK city, region, or postcode (e.g., 'london', 'manchester', 'se1', 'remote'). Reed accepts full or partial postcodes and town names.

## `distance` (type: `string`):

Search radius from the location. Ignored when location is empty.

## `urls` (type: `array`):

Optional. Paste Reed.co.uk search URLs (e.g., https://www.reed.co.uk/jobs/python-jobs-in-london) or individual job URLs (e.g., https://www.reed.co.uk/jobs/job/55123456). Filters baked into pasted URLs are honored as-is — useful when you have already dialed in a search on the Reed website.

## `permanent` (type: `boolean`):

Include permanent contract roles.

## `contract` (type: `boolean`):

Include fixed-term contract roles.

## `temp` (type: `boolean`):

Include temporary roles.

## `fullTime` (type: `boolean`):

Include full-time roles.

## `partTime` (type: `boolean`):

Include part-time roles.

## `minSalary` (type: `integer`):

Minimum annual salary in pounds sterling. Leave empty for no lower bound. Note: many Reed listings have unspecified salary text (e.g., 'Competitive') and may be excluded by Reed's own server-side filter when this is set.

## `maxSalary` (type: `integer`):

Maximum annual salary in pounds sterling. Leave empty for no upper bound.

## `postedBy` (type: `string`):

Filter by who listed the role. Reed marks every posting as either an agency listing or a direct-employer listing.

## `datePosted` (type: `string`):

Only show roles posted within this window.

## `fetchDescription` (type: `boolean`):

Off by default. Adds three extra fields to every row: descriptionHtml (the description with its original formatting), sector (Reed's category), and recruiterReedProfileUrl for the recruiters Reed publishes a page for. The full plain-text description is already included without this option. Turning it on opens every posting one by one, so the run takes substantially longer; the price per result is unchanged.

## `maxResults` (type: `integer`):

Cap on total job rows across all keywords and URLs. Default 100. Hard upper bound is 5,000 to prevent runaway pagination — set to 0 to use that internal cap directly. The actor stops requesting new pages once this number is reached but keeps the full final page even if it slightly overshoots (up to ~100 results per page).

## Actor input object example

```json
{
  "keywords": "python developer",
  "location": "london",
  "distance": "10",
  "urls": [],
  "permanent": true,
  "contract": true,
  "temp": true,
  "fullTime": true,
  "partTime": false,
  "postedBy": "any",
  "datePosted": "any",
  "fetchDescription": false,
  "maxResults": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

Table of scraped job listings with key fields.

## `detail` (type: `string`):

Complete job data including descriptions, parsed salary fields, and recruiter info.

# 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": "python developer",
    "location": "london",
    "distance": "10",
    "urls": [],
    "permanent": true,
    "contract": true,
    "temp": true,
    "fullTime": true,
    "partTime": false,
    "postedBy": "any",
    "datePosted": "any",
    "fetchDescription": false,
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/reed-co-uk-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": "python developer",
    "location": "london",
    "distance": "10",
    "urls": [],
    "permanent": True,
    "contract": True,
    "temp": True,
    "fullTime": True,
    "partTime": False,
    "postedBy": "any",
    "datePosted": "any",
    "fetchDescription": False,
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/reed-co-uk-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": "python developer",
  "location": "london",
  "distance": "10",
  "urls": [],
  "permanent": true,
  "contract": true,
  "temp": true,
  "fullTime": true,
  "partTime": false,
  "postedBy": "any",
  "datePosted": "any",
  "fetchDescription": false,
  "maxResults": 50
}' |
apify call solidcode/reed-co-uk-scraper --silent --output-dataset

```

## MCP server setup

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