# Vektis open data on healthcare costs

What basic health insurance pays out per year, split into 26 cost types such as hospital care, medicines, GP and mental health. Per municipality (age in 5-year bands) and per three-digit postcode area (per year of age), for all insured people. Cost years 2011 to 2024.

- Publisher: Vektis
- Area: Netherlands · Finest detail: postcode (3 digits) and municipality
- Period: 2011 – 2024 · Refreshed: yearly
- Access: Open · Licence: Vektis-voorwaarden: niet-commercieel, bronvermelding (bron: Vektis)
- Join keys: gemeentenaam, postcode (3 cijfers), leeftijdsklasse, geslacht
- Status: ok (2026-07-20) · kostenjaar 2024, gemeentebestand
- URL: https://www.vektis.nl/zorgprisma/open-databestanden

## What can you do with it?
- **Healthcare costs per resident in your municipality.** Add up all cost categories per municipality and divide by insured-years. Put your municipality next to the national figure and its neighbours.
- **Where does the money go after 65?.** Plot costs per insured-year by age band, per cost type. You see where medicines, hospital care and community nursing start to weigh most.
- **Correct for ageing.** A municipality with many older people naturally has higher costs. Calculate what each municipality would cost with the national age profile, and only then compare.
- **Mental health costs and income per postcode area.** Join the postcode3 figures with income data and see whether mental health consultation costs rise in poorer areas. Beware of small areas and of categories that changed name.

## How to process it
1. **Read the leaflet.** It defines every cost category, explains the residual category and says which costs are still missing.
   `https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/Open%20Data%20Bestanden/2024/Bijsluiter%20bij%20de%20Vektis%20Open%20Databestanden%20Zorgverzekeringswet%202011%20-%202024.pdf`
2. **Download one year per municipality.** A semicolon-separated CSV. The 2024 municipality file is 2.9 MB with 12,992 rows (342 municipalities, two sexes, 19 age bands). The postcode file is 21.8 MB.
   `https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/Open%20Data%20Bestanden/2024/Vektis%20Open%20Databestand%20Zorgverzekeringswet%202024%20-%20gemeente.csv`
3. **Remove the residual category.** The row without sex, age and municipality is the residual category: groups of fewer than 10 people and insured people with unknown characteristics. In 2024 that was 412,394 people. Include it in the national total, not per municipality.
4. **Divide by insured-years, not persons.** aantal_verzekerdejaren weighs how long someone was insured or lived in the municipality. Anyone born, deceased or moving during the year counts only partly.
5. **Join municipalities by name.** There is no municipality code, only the name in capitals ('AA EN HUNZE'). The 2024 file follows the 2026 municipal boundaries. Build a lookup table to the GM code.

## Interesting combinations
- Are healthcare costs linked to income? → [cbs-kwb](https://www.opendataindex.nl/en/bron/cbs-kwb.md) via gemeente (naam naar GM-code). The key figures give income and age profile per municipality. Compare municipalities with a similar age profile first.
- Where in the Netherlands are costs per insured person highest? → [pdok-wijkenbuurten](https://www.opendataindex.nl/en/bron/pdok-wijkenbuurten.md) via gemeente. Use municipal boundaries from the same year as the file's classification (2026 for cost year 2024).

## Similar sources
- [waarstaatjegemeente](https://www.opendataindex.nl/en/bron/waarstaatjegemeente.md): The Zorggebruik dashboard shows municipal figures already processed and charted, from several sources.
- [cbs-statline](https://www.opendataindex.nl/en/bron/cbs-statline.md): CBS publishes total Dutch healthcare spending, also outside basic insurance, but not per municipality and age.

## What to watch out for
- **Not for commercial use.** The files are for personal use and research. Reselling and commercial use are not allowed. Always credit 'source: Vektis'.
- **Only what goes through the insurer.** Costs you pay yourself without claiming, and statutory personal contributions, are not included. The deductible that the insurer paid first and then reclaimed is included.
- **Two years of claims, not everything.** Each cost year includes claims over 8 quarters. For specialist mental health about 90% is in by then. Cross-border care is incomplete. Negative amounts are corrections.
- **Cost categories change.** The mental health category was called second-line up to 2013 and specialist up to 2021. From 2022 there are new categories for consultations, inpatient stays and other services. GP-MDZ only exists from 2015. Check the columns per year.
- **Age bands sort badly.** The bands are text with double spaces ('0 t/m  4 jaar', '5 t/m  9 jaar'). Sorted alphabetically, '10 t/m 14' comes before '5 t/m 9'. Turn them into numbers yourself.

## API (Bestanden (CSV))

- Base: https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/Open%20Data%20Bestanden
- Access: No key or account needed (tested)
- Formats: csv
- Size: 12992 rows in the 2024 municipality file (2.9 MB); the postcode3 file is 21.8 MB (experience)
- Filtering: No filters: whole files. Find the newest year by trying the fixed path with descending years (HEAD).; 

### Endpoints
- `GET /{jaar}/Vektis%20Open%20Databestand%20Zorgverzekeringswet%20{jaar}%20-%20gemeente.csv`: Costs per municipality, sex and 5-year age band, cost years 2017 to 2024 (2024: Last-Modified 20 July 2026).
- `GET /{jaar}/Vektis%20Open%20Databestand%20Zorgverzekeringswet%20{jaar}%20-%20postcode3.csv`: Costs per 3-digit postcode area, sex and age in years, 2017 to 2024 (2024: 21.8 MB).
- `GET /Gemeentebestanden%202011-2016/Vektis%20Open%20Databestand%20Zorgverzekeringswet%20{jaar}%20-%20gemeente.csv`: Municipality files 2011 to 2016 (different folder).
- `GET /Oud/Vektis%20Open%20Databestand%20Zorgverzekeringswet%20{jaar}%20-%20postcode3.csv`: Postcode3 files 2011 to 2016 (folder Oud).
- `GET /2020/Vektis%20Open%20Databestand%20Zorgverzekeringswet%202020%20-%20gemeente_versie2.csv`: Exception: 2020 is named _versie2 (municipality and postcode3).

### Parameters
- `jaar`: Cost year 2011 to 2024; one file per year and per breakdown. 2025 didn't exist yet on 16 Oct 2026 (404); next release mid-2027. (tested)

### Columns in the 2024 CSV file (selection) (10)
`geslacht` tekst, `leeftijdsklasse` tekst, `gemeentenaam` tekst, `aantal_bsn` getal, `aantal_verzekerdejaren` getal, `kosten_medisch_specialistische_z` getal, `kosten_farmacie` getal, `kosten_huisarts_inschrijftarief` getal, `kosten_consulten_ggz` getal, `kosten_overig` getal

### Limits and pitfalls
- No key and no limit; plain files with Last-Modified and Accept-Ranges (Range returns 206). (tested)
- The first data row is the residual category: sex, age and municipality empty (2024: 412,394 insured). Include it in the national total, not per municipality. (tested)
- Semicolon separator, dot as decimal mark, CRLF line endings, no BOM. (tested)
- Columns differ per year: 2011 uses upper case and full names (KOSTEN_MEDISCH_SPECIALISTISCHE_ZORG, KOSTEN_TWEEDELIJNS_GGZ), 2024 lower case truncated at 32 characters and different mental-health categories. Check the header per year. (tested)
- Matching municipality names to CBS codes works by name with a few aliases (BERGEN LB = Bergen (L.), NUENEN CA = Nuenen, Gerwen en Nederwetten). (experience)
- Costs are claims over 8 quarters; negative amounts are corrections. Specialist mental healthcare is about 90% complete. (experience)
- robots.txt allows everything for normal user agents; only AGB register pages are forbidden for AI crawlers. (tested)

### Example
```
https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/Open%20Data%20Bestanden/2024/Vektis%20Open%20Databestand%20Zorgverzekeringswet%202024%20-%20gemeente.csv
```

## How to fetch it

### curl
```bash
curl -o vektis-2024-gemeente.csv "https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/Open%20Data%20Bestanden/2024/Vektis%20Open%20Databestand%20Zorgverzekeringswet%202024%20-%20gemeente.csv"
```

### python
```python
import pandas as pd

url = ("https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/"
       "Open%20Data%20Bestanden/2024/Vektis%20Open%20Databestand%20Zorgverzekeringswet%202024%20-%20gemeente.csv")
df = pd.read_csv(url, sep=";")
df = df[df["gemeentenaam"].notna()]          # restcategorie eruit
kosten = df.filter(like="kosten_").sum(axis=1)
per_gemeente = (kosten.groupby(df["gemeentenaam"]).sum()
                / df.groupby("gemeentenaam")["aantal_verzekerdejaren"].sum())
print(per_gemeente.sort_values().round(0).tail(5))   # euro per verzekerdejaar
```

## What you can build with it
- [Healthcare cost comparer per municipality](https://www.opendataindex.nl/en/bouwen/zorgkosten-vergelijker.md): A tool that shows what basic health insurance spends per resident in your municipality, per type of care, and how that compares with the rest of the Netherlands, also after correcting for age.


## Examples with real figures (2)

For each example the finding, the reference date and the call that fetches exactly these figures.

- **Basic health insurance costs by type of care: most Specialist medical care (31,273 million euros), then Pharmaceuticals and Mental health, consultations** (2024). Table Zvw 2024 gemeente. [Example](https://www.opendataindex.nl/en/voorbeeld/vektis-zorgkosten-per-rubriek)
  - `https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/Open%20Data%20Bestanden/2024/Vektis%20Open%20Databestand%20Zorgverzekeringswet%202024%20-%20gemeente.csv`
- **Basic health insurance costs per insured person: highest in Heerlen and 1 other municipality (4,520 euros), lowest in Urk (2,601 euros)** (2024). Table Zvw 2024 gemeente. [Example](https://www.opendataindex.nl/en/voorbeeld/vektis-zorgkosten-per-verzekerde)
  - `https://www.vektis.nl/vektisnl-assets/prd/storage/uploads/Docs%20per%20pagina/Open%20Data%20Bestanden/2024/Vektis%20Open%20Databestand%20Zorgverzekeringswet%202024%20-%20gemeente.csv`
