# CharityJob.co.uk scraper (`memo23/charityjob-scraper`) Actor

Scrape UK charity-sector job postings from CharityJob.co.uk — title, salary band, workplace type, employer, posted/closing dates, full description. Works with any search URL, filter combo or single job URL. Optional company enrichment adds website domain and About copy. JSON or CSV out.

- **URL**: https://apify.com/memo23/charityjob-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Jobs, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## CharityJob.co.uk Scraper

**Turn CharityJob.co.uk into structured job-market data you can actually use.** Scrape full job postings — title, salary band, workplace type, employer, closing date, full HTML description — straight from search URLs or single job pages. Optional one-shot organisation enrichment adds the company website domain and "About us" copy. JSON or CSV out, no compute charge per run, just per result.

#### How it works

![How CharityJob Scraper works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-charityjob.png)

#### ✨ Why use this scraper?

Trying to track UK charity-sector hiring without paying for a recruitment SaaS? Building salary benchmarks across causes? Need a clean dataset for analysis instead of copy-pasting from job boards?

- 🎯 **Two starting points.** Paste a CharityJob search URL (any combination of filters supported by the site) or a direct job URL — both classified automatically.
- 📋 **JSON-LD–backed accuracy.** Title, salary, location, posting/closing dates, employment type, and industries come from the page's `application/ld+json` block — same data the site itself ships to Google for Jobs.
- 🏢 **Optional org enrichment.** One extra fetch per *unique* company adds `companyDescription` and `companyDomain`, deduplicated across the run.
- 🔁 **Two HTTP pipelines.** Strict impit-only mode (sliding-window concurrency, proxy rotation, parallel impit/got race on tough pages) or `CheerioCrawler` with `ImpitHttpClient` — switch via one boolean.
- 🧰 **Filter-agnostic.** Cause, workplace, contract type, employer type, salary band, days-since-posted — every CharityJob filter combination just works through the URL.
- 📤 **Clean exports.** Dataset rows are stable JSON; CSV export is generated automatically at the end of every run.

#### 🎯 Use cases

| Team | What they build |
|------|-----------------|
| **Recruitment / agencies** | Daily new-vacancy feeds for direct-employer listings, sliced by cause and workplace type |
| **Charity-sector analysts** | Hiring-trend dashboards across UK third-sector causes (mental health, climate, refugee support, etc.) |
| **Compensation & benefits** | Salary benchmarks for charity roles by contract type, region, and employer size |
| **Talent acquisition (in-house)** | Competitive intelligence on what other charities are paying and how they're framing roles |
| **Researchers / journalists** | Longitudinal datasets on workforce shifts in the UK voluntary sector |
| **Job aggregators** | Source-of-truth feed of new charity vacancies to ingest into their own platform |

#### 📥 Supported inputs

You can pass two kinds of URL in `startUrls`. Each URL is classified automatically.

| URL pattern | Behaviour |
|---|---|
| `https://www.charityjob.co.uk/jobs?<any-filters>` | **Search** — paginates `?page=2`, `?page=3`, … and fans out to every job link found |
| `https://www.charityjob.co.uk/jobs/{org-slug}/{job-slug}/{numeric-id}` (with or without `?tsId=`) | **Detail** — routed straight to the job parser, no listing crawl |

Filter parameters that map to CharityJob's own URL params (multi-value where supported):

`cause`, `workplace` (on-site/hybrid/remote), `contracttype` (full-time/part-time/permanent/contract/temporary/internship), `employerType` (direct-employer/recruitment-agency), `days` (1/3/7/14), `minsalary`, `maxsalary`, `joblevel`, `applytype`.

Easiest workflow: apply your filters on charityjob.co.uk in the browser, copy the URL out of the address bar, paste into `startUrls`.

**Not supported:**

- Volunteer listings (`/volunteer-jobs/...`)
- Organisation profile URLs as a starting point (they're fetched automatically as enrichment)
- Hosts outside `www.charityjob.co.uk` / `charityjob.co.uk`

#### 🔄 How it works

1. **Classify each `startUrl`** as a search URL or a single job URL.
2. **Walk every search result page** (`?page=N`), collecting unique job links until `maxItems` is reached or the last page is hit.
3. **Fetch each job detail page**, parse the JSON-LD `JobPosting` block + supplementary HTML (workplace label, apply button class, organisation slug).
4. **Enrich each unique organisation** once (when `enrichOrganisation` is on) by fetching `/organisation/{slug}` for company description + outbound website domain.
5. **Push to dataset and export** — JSON rows during the run, plus `data.csv` and `data.json` at the end.

#### ⚙️ Input parameters

##### Search

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `startUrls` | array | * | — | Full charityjob.co.uk URLs (search and/or detail). When provided, filter fields below are ignored. |
| `cause` | array | * | — | One or more cause slugs (`human-rights`, `mental-health`, `education`, …). Used only when `startUrls` is empty. |
| `workplace` | array | No | — | Multi-select of `on-site`, `hybrid`, `remote`. |
| `contractType` | array | No | — | Multi-select: `full-time`, `part-time`, `permanent`, `contract`, `temporary`, `internship`. |
| `employerType` | string | No | — | `direct-employer` or `recruitment-agency`. |
| `days` | string | No | — | `1`, `3`, `7`, or `14` — limits posting age. |
| `minSalary` / `maxSalary` | integer | No | — | Salary band in GBP. |

\* Either `startUrls` or `cause` is required. If both are empty the actor will use the schema's default search URL.

##### Options

| Parameter | Type | Default | Description |
|---|---|---|---|
| `enrichOrganisation` | boolean | `true` | Fetch each unique `/organisation/{slug}` page once for `companyDescription` + `companyDomain`. |
| `maxItems` | integer | `1000` | Hard cap on jobs collected. Pagination stops when the cap is reached. |
| `maxConcurrency` / `minConcurrency` | integer | `10` / `1` | Parallel HTTP request limits. |
| `maxRequestRetries` | integer | `5` | Retries before a request is given up. |
| `proxy` | object | Apify residential | Apify proxy configuration. |

#### 📊 Output overview

Each scraped job is one **single dataset row**. When `enrichOrganisation` is `true`, organisation fields (description, domain, headquarters, banner image) are **merged into the same row** — no separate organisation rows, so the dataset row count equals the job count exactly. For external-apply jobs (CharityJob's "Redirect to recruiter" flow), the actual recruiter URL is captured into `externalApplyUrl`.

#### 📦 Output sample

One merged row per job (organisation enrichment + external apply URL inline; trimmed to the most useful fields):

```json
{
    "type": "job",
    "jobId": "1066939",
    "jobUrl": "https://www.charityjob.co.uk/jobs/crisis-uk/strengths-and-assets-coach/1066939",
    "title": "Strengths and Assets Coach",
    "companyName": "Crisis UK",
    "companyProfileUrl": "https://www.charityjob.co.uk/organisation/crisis-uk",
    "organisationSlug": "crisis-uk",
    "logoUrl": "https://downloads.charityjob.co.uk/.../crisis_logo.png",
    "location": "Edinburgh, Edinburgh",
    "postcode": "EH3",
    "addressLocality": "Edinburgh",
    "addressRegion": "Scotland",
    "country": "GB",
    "workplaceType": "Hybrid",
    "salary": { "currency": "GBP", "min": 33352, "max": 36919, "unit": "YEAR", "raw": "£33,352 - £36,919 per year" },
    "employmentType": ["FULL_TIME"],
    "contractType": "Contract (Fixed term until 31 March 2026)",
    "hours": "Full-time (35 hours per week)",
    "industry": ["Advice / Information", "Housing", "Social Welfare"],
    "tags": ["Advice / Information", "Advocacy", "Homelessness", "Mentoring / Coaching", "Social / Support Work"],
    "postedDate": "2026-05-06",
    "postedDateLabel": "06 May 2026",
    "closingDate": "2026-05-24",
    "closingDateLabel": "24 May 2026 at 23:30",
    "closingDateTime": "2026-05-24T23:30:00.000Z",
    "jobReference": null,
    "organisationType": "Registered Charity",
    "organisationSizeBand": "501 - 1000",
    "agencyContactRestriction": true,
    "description": "<p>Crisis is the national charity for people experiencing homelessness...</p> ... (full HTML)",
    "attachments": [
        {
            "name": "Strength & Assets Coach Skylight Edinburgh Job Pack May 26 (.pdf)",
            "url": "https://downloads.charityjob.co.uk/attachments/strength_asset_coach_skylight_edinburgh_job_pack_may_26_2026_05_06_11_32_00_am.pdf",
            "type": "pdf"
        }
    ],
    "applyType": "external",
    "applyUrl": "https://www.charityjob.co.uk/jobs/crisis-uk/strengths-and-assets-coach/1066939",
    "externalApplyUrl": "https://jobs.crisis.org.uk/Job/JobDetail?JobId=11778",
    "accreditations": ["Disability Confident"],
    "companyTagline": "Together we will end homelessness",
    "companyDescription": "Crisis is the national charity for people experiencing homelessness. We help people directly out of homelessness...",
    "companyWebsite": "https://www.crisis.org.uk/",
    "companyDomain": "crisis.org.uk",
    "companyHeadquarters": {
        "postcode": "E1 6LT",
        "country": "United Kingdom",
        "mapEmbedUrl": "https://www.google.com/maps/embed/v1/place?q=E1+6LT,United+Kingdom&key=..."
    },
    "companyBannerImage": "https://downloads.charityjob.co.uk/cdn-cgi/image/width=960,height=240,fit=cover/media/...jpg",
    "companyBenefits": [
        { "name": "Enhanced pension", "iconUrl": "https://www.charityjob.co.uk/Assets/img/benefits/pension.svg" },
        { "name": "Cycle to work scheme", "iconUrl": "https://www.charityjob.co.uk/Assets/img/benefits/cycle.svg" },
        { "name": "Mental wellbeing support", "iconUrl": "https://www.charityjob.co.uk/Assets/img/benefits/mental_wellbeing.svg" }
    ],
    "companyMedia": [
        { "type": "video", "url": "https://www.youtube.com/embed/he8pi3nbUDk" }
    ],
    "scrapedAt": "2026-05-08T08:21:10.114Z"
}
````

#### 🗂 Key output fields

| Group | Fields |
|---|---|
| **Identifiers** | `type`, `jobId`, `jobReference` (employer's internal ref, when present), `jobUrl`, `scrapedAt` |
| **Role** | `title`, `description` (full HTML), `industry[]`, `tags[]` (job-specific, separate from industry) |
| **Dates** | `postedDate` (ISO date), `postedDateLabel` (human), `closingDate` (ISO date), `closingDateLabel` ("24 May 2026 at 23:30"), `closingDateTime` (precise ISO datetime including cut-off time) |
| **Employer** | `companyName`, `companyProfileUrl`, `organisationSlug`, `organisationType` (e.g. `Registered Charity`), `organisationSizeBand` (e.g. `501 - 1000`), `logoUrl` |
| **Location** | `location`, `postcode`, `addressLocality`, `addressRegion`, `country`, `workplaceType` (`On-site`/`Hybrid`/`Remote`) |
| **Compensation** | `salary.{currency,min,max,unit,raw}`, `employmentType[]`, `contractType`, `hours` |
| **Application resources** | `attachments[]` — array of `{name, url, type}` for PDF/Doc job descriptions, person specs, application packs |
| **Apply flow** | `applyType` (`internal` / `external` / `unknown`), `applyUrl`, `externalApplyUrl` (resolved recruiter destination for redirect-to-recruiter jobs), `agencyContactRestriction` (boolean — true when the employer has flagged "no contact from agencies") |
| **Accreditations** | `accreditations[]` — known UK employer accreditations detected in the description prose (`Disability Confident`, `Living Wage Employer`, `Mindful Employer`, `Investors in People`, `Stonewall Diversity Champion`, `B Corp`, `Race at Work Charter`) |
| **Company enrichment** *(merged into the same row when `enrichOrganisation: true`)* | `companyTagline`, `companyDescription`, `companyWebsite`, `companyDomain`, `companyHeadquarters.{postcode,country,mapEmbedUrl}`, `companyBannerImage`, `companyBenefits[]` (e.g. `Cycle to work scheme`, `Enhanced pension`, `Mental wellbeing support`), `companyMedia[]` (YouTube videos / images from the org's CharityJob profile) |

#### ❓ FAQ

**Which CharityJob URLs are supported?**
Search URLs (`/jobs?...`) and single job URLs (`/jobs/{org}/{slug}/{id}`). Volunteer listings, organisation pages used as starting points, and any host outside `www.charityjob.co.uk` are skipped.

**Does `externalApplyUrl` show the actual recruiter URL?**
Yes — for jobs marked `applyType: "external"` (CharityJob's "Redirect to recruiter" button), the actor performs a 2-step flow against CharityJob's apply endpoints to retrieve the real recruiter destination (e.g. `https://jobs.crisis.org.uk/...`, `https://app.beapplied.com/apply/...`). Internal-apply jobs return `applyUrl` only.

**Can I scrape private pages, premium recruiter listings, or candidate profiles?**
No. The scraper accesses only publicly available pages — no logged-in content, no recruiter-only views, no candidate data.

**How do I limit results?**
Set `maxItems`. Pagination short-circuits as soon as the cap is reached, so a `maxItems: 50` run stops fetching listing pages roughly halfway through page 4 (the site shows ~15 jobs per page).

#### 💬 Support

- For issues or feature requests, please use the [**Issues**](https://console.apify.com/actors/zQuZx45r3BPT3BEfs/issues) tab on the actor's Apify Console page.
- Author's website: <https://muhamed-didovic.github.io/>
- Email: <muhamed.didovic@gmail.com>

#### 🛠 Additional services

- Custom output shape, additional fields, or one-off datasets: <muhamed.didovic@gmail.com>
- Need this scraper customised, or want a similar scraper for TotalJobs / other UK job boards? Drop an email.
- For API access (no Apify fee, just a usage fee for the API): <muhamed.didovic@gmail.com>

#### 🔎 Explore more scrapers

If this CharityJob.co.uk Scraper was useful, see other scrapers and actors at [memo23's Apify profile](https://apify.com/memo23) — covering job boards, real estate, social media, and more.

***

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by CharityJob.co.uk or any of its operators, subsidiaries, or affiliates. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available job-listing and organisation-profile pages — no authenticated endpoints, recruiter-only features, candidate accounts, or content behind the charityjob.co.uk login wall. Users are responsible for ensuring their use complies with charityjob.co.uk's Terms of Service, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organisation.

***

### SEO Keywords

charityjob scraper, scrape charityjob, charityjob api, charityjob.co.uk scraper, Apify charityjob, charity jobs scraper, nonprofit jobs scraper, third sector jobs scraper, uk charity jobs data, charity sector hiring data, charity salary benchmarks, nonprofit recruitment data, charity vacancies api, fundraising jobs scraper, policy jobs scraper, mental health jobs uk, uk job board scraper, charity recruitment intelligence, third sector talent pipeline, voluntary sector hiring trends, totaljobs alternative scraper

# Actor input Schema

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

Full charityjob.co.uk URLs (e.g. https://www.charityjob.co.uk/jobs?days=1\&workplace=on-site).

## `cause` (type: `array`):

Maps to `cause`. Add one slug per row (e.g. human-rights, education, mental-health).

## `workplace` (type: `array`):

Maps to `workplace`. Multi-select. Allowed values: on-site, hybrid, remote.

## `contractType` (type: `array`):

Maps to `contracttype`. Multi-select. Allowed values: full-time, part-time, permanent, contract, temporary, internship. CharityJob combines hours and contract type into one field.

## `employerType` (type: `string`):

Maps to `employerType`.

## `days` (type: `string`):

Maps to `days` (1, 3, 7, 14).

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

Maps to `minsalary`.

## `maxSalary` (type: `integer`):

Maps to `maxsalary`.

## `enrichOrganisation` (type: `boolean`):

When enabled, each unique organisation profile (`/organisation/{slug}`) is fetched once to enrich jobs with `companyDescription` and `companyDomain`. Costs one extra request per unique company.

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

Hard cap on the number of jobs collected.

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

Maximum number of pages processed in parallel.

## `minConcurrency` (type: `integer`):

Minimum number of pages processed in parallel.

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

Number of retries before a failed request is given up.

## `proxy` (type: `object`):

Apify proxy settings used by the scraper.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.charityjob.co.uk/jobs?days=1&workplace=on-site&workplace=hybrid&employerType=direct-employer"
  ],
  "cause": [
    "human-rights"
  ],
  "workplace": [
    "hybrid"
  ],
  "contractType": [
    "full-time"
  ],
  "employerType": "direct-employer",
  "days": "7",
  "minSalary": 30000,
  "maxSalary": 60000,
  "enrichOrganisation": true,
  "maxItems": 1000,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 5,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "startUrls": [
        "https://www.charityjob.co.uk/jobs?days=1&workplace=on-site&workplace=hybrid&employerType=direct-employer"
    ],
    "cause": [
        "human-rights"
    ],
    "workplace": [
        "hybrid"
    ],
    "contractType": [
        "full-time"
    ],
    "employerType": "direct-employer",
    "days": "7",
    "minSalary": 30000,
    "maxSalary": 60000,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/charityjob-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 = {
    "startUrls": ["https://www.charityjob.co.uk/jobs?days=1&workplace=on-site&workplace=hybrid&employerType=direct-employer"],
    "cause": ["human-rights"],
    "workplace": ["hybrid"],
    "contractType": ["full-time"],
    "employerType": "direct-employer",
    "days": "7",
    "minSalary": 30000,
    "maxSalary": 60000,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/charityjob-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://www.charityjob.co.uk/jobs?days=1&workplace=on-site&workplace=hybrid&employerType=direct-employer"
  ],
  "cause": [
    "human-rights"
  ],
  "workplace": [
    "hybrid"
  ],
  "contractType": [
    "full-time"
  ],
  "employerType": "direct-employer",
  "days": "7",
  "minSalary": 30000,
  "maxSalary": 60000,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call memo23/charityjob-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=memo23/charityjob-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "CharityJob.co.uk scraper",
        "description": "Scrape UK charity-sector job postings from CharityJob.co.uk — title, salary band, workplace type, employer, posted/closing dates, full description. Works with any search URL, filter combo or single job URL. Optional company enrichment adds website domain and About copy. JSON or CSV out.",
        "version": "0.0",
        "x-build-id": "ByIwh1LIMfRkH5B8N"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/memo23~charityjob-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-memo23-charityjob-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/memo23~charityjob-scraper/runs": {
            "post": {
                "operationId": "runs-sync-memo23-charityjob-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/memo23~charityjob-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-memo23-charityjob-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrls": {
                        "title": "URLs of CharityJob search or job pages",
                        "type": "array",
                        "description": "Full charityjob.co.uk URLs (e.g. https://www.charityjob.co.uk/jobs?days=1&workplace=on-site).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "cause": {
                        "title": "Cause / sector",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Maps to `cause`. Add one slug per row (e.g. human-rights, education, mental-health).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "workplace": {
                        "title": "Workplace type",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Maps to `workplace`. Multi-select. Allowed values: on-site, hybrid, remote.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "on-site",
                                "hybrid",
                                "remote"
                            ]
                        }
                    },
                    "contractType": {
                        "title": "Contract type / hours",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Maps to `contracttype`. Multi-select. Allowed values: full-time, part-time, permanent, contract, temporary, internship. CharityJob combines hours and contract type into one field.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "full-time",
                                "part-time",
                                "permanent",
                                "contract",
                                "temporary",
                                "internship"
                            ]
                        }
                    },
                    "employerType": {
                        "title": "Employer type",
                        "enum": [
                            "direct-employer",
                            "recruitment-agency"
                        ],
                        "type": "string",
                        "description": "Maps to `employerType`."
                    },
                    "days": {
                        "title": "Posted within (days)",
                        "enum": [
                            "1",
                            "3",
                            "7",
                            "14"
                        ],
                        "type": "string",
                        "description": "Maps to `days` (1, 3, 7, 14)."
                    },
                    "minSalary": {
                        "title": "Minimum salary (£)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maps to `minsalary`."
                    },
                    "maxSalary": {
                        "title": "Maximum salary (£)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maps to `maxsalary`."
                    },
                    "enrichOrganisation": {
                        "title": "Fetch organisation profile (company description + domain)",
                        "type": "boolean",
                        "description": "When enabled, each unique organisation profile (`/organisation/{slug}`) is fetched once to enrich jobs with `companyDescription` and `companyDomain`. Costs one extra request per unique company.",
                        "default": true
                    },
                    "maxItems": {
                        "title": "Maximum items to scrape",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Hard cap on the number of jobs collected.",
                        "default": 1000
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of pages processed in parallel.",
                        "default": 10
                    },
                    "minConcurrency": {
                        "title": "Min concurrency",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Minimum number of pages processed in parallel.",
                        "default": 1
                    },
                    "maxRequestRetries": {
                        "title": "Max request retries",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Number of retries before a failed request is given up.",
                        "default": 5
                    },
                    "proxy": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify proxy settings used by the scraper.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
