# Jobbird Jobs Scraper (`parsebird/jobbird-jobs-scraper`) Actor

Scrape job listings from Jobbird.com (Netherlands) by keyword, location, category, and contract type. Get titles, employers, salaries, hours, descriptions, and incremental change monitoring. Export as JSON, CSV, or Excel.

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

## Pricing

from $0.79 / 1,000 job 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?

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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

### Jobbird Jobs Scraper

Scrape job listings from **[Jobbird.com](https://www.jobbird.com)** — one of the largest job boards in the Netherlands — into clean, structured JSON. The Jobbird Jobs Scraper pulls the job title, employer, location, salary, weekly hours, contract type, category, education level, and the full description for any keyword and city search, with no login and no Jobbird API.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Search Jobbird by keyword, city, category, contract type, weekly hours, and education level — or paste a Jobbird search URL — and get a structured record per vacancy with salary, hours, description (HTML, text, and markdown), and incremental change monitoring 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.

```
Actor: parsebird/jobbird-jobs-scraper (Apify). Scrapes vacancies from jobbird.com (Netherlands). Call with ApifyClient.
Input JSON fields:
  query: string — job keyword, e.g. "software engineer", "verpleegkundige"
  location: string — Dutch city or region, e.g. "Amsterdam", "Rotterdam"
  radius: int — km around the location (default 30)
  category: string[] — Jobbird category slugs, e.g. ["ict"], ["zorg-medisch"], ["logistiek"]
  contractType: string[] — ["fulltime"|"parttime"|"tijdelijk-werk"|"stage"|"freelance-zzp"|"bijbaan"|...]
  recruitmentType: string[] — ["intern"|"uitzendwerk"|"detachering"|"werving-selectie"]
  workHours: string[] — ["0-8"|"9-16"|"17-24"|"25-32"|"33-36"|"37-*"]
  educationLevel: string[] — ["mbo"|"hbo"|"wo"|"phd"|...]
  sortBy: "date"|"relevance" (default "date")
  postedWithinDays: "0"|"1"|"7"|"30" (default "0" = any)
  includeDetails: bool (default true) — fetch each vacancy's full detail record
  descriptionFormat: "all"|"text"|"html"|"markdown" (default "all")
  descriptionMaxLength: int — truncate description, 0 = no truncation
  compact: bool (default false) — core fields only
  excludeEmptyFields: bool (default false) — drop null/empty fields
  maxResults: int (default 25, 0 = unlimited) — number of billed rows
  startUrls: string[] — jobbird.com search or single-vacancy URLs; overrides query/filters
  incrementalMode: bool + stateKey: string — return only changed vacancies since last run
  proxyConfiguration: { "useApifyProxy": true }
Output: one dataset item per vacancy — jobId, title, company, companyId, location, salaryMin, salaryMax,
  salaryType, employmentType, hoursMin, hoursMax, hoursType, category, educationLevel, skills, benefits,
  description (+ descriptionText, descriptionMarkdown), isPremium, url, postedDate, scrapedAt, source.
  Incremental adds changeType, firstSeenAt, lastSeenAt, isRepost.
Example: { "query": "software engineer", "location": "Amsterdam", "maxResults": 50 }
API: https://api.apify.com/v2/acts/parsebird~jobbird-jobs-scraper  ·  Token: https://console.apify.com/account/integrations
```

### What does Jobbird Jobs Scraper do?

[Jobbird.com](https://www.jobbird.com) aggregates tens of thousands of live vacancies from Dutch employers, temp agencies, and recruiters across every province. There is no public Jobbird API — this Jobbird scraper reads the site's own search and vacancy data instead. It extracts:

- 💼 **Job** — title, contract type, weekly hours, category, and the direct vacancy URL.
- 🏢 **Employer** — company name, company ID, and advertiser type (direct employer, temp agency, secondment, recruiter).
- 📍 **Location** — city or region, with the Jobbird location page URL.
- 💶 **Salary** — minimum and maximum, when the employer discloses it.
- 🎓 **Requirements** — education level, required languages, and skills.
- 🎁 **Benefits** — the perks the employer lists.
- 📅 **Dates** — when the vacancy was posted or last refreshed.
- 📄 **Description** — the full job description as HTML, clean text, and markdown.

Common uses: Netherlands recruitment-market research, building a jobs board or alert service, salary and working-hours analysis, and monitoring hiring in a city or sector.

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| query | string | Yes\* | — | Job title, role, or skill. \*Not required when `startUrls`, `location`, or `category` is set. |
| location | string | No | — | Dutch city or region (`Amsterdam`, `Rotterdam`, `Utrecht`). |
| radius | integer | No | 30 | Search radius in km around the location. |
| category | array | No | — | Jobbird category slugs (`ict`, `zorg-medisch`, `logistiek`, …). |
| contractType | array | No | — | `fulltime`, `parttime`, `tijdelijk-werk`, `stage`, `freelance-zzp`, `bijbaan`, … |
| recruitmentType | array | No | — | `intern` (direct), `uitzendwerk`, `detachering`, `werving-selectie`. |
| workHours | array | No | — | Weekly-hours bands (`33-36`, `37-*`, …). |
| educationLevel | array | No | — | `mbo`, `hbo`, `wo`, `phd`, … |
| sortBy | string | No | date | `date` or `relevance`. |
| postedWithinDays | string | No | 0 | Limit to the last `1`, `7`, or `30` days. |
| includeDetails | boolean | No | true | Fetch each vacancy's full detail record. |
| descriptionFormat | string | No | all | `all`, `text`, `html`, or `markdown`. |
| descriptionMaxLength | integer | No | 0 | Truncate the description to N characters. |
| compact | boolean | No | false | Return core fields only. |
| excludeEmptyFields | boolean | No | false | Drop null and empty fields from each record. |
| maxResults | integer | No | 25 | Maximum vacancies to return (0 = unlimited; billed rows). |
| startUrls | array | No | — | Jobbird search or single-vacancy URLs. Overrides `query` and filters. |
| incrementalMode | boolean | No | false | Return only vacancies that changed since the last run with the same `stateKey`. |
| stateKey | string | No | default | Separates one watchlist or schedule from another. |
| proxyConfiguration | object | No | Apify Proxy | Proxy settings. The automatic default works well for Jobbird. |

#### Example inputs

Basic keyword search:

```json
{ "query": "software engineer", "maxResults": 50 }
```

Filtered search — ICT, fulltime, within 25 km of Amsterdam:

```json
{
  "query": "developer",
  "location": "Amsterdam",
  "radius": 25,
  "category": ["ict"],
  "contractType": ["fulltime"],
  "maxResults": 50
}
```

Incremental tracking — only emit vacancies that changed since the previous run:

```json
{
  "query": "software engineer",
  "maxResults": 200,
  "incrementalMode": true,
  "stateKey": "software-engineer-tracker"
}
```

Compact output for an AI agent or MCP data source:

```json
{ "query": "software engineer", "maxResults": 50, "compact": true }
```

### What data can you extract from Jobbird?

| Field | Description |
|-------|-------------|
| jobId | Stable content-based identifier |
| title | Job title |
| company / companyId | Employer name and Jobbird company ID |
| location / locationUrl | City or region and its Jobbird page |
| salaryMin / salaryMax / salaryType | Advertised salary range (in cents) and period |
| employmentType | Contract type (fulltime, parttime, …) |
| hoursMin / hoursMax / hoursType | Weekly working hours |
| category / categorySlug | Jobbird job category |
| educationLevel / education | Required education level |
| skills / benefits / languages | Listed skills, perks, and required languages |
| recruitmentType | Direct employer, temp agency, secondment, or recruiter |
| isPremium | Whether the listing is sponsored |
| description / descriptionText / descriptionMarkdown | Full job description in three formats |
| url / applicationUrl | Vacancy page and apply link |
| postedDate | Publication or last-refresh date |
| changeType / firstSeenAt / lastSeenAt / isRepost | Monitoring fields (with `incrementalMode`) |
| source / scrapedAt / query | Run context |

### Output example

```json
{
  "jobId": "7b1da25ee66b1db9983bc5acc6ef53803e8d5dd3d9a1bf602e53801d4c710bc7",
  "title": "Business Analist",
  "company": "EIFFEL",
  "companyId": 50185,
  "location": "Hilversum",
  "locationUrl": "https://www.jobbird.com/nl/vacatures/hilversum",
  "salaryMin": null,
  "salaryMax": null,
  "salaryType": null,
  "employmentType": "fulltime",
  "hoursMin": 32,
  "hoursMax": 40,
  "hoursType": "FULLTIME",
  "category": "ICT",
  "categorySlug": "ict",
  "educationLevel": "preferred",
  "education": "HBO",
  "skills": [],
  "benefits": ["Laptop van de zaak", "Flexibele werktijden"],
  "isPremium": true,
  "url": "https://www.jobbird.com/nl/vacature/25735611-business-analist",
  "postedDate": "2026-09-01T09:27:13+02:00",
  "scrapedAt": "2026-09-04T08:28:58.775Z",
  "source": "jobbird.com",
  "description": "<p><strong>Over de functie</strong></p><p>Als Business Analist ...</p>",
  "descriptionText": "Over de functie\nAls Business Analist ...",
  "descriptionMarkdown": "**Over de functie**\n\nAls Business Analist ..."
}
```

Download the dataset as **JSON, CSV, Excel, HTML, or XML** from the Storage tab or the [Apify API](https://docs.apify.com/api/v2).

### Use cases

- **Netherlands jobs board** — feed an aggregator or alert service with live Jobbird vacancies.
- **Recruitment-market research** — measure hiring volume by role, city, category, and contract type.
- **Salary and hours analysis** — collect advertised salary ranges and weekly-hours bands across a sector.
- **Employer monitoring** — start from a company- or city-filtered URL and track everything it posts.
- **AI and MCP data source** — pipe compact, structured job data into agents and downstream tools.

### How it works

1. **Search** — the scraper queries Jobbird's own search endpoint (15 vacancies per page) with your `query`, `location`, and filters.
2. **Paginate** — it pages through results up to `maxResults` or the end of the listing.
3. **Detail** — when `includeDetails` is on, each vacancy's full detail record is fetched for the complete description, salary, hours, education, skills, and benefits.
4. **Monitor** — in incremental mode, the run is compared against the stored state for your `stateKey` and only new, updated, reappeared, or expired vacancies are returned.
5. Rows stream to the dataset and stop at `maxResults`.

### How much does it cost to scrape Jobbird?

This actor is **pay per result** — charged once per vacancy saved to the dataset.

| Plan | Price per 1,000 vacancies |
|------|---------------------------|
| Free | **$0.99** |
| Bronze | **$0.89** |
| Silver | **$0.89** |
| Gold | **$0.79** |

A small platform **Actor start** fee also applies per run. `maxResults` is the exact number of billed rows. Scraping 1,000 vacancies on the Free plan costs about **$0.99**. Apify's monthly free platform usage covers small runs.

### How to scrape Jobbird

1. Click **Try for free** and sign in to Apify.
2. Enter a **search keyword** and, optionally, a **location**.
3. Add filters — category, contract type, weekly hours, or education level.
4. Set **max results** (start low, e.g. 25).
5. Leave **Fetch full job details** on for complete records, or turn it off for a fast listing-only run.
6. Click **Start**, then watch rows appear in the **Output** tab.
7. Export from **Storage**, or pull results via the API.

#### Run it via API

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("parsebird/jobbird-jobs-scraper").call(run_input={
    "query": "software engineer",
    "location": "Amsterdam",
    "maxResults": 50,
})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(job["title"], "-", job["company"], "-", job.get("location"))
```

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('parsebird/jobbird-jobs-scraper').call({
    query: 'developer',
    category: ['ict'],
    contractType: ['fulltime'],
    maxResults: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Schedule recurring runs, add webhooks, or push results to Google Sheets, Slack, Zapier, and Make with [Apify integrations](https://docs.apify.com/platform/integrations).

### FAQ

**Do I need a Jobbird account or API key?**
No. The scraper reads public Jobbird data only. Jobbird has no public API — this actor is the alternative.

**How current is the data?**
Live. Each run reads Jobbird at that moment. Use Apify's scheduler to keep a dataset fresh, and `incrementalMode` to receive only what changed.

**What does turning off `includeDetails` change?**
The scraper skips the per-vacancy detail fetch. You still get every listing field, but education, skills, benefits, and the fullest description come from the detail record — much faster for large listing-only runs.

**Why are `skills` and `benefits` often empty?**
Most Jobbird employers do not fill in structured skills or benefits; the scraper returns them when present and an empty list otherwise.

**How does incremental monitoring work?**
The first run with a given `stateKey` records a baseline. Later runs return only vacancies that are new, updated, or reappeared. Add `emitUnchanged` or `emitExpired` to widen the output, and `skipReposts` to drop re-advertised vacancies.

**Something's not working.**
Open an issue on the **Issues** tab with your input and the run link — we respond quickly.

### Is it legal to scrape Jobbird?

Jobbird vacancy pages are public information that any visitor can see without logging in. Scraping publicly available pages is legal in most jurisdictions, and this actor does not access private data or bypass any login. You are responsible for how you use the data — follow Jobbird's terms and the GDPR when handling any personal data, and consult a lawyer if you are unsure. See Apify's guide on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Related actors

- [Jobs.ie Scraper](https://apify.com/parsebird/jobs-ie-scraper) — job listings from Ireland's Jobs.ie.
- [NHS UK Jobs Scraper](https://apify.com/parsebird/nhs-uk-jobs-scraper) — vacancies from the official NHS Jobs board.
- [Indeed Jobs Scraper](https://apify.com/parsebird/indeed-jobs-scraper) — job listings from Indeed worldwide.
- [hh.ru Jobs Scraper](https://apify.com/parsebird/hh-ru-jobs-scraper) — vacancies from HeadHunter (Russia).

Browse all [ParseBird actors](https://apify.com/parsebird) on Apify Store.

# Actor input Schema

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

Public Jobbird search URLs (`https://www.jobbird.com/nl/vacature?s=...`) or single-vacancy URLs (`https://www.jobbird.com/nl/vacature/12345678-...`). When set, these take precedence over the keyword and filters below.

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

Job title, role, or skill to search for on Jobbird, for example `software engineer`, `verpleegkundige`, or `magazijnmedewerker`.

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

City or region in the Netherlands, for example `Amsterdam`, `Rotterdam`, or `Utrecht`.

## `radius` (type: `integer`):

Search radius around the location in kilometres. Only applies when a location is set.

## `category` (type: `array`):

Filter by one or more Jobbird category slugs.

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

Filter by contract type.

## `recruitmentType` (type: `array`):

Filter by who posted the vacancy.

## `workHours` (type: `array`):

Filter by weekly working-hours band.

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

Filter by required education level.

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

Order results are returned in.

## `postedWithinDays` (type: `string`):

Only return vacancies posted within this window.

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

Fetch each vacancy's full detail record (description, skills, benefits, salary, hours, education). Turn off for a faster listing-only run.

## `descriptionFormat` (type: `string`):

`all` keeps HTML, text, and markdown variants. `text` / `html` / `markdown` keep only that one.

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

Truncate the description to N characters. 0 = no truncation.

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

Return only core fields (title, company, location, salary, category, URL, dates) — ideal for AI-agent and MCP workflows.

## `excludeEmptyFields` (type: `boolean`):

Drop null, empty-string, and empty-array fields from each record before it is saved. Smaller payloads for AI agents and dashboards.

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

Maximum number of vacancies to return (0 = unlimited). This is the number of billed rows. Start small and raise it after checking the search.

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

Compare this run against previous runs with the same state key and return only vacancies that are new, updated, or reappeared. The first run records a baseline.

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

A stable name that separates one watchlist or schedule from another.

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

Also return vacancies whose tracked content did not change since the last run.

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

Also return a record for vacancies that were present before but have now disappeared from the search.

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

Drop new listings that match the tracked content of a previously expired vacancy.

## `notificationWebhookUrl` (type: `string`):

Optional HTTPS endpoint that receives a compact JSON summary after a monitoring run.

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

Apify Proxy routing. The default (automatic) works well for Jobbird.

## Actor input object example

```json
{
  "startUrls": [],
  "query": "software engineer",
  "radius": 30,
  "category": [],
  "contractType": [],
  "recruitmentType": [],
  "workHours": [],
  "educationLevel": [],
  "sortBy": "date",
  "postedWithinDays": "0",
  "includeDetails": true,
  "descriptionFormat": "all",
  "descriptionMaxLength": 0,
  "compact": false,
  "excludeEmptyFields": false,
  "maxResults": 25,
  "incrementalMode": false,
  "stateKey": "default",
  "emitUnchanged": false,
  "emitExpired": false,
  "skipReposts": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "startUrls": [],
    "query": "software engineer",
    "location": "",
    "radius": 30,
    "descriptionMaxLength": 0,
    "maxResults": 25,
    "stateKey": "default",
    "notificationWebhookUrl": "",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/jobbird-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 = {
    "startUrls": [],
    "query": "software engineer",
    "location": "",
    "radius": 30,
    "descriptionMaxLength": 0,
    "maxResults": 25,
    "stateKey": "default",
    "notificationWebhookUrl": "",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/jobbird-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 '{
  "startUrls": [],
  "query": "software engineer",
  "location": "",
  "radius": 30,
  "descriptionMaxLength": 0,
  "maxResults": 25,
  "stateKey": "default",
  "notificationWebhookUrl": "",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call parsebird/jobbird-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/jobbird-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/L0F84iuEDZH6IdKjd/builds/LMDpNtoSnIFetKnuS/openapi.json
