# Reed Jobs Scraper: UK Jobs with Salary, Remote & Contract Type (`datadesk-io/reed-jobs-scraper`) Actor

Scrape Reed.co.uk jobs by keyword and UK location: title, company, salary min/max with period and yearly equivalent, permanent/contract/temp, remote/hybrid, category, posting and expiry dates, URL. Job alerts mode returns only new jobs. No login. $1 per 1,000 jobs.

- **URL**: https://apify.com/datadesk-io/reed-jobs-scraper.md
- **Developed by:** [DataDesk](https://apify.com/datadesk-io) (community)
- **Categories:** Jobs, Lead generation
- **Security:** Limited permissions
- **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.

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: UK Jobs with Salary, Remote & Contract Filters

Scrape Reed.co.uk jobs by keyword and UK location: title, company, salary min/max with period and yearly equivalent, permanent/contract/temp, remote/hybrid, category, posting and expiry dates, URL. Job alerts mode returns only new jobs. No login. $1 per 1,000 jobs.

Scrape jobs from **Reed (reed.co.uk), one of the largest UK job boards** in seconds: no login, no browser, no proxy setup. Built for UK recruiters, agencies, salary analysts and job seekers.

### What you can do with it

- UK salary and day-rate benchmarks (permanent and contract)
- Lead lists of UK companies hiring, with agency vs direct employer filter
- Remote UK job feeds
- Daily job alerts by keyword and town

### Why this scraper

- **Clean, normalized salary**: the text as shown plus `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` and a yearly equivalent (`salaryYearlyMin` / `salaryYearlyMax`) so you can sort and compare.
- **Job alerts mode**: turn on *Only new jobs*, schedule the Actor daily, and you get (and pay for) only jobs you have not received before.
- **Fast and cheap**: reads the site's own search data instead of rendering pages. A default run finishes in a few seconds.
- **Pay only for results**: $1.00 per 1,000 jobs + $0.005 per run. No results, no job charges. Your spending limit is respected exactly: we never deliver rows you did not pay for, and never charge for rows we did not deliver.
- **Deduplicated** across keywords and pages.

### Job alerts (only new jobs)

1. Set your search and turn on **Job alerts mode: only new jobs**.
2. Give it an **Alert name** (one per saved search).
3. Create a Schedule (e.g. every morning) and connect an integration (email, Slack, Google Sheets, Make, Zapier, webhook).
   Each run returns only jobs posted since the previous run. Runs with no new jobs cost almost nothing.

### Sources and coverage

| Source | Coverage | Data |
|---|---|---|
| **Reed (reed.co.uk)** | United Kingdom | title, employer, location, salary, contract type, remote, agency flag, description snippet |

### How to use it

1. Click **Try for free** (or **Start**): the prefilled input runs a quick test.
2. Fill in the input fields (see the examples below). Every field is optional.
3. Click **Start** and wait a few seconds to minutes, depending on how many jobs you ask for.
4. Open the **Output** tab and export as **JSON, CSV, Excel, XML or HTML**, or read the results via API.

### Input examples

**Data analysts (default):**

```json
{"keywords": ["data analyst"], "maxJobsPerSearch": 20}
```

**Manchester, 20 miles, permanent:**

```json
{"keywords": ["nurse"], "location": "Manchester", "radiusMiles": 20, "contractTypes": ["permanent"]}
```

**Direct employers, £40k+:**

```json
{"keywords": ["accountant"], "salaryFrom": 40000, "directEmployersOnly": true}
```

**Visa sponsorship, daily alerts:**

```json
{"keywords": ["software engineer"], "visaSponsorship": true, "onlyNewJobs": true, "alertsKey": "uk-visa"}
```

#### Input fields

| Field | Type | Description |
|---|---|---|
| `keywords` | array | Job titles or skills, e.g. data analyst, nurse, warehouse. |
| `location` | string | UK town, city or postcode area, e.g. London, Manchester. Empty = all UK. |
| `radiusMiles` | integer | Search radius in miles around the location (e.g. 10, 20, 50). Only used when a location is set. |
| `contractTypes` | array | Only these contract types (permanent, contract, temporary, part-time, full-time, graduate). Empty = all. |
| `remoteOnly` | boolean | Keep only jobs Reed marks as remote / work from home. |
| `salaryFrom` | integer | Optional minimum salary in GBP per year (e.g. 40000). Jobs below it are skipped. |
| `directEmployersOnly` | boolean | Exclude recruitment agencies; keep only jobs posted directly by employers. |
| `visaSponsorship` | boolean | Keep only jobs that offer UK visa sponsorship. |
| `maxJobsPerSearch` | integer | Cap per keyword (and per country). You only pay for jobs saved. |
| `postedWithinDays` | integer | Only jobs posted in the last N days. 0 = any date. |
| `onlyNewJobs` | boolean | Remember jobs from earlier runs and save only jobs you have not received before. Schedule the Actor daily to get a job alert feed. You pay only for new jobs. |
| `alertsKey` | string | Separate memory per alert (e.g. "sydney-nurses"). Use a different name for each saved search. |

### Output example

One row per item. Values below are **example values** from a real test run (long text shortened):

```json
{
  "source": "reed",
  "jobId": "57513660",
  "title": "Assistant Data Analyst",
  "company": "Anglian Home Improvements",
  "isRecruiter": false,
  "companyUrl": "https://www.reed.co.uk/jobs/anglian-home-improvements-102505/p102505",
  "location": "Norwich",
  "county": "Norfolk",
  "country": "GB",
  "workingOption": "onSite",
  "isRemote": false,
  "jobType": "permanent",
  "isFullTime": true,
  "isPartTime": false,
  "salary": "£30,000 - £35,000 per year",
  "salaryMin": 30000,
  "salaryMax": 35000,
  "salaryCurrency": "GBP"
  "…": "more fields below"
}
```

Fields a source does not publish are `null`.

#### Output fields

| Field | Description |
|---|---|
| `source` | Site the job came from |
| `jobId` | Job ID on the source site |
| `title` | Job title |
| `company` | Employer name |
| `isRecruiter` | True if posted by a recruitment agency |
| `companyUrl` | Public LinkedIn company page of the employer (null if the job has none) |
| `location` | Location as shown |
| `county` | County / region |
| `country` | Country code |
| `workingOption` | Working option (on-site, hybrid, remote) |
| `isRemote` | True for remote jobs |
| `jobType` | Job type (full-time, part-time, contract...) |
| `isFullTime` | True if full-time |
| `isPartTime` | True if part-time |
| `salary` | Salary as shown |
| `salaryMin` | Minimum salary (number) |
| `salaryMax` | Maximum salary (number) |
| `salaryCurrency` | ISO currency code |
| `salaryPeriod` | hour, day, week, month or year |
| `salaryYearlyMin` | Minimum salary converted to a yearly amount |
| `salaryYearlyMax` | Maximum salary converted to a yearly amount |
| `category` | Leaderboard category |
| `subCategory` | Job sub-category |
| `easyApply` | True if the job supports one-click/easy apply |
| `ukOnly` | True if only UK-based applicants are accepted |
| `isPromoted` | True for promoted (ad) pins |
| `descriptionSnippet` | Short excerpt of the job description |
| `postedAt` | Posting date (ISO 8601 UTC) |
| `expiresAt` | Date the posting expires (ISO 8601) |
| `url` | Job page URL |
| `externalUrl` | External application URL, if any |
| `keyword` | Search keyword that found the job |
| `scrapedAt` | When the job was scraped (ISO 8601 UTC) |
| `isNew` | True when job alerts mode is on (job not seen in earlier runs) |

The Output tab has a **Jobs** view.

### Pricing

Pay-per-event: you pay only for results delivered, no monthly fee.

- **Job** (`job`): **$1.00 per 1,000** ($0.001 each)
- **Actor start:** $0.005 per run

| Run | Jobs | Cost |
|---|---|---|
| Quick test | 20 | $0.025 |
| Small run | 100 | $0.105 |
| Regular run | 1,000 | $1.005 |
| Large run | 10,000 | $10.005 |

Rows that are not delivered are never charged. Apify's free plan includes monthly credit, and you can set a maximum cost per run in the run options.

### Integrations and API

- Export results as JSON, CSV, Excel, XML or HTML from the Output tab.
- **Schedule** runs (daily, hourly) and send results to Google Sheets, Slack, Zapier, Make, n8n, Airbyte or webhooks.
- Call it from code with the [Apify API](https://docs.apify.com/api/v2):

```bash
curl -X POST "https://api.apify.com/v2/acts/datadesk-io~reed-jobs-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["data analyst"], "maxJobsPerSearch": 20}'
```

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("datadesk-io/reed-jobs-scraper").call(run_input={'keywords': ['data analyst'], 'maxJobsPerSearch': 20})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get('title'), item.get('company'), item.get('url'))
```

### FAQ

**Do I need an account or cookies?** No. The Actor only reads public job listings.

**Does it scrape personal data?** No. It returns job ads and company names only, no candidate or recruiter profiles. Use the data in line with the site's terms and applicable laws (GDPR etc.).

**Can I get full job descriptions?** Rows include the summary/snippet the search shows. Open `url` for the full ad.

**Something broke or you need a field?** Open an issue on the Issues tab; we usually answer within a day.

**How fresh is the data?** Live: every run reads the source at that moment. Schedule it to keep a dataset up to date.

**Why did I get fewer jobs than the maximum?** The source had fewer matching jobs, or duplicates were removed. You only pay for jobs delivered.

*Not affiliated with or endorsed by the job board. Trademarks belong to their owners.*

### Limitations

- UK jobs only.
- Description is a snippet; open `url` for the full text.
- Up to the max per keyword.

### Support

Found a bug, or need a new field, source or filter? Open an issue in the **Issues** tab; we usually answer within 24 hours. Custom data work: datadesk.io@proton.me.

# Actor input Schema

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

Job titles or skills, e.g. data analyst, nurse, warehouse.

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

UK town, city or postcode area, e.g. London, Manchester. Empty = all UK.

## `radiusMiles` (type: `integer`):

Search radius in miles around the location (e.g. 10, 20, 50). Only used when a location is set.

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

Only these contract types (permanent, contract, temporary, part-time, full-time, graduate). Empty = all.

## `remoteOnly` (type: `boolean`):

Keep only jobs Reed marks as remote / work from home.

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

Optional minimum salary in GBP per year (e.g. 40000). Jobs below it are skipped.

## `directEmployersOnly` (type: `boolean`):

Exclude recruitment agencies; keep only jobs posted directly by employers.

## `visaSponsorship` (type: `boolean`):

Keep only jobs that offer UK visa sponsorship.

## `maxJobsPerSearch` (type: `integer`):

Cap per keyword (and per country). You only pay for jobs saved.

## `postedWithinDays` (type: `integer`):

Only jobs posted in the last N days. 0 = any date.

## `onlyNewJobs` (type: `boolean`):

Remember jobs from earlier runs and save only jobs you have not received before. Schedule the Actor daily to get a job alert feed. You pay only for new jobs.

## `alertsKey` (type: `string`):

Separate memory per alert (e.g. "sydney-nurses"). Use a different name for each saved search.

## Actor input object example

```json
{
  "keywords": [
    "data analyst"
  ],
  "remoteOnly": false,
  "directEmployersOnly": false,
  "visaSponsorship": false,
  "maxJobsPerSearch": 20,
  "onlyNewJobs": false
}
```

# Actor output Schema

## `jobs` (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": [
        "data analyst"
    ],
    "maxJobsPerSearch": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("datadesk-io/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": ["data analyst"],
    "maxJobsPerSearch": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("datadesk-io/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": [
    "data analyst"
  ],
  "maxJobsPerSearch": 20
}' |
apify call datadesk-io/reed-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datadesk-io/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/IGmmtwIthLOZXGiZc/builds/9d5aKqh9TeuJ5LVIG/openapi.json
