# Totaljobs Scraper - UK Jobs, Salaries & Hiring Companies (`clearpath/totaljobs-uk-job-scraper`) Actor

Scrape UK jobs from Totaljobs, CWJobs, Jobsite, Caterer and Milkround. Every row carries the salary the employer advertised, not an estimate, plus their sector, size, employee rating and open roles, and the skills named in the advert. Filter to direct employers and leave the agencies out.

- **URL**: https://apify.com/clearpath/totaljobs-uk-job-scraper.md
- **Developed by:** [ClearPath](https://apify.com/clearpath) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.99 / 1,000 job scrapeds

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

## Totaljobs Scraper | UK Jobs, Advertised Salaries & Hiring Companies (2026)

[![More than job ads. The company details too. Employee counts. Staff ratings. Company profiles.](https://api.apify.com/v2/key-value-stores/rfpznBPgVbyLYqNaQ/records/totaljobs-uk-job-scraper-readme-hero-v2-066fa785dd44.png)](https://console.apify.com/actors/bc0M5EvO4rEZNuHqM/input)

From **Clearpath**, creators of [StepStone Jobs](https://apify.com/clearpath/stepstone-de-job-scraper), [Welcome to the Jungle Jobs](https://apify.com/clearpath/welcome-to-the-jungle-jobs-api) and [Wellfound Jobs](https://apify.com/clearpath/wellfound-api-ppe). Specialist job scrapers for recruitment, salary research and finding companies that are hiring.

### Why choose this actor?

**Get the company details too.** Get employee count bands, sector, founding year, staff ratings, open vacancies, address and company description where published. Find employers of the right size and see how actively they are hiring, alongside the full job advert.

**Richer employer data than leading alternatives document.** Black Falcon’s Totaljobs and StepStone Group outputs document company identity, links and ratings; our records also include company size, founding year, open vacancies and company descriptions. Shahidirfan’s TotalJobs output documents the company name, link and logo. See the [field comparison](#how-it-compares) below.

**Full job details across five UK boards.** Collect advertised salaries, skills and complete descriptions across **Totaljobs, CWJobs, Jobsite, Caterer and Milkround**. No separate detail upgrade. Filter to direct employers when your goal is a list of companies hiring for themselves.

<a href="https://console.apify.com/actors/bc0M5EvO4rEZNuHqM/input"><img src="https://api.apify.com/v2/key-value-stores/rfpznBPgVbyLYqNaQ/records/totaljobs-uk-job-scraper-readme-cta-3ac03a65f4bd.svg" width="244" height="48" alt="Find hiring companies on Totaljobs"/></a>

### Try a search

Start with 10 Python roles around London. Employer details are included automatically where the company publishes them.

```json
{
  "keyword": "python developer",
  "location": "London",
  "site": "totaljobs",
  "radius": 10,
  "maxItems": 10
}
```

[Open actor input](https://console.apify.com/actors/bc0M5EvO4rEZNuHqM/input) to change the role, location or job board. To exclude recruitment agencies, add `"postedBy": "employer"`. Export JSON, CSV or Excel; JSON keeps the nested salary, skills and company details together.

<table><tr><td colspan="4" style="background:#0C2577;color:#FFFFFF;padding:10px 14px;font-size:13px;font-weight:700">Clearpath · Job Market Data</td></tr><tr><td style="background:#D2F3F5;padding:9px 10px;border:1px solid #A7B3D3;vertical-align:top;white-space:nowrap"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-bc0M5EvO4rEZNuHqM-2cGUywMaMX-stepstone-deutschland-scraper-logo.png" width="20" height="20" alt="" style="display:inline-block;vertical-align:middle;margin:0"/>&nbsp;<a href="https://apify.com/clearpath/totaljobs-uk-job-scraper" style="color:#0C2577;text-decoration:none;font-weight:700;font-size:13px">Totaljobs</a></span><br><span style="color:#003954;font-size:12px;white-space:nowrap">You are here</span></td><td style="background:#E1F6F7;padding:9px 10px;border:1px solid #A7B3D3;vertical-align:top;white-space:nowrap"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-cB8bzys6LuwcwX70q-fJBZqO5VQe-stepstone-deutschland-scraper-logo.png" width="20" height="20" alt="" style="display:inline-block;vertical-align:middle;margin:0"/>&nbsp;<a href="https://apify.com/clearpath/stepstone-de-job-scraper" style="color:#0C2577;text-decoration:none;font-weight:700;font-size:13px">StepStone</a></span><br><span style="color:#003954;font-size:12px;white-space:nowrap">DE · AT · BE · NL</span></td><td style="background:#E1F6F7;padding:9px 10px;border:1px solid #A7B3D3;vertical-align:top;white-space:nowrap"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-MdJIadsWKRaguareT-XPALnVdNgE-welcome-to-the-jungle-jobs-scraper-logo.png" width="20" height="20" alt="" style="display:inline-block;vertical-align:middle;margin:0"/>&nbsp;<a href="https://apify.com/clearpath/welcome-to-the-jungle-jobs-api" style="color:#0C2577;text-decoration:none;font-weight:700;font-size:13px">Welcome to the Jungle</a></span><br><span style="color:#003954;font-size:12px;white-space:nowrap">Jobs & companies</span></td><td style="background:#E1F6F7;padding:9px 10px;border:1px solid #A7B3D3;vertical-align:top;white-space:nowrap"><span style="white-space:nowrap"><img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/DSvMCAwsufMyZeLyt-actor-sqkHGNG0toRTR3ORV-zgctRChWeu-wellfound-jobs-scraper-logo.png" width="20" height="20" alt="" style="display:inline-block;vertical-align:middle;margin:0"/>&nbsp;<a href="https://apify.com/clearpath/wellfound-api-ppe" style="color:#0C2577;text-decoration:none;font-weight:700;font-size:13px">Wellfound</a></span><br><span style="color:#003954;font-size:12px;white-space:nowrap">Salary & equity</span></td></tr></table>

#### Copy to your AI assistant

```
clearpath/totaljobs-uk-job-scraper on Apify. Scrapes UK job listings from Totaljobs, CWJobs, Jobsite, Caterer and Milkround and returns one fully detailed row per job: the employer's advertised salary, the full description and its sections, skills named in the advert, postcode and coordinates, and the hiring company's sector, employee band, founding year, staff rating, open-role count, address and self-description. There are no modes and no enrichment switch, every row is full detail at one price. Search with keyword + location (+ site totaljobs|cwjobs|jobsite|caterer|milkround, radius in miles needs a location, jobType permanent|contract|part-time|temporary|work-from-home, publishedSince 24h|3d|7d|14d, postedBy employer|agency, minSalary with salaryPeriod year|day|hour), OR pass startUrls with result/job page URLs, which REPLACE the keyword search and its filters entirely and split maxItems evenly between result pages; a page= in a pasted address is ignored. maxItems is the run-wide total, default 100, 0 means keep going until results run out but never past 10,000 in one run. Every filter is off by default and each one returns fewer jobs; postedBy is an input filter only and no row states whether the advertiser was an employer or an agency. exactMatchesOnly (default false) drops the related-title and nearby-town rows the boards pad a list with, before they are fetched or charged; matchType exact|related|nearby|suggested is on every row reached through a search and is null on a job reached by a pasted URL. Constraints to respect before promising fields: salary is the employer's own line and never an estimate (isEstimate is always false), but the figures are read out of free text, so min/max can be null while description still carries wording like "Negotiable"; workType, benefits, streetAddress and badges are always empty on these boards; contactEmails/contactPhones appear only where the employer printed them; the five boards cross-post, so site and url can name a different board from the one searched. Expired listings are skipped, never billed. Pricing: pay per event, $1.99 per 1,000 jobs, plus the standard Apify Actor start fee per run. Full spec (input schema, dataset fields, README): GET https://api.apify.com/v2/actors/clearpath~totaljobs-uk-job-scraper/builds/default with Authorization: Bearer <APIFY_TOKEN>. Token: https://console.apify.com/account/integrations
```

### What you get

- **The hiring company, in depth.** Sector, employee band, the year it was founded, its staff rating and review count, how many other roles it currently has open, its address, its own description of itself, logo and photos. These extra employer details are included when the company publishes them; availability varies by listing.
- **The salary the employer advertised.** Both the wording (`"£90000 - £110000 per annum + bonus + benefits"`) and the parsed range. Annual salaries, day rates, hourly rates, `£50k` shorthand and "up to" ceilings are all handled, and a figure is never invented where the advert says "Negotiable".
- **Skills mentioned in the advert.** Matched against a vocabulary of the tools, standards, licences and certifications UK job ads name: SC clearance, CSCS, NEBOSH, ACCA, NMC, IR35, HGV and the usual technical stack. Deterministic matching of what the advert says, so no AI cost and nothing invented.
- **The job's own address.** Postcode and coordinates where the advert states them, not just the city.
- **Application contacts the employer printed.** Where the advert names a recruiter address or phone number, you get it. Nothing is looked up anywhere else.
- **Built for volume.** A measured run collected **500 jobs in 1 minute 41 seconds**, every one unique, with no failed pages. Set `maxItems` to `0` and it keeps going until the search runs out, up to 10,000 jobs in one run.

#### How it compares

The difference is employer detail you can use to qualify a lead. This compares the published output schemas and examples of the first three results for “totaljobs” in Apify Store relevance search. “Not documented” means the field is not shown in the checked output documentation; it is not a claim that we tested their runtime.

| Employer data | This actor | Black Falcon Totaljobs / StepStone Group | Shahidirfan TotalJobs |
|---|---|---|---|
| Name, profile link and logo | Included when published | Documented | Documented |
| Staff rating | Included when published | Documented | Not documented |
| Company size and founding year | Included when published | Not documented | Not documented |
| Open vacancies and company description | Included when published | Not documented | Not documented |
| Company sector and address | Included when published | Not documented as employer fields | Not documented |

Sources: [Black Falcon Totaljobs](https://apify.com/blackfalcondata/totaljobs-scraper), [Black Falcon StepStone Group](https://apify.com/blackfalcondata/stepstone-jobs-feed), [Shahidirfan TotalJobs](https://apify.com/shahidirfan/total-jobs-scraper). Black Falcon also documents change tracking and social-link extraction. Our advantage here is employer-profile depth, not a claim to offer every competing feature.

**Nothing is filtered unless you ask.** Every filter is off by default, so an untouched run returns as much as the search can give. `postedBy` and `exactMatchesOnly` both return fewer jobs when you turn them on, and what they remove is never fetched or charged. `matchType` is on every row that came from a search, so you can leave both off and filter afterwards without losing anything. A job you pasted the address of directly has no search to be matched against, so it has no `matchType`.

### Search examples

#### Direct employers only, paying £60,000 or more

```json
{
    "keyword": "financial controller",
    "location": "Manchester",
    "postedBy": "employer",
    "minSalary": 60000,
    "salaryPeriod": "year",
    "maxItems": 200
}
```

#### Contract roles posted in the last three days

```json
{
    "keyword": "devops engineer",
    "location": "London",
    "site": "cwjobs",
    "jobType": "contract",
    "publishedSince": "3d",
    "maxItems": 100
}
```

#### Work-from-home roles, no keyword

```json
{
    "location": "United Kingdom",
    "jobType": "work-from-home",
    "exactMatchesOnly": true,
    "maxItems": 500
}
```

#### Your own searches, across boards

Build the search on the board with whatever filters you like, then paste the address. The maximum is split evenly across the pages you add.

```json
{
    "startUrls": [
        { "url": "https://www.totaljobs.com/jobs/accountant/in-leeds" },
        { "url": "https://www.cwjobs.co.uk/jobs/devops/in-manchester" },
        { "url": "https://www.caterer.com/jobs/head-chef/in-oxford" }
    ],
    "maxItems": 300
}
```

### Sample output

```json
{
  "id": "108005981",
  "title": "Senior Python Developer FastAPI Azure",
  "url": "https://www.totaljobs.com/job/senior-python-developer-fastapi-azure/client-server-job108005981",
  "site": "totaljobs",
  "country": "gb",
  "location": "The City, City of London (EC4)",
  "postalCode": "EC2V 6EE",
  "latitude": 51.5133018,
  "longitude": -0.0919163,
  "contractType": "Permanent Contract; Hybrid",
  "isRemote": true,
  "matchType": "exact",
  "employmentType": "REMOTE_WORKING",
  "industry": "IT, IT-Software Development",
  "postedAt": "2026-09-18T13:43:07.027Z",
  "expiresAt": "2026-09-25T13:43:07.027Z",
  "isDirectApply": true,
  "salary": {
    "description": "£90000 - £110000 per annum + bonus + benefits",
    "min": 90000,
    "max": 110000,
    "currency": "GBP",
    "period": "YEAR",
    "type": null,
    "isEstimate": false
  },
  "skills": ["AWS", "Azure", "CI/CD", "Python"],
  "benefits": [],
  "contactEmails": [],
  "contactPhones": [],
  "company": {
    "id": 1375834,
    "name": "Client Server",
    "sectors": ["HR & Recruitment"],
    "employees": "51-250",
    "foundedYear": 1999,
    "openJobs": 43,
    "address": "London, Esher, Europe",
    "rating": { "score": 4.44562, "reviews": 20 },
    "logoUrl": "https://tjgliveassets.s3.eu-west-1.amazonaws.com/company-logos/0121bf260b964108866f00d1d5d91ae1.png",
    "jobsUrl": "https://www.totaljobs.com/jobs/client-server?cmpId=1375834&cmp=1",
    "videos": [{ "url": "https://player.vimeo.com/video/975047391", "provider": "vimeocom" }],
    "about": [{ "title": "Who We Are", "contentHtml": "..." }]
  },
  "descriptionSections": [
    { "name": "jobDescription", "title": "", "contentHtml": "..." }
  ],
  "descriptionHtml": "...",
  "language": "en"
}
```

### Input reference

| Field | Type | What it does |
|---|---|---|
| `keyword` | string | What to search for. Leave empty to get every job in the location. |
| `location` | string | Town, city or region. Leave empty to search the whole UK. |
| `site` | select | `totaljobs`, `cwjobs`, `jobsite`, `caterer` or `milkround`. Totaljobs when not set. |
| `radius` | integer | Miles around the location, up to 100. Needs a location. |
| `jobType` | select | `permanent`, `contract`, `part-time`, `temporary` or `work-from-home`. All types when not set. |
| `postedBy` | select | `employer` for direct employers only, `agency` for agencies only. Off by default. Returns fewer jobs; removed ones are not charged. |
| `publishedSince` | select | `24h`, `3d`, `7d` or `14d`. Any age when not set. |
| `minSalary` | integer | Only jobs advertised at or above this figure, in pounds. |
| `salaryPeriod` | select | What `minSalary` is measured in: `year`, `day` or `hour`. Per year when not set. |
| `startUrls` | array | Result pages or single job pages from any of the five boards. Replaces the keyword search. Each result page is walked from its first page, so a `page=` in the address is ignored. |
| `exactMatchesOnly` | boolean | Keep only jobs that match your search. The board pads result lists with related titles and nearby towns. Off by default. Returns fewer jobs; skipped ones are never fetched or charged, and `matchType` lets you filter afterwards instead. |
| `maxItems` | integer | Total jobs for the run. `0` means keep going until results run out, up to 10,000. Default 100. |

### Pricing

**$1.99 per 1,000 jobs.** No monthly fee. Expired listings are skipped and never billed.

Every row is a full job: the advertised salary, the skills, the company detail and the complete description. There is no cheaper "listing only" tier to upgrade from and no second charge for detail.

New accounts get a free allowance to try the actor before paying.

### FAQ

**Which boards are covered?**
Totaljobs, CWJobs, Jobsite, Caterer and Milkround. CWJobs is IT and tech, Caterer is hospitality and catering, Milkround is graduate and entry level; Totaljobs and Jobsite carry all sectors. These boards cross-post between each other, so a search on one can return a job whose page lives on another. The row's `site` and `url` always say where the job actually is.

**Do all jobs have a salary?**
Most do. Across 500 measured jobs, 95% carried a pay line and 61% of those lines contained figures. The rest say things like "Negotiable" or "Competitive", and those come back with the wording kept and `min`/`max` left empty rather than a guess. `isEstimate` is always `false`: this is what the employer advertised, not a prediction.

**Can I get only direct employers?**
Yes. Set `postedBy` to `employer`. Recruitment agencies place a large share of UK listings, and this filter removes them before anything is fetched or charged.

**Where do the skills come from?**
From the advert text, matched against a vocabulary of the tools, standards, licences and certifications UK job ads name. It reports what the advert says and never guesses.

**Where do the contact details come from?**
From the advert itself, where the employer printed a recruiter address or phone number. Many adverts do not name one, and those rows come back with empty lists.

**Can I scrape a single job page?**
Yes. Put the job address in `startUrls` and you get that one row.

**How far back does a search go?**
As deep as the board's own results go. Set `maxItems` to `0` to take everything a search returns.

**What happens to expired jobs?**
Listings that have already closed are skipped and reported separately, never billed and never returned as empty rows.

**Do you cover jobs outside the UK?**
Not in this actor. For Germany, Austria, Belgium and the Netherlands, use <a href="https://apify.com/clearpath/stepstone-de-job-scraper">StepStone Jobs</a>.

# Actor input Schema

## `keyword` (type: `string`):

What to search for, for example <b>python developer</b>, <b>registered nurse</b> or <b>management accountant</b>. Leave empty to get every job in the location.

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

Town, city or region to search in, for example <b>London</b>, <b>Manchester</b> or <b>West Midlands</b>. Leave empty to search the whole UK.

## `site` (type: `string`):

Which board to search. Totaljobs is used when nothing is selected. All five carry UK jobs; CWJobs is tech only, Caterer is hospitality, Milkround is graduate roles.

## `radius` (type: `integer`):

How far around the location to include jobs. Only applies when a location is set.

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

Leave empty to get every type of contract.

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

<b>Off by default, so nothing is dropped unless you ask.</b> Most UK listings are placed by recruitment agencies. Pick <b>Direct employers only</b> to keep just the companies hiring for themselves, which is what you want for lead generation. This is a filter: it returns fewer jobs than the same search without it, and you are not charged for what it removes.

## `publishedSince` (type: `string`):

Only return recently published jobs. Useful for a daily or weekly run that should pick up new postings only.

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

Only return jobs advertised at or above this figure, in pounds. Set the period below to match, for example <b>45000</b> per year or <b>450</b> per day.

## `salaryPeriod` (type: `string`):

What the minimum salary above is measured in. Per year is used when nothing is selected.

## `exactMatchesOnly` (type: `boolean`):

<b>Off by default, so you get everything the board returns.</b> The board pads a result list with jobs that carry a different title or sit outside the town you asked for. Tick this to keep only the jobs that match your search. It returns fewer jobs, and the ones it removes are never fetched or charged. Every row tells you which it is in <b>matchType</b> either way, so you can leave this off and filter afterwards without losing anything.

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

Paste result pages or single job pages from any of the five boards. <b>These replace the keyword search above</b>, including the filters. Each result page is walked from its first page, so a <code>page=</code> in the address you paste is ignored. The maximum below is split evenly across the result pages you add.

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

How many jobs to return in total across the whole run. Set to <b>0</b> to keep going until the search runs out, up to 10,000 jobs per run.

## Actor input object example

```json
{
  "keyword": "python developer",
  "location": "London",
  "site": "totaljobs",
  "radius": 10,
  "salaryPeriod": "year",
  "exactMatchesOnly": false,
  "maxItems": 100
}
```

# Actor output Schema

## `results` (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 = {
    "keyword": "python developer",
    "location": "London",
    "site": "totaljobs",
    "radius": 10,
    "salaryPeriod": "year"
};

// Run the Actor and wait for it to finish
const run = await client.actor("clearpath/totaljobs-uk-job-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 = {
    "keyword": "python developer",
    "location": "London",
    "site": "totaljobs",
    "radius": 10,
    "salaryPeriod": "year",
}

# Run the Actor and wait for it to finish
run = client.actor("clearpath/totaljobs-uk-job-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 '{
  "keyword": "python developer",
  "location": "London",
  "site": "totaljobs",
  "radius": 10,
  "salaryPeriod": "year"
}' |
apify call clearpath/totaljobs-uk-job-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clearpath/totaljobs-uk-job-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/bc0M5EvO4rEZNuHqM/builds/hX5gk3A2O2JKIkg3v/openapi.json
