# Werk.nl Jobs Scraper (`parsebird/werk-nl-jobs-scraper`) Actor

Scrape werk.nl vacatures (UWV) by keyword, location, contract type, and education level. Get title, employer, salary indication, hours, contact email and phone, apply URL, and full description. Export as JSON, CSV, or Excel.

- **URL**: https://apify.com/parsebird/werk-nl-jobs-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Stats:** 2 total users, 1 monthly users, 87.5% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.79 / 1,000 vacature scrapeds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Werk.nl Jobs Scraper

Werk.nl Jobs Scraper extracts vacatures from [werk.nl](https://www.werk.nl/nl/vacatures), the public job board run by UWV, the Dutch employee insurance agency, with structured fields for job title, employer, location, contract type, education level, hours, salary indication, contact email and phone, apply URL, and the full job description.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Search all werk.nl vacatures by keyword, city or postcode with a radius, contract type, education level, hours per week, working times, driver's license, language, and profession, then track new, updated, and expired vacatures across scheduled runs.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```text
Apify Actor parsebird/werk-nl-jobs-scraper scrapes vacatures from werk.nl (UWV, Netherlands). Call it with the apify-client package: client.actor("parsebird/werk-nl-jobs-scraper").call(run_input={"query": "verpleegkundige", "location": "Utrecht", "distanceKm": "25", "contractType": ["vast"], "maxResults": 100}). Inputs: query (string, keyword; empty = all vacatures), location (string, Dutch city or postcode), distanceKm (string "0","5","10","25","50","75","100","125","150","300", default "25"), includeVariableLocations (bool), referenceNumbers (array of werk.nl reference numbers or vacature URLs), contractType (array: "vast","mogelijk vast","tijdelijk"), educationLevel (array: "basisonderwijs","vmbo","havo/vwo","mbo","hbo","wo","niet opgegeven"), workingHours (array "1"-"6" = 0-8, 9-16, 17-24, 25-32, 33-40, 40+ hours), workSchedule (array: "kantoortijden","anders"), profession (array of werk.nl profession names), driversLicense (array: "a","am","b","be","c","c1","c1e","ce","d","d1","d1e","de","t"), language (array of werk.nl language codes, "1" = Nederlands, "3" = Engels), daysOld (int, 0 = any), sortBy ("datum" newest, "afstand" nearest, "leerbaan", "stageplaats"), maxResults (int, default 100, 0 = unlimited), includeDetails (bool, default true), descriptionMaxLength (int, 0 = full), compact (bool), incrementalMode (bool), stateKey (string), emitUnchanged (bool), emitExpired (bool), skipReposts (bool). Output: one dataset item per vacature with jobId, referenceNumber, title, profession, functionName, companyName, companyWebsite, location, postcode, address, workLocationType, distanceKm, contractType, startDate, requiredEducation, minHours, maxHours, workSchedule, salaryIndication, rewardType, description, descriptionHtml, otherRequirements, requiredLanguages, driversLicenses, requiredExperience, contactName, contactPhone, contactEmail, applyUrl, applicationMethods, postedDate, modifiedDate, expirationDate, externalId, employerVacancyId, sourceChannel, isInternship, isLearningPosition, portalUrl, contentHash, scrapedAt; plus changeType, firstSeenAt, lastSeenAt, isRepost, repostOfId in incremental mode. API docs: https://apify.com/parsebird/werk-nl-jobs-scraper/api. Get a token: https://console.apify.com/settings/integrations
```

### What is Werk.nl Jobs Scraper?

**Werk.nl Jobs Scraper** is a data extraction tool for **werk.nl vacatures**. Werk.nl is the Dutch government's job site from UWV and lists more than 270,000 open vacatures from employers, recruiters, and job boards across the Netherlands. The Actor works as a **werk.nl API alternative**: you enter a keyword, a location, and filters, and get clean JSON records instead of browsing page by page.

The easiest way to try it: open the **Input** tab, keep the prefilled keyword `verpleegkundige`, and click **Start**. You get 50 nursing vacatures with full details in a few seconds.

### What can Werk.nl Jobs Scraper do?

- 🔍 **Search werk.nl by keyword**: job title, skill, or any word in Dutch or English, or leave it empty to browse every vacature on werk.nl.
- 📍 **Search by location**: Dutch city or postcode with a radius from 5 to 300 km, with the distance to each job in the output.
- 🎯 **Use the werk.nl filters**: contract type (vast, mogelijk vast, tijdelijk), education level, hours per week, working times, driver's license, required language, and profession (beroep).
- 📄 **Get full job details**: description, salary indication, reward type, contact person, email, phone, apply URL, employer address, language and experience requirements, start date, and expiry date.
- 🔢 **Look up vacatures directly**: paste werk.nl reference numbers or vacature URLs.
- 🔁 **Track changes with incremental mode**: scheduled runs return only NEW, UPDATED, and REAPPEARED vacatures, and can also return EXPIRED ones and flag reposts.
- 🤖 **Use compact output**: core fields only, so AI agents and MCP tools use fewer tokens.

On the Apify platform you also get [scheduled runs](https://docs.apify.com/platform/schedules), a full [REST API](https://docs.apify.com/api/v2), [integrations](https://apify.com/integrations) with Make, Zapier, n8n, Google Sheets, Slack, and webhooks, and export to JSON, CSV, Excel, XML, or HTML.

### What data can you extract from werk.nl?

| Field | Description |
|-------|-------------|
| `title` | Vacature title as published |
| `profession` / `functionName` | werk.nl profession (beroep) and the UWV function name |
| `companyName` / `companyWebsite` | Employer name and website |
| `location` / `postcode` / `address` | Work location city, postcode, and employer address |
| `workLocationType` | Vaste werklocatie, Regio, Wisselend door heel Nederland, or Buitenland |
| `distanceKm` | Distance from your search location (location searches only) |
| `contractType` / `startDate` | Vast, Mogelijk vast, or Tijdelijk, plus start date if given |
| `requiredEducation` / `educationLevel` | Education level asked for |
| `minHours` / `maxHours` / `workSchedule` | Hours per week and office hours vs. varying times |
| `salaryIndication` / `rewardType` | Salary amount indication (when the employer gives one) and reward type |
| `description` / `descriptionHtml` | Job description as plain text and simple HTML |
| `requiredLanguages` / `driversLicenses` / `requiredExperience` | Language levels, license categories, and work experience asked for |
| `contactName` / `contactPhone` / `contactEmail` | Contact person, when the employer lists one |
| `applyUrl` / `applicationMethods` | Application link and accepted ways to apply |
| `postedDate` / `modifiedDate` / `expirationDate` | Created, last modified, and expiry dates |
| `externalId` / `employerVacancyId` / `sourceChannel` | IDs from the original job source and the source channel code |
| `portalUrl` | Link to the vacature on werk.nl |

In standard mode every record has the same keys. Values werk.nl does not provide are `null` (or an empty list), never left out.

### How to scrape werk.nl

1. Open [Werk.nl Jobs Scraper](https://apify.com/parsebird/werk-nl-jobs-scraper) and click **Try for free**.
2. Enter a **Search keyword**, such as `verpleegkundige`, `chauffeur`, or `developer`. Leave it empty to browse all vacatures.
3. Optionally enter a **Location** (city or postcode) and pick a **Search radius**.
4. Open **Filters** to narrow by contract type, education level, hours, working times, driver's license, language, or profession.
5. Set **Max results** and click **Start**.
6. Download the results from the **Output** tab as JSON, CSV, Excel, XML, or HTML, or fetch them through the API.

To monitor the job market, turn on **Incremental mode** and add the run to a [schedule](https://docs.apify.com/platform/schedules), for example every morning.

### Input example

Basic keyword search:

```json
{
    "query": "verpleegkundige",
    "maxResults": 50
}
```

Location and filters:

```json
{
    "query": "verpleegkundige",
    "location": "Utrecht",
    "distanceKm": "25",
    "contractType": ["vast"],
    "educationLevel": ["mbo", "hbo"],
    "workingHours": ["4", "5"],
    "maxResults": 200
}
```

Daily tracking of new and changed vacatures:

```json
{
    "query": "verpleegkundige",
    "location": "Amsterdam",
    "incrementalMode": true,
    "stateKey": "verpleegkundige-amsterdam",
    "maxResults": 0
}
```

All input parameters:

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| query | string | No | — | Job title, skill, or keyword. Empty = all vacatures |
| location | string | No | — | Dutch city or postcode |
| distanceKm | string | No | `"25"` | Radius around the location: 0 (no radius), 5, 10, 25, 50, 75, 100, 125, 150, 300 |
| includeVariableLocations | boolean | No | `false` | Also include jobs with varying work locations |
| referenceNumbers | array | No | `[]` | werk.nl reference numbers or vacature URLs to fetch directly |
| contractType | array | No | `[]` | `vast`, `mogelijk vast`, `tijdelijk` |
| educationLevel | array | No | `[]` | `basisonderwijs`, `vmbo`, `havo/vwo`, `mbo`, `hbo`, `wo`, `niet opgegeven` |
| workingHours | array | No | `[]` | `1`–`6` = 0-8, 9-16, 17-24, 25-32, 33-40, 40+ hours per week |
| workSchedule | array | No | `[]` | `kantoortijden` (office hours) or `anders` (other times) |
| profession | array | No | `[]` | werk.nl profession names, e.g. `Verpleegkundige` |
| driversLicense | array | No | `[]` | License categories, e.g. `b`, `c`, `ce` |
| language | array | No | `[]` | werk.nl language codes, e.g. `1` Nederlands, `3` Engels |
| daysOld | integer | No | `0` | Only vacatures modified in the last N days. 0 = any |
| sortBy | string | No | `datum` | `datum` (newest), `afstand` (nearest), `leerbaan`, `stageplaats` |
| maxResults | integer | No | `100` | Maximum vacatures to save. 0 = no limit |
| includeDetails | boolean | No | `true` | Open each vacature for the full detail fields |
| descriptionMaxLength | integer | No | `0` | Cut descriptions to N characters. 0 = full text |
| compact | boolean | No | `false` | Return core fields only |
| incrementalMode | boolean | No | `false` | Return only vacatures that changed since the previous run |
| stateKey | string | No | auto | Name of the tracked search. Empty = derived from your inputs |
| emitUnchanged | boolean | No | `false` | Also return UNCHANGED vacatures in incremental mode |
| emitExpired | boolean | No | `false` | Also return EXPIRED vacatures in incremental mode |
| skipReposts | boolean | No | `false` | Drop detected reposts in incremental mode |
| proxyConfiguration | object | No | no proxy | Optional proxy. werk.nl works without one |

### Output example

```json
{
    "jobId": "70313877",
    "referenceNumber": 70313877,
    "title": "Nachtdienst Verpleegkundige",
    "profession": "Verpleegkundige",
    "functionName": "Revalidatieverpleegkundige",
    "functionCode": "1000400109",
    "employerFunctionTitle": "Verzorgende individuele gezondheidszorg (ig)",
    "companyName": "Archipel",
    "companyWebsite": "http://www.werkenbijarchipel.nl",
    "location": "EINDHOVEN",
    "postcode": "5654NN",
    "workLocationType": "Vaste werklocatie",
    "workLocationCountry": null,
    "workLocationForeignCity": null,
    "distanceKm": null,
    "address": "Karel de Grotelaan 415, 5654NN EINDHOVEN",
    "contractType": "Tijdelijk",
    "startDate": "2026-10-03T00:00:00",
    "endDate": null,
    "requiredEducation": "MBO",
    "educationLevel": "Mbo-algemeen",
    "educationSector": null,
    "minHours": 30,
    "maxHours": 30,
    "workSchedule": "Wisselende werktijden",
    "salaryIndication": null,
    "salaryText": null,
    "rewardType": "Vast loon / uurloon",
    "termsOfEmployment": null,
    "description": "- Werkvelden & locaties - Opleiden & ontwikkelen - Archipel als werkgever\nNachtdienst Verpleegkundige - Revalidatie - Archipel Eindhoven\n- Dommelhoef Eindhoven - MBO 4 - Uren in overleg - 3.502,45 - 4.245,84\nWij zien de ...",
    "descriptionHtml": "<p>- Werkvelden &amp; locaties - Opleiden &amp; ontwikkelen - Archipel als werkgever<br>Nachtdienst Verpleegkundige - Revalidatie - Archipel Eindhoven<br>- Domm...",
    "additionalDescription": null,
    "otherRequirements": null,
    "requiredLanguages": [],
    "driversLicenses": [],
    "requiredExperience": [],
    "contactName": null,
    "contactDepartment": null,
    "contactPhone": "+31402641111",
    "contactEmail": "werkenbij@archipelzorggroep.nl",
    "applyUrl": "https://www.werkenbijarchipel.nl/vacatures/nachtdienst-verpleegkundige-revalidatie-archipel-eindhoven",
    "applicationMethods": ["E-mail via werk.nl", "Online sollicitatieformulier", "Telefoon"],
    "postedDate": "2026-07-13T00:00:00",
    "modifiedDate": "2026-10-28T00:00:00",
    "expirationDate": "2026-11-27T00:00:00",
    "externalId": "DGR72649198",
    "employerVacancyId": "72649198",
    "sourceChannel": "DGR",
    "postedDirectly": true,
    "isInternship": false,
    "isLearningPosition": false,
    "isEuresPriority": false,
    "recruitersNotWelcome": true,
    "detailsFetched": true,
    "portalUrl": "https://www.werk.nl/nl/vacatures/70313877",
    "source": "werk.nl",
    "contentHash": "57b0baaec0ed1288690e133eb2434b70b4e5169cf864d46fcedbaf163b40aeb9",
    "scrapedAt": "2026-10-28T11:15:11.912Z"
}
```

The descriptions above are shortened for readability. In incremental mode, each record also has `changeType` (`NEW`, `UPDATED`, `UNCHANGED`, `REAPPEARED`, or `EXPIRED`), `firstSeenAt`, `lastSeenAt`, `isRepost`, `repostOfId`, and `repostDetectedAt`.

### Use cases

- 📊 **Labour market research**: count vacatures by profession, region, education level, or contract type across the Netherlands.
- 🧑‍💼 **Recruitment and staffing**: find employers hiring for the roles you place, with contact emails and phone numbers where employers list them.
- 🔔 **Job alerts**: schedule a daily incremental run and send new vacatures to Slack, email, or Google Sheets.
- 🏢 **Competitor monitoring**: track which roles an employer or agency publishes, and when they change or expire.
- 🤖 **AI agents and job matching**: feed compact vacature records into an LLM, RAG pipeline, or matching model.

### How it works

1. The Actor sends your keyword, location, radius, filters, and sort order to the public werk.nl vacature search, 20 results per page.
2. It goes through the result pages until it reaches **Max results**, the end of the results, or (with **Modified within** and newest-first sorting) vacatures older than your cutoff.
3. With **Include full job details** on, it opens each vacature, 8 at a time, and decodes the werk.nl codes (contract, schedule, language levels, apply methods) into readable labels.
4. In incremental mode, it compares each vacature with the saved state for your search. A vacature whose search listing has not changed is skipped without opening its detail page.
5. Each vacature is saved to the dataset and charged as it is collected, so the run stops as soon as your spending limit is reached.

### How much does it cost to scrape werk.nl?

Werk.nl Jobs Scraper uses pay-per-event pricing. You pay per vacature saved to the dataset. Compute and traffic are included in the event price, so they are not billed separately.

| Event | Price per event | Price per 1,000 |
|-------|----------------|-----------------|
| job-scraped (Free plan) | $0.00099 | **$0.99** |
| job-scraped (Bronze plan) | $0.00089 | **$0.89** |
| job-scraped (Silver and Gold plans) | $0.00079 | **$0.79** |

One event is one vacature in the dataset. A small platform **Actor start** fee also applies per run. For example, 1,000 nursing vacatures with full details cost $0.99 on the Free plan. In incremental mode you pay only for the rows that are returned, so a daily run that finds 40 new vacatures costs about $0.04. Apify's free plan includes monthly platform credit you can use for this Actor.

### Python and JavaScript API examples

Python ([apify-client](https://docs.apify.com/api/client/python)):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("parsebird/werk-nl-jobs-scraper").call(run_input={
    "query": "verpleegkundige",
    "location": "Utrecht",
    "distanceKm": "25",
    "contractType": ["vast"],
    "maxResults": 100,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], "|", job["companyName"], "|", job["location"], "|", job["contactEmail"])
```

JavaScript ([apify-client](https://docs.apify.com/api/client/js)):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('parsebird/werk-nl-jobs-scraper').call({
    query: 'verpleegkundige',
    location: 'Utrecht',
    distanceKm: '25',
    contractType: ['vast'],
    maxResults: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((job) => console.log(job.title, job.companyName, job.location));
```

Find all endpoints on the [API tab](https://apify.com/parsebird/werk-nl-jobs-scraper/api).

### FAQ

**Do I need a werk.nl account or the UWV API?**
No. The Actor reads the vacatures werk.nl shows to logged-out visitors. You don't need a werk.nl login or API key.

**How many vacatures can I scrape from werk.nl?**
Werk.nl lists more than 270,000 vacatures. One search returns at most 200,000 results, which werk.nl caps at 10,000 pages. Set **Max results** to `0` to collect everything a search returns, or split very broad searches by location or filter.

**Why are some descriptions cut off at about 2,000 characters?**
For many vacatures that werk.nl imports from other job sites, werk.nl itself stores only the first part of the description. The Actor returns the full text werk.nl has. Use `applyUrl` to open the original posting.

**Is the salary monthly or yearly?**
Werk.nl gives a single salary amount indication without a pay period, so the Actor returns it as `salaryIndication` with `rewardType`. Salary ranges that employers write in the description stay in `description`.

**Why are contact fields empty for some vacatures?**
Not every employer lists a contact person, email, or phone number on werk.nl. Those fields are then `null`.

**How does incremental mode work?**
The first run saves every vacature as `NEW` and builds a baseline. Later runs with the same search (or `stateKey`) return only `NEW`, `UPDATED`, and `REAPPEARED` vacatures. Turn on **Include expired vacatures** to also get vacatures that have left the search. Expiry is checked only when the whole search was scanned, so set **Max results** to `0` or above the search size for reliable expiry detection. A new vacature whose title, employer, location, and description match an expired one is flagged with `isRepost: true` and `repostOfId`.

**Can I filter by city without a radius?**
Yes. Set **Search radius** to `No radius` and sort by **Nearest first**. You then get all vacatures, nearest to your location first, with `distanceKm` filled in.

**Can I schedule the scraper and connect it to other tools?**
Yes. Use [Apify schedules](https://docs.apify.com/platform/schedules) to run it daily or weekly, and connect the results to Google Sheets, Slack, Make, Zapier, n8n, or your own system through [integrations](https://apify.com/integrations), webhooks, or the API.

**Something does not work or a field is missing.**
Open an issue on the **Issues** tab with your input and run ID, and we will look into it.

### Is it legal to scrape werk.nl?

The Actor collects only vacature data that werk.nl publishes openly to all visitors. Some vacatures include the name, email, or phone number of a contact person, which is personal data under the GDPR. Make sure you have a lawful basis for storing and using it, and do not use it for unsolicited bulk messaging. Many employers also mark their vacatures as "acquisitie wordt niet op prijs gesteld" (the `recruitersNotWelcome` field). For more background, read Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/) and consult a lawyer if you are unsure about your use case.

### Other job scrapers from ParseBird

| Actor | What it scrapes |
|-------|-----------------|
| [Jobbird Jobs Scraper](https://apify.com/parsebird/jobbird-jobs-scraper) | Dutch vacatures from Jobbird.com |
| [EURES Jobs Scraper](https://apify.com/parsebird/eures-jobs-scraper) | European job mobility portal vacancies, including the Netherlands |
| [Indeed Jobs Scraper](https://apify.com/parsebird/indeed-jobs-scraper) | Indeed job listings |
| [LinkedIn Jobs Scraper](https://apify.com/parsebird/linkedin-jobs-scraper) | LinkedIn job postings |
| [Xing Jobs Scraper](https://apify.com/parsebird/xing-jobs-scraper) | Xing jobs in Germany, Austria, and Switzerland |
| [Funda.nl Scraper](https://apify.com/parsebird/funda-scraper) | Dutch property listings from Funda.nl |

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/werk-nl-jobs-scraper/changelog.md

# Actor input Schema

## `query` (type: `string`):

Enter a job title, skill, or keyword in Dutch or English (for example verpleegkundige, chauffeur, or developer). Leave empty to browse all vacatures on werk.nl.

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

Enter a Dutch city or postcode (for example Amsterdam or 1012WZ). Combined with the search radius below.

## `distanceKm` (type: `string`):

Distance around the location to include. Only used when a location is set. 'No radius' returns all vacatures, ordered by distance when you sort by nearest.

## `includeVariableLocations` (type: `boolean`):

Also include vacatures whose work location changes (werk.nl 'wisselende werklocatie') when searching around a location.

## `referenceNumbers` (type: `array`):

Fetch specific vacatures directly by werk.nl reference number (for example 71735353) or vacature URL (https://www.werk.nl/nl/vacatures/71735353). When set, the search fields above are ignored.

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

Keep only vacatures with these contract types. Leave empty for all.

## `educationLevel` (type: `array`):

Keep only vacatures that ask for these education levels.

## `workingHours` (type: `array`):

Keep only vacatures in these weekly-hours ranges.

## `workSchedule` (type: `array`):

Keep only office-hours jobs or jobs with other (shift, evening, weekend) working times.

## `profession` (type: `array`):

Keep only vacatures in these werk.nl professions, written exactly as werk.nl shows them in the 'Beroep' filter (for example Verpleegkundige or Vrachtwagenchauffeur).

## `driversLicense` (type: `array`):

Keep only vacatures that ask for these driver's license categories.

## `language` (type: `array`):

Keep only vacatures that list these languages as a requirement.

## `daysOld` (type: `integer`):

Only return vacatures modified within the last N days. 0 returns all.

## `sortBy` (type: `string`):

Order of the search results. Nearest first needs a location.

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

Maximum number of vacatures to save. 0 = no limit (werk.nl serves up to 200,000 results per search). Start small to check your search.

## `includeDetails` (type: `boolean`):

Open each vacature to add the description, salary indication, contact person, email, phone, apply URL, employer address, and requirements. Turn off for faster search-results-only output.

## `descriptionMaxLength` (type: `integer`):

Cut descriptions to this many characters. 0 = keep the full text.

## `compact` (type: `boolean`):

Return only the core fields. Useful for AI agents, MCP tools, and token-limited workflows.

## `incrementalMode` (type: `boolean`):

Compare each run with the previous run of the same search and return only NEW, UPDATED, and REAPPEARED vacatures. Use it on a schedule.

## `stateKey` (type: `string`):

Optional name for the tracked search. Leave empty to derive one automatically from your search inputs, so different searches never share state.

## `emitUnchanged` (type: `boolean`):

Also return vacatures that did not change since the previous run (as changeType UNCHANGED).

## `emitExpired` (type: `boolean`):

Also return vacatures that disappeared from the search since the previous run (as changeType EXPIRED). Only checked when the whole search was scanned.

## `skipReposts` (type: `boolean`):

Drop new vacatures that match the content of a previously expired vacature (same title, employer, location, and description).

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

werk.nl works without a proxy. Set one only if your account needs a specific outgoing IP.

## Actor input object example

```json
{
  "query": "verpleegkundige",
  "distanceKm": "25",
  "includeVariableLocations": false,
  "referenceNumbers": [],
  "contractType": [],
  "educationLevel": [],
  "workingHours": [],
  "workSchedule": [],
  "profession": [],
  "driversLicense": [],
  "language": [],
  "daysOld": 0,
  "sortBy": "datum",
  "maxResults": 50,
  "includeDetails": true,
  "descriptionMaxLength": 0,
  "compact": false,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "skipReposts": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# 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 = {
    "query": "verpleegkundige",
    "location": "",
    "referenceNumbers": [],
    "profession": [],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/werk-nl-jobs-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 = {
    "query": "verpleegkundige",
    "location": "",
    "referenceNumbers": [],
    "profession": [],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/werk-nl-jobs-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "query": "verpleegkundige",
  "location": "",
  "referenceNumbers": [],
  "profession": [],
  "maxResults": 50
}' |
apify call parsebird/werk-nl-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/werk-nl-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/atR3hjMmwqphldSCm/builds/yYifF4XImKE3AqimN/openapi.json
