# Netherlands Jobs Scraper (`carabain-digital/netherlands-jobs`) Actor

Search Nationale Vacaturebank, Intermediair and Jobbird at once for vacatures in the Netherlands. One keyword, one dataset: merged, deduplicated across boards, newest first. Optional full descriptions. Residential proxy included. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/carabain-digital/netherlands-jobs.md
- **Developed by:** [Carabain Digital](https://apify.com/carabain-digital) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.56 / 1,000 job postings

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

### What is Netherlands Jobs Scraper?

**Netherlands Jobs Scraper** searches **three job boards in the Netherlands with one query** (Nationale Vacaturebank, Intermediair and Jobbird) and returns one clean dataset of vacatures: **merged, deduplicated across sites and sorted newest first**. Export as JSON, CSV or Excel. Costs **$0.80 per 1,000 jobs**; full descriptions are an optional add-on at $1 per 1,000. A residential proxy is built in.

- 🌍 **3 sites, one run**: Nationale Vacaturebank, Intermediair and Jobbird are searched in parallel (a few seconds for 60 jobs)
- 🧹 **Cross-site dedup**: the same job on several boards (same title, company and city) appears once, with an `also_on` list of the other sites
- 📅 **Newest first** across all sites, with a total **Max jobs** cap and an optional cap per site
- 🎯 **Pick the sites** you want under **Sites**
- 🛡️ **A blocked or failing site never fails the run**: it is retried on a fresh proxy session, then skipped and logged; the others still deliver
- 📄 **Optional full details**: description and extra fields, charged only for jobs actually enriched
- 🤖 **Agent friendly**: small flat items, one schema for all sites, works through the Apify MCP server

#### Which sites are included?

| Site | Country | Single-site Actor | Default | Notes |
|---|---|---|---|---|
| [Nationale Vacaturebank](https://www.nationalevacaturebank.nl) | Netherlands | [nationale-vacaturebank-jobs](https://apify.com/carabain-digital/nationale-vacaturebank-jobs) | yes | Up to 10,000 per search; Dutch residential proxy; full description included |
| [Intermediair](https://www.intermediair.nl) | Netherlands | [intermediair-jobs](https://apify.com/carabain-digital/intermediair-jobs) | yes | Same DPG Media platform as Nationale Vacaturebank, so many jobs overlap (and are deduplicated); full description included |
| [Jobbird](https://www.jobbird.com/nl) | Netherlands | [jobbird-jobs](https://apify.com/carabain-digital/jobbird-jobs) | yes | Aggregator of recruiter and employer ads; no proxy needed |

**Results per site are capped by each site, not by this Actor** (10,000 per search on Nationale Vacaturebank and Intermediair, Jobbird up to 10,000). Asking for more returns what the site offers.

#### What data can I extract?

<table>
<tr><td>🆔 Stable job ID, source site and URL</td><td>📝 Job title</td></tr>
<tr><td>🏢 Company (and company page)</td><td>📍 Location, city, postcode, region, country</td></tr>
<tr><td>📅 Posting date and valid-through date</td><td>🏠 Remote: onsite / hybrid / remote</td></tr>
<tr><td>💶 Salary range (when stated)</td><td>⏱️ Hours per week and employment type</td></tr>
<tr><td>🎓 Education level</td><td>🔁 <code>also_on</code>: other sites with the same job</td></tr>
<tr><td>📄 Full description (included or via the add-on, see below)</td><td>🔗 Apply link (where the site has one)</td></tr>
</table>

Every site fills what it has; coordinates, postcodes, hours and education come from some boards only. Missing fields are `null`.

#### How do I scrape Dutch jobs?

1. [Create a free Apify account](https://console.apify.com/sign-up) and open this Actor.
2. Enter a **keyword** (for example `verpleegkundige`) and optionally a **location** and radius. Leave **Sites** on the default or pick some.
3. Set **Max jobs** and optionally **Posted in the last (days)**.
4. Switch on **Full details** if you need descriptions from every board that has one.
5. Click **Start** and download the jobs from the **Output** tab as JSON, CSV, Excel, XML or HTML.

### How much does it cost to scrape Dutch job boards?

You **pay per job** that ends up in your dataset: **$0.80 per 1,000 unique jobs**, after duplicates are removed. No subscription, the proxy is included.

- **Add-on: Full details, $1 per 1,000** jobs, **off by default**. Charged only for jobs whose detail page was actually fetched. Nationale Vacaturebank and Intermediair jobs already include the full description and are never charged for it; the add-on enriches Jobbird.
- The monthly credit of Apify's free plan covers thousands of jobs.
- You are charged for the jobs in the dataset, not for the (more numerous) jobs fetched before deduplication and the **Max jobs** cut. Set a maximum cost per run in the run options.

### Input

See the **Input** tab for all options. The shared fields are the same as in our single-site job Actors.

| Field | Description |
|---|---|
| **Keyword** (`keyword`) | Job title or skill, sent to every site, e.g. `verpleegkundige` |
| **Location** (`location`) | City or postcode, sent to every selected site, e.g. `Utrecht` |
| **Radius (km)** (`radius_km`) | Distance around the location; needs a location |
| **Posted in the last (days)** (`posted_since_days`) | Only jobs posted in the last N days |
| **Sites** (`sites`) | `nationalevacaturebank`, `intermediair`, `jobbird` (default: `nationalevacaturebank`, `intermediair`, `jobbird`) |
| **Max jobs** (`limit`) | Cap on the merged dataset; every site gets a fair share |
| **Max jobs per site** (`limit_per_site`) | Optional cap per site (default: Max jobs) |
| **Full details** (`includeDetails`) | Paid add-on: detail page data |
| **Proxy** (`proxyConfiguration`) | Apify RESIDENTIAL, country NL by default; the Actor applies it only to the sites that need it |

Example input:

```json
{
    "keyword": "verpleegkundige",
    "location": "Utrecht",
    "posted_since_days": 7,
    "limit": 100
}
```

#### Location and keyword

Languages differ per country, and the Actor sends your keyword and location to **every selected site as is**. Use terms that people use in the Netherlands's job ads (`verpleegkundige`, `developer`, `monteur`); English words such as `developer` or `engineer` also work on most boards.

- `posted_since_days`, `limit` and the keyword are applied the same way on every site.
- If **every** selected site rejects the input, the run fails so you notice.

### Output

Jobs are stored in the default dataset, one item per unique job. Export them as JSON, CSV, Excel, XML or HTML. Every site uses the same field names (`id` is `<source>:<site id>`). Example (shortened):

```json
{
    "id": "nationalevacaturebank:9f272689-f023-40db-913e-1692845f0bd2",
    "source": "nationalevacaturebank",
    "url": "https://www.nationalevacaturebank.nl/vacature/9f272689-f023-40db-913e-1692845f0bd2/verpleegkundige",
    "title": "Verpleegkundige",
    "company": "Zorgorganisatie Voorbeeld",
    "location": "Utrecht",
    "city": "Utrecht",
    "postcode": "3511AB",
    "country": "NL",
    "posted_at": "2026-10-30T23:00:00Z",
    "employment_type": ["Vast"],
    "hours_per_week_min": 32,
    "hours_per_week_max": 36,
    "education_level": "HBO",
    "description": "Over de functie…",
    "scraped_at": "2026-10-31T09:00:01Z",
    "also_on": [
        "intermediair"
    ]
}
```

(shortened; values are illustrative). Some sites add extra fields. `employment_type` is always a list of the site's own labels.

#### How duplicates are removed

Two jobs are the same when title, company and city match (ignoring case and accents) on different sites. The first one is kept (order: Nationale Vacaturebank, Intermediair, Jobbird) and the other sites go in `also_on`. Two jobs of the same site are never merged. Nationale Vacaturebank and Intermediair share a platform, so they overlap a lot.

#### Sorting

With **Max jobs**, every site gets a fair share: jobs are taken in turns from each site (each in its own newest-first order), so sites without exact dates are not pushed out. The result is then sorted newest first by `posted_at`; items without a date keep their site order.

### What can I do with Dutch job data?

- 📈 **Labour market research**: compare demand for a role across cities and boards
- 🧲 **Recruitment and lead generation**: find companies hiring, and how many roles they have open
- 🔔 **Job alerts**: schedule a daily run with "posted in the last 1 day" and push new jobs to Slack or e-mail
- 🤖 **AI and analysis**: feed real vacancy text into your own models

### Tips for best results

- Nationale Vacaturebank and Intermediair share a platform and overlap a lot; the duplicates are removed for you, so the dataset can be smaller than the sum of the sites.
- **Max jobs** keeps the newest jobs over all sites. Use **Max jobs per site** to keep the mix balanced.
- Descriptions are included for Nationale Vacaturebank and Intermediair; switch on **Full details** for Jobbird.
- For monitoring, schedule a daily run with **Posted in the last (days)** set to `1`.

### Frequently asked questions

#### Can I use Netherlands Jobs Scraper with the Apify API?

Yes. Use the [Apify API](https://docs.apify.com/api/v2) or the Apify clients. Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("carabain-digital/netherlands-jobs").call(run_input={"keyword": "verpleegkundige", "location": "Utrecht", "posted_since_days": 7, "limit": 100})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["source"], item["title"])
```

#### Can I use Netherlands Jobs Scraper through an MCP server or with AI agents?

Yes. Add the [Apify MCP server](https://mcp.apify.com) to your AI agent (Claude, ChatGPT, Cursor and others) and let it call `carabain-digital/netherlands-jobs` with `call-actor`. The input is small and every field has a description, so an agent can fill it from a request such as "find 20 new verpleegkundige jobs in Utrecht" (`keyword`, `location`, `limit`). A small run finishes in seconds; the agent then reads the dataset with `get-dataset-items`. Add-ons are off by default, so an agent pays only the base price unless it asks for more.

#### Can I integrate the data with other apps?

Yes: Make, Zapier, Google Sheets, Slack, Airbyte and webhooks, via Apify's [integrations](https://apify.com/integrations).

#### Why are there fewer jobs than Max jobs?

Each site returns what matches your search, duplicates across sites are removed, and sites that do not know a filter are skipped. A narrow search or a site's own ceiling can leave you with fewer.

#### Why does one site return nothing?

Either it has no match for your search, or it was blocked and skipped after retries. The run log lists skipped sites. If **all** selected sites fail, the run fails so you notice. Try again later or open an issue.

#### Is it legal to scrape job boards?

The Actor only collects publicly visible job ad data. Job ads can contain personal data such as a contact name, and rules such as GDPR may apply to how you store and use it. Check your use case with a lawyer. See also [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

#### Netherlands Jobs Scraper not working? / Feedback

Open an issue in the **Issues** tab of this Actor with the run link and the input you used; I usually answer within a few days.

### Other scrapers by us

The three single-site Actors behind this one are linked in the table above: [nationale-vacaturebank-jobs](https://apify.com/carabain-digital/nationale-vacaturebank-jobs), [intermediair-jobs](https://apify.com/carabain-digital/intermediair-jobs), [jobbird-jobs](https://apify.com/carabain-digital/jobbird-jobs). They are cheaper per job when you need one site only, and have site-specific filters.

# Actor input Schema

## `keyword` (type: `string`):

Job title or skill, searched on all selected sites. Dutch terms work best. Example: `verpleegkundige` or `developer`. Leave empty to list all jobs.

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

Dutch city, town or postcode, passed to all selected sites. Example: `Utrecht` or `3511`. Leave empty to search all of the Netherlands.

## `radius_km` (type: `integer`):

Search radius around the location, in km. Example: `25`. Needs a location.

## `posted_since_days` (type: `integer`):

Only jobs posted in the last N days. Example: `7`. Leave empty for all.

## `limit` (type: `integer`):

Maximum number of jobs in the dataset, newest first, after merging and removing duplicates. Example: `200`. Each site is also capped by itself: 10,000 per search.

## `limit_per_site` (type: `integer`):

Optional. Fetch at most this many jobs from each site, so one big site cannot crowd out the rest. Example: `30`. Default: the value of Max jobs.

## `sites` (type: `array`):

Which sites to search. Default: all of them. Example: `["nationalevacaturebank", "intermediair", "jobbird"]`.

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

Open each job's detail page on Jobbird to add the full description, apply link and more. Nationale Vacaturebank and Intermediair already include the description: no charge for those. Adds $1 per 1,000 enriched jobs. Slower.

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

Residential proxy, on by default: Nationale Vacaturebank and Intermediair need one. The Actor sets the exit country to the Netherlands for them; Jobbird runs without proxy.

## Actor input object example

```json
{
  "keyword": "verpleegkundige",
  "location": "Utrecht",
  "limit": 20,
  "sites": [
    "nationalevacaturebank",
    "intermediair",
    "jobbird"
  ],
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NL"
  }
}
```

# Actor output Schema

## `jobs` (type: `string`):

All jobs from the selected sites, merged and deduplicated, newest first.

# 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 = {
    "keyword": "verpleegkundige",
    "location": "Utrecht",
    "limit": 20,
    "sites": [
        "nationalevacaturebank",
        "intermediair",
        "jobbird"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "NL"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("carabain-digital/netherlands-jobs").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 = {
    "keyword": "verpleegkundige",
    "location": "Utrecht",
    "limit": 20,
    "sites": [
        "nationalevacaturebank",
        "intermediair",
        "jobbird",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "NL",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("carabain-digital/netherlands-jobs").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 '{
  "keyword": "verpleegkundige",
  "location": "Utrecht",
  "limit": 20,
  "sites": [
    "nationalevacaturebank",
    "intermediair",
    "jobbird"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NL"
  }
}' |
apify call carabain-digital/netherlands-jobs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,carabain-digital/netherlands-jobs"
        }
    }
}
```

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/vlth2mRJpouSB6mX5/builds/15P99bbA0AVgywdrp/openapi.json
