# Totaljobs Jobs Search Scraper (`jobsapi/totaljobs-jobs-search-scraper`) Actor

Scrape job listings from Totaljobs.com, one of the UK's largest job boards and part of the StepStone Group. Extract job titles, companies, locations, salary ranges, job types, and descriptions for UK recruitment intelligence and market analysis.

- **URL**: https://apify.com/jobsapi/totaljobs-jobs-search-scraper.md
- **Developed by:** [Jobs API](https://apify.com/jobsapi) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 job details

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## TotalJobs Jobs Search Scraper

Extract structured UK job vacancies from official TotalJobs search and detail pages. The Actor supports keyword search, one detail URL, or a bounded list of detail URLs. It follows detail pages before saving data and fails closed instead of publishing search-card fragments as complete jobs.

### What it extracts

- Job title, company, location, and canonical job URL
- Salary text and normalized minimum/maximum values when published
- Employment type, work arrangement, and contract information
- Full job description and description HTML
- Skills, benefits, category, seniority, and education fields when available
- Publication and expiry dates when exposed by the source
- Source provenance, stable job ID, extraction timestamp, and detail-verification metadata

TotalJobs controls which fields are available for each vacancy. Missing optional source fields remain `null` or empty; the Actor never invents values.

### Input modes

#### Search

Set `mode` to `search`, provide `query` and `location`, and bound the run with `maxItems`, `maxPages`, and `maxRequests`.

```json
{
    "mode": "search",
    "query": "software engineer",
    "location": "London",
    "maxItems": 3,
    "maxPages": 1,
    "maxRequests": 4
}
```

#### Single job

```json
{
    "mode": "single",
    "jobUrl": "https://www.totaljobs.com/job/example-job/example-company-job123456789"
}
```

#### Multiple jobs

Set `mode` to `multiple` and provide at least two official `/job/...-job<ID>` URLs in `jobUrls` or `startUrls`. Direct URLs are canonicalized and deduplicated.

### Proxy and access

The default is a direct connection. TotalJobs can return Akamai challenge pages or `403` responses from some data-center networks. If that happens, enable `proxyConfiguration`; a country-matched residential proxy is generally more reliable for this UK source. Proxy use is optional and billed according to the selected proxy service.

```json
{
    "mode": "search",
    "query": "software engineer",
    "location": "London",
    "maxItems": 1,
    "maxPages": 1,
    "maxRequests": 2,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB"
    }
}
```

The Actor uses the browser bundled in its container on Apify Cloud and can use installed Google Chrome during local execution.

### Output

Each dataset item is one detail-verified job. The dataset schema provides table, JSON, and overview views. The `OUTPUT` key-value-store record contains the run summary, including requested and extracted counts, runtime, access method, diagnostics, and proxy telemetry.

```json
{
    "jobId": "123456789",
    "title": "Software Engineer",
    "company": "Example Ltd",
    "location": "London",
    "description": "Full source-provided job description...",
    "url": "https://www.totaljobs.com/job/example-job/example-ltd-job123456789",
    "source": "TotalJobs",
    "detailVerified": true
}
```

### Reliability and limits

- Search results are paginated only up to `maxPages` and stop after `maxItems` complete records.
- `maxRequests` is a hard request ceiling and must allow one search request plus the requested detail pages.
- Requests use bounded timeouts, retries, and an optional delay.
- Job identity is checked between the requested URL and extracted page data.
- Duplicate IDs and URLs, challenge pages, non-job pages, and incomplete detail records cause a diagnostic failure instead of partial output.
- Vacancies can expire between search discovery and detail extraction. Reduce `maxItems` or rerun with fresh URLs if the source removes a listing.

### Local development

```bash
npm install
npm test
apify run --purge --input-file INPUT.json
npm run validate:dataset
```

Use small inputs when validating source behavior. Automated use remains subject to TotalJobs terms and applicable law.

# Actor input Schema

## `mode` (type: `string`):

Search by keyword and location, extract one job URL, or extract several job URLs.

## `query` (type: `string`):

Job title, skill, or keyword used in search mode.

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

UK city, region, or postcode used in search mode.

## `jobUrl` (type: `string`):

An official https://www.totaljobs.com/job/...-job<ID> URL used in single mode.

## `jobUrls` (type: `array`):

Two or more official TotalJobs job detail URLs used in multiple mode.

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

Alternative request-list input for official TotalJobs job detail URLs.

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

Maximum number of complete job records to save in search mode.

## `maxPages` (type: `integer`):

Maximum number of search-result pages to inspect.

## `maxRequests` (type: `integer`):

Safety ceiling for search and detail requests combined.

## `requestTimeoutSecs` (type: `integer`):

Timeout applied to each browser request.

## `requestDelayMs` (type: `integer`):

Optional polite delay before processing each request.

## `maxRequestRetries` (type: `integer`):

Retry count for transient navigation or blocking failures.

## `headless` (type: `boolean`):

Keep enabled for normal local and cloud runs.

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

Optional Apify Proxy or custom proxy configuration. Leave disabled for a direct-access baseline.

## Actor input object example

```json
{
  "mode": "search",
  "query": "software engineer",
  "location": "London",
  "maxItems": 3,
  "maxPages": 1,
  "requestTimeoutSecs": 45,
  "requestDelayMs": 0,
  "maxRequestRetries": 2,
  "headless": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `runSummary` (type: `string`):

No description

## `diagnostics` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("jobsapi/totaljobs-jobs-search-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("jobsapi/totaljobs-jobs-search-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 '{}' |
apify call jobsapi/totaljobs-jobs-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jobsapi/totaljobs-jobs-search-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/PLUMaBfkS2NaD4uB5/builds/qeL0F2MMNH22NPmnb/openapi.json
