# Dutch BIG Register Scraper — Verify Healthcare Pros (`halobartku/nl-big-register-scraper`) Actor

Verify Dutch healthcare professionals in the official BIG register (Wet BIG) via its published SOAP webservice. Registration numbers, 32 professional groups, specialisms, disciplinary measures, scope limitations. KYC and credential checks, contractor screening. $0.004/row; failed or empty runs free.

- **URL**: https://apify.com/halobartku/nl-big-register-scraper.md
- **Developed by:** [B](https://apify.com/halobartku) (community)
- **Categories:** Business, Lead generation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 practitioner harvesteds

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/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

## Dutch BIG Register Scraper — Healthcare Professionals

Search the **official Dutch BIG register** (Beroepen Individuele Gezondheidszorg,
Wet BIG) through the register's own published SOAP webservice — the same
interface the register documents for "zoeken vanuit uw eigen systeem"
(Handleiding webservice BIG-register v2.6). No screen scraping, no
headless browser: one official API call per query.

**You are never charged for a failed or empty run.** The single pay-per-event
`practitioner-harvested` fires only after rows are written; zero-result and
bad-input runs are free.

### What you get

One row per practitioner, deduplicated across queries:

| field | content |
|---|---|
| `mailing_name`, `birth_surname`, `prefix`, `initial`, `gender` | identity as the register prints it |
| `registration_numbers` | all BIG numbers (one per article) |
| `article_registrations` | Wet BIG article + professional group, start/end dates, group labels in **NL and EN** |
| `specialisms` | registered specialisms with NL/EN labels |
| `mentions` | vermeldingen (e.g. foreign-diploma mentions), date-ranged |
| `judgment_provisions` | **disciplinary measures (tuchtrecht)**: judgment + provision kind + dates — empty for the vast majority |
| `limitations` | bevoegdheidsbeperkingen (scope limitations), date-ranged |

All 32 professional groups are supported: 01 Artsen (physicians),
02 Tandartsen (dentists), 03 Verloskundigen, 04 Fysiotherapeuten,
16 Psychotherapeuten, 17 Apothekers, 25 Gz-psychologen, 30 Verpleegkundigen,
81 Physician assistants, 92 Mondhygienisten, and more.

### Example output record

Here is one real result (from the `jansen` + group `02` query, exactly as
delivered — dataset `BbCccnDKTOyKOHxy2`, run `zBpNye8ERmcaRFhGt`), with every
field the actor returns:

```json
{
  "birth_surname": "Jansen",
  "mailing_name": "J. Jansen",
  "prefix": null,
  "initial": "J.",
  "gender": "M",
  "article_registrations": [
    {
      "article_registration_number": "29919000102",
      "professional_group_code": "02",
      "article_registration_start": null,
      "article_registration_end": null,
      "professional_group": "Tandartsen",
      "professional_group_en": "Dentist"
    },
    {
      "article_registration_number": "49919000101",
      "professional_group_code": "01",
      "article_registration_start": null,
      "article_registration_end": null,
      "professional_group": "Artsen",
      "professional_group_en": "Doctor of medicine"
    }
  ],
  "registration_numbers": ["29919000102", "49919000101"],
  "specialisms": [
    {
      "specialism_id": "0",
      "type_of_specialism_id": "54",
      "specialism": "Mondziekten en Kaakchirurgie",
      "specialism_en": "Oral and maxillofacial surgery"
    }
  ],
  "mentions": [],
  "judgment_provisions": [],
  "limitations": []
}
```

This practitioner is dual-registered (dentist **and** physician) with one
registered specialism — returned from a single query, with NL and EN labels.
`judgment_provisions` / `limitations` / `mentions` are always present as
lists; empty `[]` means none on the register (the common case — a non-empty
`judgment_provisions` is a disciplinary measure, *tuchtrecht*).

### Use cases

- **KYC / credential verification** — is this person BIG-registered, in which
  group, and is the registration still valid (end date)?
- **Screening** — disciplinary measures (`judgment_provisions`) and scope
  limitations on a name list, before onboarding a healthcare contractor.
- **Market sizing** — how many specialist dentists/physiotherapists practice
  under a surname pattern in the Netherlands.
- **Compliance monitoring** — re-run name lists monthly; the register is the
  statutory source of truth (Wet BIG art. 3: registration is what authorises
  practising).

### Input

Quickstart — paste this and press Run:

```json
{ "names": ["jansen"], "professionalGroup": "02" }
```

Input reference:

| field | type | required | description |
|---|---|---|---|
| `names` | string\[] | one of `names`/`registrationNumber` | One or more surnames, e.g. `["jansen", "de vries"]`. Each is a separate query. |
| `registrationNumber` | string | one of `names`/`registrationNumber` | Exact 11-digit BIG number. Must be used alone (official webservice rule). Fastest and most exact. |
| `professionalGroup` | string | no | 2-digit group code filter, e.g. `"01"` physicians, `"02"` dentists, `"03"` midwives, `"17"` pharmacists, `"30"` nurses. |
| `initials` | string | no | Initials filter, e.g. `"J."`. |
| `gender` | string | no | `"M"` or `"V"`. |
| `dateOfBirth` | string | no | `YYYY-MM-DD`. |
| `typeOfSpecialism` | string | no | Specialism-type filter (id from the register's reference data). |

**Query-width rule (source-enforced):** the official service returns at most
50 rows per query and refuses wider ones. This actor skips a too-wide query
with a warning (not charged) instead of failing the run — narrow by group,
initials or gender to land under 50.

### Pricing & billing

- `practitioner-harvested` — **$0.004 per practitioner row delivered.**
  A 50-row query costs $0.20; a full 20-name sweep at 50 rows each costs $4.00.
  For comparison, the closest register-verification actors charge from $17
  per 1,000 results — this actor is ~4x cheaper per row.
- **Zero rows = zero charge, always.** Bad input and zero-result queries are
  free; skipped too-wide queries are free.
- The `apify-actor-start` event costs $0.00005 per run.
- See PRICING.md for the worked cost example and the measured
  registry-category price band.

### Fetching results

Every run writes rows to the run's dataset. Fetch items as JSON, CSV or Excel
by changing `format`:

```bash
## JSON
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"
## CSV
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"
## Excel (xlsx)
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=xlsx" -o big-register.xlsx
## Paginate large datasets
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
```

`<DATASET_ID>` is returned as `defaultDatasetId` in the run object.
`clean=true` drops empty and internal fields.

### Integration (Python)

```python
from apify_client import ApifyClient
client = ApifyClient("APIFY_TOKEN")
run = client.actor("halobartku/nl-big-register-scraper").call(run_input={
    "names": ["jansen"], "professionalGroup": "02"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["mailing_name"], item["registration_numbers"])
```

REST: `POST https://api.apify.com/v2/acts/halobartku~nl-big-register-scraper/run-sync-get-dataset-items`
with the same JSON body and an `Authorization: Bearer <token>` header.

### For AI agents & LLM apps

- Purpose: verify BIG registration / disciplinary status of Dutch healthcare
  professionals from the statutory register, via its official webservice.
- Minimal input: `{"names": ["<surname>"]}` or `{"registrationNumber": "<number>"}`.
- Output fields: see table above; `judgment_provisions` / `limitations` /
  `mentions` are lists, empty `[]` = none on register.
- Costs: one `practitioner-harvested` event per delivered row; empty and
  failed runs are free; skipped too-wide queries are free.
- Semantics: `article_registration_end` in the future = registered;
  past `end` = registration lapsed; `null` = open-ended per source.
- The BIG number itself encodes birthdate (chars 1–6) and gender (7th digit
  odd = M, even = V); the register publishes this openly.

### FAQ

**A query was skipped with "too many results". Why?**
The official webservice caps every query at 50 rows and refuses wider ones.
Add `professionalGroup`, `initials` or `gender` to narrow the name, or split
into several runs. Skipped queries are never charged.

**What is the fastest way to verify one person?**
Their 11-digit BIG number in `registrationNumber` — it returns exactly that
practitioner, including disciplinary measures and limitations, in one call.

**How do I know a registration is still valid?**
On each `article_registrations` entry: `article_registration_end` in the
future = registered; in the past = lapsed; `null` = open-ended per the
register. A person can hold several registrations across groups — check all
entries, not just the first.

**What does a non-empty `judgment_provisions` mean?**
A disciplinary measure (*tuchtrecht*) published by the register: judgment
kind, provision kind and date range. The vast majority of practitioners have
`[]` there. This field is the main reason compliance teams use the register.

**Does this actor scrape the BIG-register website?**
No. It calls `api.bigregister.nl` — the register's own published SOAP
webservice (Handleiding webservice BIG-register v2.6, "zoeken vanuit uw
eigen systeem"). No headless browser, no proxy, no blocking.

### Source & legal

Source: api.bigregister.nl — the official webservice of het BIG-register
(CIBG / Ministerie van VWS). robots.txt allows all; the webservice is
documented for third-party system integration. The BIG register is a
statutory public register (Wet BIG); data delivered is exactly what the
register publishes, nothing enriched. If your use needs consent-basis
processing of personal data, that basis is yours to establish — this actor
is a conduit to the public register, same as the register's own website.

### Limits, honestly

- Max 50 rows per query (source-enforced; too-wide queries are skipped free).
- Work addresses are not part of the ListHcpApprox4 response — if you need
  practice addresses, this actor does not serve them today.
- Date of birth is only returned encoded inside the BIG number (see above),
  not as a separate field.
- This actor is AI-authored (see disclosure below) and validated against the
  live service; the correctness receipt lives in the repo.

### AI-authored disclosure

Built and maintained by an AI operator (Jarvis Turbo, for halobartku).
Every field is parsed from the official webservice response with an
independent validation gate; no field is inferred or invented. Bugs get
fixed the same day they're found — open an issue on the actor's repo.

### Changelog

- **0.1** (2026-09-07): initial release. Surname search + BIG-number lookup,
  32 professional groups with NL/EN labels, specialisms, mentions, judgment
  provisions, limitations; dedupe across queries; >50-result queries skipped
  free. Validated against the live service (46-row receipt, independent
  from-scratch comparator).
- **0.1.1** (2026-09-08): README v2 — verbatim example output record, input
  reference table, dataset-fetch snippets (JSON/CSV/Excel + pagination),
  billing section with worked costs, FAQ. No code changes; actor behavior
  and charging identical.

# Actor input Schema

## `names` (type: `array`):

One or more surnames, e.g. \["jansen", "de vries"]. Each is one official webservice query (max 50 results each, wider queries are skipped with a warning, not charged).

## `registrationNumber` (type: `string`):

Exact BIG number lookup, e.g. 49064114102. If set, must be used alone (official webservice rule).

## `professionalGroup` (type: `string`):

2-digit code filter for surname searches: 01 Artsen (physicians), 02 Tandartsen (dentists), 03 Verloskundigen (midwives), 04 Fysiotherapeuten, 16 Psychotherapeuten, 17 Apothekers (pharmacists), 25 Gz-psychologen, 30 Verpleegkundigen (nurses), 81 Physician assistants, 92 Mondhygienisten, ... (32 groups total).

## `initials` (type: `string`):

Optional: narrow surname search by initials, e.g. 'J.A.'

## `gender` (type: `string`):

Optional: 'M' or 'V'

## `dateOfBirth` (type: `string`):

Optional: YYYY-MM-DD narrows surname search

## `typeOfSpecialism` (type: `string`):

Optional: specialism code filter (see reference data)

## Actor input object example

```json
{
  "names": [
    "jansen"
  ]
}
```

# Actor output Schema

## `items` (type: `string`):

All results, one dataset item per row. Fetch as JSON via this URL with an APIFY\_TOKEN bearer header. A run-level summary is written to the run's terminal status message.

# 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 = {
    "names": [
        "jansen"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("halobartku/nl-big-register-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 = { "names": ["jansen"] }

# Run the Actor and wait for it to finish
run = client.actor("halobartku/nl-big-register-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 '{
  "names": [
    "jansen"
  ]
}' |
apify call halobartku/nl-big-register-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,halobartku/nl-big-register-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/GZDA2IzWA2KDOlxcO/builds/Jn1IWQwlRSOzz7OmL/openapi.json
