# CV-Library Jobs Scraper (`solidcode/cv-library-co-uk-scraper`) Actor

\[💰 $4.0 / 1K] Extract UK job postings from CV-Library at scale — title, company, location, salary (parsed min/max), job type, remote flag, posted date, full description, and apply link. Search by keyword, location, and radius with job-type, salary, date, and remote filters, or paste search URLs.

- **URL**: https://apify.com/solidcode/cv-library-co-uk-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 5 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## CV-Library Jobs Scraper

Pull live UK job postings from CV-Library at scale — titles, companies, locations, salaries, job types, posted dates, and full descriptions, with every salary parsed into structured min, max, currency, and pay period. Search by keyword and location or paste CV-Library URLs, and get a clean dataset of 20 fields per job. Built for recruiters, job-market analysts, and lead-generation teams who need fresh UK hiring data without copy-pasting listings one page at a time.

### Why This Scraper?

- **Parsed salary, not just raw text** — every job ships the original salary string *plus* a structured `salaryMin`, `salaryMax`, `salaryCurrency`, and `salaryPeriod` (annum, day, hour, week, or month), so you can sort, filter, and average without writing your own parser.
- **20 structured fields per job** — including job ID, company name, company profile URL, company logo, location, ISO posted date, direct apply link, and the source search URL each result came from.
- **Description in both plain text and HTML** — `description` for clean analysis and `descriptionHtml` to keep the original markup, on the same record.
- **Multi-keyword search in one run** — pass a whole list of job titles and each runs its own search, with a shared results budget across all of them.
- **Four job-type filters** — Permanent, Contract, Temporary, and Part-Time, applied to exactly CV-Library's real employment taxonomy.
- **Salary band and remote-only filters** — keep only jobs within a GBP minimum and maximum, or only roles that read as remote, hybrid, or work-from-home.
- **Search radius from this-area-only up to 100 miles** — eight named distance bands around any town, city, county, or postcode, plus a posted-since window (today, last 3, 7, or 14 days).
- **Paste a CV-Library search URL or a single job URL** — re-scrape one exact posting by its job link, or hand over a fully-filtered search page and the actor respects the filters baked into it.
- **Automatic deduplication by job ID** — the same listing shown across several pages or keyword searches is returned once, even when your searches overlap.

### Use Cases

**Recruitment & Talent Sourcing**
- Build candidate-facing job feeds for a niche, location, or salary band
- Source live vacancies for a specialist desk across multiple job titles at once
- Track which companies are actively hiring for a given role
- Pull direct apply links to route candidates straight to the application

**Market & Salary Research**
- Benchmark salary ranges by role and region using parsed min/max values
- Measure hiring volume for a skill across UK cities and counties
- Compare permanent vs. contract vs. temporary demand over time
- Map remote and hybrid availability by job title

**Lead Generation**
- Build prospect lists of companies posting roles in your target market
- Capture hiring-company names and profile links for outreach
- Identify employers expanding in a specific town or postcode
- Spot agencies and direct employers recruiting for the same role

**Competitor & Job-Board Monitoring**
- Watch a competitor's open roles by company name
- Monitor newly posted jobs with the today / last-3-days window
- Track how long roles stay live by re-running a saved search
- Audit your own postings against the wider CV-Library market

### Getting Started

#### Simple Keyword Search

Just a job title and a location:

```json
{
    "keywords": ["software engineer"],
    "location": "London",
    "maxResults": 100
}
````

#### Keyword Search with Filters

Add a radius, a job type, a salary floor, and a posted-since window:

```json
{
    "keywords": ["registered nurse", "healthcare assistant"],
    "location": "Manchester",
    "distance": "30",
    "jobType": ["permanent"],
    "salaryMin": 30000,
    "postedSince": "7",
    "maxResults": 250
}
```

#### Advanced — Paste CV-Library URLs

Mix a fully-filtered search page with a single job link to re-scrape one exact posting:

```json
{
    "startUrls": [
        "https://www.cv-library.co.uk/software-engineer-jobs-in-london",
        "https://www.cv-library.co.uk/job/123456789/Senior-Software-Engineer"
    ],
    "includeDescription": true,
    "onlyUniqueJobs": true,
    "maxResults": 500
}
```

### Input Reference

#### Search

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `keywords` | string\[] | `["software engineer"]` | Job titles, skills, or keywords to search for. Each keyword runs its own search. Leave empty if you only want to use URLs. |
| `location` | string | `"London"` | Town, city, county, or postcode to search around. Applied to every keyword search. |
| `distance` | select | `Within 15 miles` | Search radius around the location: This area only, or within 5, 10, 15, 20, 30, 50, or 100 miles. |
| `startUrls` | string\[] | `[]` | Paste full CV-Library search or individual job URLs. Filters baked into a pasted search page are respected. Mix with keyword search. |

#### Filters

Salary, job-type, and remote filters refine the jobs you receive after collection — they are not re-applied to jobs reached via a pasted URL.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `jobType` | select\[] | `[]` (all) | Keep only these employment types: Permanent, Contract, Temporary, Part-Time. |
| `salaryMin` | integer | — | Keep only jobs offering at least this annual salary (GBP). Jobs with no stated salary are kept. |
| `salaryMax` | integer | — | Keep only jobs offering up to this annual salary (GBP). Jobs with no stated salary are kept. |
| `postedSince` | select | `Any time` | Only jobs posted within: Today, Last 3 days, Last 7 days, or Last 14 days. |
| `remoteOnly` | boolean | `false` | Keep only jobs that read as remote, hybrid, or work-from-home. |

#### Output & Limits

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `includeDescription` | boolean | `true` | Fetch the full job description plus detail-page metadata (apply link, exact posted date). Turn off for lighter, faster records. |
| `onlyUniqueJobs` | boolean | `true` | Return each job once even if it appears across several pages or searches. Deduplicates by job ID. |
| `maxResults` | integer | `100` | Cap on the total jobs returned across all searches and URLs. Use 0 for unlimited. |

### Output

Each job is one flat row. Here's a representative result with full descriptions enabled:

```json
{
    "jobId": "123456789",
    "title": "Senior Software Engineer",
    "url": "https://www.cv-library.co.uk/job/123456789/Senior-Software-Engineer",
    "companyName": "Acme Recruitment Ltd",
    "companyUrl": "https://www.cv-library.co.uk/list-jobs/123456/Acme-Recruitment",
    "companyLogo": "https://www.cv-library.co.uk/logos/123456.png",
    "location": "London",
    "salary": "£60,000 - £75,000 per annum",
    "salaryMin": 60000,
    "salaryMax": 75000,
    "salaryCurrency": "GBP",
    "salaryPeriod": "annum",
    "jobType": "Permanent",
    "isRemote": true,
    "postedDate": "2026-06-15",
    "description": "We are looking for a Senior Software Engineer to join our growing team...",
    "descriptionHtml": "<p>We are looking for a Senior Software Engineer to join our growing team...</p>",
    "applyUrl": "https://www.cv-library.co.uk/job/apply/123456789",
    "searchUrl": "https://www.cv-library.co.uk/software-engineer-jobs-in-london",
    "scrapedAt": "2026-06-18T14:30:00Z"
}
```

#### Core Fields

| Field | Type | Description |
|-------|------|-------------|
| `jobId` | string | CV-Library job ID — used as the deduplication key. |
| `title` | string | Job title. |
| `url` | string | Canonical CV-Library job posting URL. |
| `location` | string | Job location as shown on CV-Library. |
| `jobType` | string | Employment type: Permanent, Contract, Temporary, or Part-Time. |
| `isRemote` | boolean | Whether the posting reads as remote, hybrid, or work-from-home. |
| `postedDate` | string | Posting date (ISO format where available). |

#### Company

| Field | Type | Description |
|-------|------|-------------|
| `companyName` | string | Hiring company or recruiter name. |
| `companyUrl` | string | Link to the company's CV-Library profile, if present. |
| `companyLogo` | string | Company logo image URL, if present. |

#### Salary

| Field | Type | Description |
|-------|------|-------------|
| `salary` | string | Raw salary text (e.g. "£60,000 - £75,000 per annum"). |
| `salaryMin` | number | Parsed minimum salary. |
| `salaryMax` | number | Parsed maximum salary. |
| `salaryCurrency` | string | Parsed currency (typically GBP). |
| `salaryPeriod` | string | Parsed pay period: annum, day, hour, week, or month. |

#### Description & Meta

| Field | Type | Description |
|-------|------|-------------|
| `description` | string | Plain-text job description (when descriptions are enabled). |
| `descriptionHtml` | string | Original HTML job description (when descriptions are enabled). |
| `applyUrl` | string | Direct apply link for the posting. |
| `searchUrl` | string | The search or start URL this job was found under (provenance). |
| `scrapedAt` | string | ISO-8601 timestamp the row was collected. |

### Tips for Best Results

- **Start small to validate** — set `maxResults` to 50 on your first run to confirm the data matches what you need, then scale up.
- **Keep keywords specific** — the salary, job-type, and remote filters are applied to the matched results rather than narrowed at the search, so a precise keyword like "registered nurse" returns cleaner results than a broad one like "nurse".
- **Re-scrape one posting by its job URL** — paste a single `https://www.cv-library.co.uk/job/...` link to pull exactly that job as one row, ideal for refreshing a saved listing.
- **Turn off descriptions for fast bulk scans** — set `includeDescription` to false when you only need titles, companies, locations, salaries, and links; turn it on for full text and apply links.
- **Widen the radius on thin markets** — outside major cities, a 30 or 50-mile radius pulls far more matches than this-area-only.
- **Use a list of keywords for breadth** — one run can cover several job titles at once and share a single results budget across them.
- **Pasted search URLs carry their own filters** — build a fully-filtered search on CV-Library, copy the URL into `startUrls`, and the actor honors exactly what you set on the site.

### Pricing

**From $4.00 per 1,000 results** — undercuts comparable CV-Library actors on the market, and your salary, job-type, and remote filters are included at no extra cost. Bronze, Silver, and Gold subscribers pay progressively less; the table below shows total cost at each discount tier.

| Results | No discount | Bronze | Silver | Gold |
|---------|-------------|--------|--------|------|
| 100 | $0.48 | $0.45 | $0.43 | $0.40 |
| 1,000 | $4.80 | $4.50 | $4.25 | $4.00 |
| 10,000 | $48.00 | $45.00 | $42.50 | $40.00 |
| 100,000 | $480.00 | $450.00 | $425.00 | $400.00 |

A "result" is one job row in your output dataset. No compute or time-based charges — you pay per result, plus a small fixed per-run start fee.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on new results
- **Webhooks** — Trigger custom APIs on run completion
- **Apify API** — Full programmatic access

### Legal & Ethical Use

This actor is designed for legitimate recruitment research, labour-market analysis, and lead generation using publicly available job postings. You are responsible for complying with applicable laws and CV-Library's Terms of Service. Do not use extracted data for spam, harassment, or any unlawful purpose, and handle any personal data in line with UK GDPR and other applicable data-protection regulations. </content> </invoke>

# Actor input Schema

## `keywords` (type: `array`):

Job titles, skills, or keywords to search for, such as 'software engineer', 'registered nurse', or 'HGV driver'. Each keyword runs its own search. Leave empty if you only want to use the URLs below.

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

Town, city, county, or postcode to search around, such as 'London', 'Manchester', or 'M1 4BT'. Matches what you would type into CV-Library's location box. Applied to every keyword search above.

## `distance` (type: `string`):

How far around the location to search, in miles.

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

Optional. Paste full CV-Library search or job URLs (e.g. https://www.cv-library.co.uk/software-engineer-jobs). Any filters already applied on the site are respected. Useful for advanced searches the fields above don't cover. You can mix URLs with the keyword search.

## `jobType` (type: `array`):

Keep only jobs of these employment types. This filter is applied to the results after they are collected (CV-Library does not narrow the search by type on these pages), so on a thin market up to 8 extra pages may be scanned to find matches before the run stops. Leave empty for all types.

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

Keep only jobs offering at least this annual salary, in GBP. Applied to the results after collection (filtered from results, not sent to CV-Library), using each job's parsed salary. Jobs with no stated salary are kept. Leave empty for no lower bound.

## `salaryMax` (type: `integer`):

Keep only jobs offering up to this annual salary, in GBP. Applied to the results after collection (filtered from results, not sent to CV-Library), using each job's parsed salary. Jobs with no stated salary are kept. Leave empty for no upper bound.

## `postedSince` (type: `string`):

Only return jobs posted within this time window. Leave on 'Any time' to include all jobs.

## `remoteOnly` (type: `boolean`):

Keep only jobs that read as remote or work-from-home. Applied to the results after collection (filtered from results, not sent to CV-Library) by checking each job's title, location, and description for remote / hybrid / work-from-home wording. On searches with few remote roles, up to 8 extra pages are scanned before the run stops.

## `includeDescription` (type: `boolean`):

Off by default for fast results. Each job card already includes the title, company, location, salary, job type, posted date, and link. Turn this on to also fetch the full job description, the apply link, and the exact posted date from each job's own page — this is slower, because every job needs an extra page visit, so expect longer runs (and a higher per-run cost) on large searches.

## `onlyUniqueJobs` (type: `boolean`):

When on, each job is returned once even if CV-Library lists it across several pages or searches. Deduplicates by the job's ID. Turn off to keep every copy.

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

Cap on the total number of jobs returned across all searches and URLs. Defaults to 50 for a quick first run; raise it for larger pulls. Use 0 for unlimited (the run keeps paging until CV-Library returns no more jobs). Results are fetched a page at a time, so a small cap can return up to a full page more than you asked for.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "location": "London",
  "distance": "15",
  "startUrls": [],
  "jobType": [],
  "postedSince": "",
  "remoteOnly": false,
  "includeDescription": false,
  "onlyUniqueJobs": true,
  "maxResults": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

Table of jobs with key fields like title, company, location, salary, posted date, and link.

## `details` (type: `string`):

Full per-job detail rows including description, parsed salary, job type, remote flag, and apply link.

# 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 = {
    "keywords": [
        "software engineer"
    ],
    "location": "London",
    "distance": "15",
    "startUrls": [],
    "jobType": [],
    "postedSince": "",
    "remoteOnly": false,
    "includeDescription": false,
    "onlyUniqueJobs": true,
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/cv-library-co-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 = {
    "keywords": ["software engineer"],
    "location": "London",
    "distance": "15",
    "startUrls": [],
    "jobType": [],
    "postedSince": "",
    "remoteOnly": False,
    "includeDescription": False,
    "onlyUniqueJobs": True,
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/cv-library-co-uk-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 '{
  "keywords": [
    "software engineer"
  ],
  "location": "London",
  "distance": "15",
  "startUrls": [],
  "jobType": [],
  "postedSince": "",
  "remoteOnly": false,
  "includeDescription": false,
  "onlyUniqueJobs": true,
  "maxResults": 50
}' |
apify call solidcode/cv-library-co-uk-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "CV-Library Jobs Scraper",
        "description": "[💰 $4.0 / 1K] Extract UK job postings from CV-Library at scale — title, company, location, salary (parsed min/max), job type, remote flag, posted date, full description, and apply link. Search by keyword, location, and radius with job-type, salary, date, and remote filters, or paste search URLs.",
        "version": "1.0",
        "x-build-id": "0zjYBgSyKK3Yiadbw"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/solidcode~cv-library-co-uk-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-solidcode-cv-library-co-uk-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/solidcode~cv-library-co-uk-scraper/runs": {
            "post": {
                "operationId": "runs-sync-solidcode-cv-library-co-uk-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/solidcode~cv-library-co-uk-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-solidcode-cv-library-co-uk-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": {
                    "keywords": {
                        "title": "Search Keywords",
                        "type": "array",
                        "description": "Job titles, skills, or keywords to search for, such as 'software engineer', 'registered nurse', or 'HGV driver'. Each keyword runs its own search. Leave empty if you only want to use the URLs below.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "Town, city, county, or postcode to search around, such as 'London', 'Manchester', or 'M1 4BT'. Matches what you would type into CV-Library's location box. Applied to every keyword search above."
                    },
                    "distance": {
                        "title": "Search Radius",
                        "enum": [
                            "0",
                            "5",
                            "10",
                            "15",
                            "20",
                            "30",
                            "50",
                            "100"
                        ],
                        "type": "string",
                        "description": "How far around the location to search, in miles.",
                        "default": "15"
                    },
                    "startUrls": {
                        "title": "CV-Library Search URLs",
                        "type": "array",
                        "description": "Optional. Paste full CV-Library search or job URLs (e.g. https://www.cv-library.co.uk/software-engineer-jobs). Any filters already applied on the site are respected. Useful for advanced searches the fields above don't cover. You can mix URLs with the keyword search.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "jobType": {
                        "title": "Job Type",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Keep only jobs of these employment types. This filter is applied to the results after they are collected (CV-Library does not narrow the search by type on these pages), so on a thin market up to 8 extra pages may be scanned to find matches before the run stops. Leave empty for all types.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "permanent",
                                "contract",
                                "temporary",
                                "part-time"
                            ],
                            "enumTitles": [
                                "Permanent",
                                "Contract",
                                "Temporary",
                                "Part-Time"
                            ]
                        },
                        "default": []
                    },
                    "salaryMin": {
                        "title": "Minimum Salary",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only jobs offering at least this annual salary, in GBP. Applied to the results after collection (filtered from results, not sent to CV-Library), using each job's parsed salary. Jobs with no stated salary are kept. Leave empty for no lower bound."
                    },
                    "salaryMax": {
                        "title": "Maximum Salary",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only jobs offering up to this annual salary, in GBP. Applied to the results after collection (filtered from results, not sent to CV-Library), using each job's parsed salary. Jobs with no stated salary are kept. Leave empty for no upper bound."
                    },
                    "postedSince": {
                        "title": "Date Posted",
                        "enum": [
                            "",
                            "1",
                            "3",
                            "7",
                            "14"
                        ],
                        "type": "string",
                        "description": "Only return jobs posted within this time window. Leave on 'Any time' to include all jobs.",
                        "default": ""
                    },
                    "remoteOnly": {
                        "title": "Remote Jobs Only",
                        "type": "boolean",
                        "description": "Keep only jobs that read as remote or work-from-home. Applied to the results after collection (filtered from results, not sent to CV-Library) by checking each job's title, location, and description for remote / hybrid / work-from-home wording. On searches with few remote roles, up to 8 extra pages are scanned before the run stops.",
                        "default": false
                    },
                    "includeDescription": {
                        "title": "Fetch Full Job Descriptions",
                        "type": "boolean",
                        "description": "Off by default for fast results. Each job card already includes the title, company, location, salary, job type, posted date, and link. Turn this on to also fetch the full job description, the apply link, and the exact posted date from each job's own page — this is slower, because every job needs an extra page visit, so expect longer runs (and a higher per-run cost) on large searches.",
                        "default": false
                    },
                    "onlyUniqueJobs": {
                        "title": "Only Unique Jobs",
                        "type": "boolean",
                        "description": "When on, each job is returned once even if CV-Library lists it across several pages or searches. Deduplicates by the job's ID. Turn off to keep every copy.",
                        "default": true
                    },
                    "maxResults": {
                        "title": "Maximum Results",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap on the total number of jobs returned across all searches and URLs. Defaults to 50 for a quick first run; raise it for larger pulls. Use 0 for unlimited (the run keeps paging until CV-Library returns no more jobs). Results are fetched a page at a time, so a small cap can return up to a full page more than you asked for.",
                        "default": 50
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
