# CV-Library Scraper - UK Jobs, Salaries & Companies (`studio-amba/cv-library-scraper`) Actor

Scrape UK job listings from CV-Library by keyword and location. Extract job titles, companies, salary ranges, locations, job types, and apply links. No login or cookies required.

- **URL**: https://apify.com/studio-amba/cv-library-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 result scrapeds

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.

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

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

### What does CV-Library Scraper do?

**CV-Library Scraper** extracts job listings from [CV-Library](https://www.cv-library.co.uk), one of the UK's largest independent job boards with hundreds of thousands of live vacancies across every sector. Give it a keyword and (optionally) a location, and it returns structured data for every matching job: title, company, salary, location, job type, posting date, a description snippet, and a direct link to the advert. Optionally enable full detail-page enrichment to pull the complete job description and structured salary for each listing.

Run it on the Apify platform to get UK job market data via API, schedule recurring scrapes, and pipe results into tools like Zapier, Make, Google Sheets, Airtable, and Slack.

### How to scrape CV-Library data

1. Go to the CV-Library Scraper on the Apify Store.
2. Click **Try for free** to open the actor in the Apify Console.
3. Enter a search query (e.g. "developer", "nurse", "accountant", "project manager").
4. Optionally enter a UK location (e.g. "London", "Manchester", "Birmingham"). Leave it empty to search the whole UK.
5. Set the maximum number of results you want (default: 50).
6. Leave "Fetch full description" off for fast, listing-only runs, or turn it on if you need the complete job description and structured salary per posting.
7. Click **Start** and wait for the run to finish.
8. Download your data as JSON, CSV, Excel, or HTML from the Output tab, or pull it via the Apify API.

### Why use CV-Library Scraper?

- **UK salary benchmarking** — most listings show a salary range or day rate. Compare pay across roles, sectors, and cities.
- **Recruitment intelligence** — see which companies and agencies are hiring, for what roles, and at what pay.
- **Labour market analysis** — understand demand across sectors and regions from a job board that skews toward IT, engineering, trades, and public-sector roles.
- **Lead generation** — find employers and recruitment agencies actively hiring to target with B2B services, tools, or staffing solutions.
- **Job aggregation** — feed structured listings into your own job board, career site, or candidate-alert system.
- **Academic and policy research** — clean, structured data for labour economics, skills-gap studies, and workforce reports.

### About CV-Library

CV-Library is one of the UK's largest independent job boards, listing vacancies from employers and recruitment agencies across every sector — IT, engineering, trades, healthcare, finance, education, and more. Key characteristics:

- **Coverage**: Nationwide UK, from London to regional towns.
- **Salary data**: Most adverts show a salary range or day/hour rate; contract roles are common.
- **Work patterns**: Permanent, contract, and temporary roles, flagged per listing.
- **Easy Apply**: A large share of listings support one-click applications through CV-Library itself.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | string | No | Job keyword to search for. Defaults to `developer` if empty. |
| `location` | string | No | UK location to filter by (e.g. `London`). Leave empty to search the whole UK. |
| `maxResults` | integer | No | Maximum number of listings to scrape. Default `50`. |
| `fetchDetails` | boolean | No | When `true`, fetches each job's detail page (capped at 25 per run) for the full description and structured salary. Default `false`. |
| `brightDataApiKey` | string | No | Bright Data API key, only needed if you're running this actor's source yourself outside Apify. Not required when running it on the Apify platform. |

#### Example input

```json
{
  "searchQuery": "developer",
  "location": "London",
  "maxResults": 50,
  "fetchDetails": false
}
````

### Output

Each job listing is a flat JSON object with the following fields:

| Field | Type | Example |
|-------|------|---------|
| `jobId` | string | `225365841` |
| `jobTitle` | string | `C++ Developer Commodities Quant Trading Developer` |
| `company` | string | `Huxley Associates` |
| `companyUrl` | string | `https://www.cv-library.co.uk/list-jobs/256316/huxley-associates-jobs` |
| `location` | string | `City of London, London` |
| `salary` | string | `£150,000 - £200,000 per annum` |
| `salaryMin` | number | `150000` (only when `fetchDetails` is on) |
| `salaryMax` | number | `200000` (only when `fetchDetails` is on) |
| `salaryCurrency` | string | `GBP` (only when `fetchDetails` is on) |
| `salaryPeriod` | string | `YEAR` (only when `fetchDetails` is on) |
| `jobType` | string | `Permanent` |
| `postedDate` | string | `2026-07-13T16:07:09Z` |
| `postedDisplay` | string | `13/07/2026` |
| `expiryDate` | string | `2026-08-12T16:07:09.000Z` (only when `fetchDetails` is on) |
| `easyApply` | boolean | `true` |
| `descriptionSnippet` | string | `Top tier Energy Trading client requires a senior C++...` |
| `description` | string | Full plain-text description (only when `fetchDetails` is on) |
| `url` | string | `https://www.cv-library.co.uk/job/225365841/c-developer-commodities-quant-trading-developer` |
| `scrapedAt` | string | `2026-07-25T09:29:52.172Z` |

#### Example output

```json
{
  "jobId": "225365841",
  "jobTitle": "C++ Developer Commodities Quant Trading Developer",
  "company": "Huxley Associates",
  "companyUrl": "https://www.cv-library.co.uk/list-jobs/256316/huxley-associates-jobs",
  "location": "City of London, London",
  "salary": "£150,000 - £200,000 per annum",
  "jobType": "Permanent",
  "postedDate": "2026-07-13T16:07:09Z",
  "postedDisplay": "13/07/2026",
  "easyApply": true,
  "descriptionSnippet": "Top tier Energy Trading client requires a senior C++ Pythom Quant Strat develop core components for the new Risk & PnL engine...",
  "url": "https://www.cv-library.co.uk/job/225365841/c-developer-commodities-quant-trading-developer",
  "scrapedAt": "2026-07-25T09:29:52.172Z"
}
```

### Cost estimate

This actor is billed on Apify's Pay Per Result model. CV-Library blocks plain scraping, so every run goes through a bot-bypass proxy layer, but the listing page returns 20 jobs per request — the underlying bypass cost per result stays a small fraction of the per-result price. You pay per job returned plus a small per-run start fee. Enabling `fetchDetails` adds one extra request per job (capped at 25 per run) for the full description and structured salary — useful for smaller, targeted runs rather than large bulk scrapes.

### Limitations and known issues

- **Search results only by default** — the listing page already carries company, location, salary text, job type, posting date, and a description snippet for every job. Turn on `fetchDetails` if you need the full description body and structured salary (min/max/currency/period).
- **Salary as advertised** — salary text is exactly what the employer entered. Some adverts show "competitive", a day rate instead of an annual figure, or no salary at all.
- **UK focus** — CV-Library is a UK job board. Results are UK-only.
- **`fetchDetails` cap** — to keep runs predictable, detail-page enrichment is capped at 25 jobs per run regardless of `maxResults`. Run the actor again with a different query to enrich more.

### Related scrapers

- **Reed Scraper** — UK jobs, salaries, and companies from Reed.co.uk.
- **Jobsite Scraper** — UK jobs from Jobsite.co.uk (StepStone platform).
- **Totaljobs Scraper** — UK jobs from Totaljobs.com.
- **Caterer Scraper** — UK hospitality and catering jobs from Caterer.com.
- Browse the Studio AMBA profile on the Apify Store for more European job and marketplace scrapers.

### FAQ

**Do I need a CV-Library account or API key?**
No. This actor reads CV-Library's public job listings. There is no login, no cookies, and no account required to use it on the Apify platform.

**Can I filter by salary, contract type, or distance?**
The current version filters by keyword and location. Salary and job type are returned on every result so you can filter them yourself after scraping.

**Why is `fetchDetails` off by default?**
The search-results page already includes company, location, salary, job type, posting date, and a description snippet for every listing — enough for most use cases without the extra request per job that full detail-page enrichment requires.

**Is scraping CV-Library legal?**
This actor collects publicly available job listing data. You are responsible for using the data in line with CV-Library's terms and applicable law. Do not use it to send unsolicited communications in breach of regulations.

# Actor input Schema

## `searchQuery` (type: `string`):

Job keyword to search for (e.g. 'developer', 'nurse', 'accountant', 'project manager'). Defaults to 'developer' if empty.

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

UK location to filter by (e.g. 'London', 'Manchester', 'Birmingham'). Leave empty to search across the whole UK.

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

Maximum number of job listings to scrape.

## `fetchDetails` (type: `boolean`):

When enabled, fetches each job's detail page (one extra Bright Data request per job, capped at 25 per run) to add the full job description and structured salary. Off by default -- the search-results page already includes company, location, salary text, job type, and a description snippet for every listing.

## `brightDataApiKey` (type: `string`):

Bright Data API key used to bypass CV-Library's Akamai-style bot protection via Web Unlocker. Can also be set via the BRIGHT\_DATA\_API\_KEY environment variable.

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

Not used by this actor -- CV-Library is fetched through Bright Data Web Unlocker, which replaces Apify Proxy for this site. Present for compatibility only.

## Actor input object example

```json
{
  "searchQuery": "developer",
  "location": "London",
  "maxResults": 20,
  "fetchDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}
```

# 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 = {
    "searchQuery": "developer",
    "location": "London",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/cv-library-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 = {
    "searchQuery": "developer",
    "location": "London",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/cv-library-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 '{
  "searchQuery": "developer",
  "location": "London",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}' |
apify call studio-amba/cv-library-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "CV-Library Scraper - UK Jobs, Salaries & Companies",
        "description": "Scrape UK job listings from CV-Library by keyword and location. Extract job titles, companies, salary ranges, locations, job types, and apply links. No login or cookies required.",
        "version": "0.1",
        "x-build-id": "lUzMokbLMVPw4qC8e"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~cv-library-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-cv-library-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/studio-amba~cv-library-scraper/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-cv-library-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/studio-amba~cv-library-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-cv-library-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": {
                    "searchQuery": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Job keyword to search for (e.g. 'developer', 'nurse', 'accountant', 'project manager'). Defaults to 'developer' if empty."
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "UK location to filter by (e.g. 'London', 'Manchester', 'Birmingham'). Leave empty to search across the whole UK."
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of job listings to scrape.",
                        "default": 50
                    },
                    "fetchDetails": {
                        "title": "Fetch full description (detail page)",
                        "type": "boolean",
                        "description": "When enabled, fetches each job's detail page (one extra Bright Data request per job, capped at 25 per run) to add the full job description and structured salary. Off by default -- the search-results page already includes company, location, salary text, job type, and a description snippet for every listing.",
                        "default": false
                    },
                    "brightDataApiKey": {
                        "title": "Bright Data API key",
                        "type": "string",
                        "description": "Bright Data API key used to bypass CV-Library's Akamai-style bot protection via Web Unlocker. Can also be set via the BRIGHT_DATA_API_KEY environment variable."
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Not used by this actor -- CV-Library is fetched through Bright Data Web Unlocker, which replaces Apify Proxy for this site. Present for compatibility only."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
