# JobServe UK Scraper: IT Contract, Engineering, Finance Jobs (`santamaria-automations/jobserve-uk-scraper`) Actor

Extract UK job listings from JobServe.com, the UK's oldest IT and engineering board (since 1993). Returns title, company, day rate or annual salary, IR35 status, contract length, workplace type, skills tags, sector, description and apply URL. Pay per result.

- **URL**: https://apify.com/santamaria-automations/jobserve-uk-scraper.md
- **Developed by:** [NanoScrape](https://apify.com/santamaria-automations) (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 $3.00 / 1,000 job serp 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

## JobServe UK Scraper

Scrapes UK job listings from [JobServe](https://www.jobserve.com), the UK's oldest specialist job board (since 1993). Strongest coverage: IT contract roles, engineering, financial services, and public-sector cleared work (SC / DV / CTC).

The board is heavy on **day-rate contract** listings with IR35 status and technical-skills tags, which most generalist scrapers strip away. This actor preserves them.

### Use with AI Agents (MCP)

Connect this actor to any MCP-compatible AI client - Claude Desktop, Claude.ai, Cursor, VS Code, LangChain, LlamaIndex, or custom agents.

**Apify MCP server URL:**

```
https://mcp.apify.com?tools=santamaria-automations/jobserve-uk-scraper
```

**Example prompt once connected:**

> "Use `jobserve-uk-scraper` to find senior Java developer contract roles in London with a day rate above £500. Return results as a table showing IR35 status, day rate, and posting date."

### Features

- **UK IT contract focus** - day rates, IR35 status (inside / outside / undetermined), contract length in months
- **Technical skills tags** - React, TypeScript, AWS, Kubernetes and other tech stack chips shown on the listing
- **Structured salary** - min / max / currency / period parsed from both `£65,000 - £85,000/year` and `£500 - £650/day` conventions (with `k`/`m` suffix support)
- **Workplace signal** - remote / hybrid / onsite classification from the listing text
- **Full descriptions** - HTML and plain-text bodies from the JobServe detail endpoint
- **Sector taxonomy** - IT, Financial Services, Engineering, Public Sector, Hospitality and other JobServe industry labels
- **Recruiter capture** - both the employment business and the direct-hire employer where advertised
- **Deep employer mode** - `includeCompanyDetails=true` fetches the /Listings/Recruiters/{slug}/?lid={LID} profile page for each unique recruiter and returns logo, phone, email, website, address, About-us text, active-jobs count, and the 5 latest active roles for that recruiter. Deduplicated per employer within a run - one $0.005 charge per unique recruiter, not per job
- **Deduplication** - by JobServe job ID across pages and multi-keyword runs

### Input

| Field | Type | Description | Default |
|-------|------|-------------|---------|
| `searchQueries` | array | Search keywords (e.g. `"senior developer"`, `"devops engineer"`) | `["senior developer"]` |
| `location` | string | UK town, city or region | `""` |
| `radius` | integer | Search radius in miles around the location | `20` |
| `jobType` | string | `"permanent"`, `"contract"`, `"both"` or empty for any | `""` |
| `maxItems` | integer | Total cap across all queries | `25` |
| `maxItemsPerQuery` | integer | Cap per search keyword | `200` |
| `maxJobsPerCompany` | integer | Cap per employer/agency (0 disables) | `0` |
| `includeJobDetails` | boolean | Fetch each job's detail page for full description, sector, contract length, IR35 status | `false` |
| `includeCompanyDetails` | boolean | Fetch each unique employer's profile page for logo, phone, email, website, About-us, active-jobs count and 5 latest roles. Deduplicated per employer within a run. Implies `includeJobDetails=true`. | `false` |
| `maxConcurrency` | integer | Parallel detail fetches (1-20) | `4` |
| `proxyConfiguration` | object | Apify proxy settings | Residential UK |

#### Example: Contract roles in London

```json
{
  "searchQueries": ["senior developer", "devops engineer"],
  "location": "London",
  "radius": 20,
  "jobType": "contract",
  "maxItems": 50,
  "includeJobDetails": true
}
```

#### Example: Any-type search near Manchester

```json
{
  "searchQueries": ["data engineer"],
  "location": "Manchester",
  "radius": 30,
  "jobType": "both",
  "maxItems": 100
}
```

#### Example: Employer enrichment (contract sales, ATS seeding, market intel)

```json
{
  "searchQueries": ["service architect"],
  "location": "London",
  "includeJobDetails": true,
  "includeCompanyDetails": true,
  "maxItems": 25
}
```

### Output

Each job listing includes:

| Field | Type | Example |
|-------|------|---------|
| `_type` | string | `"job"` |
| `job_id` | string | `"D5B84D3285F57C9BAE"` |
| `title` | string | `"Senior Developer - React/TypeScript - London"` |
| `company_name` | string | `"SmartSourcing Ltd"` |
| `company_logo_url` | string | `"https://www.jobserve.com/gb/en/DirectoryImage.jsrs?p=016F1E61…"` |
| `location` | string | `"London, UK"` |
| `country` | string | `"GB"` |
| `salary_text` | string | `"£500 - £650/day"` |
| `salary_min` | number | `500` |
| `salary_max` | number | `650` |
| `salary_currency` | string | `"GBP"` |
| `salary_period` | string | `"day"` |
| `rate_type` | string | `"daily"` |
| `employment_type` | string | `"contract"` |
| `contract_length` | string | `"6 months"` |
| `ir35_status` | string | `"outside"` |
| `workplace_type` | string | `"hybrid"` |
| `sector` | string | `"IT"` |
| `category` | string | `"Software Development"` |
| `skills` | array | `["React", "TypeScript", "Node.js"]` |
| `description` | string | Full plain-text description |
| `description_html` | string | Full HTML description |
| `posted_at` | string | `"2026-08-18"` |
| `reference` | string | `"JS17325_1984440463"` |
| `job_url` | string | Canonical JobServe URL |
| `application_url` | string | Direct apply link |
| `permalink` | string | Short JobServe permalink |
| `company_profile_url` | string | `"https://www.jobserve.com/gb/en/Listings/Recruiters/SmartSourcing-Ltd/?lid=7E472EDB49"` |
| `company_about` | string | Recruiter About-us text *(when `includeCompanyDetails=true`)* |
| `company_phone` | string | `"01782 860 088"` *(when `includeCompanyDetails=true`)* |
| `company_email` | string | `"requirements@smartsourcing.plc.uk"` *(when `includeCompanyDetails=true`)* |
| `company_website` | string | External recruiter website *(when `includeCompanyDetails=true`)* |
| `company_address_street` | string | Freeform single-line address *(when `includeCompanyDetails=true`)* |
| `company_active_jobs_count` | integer | `16` *(when `includeCompanyDetails=true`)* |
| `company_active_jobs` | array | 5 latest roles from the same recruiter *(when `includeCompanyDetails=true`)* |
| `source_platform` | string | `"jobserve.com"` |
| `search_query` | string | `"senior developer in London"` |
| `scraped_at` | string | RFC 3339 UTC timestamp |

### What Makes JobServe Different

Most UK job boards will index a JobServe posting eventually, but by the time it hits Indeed or LinkedIn the day rate, IR35 status, and contract length have usually been stripped. This actor keeps them intact.

For contract-market intelligence (rate benchmarking, IR35 mix by sector, contract-length trends), JobServe is one of the few boards with structured facets for these fields.

### Sample output

Core listing:

```json
{
  "_type": "job",
  "job_id": "D8002961D8ABC0CCA8",
  "title": "Service Architect(SC) ITIL Nationwide, £600 pd Inside",
  "company_name": "SmartSourcing Ltd",
  "company_logo_url": "https://www.jobserve.com/gb/en/DirectoryImage.jsrs?p=016F1E61AFAE66D57815E087DBA9FC22ED5BAD65EF9F3F43AA",
  "location": "London, UK",
  "salary_text": "£600 pd Inside",
  "salary_min": 600,
  "salary_max": 600,
  "salary_currency": "GBP",
  "salary_period": "day",
  "rate_type": "daily",
  "employment_type": "contract",
  "contract_length": "6 months",
  "ir35_status": "inside",
  "workplace_type": "hybrid",
  "sector": "IT",
  "skills": ["ITIL", "Service Architecture", "SC clearance"],
  "job_url": "https://www.jobserve.com/gb/en/search-jobs-in-London,-London,-United-Kingdom/SERVICE-ARCHITECT-SC-ITIL-NATIONWIDE-600-PD-INSIDE-D8002961D8ABC0CCA8/",
  "company_profile_url": "https://www.jobserve.com/gb/en/Listings/Recruiters/SmartSourcing-Ltd/?lid=7E472EDB49"
}
```

With `includeCompanyDetails=true`, each row is enriched with employer-page fields:

```json
{
  "company_about": "SmartSourcing Ltd offers contract, permanent, fixed term and outcome based work package opportunities across Digital and Technology, Transformation, Project and Programme Management, PMO, Business Change, Cloud Services, Cyber Security and wider corporate functions...",
  "company_phone": "01782 860 088",
  "company_email": "requirements@smartsourcing.plc.uk",
  "company_active_jobs_count": 16,
  "company_active_jobs": [
    {
      "title": "AI Evaluation Engineer - SDET AI Engineer - AI Assurance - £750 per day, inside IR35",
      "job_url": "https://www.jobserve.com/gb/en/Listings/Recruiters/SmartSourcing-Ltd/Jobs/?...&JobID=7A27CAA90E9AEC8DD9",
      "location": "Hybrid - London, Bristol, Manchester",
      "salary_text": "£750/day, inside IR35",
      "employment_type": "contract"
    }
  ]
}
```

### Pricing

Pay-per-result:

| Event | Price |
|-------|-------|
| Actor start | $0.001 |
| SERP result | $0.003 |
| Detail-page result | $0.005 |
| Company/employer detail result (per unique recruiter) | $0.005 |

Platform costs (compute + proxy) are billed separately by Apify.

**New to Apify?** Every account gets a $5 free monthly platform credit, enough for around 1,600 detail-page results on this actor before you commit to paying anything. Test extensively first.

### Common use cases

- **Contract-rate benchmarking** - track median day rates by tech stack across quarters
- **IR35 compliance monitoring** - snapshot the inside / outside / undetermined mix per sector monthly
- **Sourcing pipeline** - feed new IT contract postings into an ATS the same day they publish
- **Public-sector cleared work watch** - filter for SC / DV / CTC roles and alert per new posting
- **Recruiter outreach** - `includeCompanyDetails=true` gives the phone, email, About-us and active roles for every recruiter behind a search - ready to import into a CRM or personalisation engine

### Notes and limits

- Day-rate parsing handles `£500/day`, `£500 - £650 pd`, and compact `£65k` annual formats. Occasional posts using non-standard formats (e.g. `£POA`, hourly rates) may leave salary fields null
- IR35 status is inferred from the job body; when a poster doesn't state it explicitly the field is `undetermined`
- Recruiter names come from the visible "Employment Business" or "Company" label - a very small fraction of postings redact this
- UK-only coverage - JobServe operates gb.jobserve.com; other Locale variants are out of scope
- **jobserve-uk fully supports deep employer mode** - logo, phone, email, address, About-us and active jobs are extracted from `/gb/en/Listings/Recruiters/{slug}/?lid={LID}` and deduplicated per unique recruiter within a run. Website + address are only populated for the ~30-40% of recruiters that configured them on JobServe. The address is a single freeform line (JobServe collapses street/city/postcode into one string); `company_address_street` carries the full text, other address split-fields are reserved for future use.

### Related Actors

- [Hays Scraper](https://apify.com/santamaria-automations/hays-scraper) - global recruitment agency, 30+ countries
- [Indeed Scraper](https://apify.com/santamaria-automations/indeed-scraper) - 60+ countries, 50+ fields per job
- [Guardian Jobs Scraper](https://apify.com/santamaria-automations/guardianjobs-scraper) - UK charity, media, education, public sector
- [StepStone Scraper](https://apify.com/santamaria-automations/stepstone-de-scraper) - Germany's largest job board

### Support

If you encounter any issues or have feature requests, please use the [Issues tab](https://apify.com/santamaria-automations/jobserve-uk-scraper/issues) to report them. We reply within a few hours.

Contact: contact@nanoscrape.com

# Actor input Schema

## `searchQueries` (type: `array`):

One or more keywords to search for on jobserve.com (for example 'senior developer', 'devops engineer', 'business analyst'). Each keyword runs as its own search. Results are deduplicated by JobServe job ID.

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

Direct SERP URLs to crawl instead of building from keywords. Mutually exclusive with searchQueries — provide one or the other.

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

UK town, city or region to restrict results to (for example 'London', 'Manchester', 'Edinburgh'). Applied to all search keywords with the radius set below.

## `includeJobDetails` (type: `boolean`):

Fetch each job's detail page for full description, sector, industry, contract length, IR35 status, workplace type, and reference number. Slower and slightly more expensive but returns the richest data.

## `includeCompanyDetails` (type: `boolean`):

Also fetch each unique employer's company profile page for the About-us text, phone, address, website, and a list of the employer's other currently-open roles. Deduplicated per employer within a run. Adds $0.005 per unique employer. Implies includeJobDetails=true (employer link only lives on the PDP).

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

Search radius in miles around the location. Ignored if no location is set.

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

Filter by contract type. 'Both' returns permanent and contract roles combined.

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

Total cap across all search keywords.

## `maxItemsPerQuery` (type: `integer`):

Maximum results per individual search keyword.

## `maxJobsPerCompany` (type: `integer`):

Optional cap on the number of listings returned per employer or recruitment agency. Set to 0 to disable. Useful when a single agency floods the SERP.

## `maxConcurrency` (type: `integer`):

Number of detail pages to fetch in parallel when full details are enabled.

## Actor input object example

```json
{
  "searchQueries": [
    "senior developer"
  ],
  "location": "London",
  "includeJobDetails": false,
  "includeCompanyDetails": false,
  "radius": 20,
  "jobType": "",
  "maxItems": 25,
  "maxItemsPerQuery": 200,
  "maxJobsPerCompany": 0,
  "maxConcurrency": 4
}
```

# Actor output Schema

## `jobListings` (type: `string`):

Dataset containing scraped JobServe UK listings. Each row includes job ID, title, company, location, salary text and structured min/max/currency/period, rate type (annual/daily/hourly), employment type (permanent/contract), contract length, IR35 status, workplace type (remote/hybrid/onsite), technical skills tags, sector, category, full description, posted date, apply URL and the canonical source URL.

# 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 = {
    "searchQueries": [
        "senior developer"
    ],
    "includeJobDetails": false,
    "maxItems": 25,
    "maxItemsPerQuery": 200,
    "maxJobsPerCompany": 0,
    "maxConcurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("santamaria-automations/jobserve-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 = {
    "searchQueries": ["senior developer"],
    "includeJobDetails": False,
    "maxItems": 25,
    "maxItemsPerQuery": 200,
    "maxJobsPerCompany": 0,
    "maxConcurrency": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("santamaria-automations/jobserve-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 '{
  "searchQueries": [
    "senior developer"
  ],
  "includeJobDetails": false,
  "maxItems": 25,
  "maxItemsPerQuery": 200,
  "maxJobsPerCompany": 0,
  "maxConcurrency": 4
}' |
apify call santamaria-automations/jobserve-uk-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,santamaria-automations/jobserve-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/IDRrMfZqXXudG70xf/builds/pudKV1ZDffu8cmRji/openapi.json
