# Guardian Jobs Scraper: UK Charity, Media, Public (`santamaria-automations/guardianjobs-scraper`) Actor

Extract UK job listings from Guardian Jobs (jobs.theguardian.com). Returns 28+ fields per row: title, employer, salary (GBP min/max), location, sector, contract type, hours, closing date, description, apply URL, plus employer phone, address, website and about text when present. Pay per result.

- **URL**: https://apify.com/santamaria-automations/guardianjobs-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 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/platform/actors/running/actors-in-store#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

### Guardian Jobs Scraper

Extract UK job listings from [Guardian Jobs](https://jobs.theguardian.com), the UK-focused job board run by The Guardian. Strong coverage of charity, media, education, government, arts and heritage, science, and public sector roles that are hard to find on generalist boards.

### What it does

Given one or more search keywords (optionally with a UK location and sector filter), or a direct SERP URL, the actor walks Guardian Jobs search results, extracts each job card, and can optionally fetch the full detail page for the complete description, structured salary, contract type, hours, application deadline, and employer contact info (phone, address, website, about text).

- Search by keyword (`charity manager`, `science teacher`, `communications officer`, ...) or feed direct SERP URLs
- Filter by UK location with a 20-mile radius
- Filter by sector (Charities, Media, Education, Government and Politics, Arts and Heritage, Health, Technology and IT, and more)
- Filter by minimum annual salary and contract type (Permanent, Contract, Temporary, Voluntary)
- Fast SERP mode returns core fields from the search page alone
- Full detail mode returns the complete job description, sector, contract type, hours, closing date, plus employer phone, address, website and about text when the employer profile exposes them
- Deep employer mode also resolves each unique employer's `/employer/{id}` page for enriched about text and a list of the employer's other currently-open roles

### Sample output

```json
{
  "_type": "job",
  "id": "10160808",
  "title": "Head of Finance",
  "company": "PERIDOT PARTNERS",
  "company_logo_url": "https://jobs.theguardian.com/getasset/8a8658b1-39cb-4e00-9ddd-9a9117e85863/;w=200",
  "location": "Remote, UK-based with c.2 in-person meetings per annum",
  "country": "GB",
  "sector": "Charities, Community & Social Care, Executive Management",
  "contract_type": "Permanent",
  "hours": "Full time",
  "employment_type": "full-time, permanent",
  "experience_level": "director",
  "remote_option": "remote",
  "salary_min": 60000,
  "salary_max": 65000,
  "salary_currency": "GBP",
  "salary_period": "year",
  "salary_text": "c.\u00a360,000 - \u00a365,000",
  "description_snippet": "Help shape the future of one of the UK's leading bereavement charities.",
  "posted_at": "2026-08-11",
  "closing_date": "2026-08-27",
  "source_url": "https://jobs.theguardian.com/job/10160808/head-of-finance/",
  "source_platform": "jobs.theguardian.com",
  "apply_url": "https://jobs.theguardian.com/job/10160808/head-of-finance/",
  "search_query": "charity manager in London",
  "scraped_at": "2026-08-20T09:08:29Z",
  "company_about": "Placing purpose and quality before profit, Peridot Partners is a values-led third sector executive recruitment agency...",
  "company_phone": "0203 0360 623",
  "company_email": null,
  "company_website": "http://www.peridotpartners.co.uk",
  "company_address_street": "PERIDOT PARTNERS THE STANLEY BUILDING 7 PANCRAS SQUARE",
  "company_address_city": "LONDON",
  "company_address_postcode": "N1C 4AG",
  "company_address_country": "GB",
  "company_active_jobs_count": 5,
  "company_active_jobs": [
    {
      "title": "Director of Finance & Corporate Services",
      "job_url": "https://jobs.theguardian.com/job/10160147/director-of-finance-and-corporate-services",
      "description_snippet": "Help shape the future of one of the UK's leading bereavement charities.",
      "location": "Remote, UK-based with occasional in-person meetings in London",
      "salary_text": "c\u00a385,000"
    }
  ]
}
```

### Pricing

**$0.001 per actor start + $0.003 per SERP result + $0.005 per full detail result + $0.005 per unique employer resolved (only when `includeCompanyDetails` is on).**

Typical cost:

- **SERP mode**: about $3 per 1,000 jobs (title, employer, salary text, location, snippet, posted date, logo)
- **Full mode**: about $8 per 1,000 jobs (adds sector, contract type, hours, full description, closing date, structured salary, employer phone, address, website, about text)
- **Deep employer mode** (adds `includeCompanyDetails=true`): about $8 per 1,000 jobs + $0.005 per unique employer. Employers are deduplicated within a run, so 100 jobs from 40 different employers cost about $8.20, not $8.50.

You only pay for detail fetches that succeed. Failed fetches are not charged.

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

### Input

| Field | Type | Description |
|---|---|---|
| `searchQueries` | array of strings | Keywords to search for (each runs as a separate search). Provide either this or `startUrls`. |
| `startUrls` | array of strings | Direct SERP URLs to crawl instead of building searches from keywords (for example `https://jobs.theguardian.com/jobs/charity/`). Mutually exclusive with `searchQueries`. |
| `location` | string | UK town, city, or region. 20-mile radius is applied automatically. Ignored when using `startUrls`. |
| `sector` | select | Optional sector filter (Charities, Media, Education, and more). |
| `salaryMin` | integer | Minimum annual salary in GBP. |
| `contractType` | select | Permanent, Contract, Temporary, or Voluntary. |
| `maxResults` | integer | Total cap across all keywords (default 25). |
| `maxResultsPerQuery` | integer | Cap per individual keyword (default 200). |
| `includeJobDetails` | boolean | Fetch each detail page for full data plus employer contact info (default false). |
| `includeCompanyDetails` | boolean | Also resolve each unique employer's Guardian Jobs company page for enriched about text and an active-jobs list. Requires `includeJobDetails=true`. Deduplicated per run. Default false. |
| `maxConcurrency` | integer | Parallel detail-page requests (default 4, max 20). |

### Output fields

**Core listing:** `_type`, `id`, `title`, `company`, `company_logo_url`, `location`, `country`, `source_url`, `apply_url`, `source_platform`, `scraped_at`.

**Structured job facets (full mode):** `sector`, `contract_type`, `hours`, `employment_type`, `experience_level`, `remote_option`.

**Salary:** `salary_min`, `salary_max`, `salary_currency`, `salary_period`, `salary_text`.

**Description:** `description_snippet` (SERP mode), `description_full` and `description_html` (full mode).

**Dates:** `posted_at`, `closing_date` (full mode).

**Context:** `search_query` (which keyword produced this row).

**Employer contact (full mode, when the employer exposes it):** `company_about`, `company_phone`, `company_email`, `company_website`, `company_address_street`, `company_address_city`, `company_address_postcode`, `company_address_country`.

**Deep employer mode (`includeCompanyDetails=true`):** `company_active_jobs_count`, `company_active_jobs` (array of `{title, job_url, description_snippet, location, salary_text}`), plus enriched `company_about`.

### 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/guardianjobs-scraper`

**Example prompt once connected:**

> "Use `guardianjobs-scraper` to find the 20 most recent charity manager roles in London with a minimum salary of 40,000. Enable `includeCompanyDetails` so I get each employer's phone number and other open roles. Return a table with employer, title, salary, phone."

Clients that support dynamic tool discovery (Claude.ai, VS Code) will receive the full input schema automatically.

### Why this scraper

- Guardian Jobs is a hand-curated UK board. Signal-to-noise on charity, media, education, and public sector roles is far higher than on aggregators.
- Structured salary and closing dates come out of the JSON-LD job posting embedded in every listing, not a fragile HTML scrape.
- Sector taxonomy is the real Guardian Jobs one (16+ sectors), not our own guessed labels.
- Employer logos, phone numbers, and postal addresses turn a job scraper into a lead-generation feed for outreach teams. Deep employer mode adds a per-employer active-jobs list without refetching the same company twice.

### Common use cases

- Sourcing candidates for a charity or media recruiter: filter by `sector=charities` or `sector=media`.
- Feeding a UK public-sector jobs board: filter by `sector=government-and-politics` or `contractType=permanent`.
- Building a nonprofit sector salary benchmark: pull all charity jobs with `includeJobDetails=true` and analyze `salary_min` / `salary_max`.
- Outbound lead-gen: run with `includeCompanyDetails=true` to get employer phone, address, website plus every other role at that employer for warm-intro talking points.
- Watching your target employer: search their name as a keyword and re-run daily to catch new roles.

### Notes and limits

- Guardian Jobs caps a single search at around 1,000 results. To pull more, split queries by sector or location.
- Some listings only advertise a salary range as free text (for example "Competitive" or "Voluntary"). In those cases `salary_min` and `salary_max` will be null and `salary_text` carries the original phrase.
- Sector, contract type, hours, closing date, and employer contact fields only populate when `includeJobDetails` is true (they live on the detail page, not the SERP card).
- `company_email` is often null. Guardian Jobs employer profiles rarely include a mailto link, unlike phone and address which are common.
- `company_active_jobs` and enriched `company_about` only populate when `includeCompanyDetails` is true, and only for employers that have a dedicated `/employer/{id}` profile page (most large employers do, some ad-hoc listings from agencies do not).
- The `company` field on the SERP mode comes from the "recruiter" line on the card, which can be either the employer or a recruitment agency. Full mode uses the JSON-LD `hiringOrganization` name which is more consistently the employer.

### Related Actors

- [Reed.co.uk Scraper](https://apify.com/santamaria-automations/reed-uk-scraper) : the UK's largest general-purpose job board, 200,000+ live roles.
- [CV-Library Scraper](https://apify.com/santamaria-automations/cvlibrary-scraper) : another large UK job board with strong industrial and trades coverage.
- [Indeed Scraper](https://apify.com/santamaria-automations/indeed-scraper) : global generalist job board.
- [Website Email Scraper](https://apify.com/santamaria-automations/website-email-scraper) : find contact emails on employer websites, useful for outreach after sourcing.

### Support

For issues, feature requests, or filter combinations that don't behave as expected, please open an issue on the [Issues tab](https://apify.com/santamaria-automations/guardianjobs-scraper/issues) of this actor. We typically respond within 6 hours.

Contact: contact@nanoscrape.com

# Actor input Schema

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

One or more keywords to search for on jobs.theguardian.com (for example 'charity manager', 'science teacher', 'communications officer'). Each keyword runs as a separate search. Results are deduplicated by job ID. Leave blank if you supply startUrls instead.

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

Direct SERP URLs to crawl instead of building searches from keywords. Example: https://jobs.theguardian.com/jobs/charity/ or a full /searchjobs/?Keywords=... URL. Mutually exclusive with searchQueries: provide one or the other. If both are set, startUrls wins and a warning is logged.

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

UK town, city or region to restrict results to (for example 'London', 'Manchester', 'Edinburgh'). Applied to all search keywords with a 20-mile radius. Ignored when you use startUrls.

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

Fetch each job's detail page for full description, sector, contract type, hours, closing date, structured salary, and employer contact info (phone, address, website, about text when present).

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

Also resolve each unique employer to its Guardian Jobs company page for the enriched about text and a list of the employer's other currently-open roles. Adds one extra HTTP hop per unique employer (deduplicated within the run) and charges a separate company-detail-result event at $0.010 each. Requires includeJobDetails=true.

## `sector` (type: `string`):

Optional sector filter. Guardian Jobs has a strong sector taxonomy including Charities, Media, Education, Government, Arts and Heritage, Health, Technology and IT, and Social Care.

## `salaryMin` (type: `integer`):

Only return jobs advertised at or above this annual salary (in GBP). Leave blank or 0 to include all salaries.

## `contractType` (type: `string`):

Optional filter on contract type.

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

Total cap across all search keywords.

## `maxResultsPerQuery` (type: `integer`):

Maximum results per individual search keyword.

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

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

## Actor input object example

```json
{
  "searchQueries": [
    "charity manager"
  ],
  "location": "London",
  "includeJobDetails": false,
  "includeCompanyDetails": false,
  "sector": "",
  "salaryMin": 0,
  "contractType": "",
  "maxResults": 25,
  "maxResultsPerQuery": 200,
  "maxConcurrency": 4
}
```

# Actor output Schema

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

Dataset containing scraped Guardian Jobs listings. Each row includes job ID, title, employer, sector, contract type, hours, salary (min/max/currency/period/text), description (snippet + full + HTML), location, country, posted and closing dates, apply URL and the 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": [
        "charity manager"
    ],
    "includeJobDetails": false,
    "includeCompanyDetails": false,
    "maxResults": 25,
    "maxResultsPerQuery": 200,
    "maxConcurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("santamaria-automations/guardianjobs-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": ["charity manager"],
    "includeJobDetails": False,
    "includeCompanyDetails": False,
    "maxResults": 25,
    "maxResultsPerQuery": 200,
    "maxConcurrency": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("santamaria-automations/guardianjobs-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": [
    "charity manager"
  ],
  "includeJobDetails": false,
  "includeCompanyDetails": false,
  "maxResults": 25,
  "maxResultsPerQuery": 200,
  "maxConcurrency": 4
}' |
apify call santamaria-automations/guardianjobs-scraper --silent --output-dataset

```

## MCP server setup

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