Family tree finder: from one record to your great-grandparents
Start with a birth record and let the app search back generation by generation through the marriage records of hundreds of Dutch archives, with a link to the National Archives inventory.
geef_project("stamboomzoeker")geef_bron("open-archieven")geef_bron("nationaal-archief")
I have the project, the tested calls and the pitfalls. I'll build a app with Open Archives (Open Archieven) and National Archives of the Netherlands, finding aids and scans. This is how it could look:
You build this yourself. Copy the prompt into Claude, ChatGPT or Cursor, with the MCP server on, or follow the steps below.
record 1277 · AlleGroningers
4 generations in ±10 s
This is a mockup, not a working version, with the records from our test run on 16 October 2026 via Open Archieven (AlleGroningers) and the National Archives; occupations are spelled as in the record. Turn the MCP server on with the address on For AI.
Who it's for
Anyone who wants to research their family history, genealogical societies, history teachers and people making a family book.
What you get
An app where you enter a name, year and place and get a tree back: parents, grandparents and great-grandparents, each with the marriage record, date, place, occupation and the archive holding the record. In the test run on 16 October 2026 with the historian Johan Huizinga (born 7 December 1872 in Groningen) the script found four generations in about 10 seconds: his parents Dirk Huizinga (professor) and Jacoba Tonkens, married 14 December 1866 in Groningen; his grandparents Jacob Huizinga (Mennonite minister) and Aaltje Meihuizen (Hoogezand, 1838) and Johannes Tonkens and Anna Jacoba Brugsma (Groningen, 1836); and four of the eight great-grandparent couples. Two couples were not found. For the surname Huizinga the National Archives gave 705 mentions through Open Archives (forced labourers, service records, petitions, administration files), and a mention leads through its access number to the inventory (2.09.16.06, item 94713).
Records in Open Archives by Dutch archive: most Brabants Historisch Informatie Centrum (25,449,700 records), then Stadsarchief Amsterdam and Stadsarchief Rotterdam
Records in Open Archives by Dutch archive, October 2026, in records. Total: 286,471,667; the largest 12 of 154 categories are shown. Brabants Historisch Informatie Centrum is 9% of the total. Dutch archives and societies only (ISIL code NL- or a website in the nl domain); all 200 participants together hold 368,619,131 records.
How you could start6 steps
- 1
Find the first record with name, year and place
records/search.json searches 368 million mentions. Put the year in the name ('Johan Huizinga 1872'), or a period ('1839-1841'), and filter with eventplace. Each hit is a person in a record: one record therefore gives several hits (child, father, mother). Pick the row with eventtype Geboorte and relationtype Kind. Open Archives asks for a descriptive User-Agent and allows 4 requests per second per IP; robots.txt allows everything.
https://api.openarchieven.nl/1.1/records/search.json?name=Johan Huizinga 1872&eventplace=Groningen&number_show=10&lang=nl
{"query":{"eventplace":"Groningen","name":"Johan Huizinga 1872","only_results_with_scans":false,"start":0,"number_show":10,"sort":1,"language":"nl"}, "response":{"number_found":1,"docs":[{"pid":"Person:ab7cee1b-d98d-36df-e5d9-9fd355dbbfe4", "identifier":"c6dfd867-9f3e-a0b1-e749-ac35bce34763","archive_code":"gra","archive":"AlleGroningers", "personname":"Johan Huizinga","relationtype":"Kind","eventtype":"Geboorte", "eventdate":{"day":7,"month":12,"year":1872},"eventplace":["Groningen"],"sourcetype":"BS Geboorte", "url":"https:\/\/www.openarchieven.nl\/gra:c6dfd867-9f3e-a0b1-e749-ac35bce34763"}]}} - 2
Read the record: who are the parents?
records/show.json with archive (the archive_code) and identifier returns the record in the A2A model: Person (the people), Event and RelationEP (who had which role). Join RelationEP.PersonKeyRef to Person['@pid']. Note: with one person Person is an object, with more a list. Source gives the register, record number and a link to the scan (SourceAvailableScans).
https://api.openarchieven.nl/1.1/records/show.json?archive=gra&identifier=c6dfd867-9f3e-a0b1-e749-ac35bce34763&lang=nl
{"Person":[{"@pid":"Person:ab7cee1b-…","PersonName":{"PersonNameFirstName":"Johan","PersonNameLastName":"Huizinga"},"Gender":"Man","BirthDate":{"Year":"1872","Month":"12","Day":"7"},"BirthPlace":{"Place":"Groningen"}}, {"@pid":"Person:f22a0acd-…","PersonName":{"PersonNameFirstName":"Dirk","PersonNameLastName":"Huizinga"},"Gender":"Onbekend","Age":{"PersonAgeLiteral":"32 jaar"},"Profession":"hoogleeraar"}, {"@pid":"Person:feab076f-…","PersonName":{"PersonNameFirstName":"Jacoba","PersonNameLastName":"Tonkens"},"Gender":"Onbekend"}], "Event":{"@eid":"Event1","EventType":"Geboorte","EventDate":{"Year":"1872","Month":"12","Day":"7"},"EventPlace":{"Place":"Groningen"}}, "RelationEP":[{"PersonKeyRef":"Person:ab7cee1b-…","RelationType":"Kind"},{"PersonKeyRef":"Person:f22a0acd-…","RelationType":"Vader"},{"PersonKeyRef":"Person:feab076f-…","RelationType":"Moeder"}], "Source":{"SourceType":"BS Geboorte","SourceReference":{"Place":"Groningen","InstitutionName":"AlleGroningers","Book":"Geboorteregister 1872","DocumentNumber":"1277"}, "SourceAvailableScans":{"Scan":{"Uri":"https:\/\/images.memorix.nl\/gra\/thumb\/640x480\/51c90b6f-713e-12dd-6399-65bbab84c4d5.jpg", …}}, …}} - 3
Find the parents' marriage record
Two names with & in between finds records in which both appear. Take the row with eventtype Huwelijk (civil registration, from 1811) or Trouwen (church books) and relationtype Bruidegom, with a year before the child's birth. A marriage record lists the parents of bride and groom ('Vader van de bruidegom', 'Moeder van de bruid'): that is how you climb one generation. Spelling differs per record: in 1866 the groom's father is called 'Jakob', in his own marriage record of 1838 'Jacob'. Then search again on the surnames only ('Huizinga & Meihuizen') and check the first names in the record.
https://api.openarchieven.nl/1.1/records/search.json?name=Huizinga %26 Meihuizen&number_show=100&lang=nl
{"query":{"name":"Huizinga & Meihuizen", …},"response":{"number_found":53,"docs":[ … {"personname":"Jacob Huizinga","relationtype":"Bruidegom","eventtype":"Huwelijk","eventdate":{"day":21,"month":8,"year":1838}, "eventplace":["Hoogezand"],"archive":"AlleGroningers","identifier":"1f5d4986-099e-f336-ea40-b1cf4e487bf9", …}, {"personname":"Jakob Huizinga","relationtype":"Vader van de bruidegom","eventtype":"Huwelijk","eventdate":{"day":14,"month":12,"year":1866}, "eventplace":["Groningen"], …}, …]}} - 4
Look for the same family in the National Archives
The National Archives also supplies its person indexes to Open Archives (archive_code ghn; ghn and rzh have ISIL code NL-HaNA). These are different kinds of sources than civil records: military service records, petitions, forced labourers in the Second World War, files of the Netherlands Property Administration Institute and the CABR. Some first names are masked with ####.
https://api.openarchieven.nl/1.1/records/search.json?name=Huizinga&archive_code=ghn&number_show=5&lang=nl
{"query":{"archive":"Nationaal Archief","name":"Huizinga", …},"response":{"number_found":705,"docs":[ {"personname":"#### Huizinga","relationtype":"Ondertekenaar","eventtype":"Handtekening","eventdate":{"year":1878},"eventplace":["'s-Gravenhage"],"sourcetype":"Verzoekschriften", …}, … {"identifier":"5f312b07-9c20-447e-e053-09f0900afd8f","archive_code":"ghn","personname":"A. Huizinga","relationtype":"Geregistreerde", "eventtype":"Registratie","eventplace":["'s-Gravenhage"],"sourcetype":"Beheersdossier", "url":"https:\/\/www.openarchieven.nl\/ghn:5f312b07-9c20-447e-e053-09f0900afd8f"}]}} - 5
From mention to inventory (OAI-PMH)
In records/show.json a National Archives mention has the access number in Source.SourceReference.Archive (here 2.09.16.06) and the item number in RegistryNumber (94713). GetRecord with that access number returns the whole inventory as EAD. The identifier of the mention (5f312b07-9c20-…) appears in the EAD as a handle (hdl.handle.net/10648/5f312b07-9c20-…): that gives you the right item with its title. Mind the size: this inventory is 9.8 MB. Put the URL with the exclamation mark in single quotes in the shell.
https://service.archief.nl/gaf/oai/!open_oai.OAIHandler?verb=GetRecord&metadataPrefix=oai_ead&identifier=2.09.16.06
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"><responseDate>2026-10-16T21:41:43Z</responseDate> <request verb="GetRecord" identifier="2.09.16.06" metadataPrefix="oai_ead">…</request><GetRecord><record><header><identifier>2.09.16.06</identifier> <datestamp>2024-10-25T11:09:41Z</datestamp>…</header><metadata><ead …> <titleproper>Inventaris van het archief van het Nederlands Beheersinstituut, beheersdossiers beginnend met de letter H</titleproper> … <extref href="http://creativecommons.org/publicdomain/zero/1.0/" …>cc0</extref> … <c level="file"><did><unitid identifier="54347153">94713</unitid> <unitid audience="internal" type="handle">http://hdl.handle.net/10648/5f312b07-9c20-447e-e053-09f0900afd8f</unitid> <unittitle>Huizinga, A., Zuidhorn</unittitle></did></c> - 6
Build the tree and show the sources
Repeat step 3 per couple and per generation; each generation doubles the number of couples. Show for every person the record (date, place, archive, register) and a link to the scan or to openarchieven.nl. Be honest when a couple was not found and why that can happen: church books before 1811 rarely name parents, some archives do not take part, or the name is spelled differently. Cache the responses: the same record often comes up several times.
How the sources fit together
- Open Archives (Open Archieven)National Archives of the Netherlands, finding aids and scansvia
toegangsnummer (Source.SourceReference.Archive, bijvoorbeeld 2.09.16.06) en de identifier, die in de EAD terugkomt als handleOpen Archives makes the people in National Archives collections searchable by name; the National Archives OAI-PMH service gives the inventory that the mention belongs to, with the file title and the rest of the archive.
Let AI build it
Paste this prompt into Claude, ChatGPT, Cursor or Lovable. It names the real endpoints, the join keys and the pitfalls, so the assistant writes working code straight away. Always check the result against the source itself.
Build a family tree app (Next.js or one HTML file with JavaScript) where I enter a name, birth year and place and get back a tree of up to three generations, with the record and archive for each person.
Data:
1. Open Archives, no key, CORS open, OpenAPI: https://api.openarchieven.nl/openapi.yaml
- Search: https://api.openarchieven.nl/1.1/records/search.json?name=Johan%20Huizinga%201872&eventplace=Groningen&number_show=100&lang=nl
- Record: https://api.openarchieven.nl/1.1/records/show.json?archive=<archive_code>&identifier=<identifier>&lang=nl
2. National Archives, OAI-PMH: https://service.archief.nl/gaf/oai/!open_oai.OAIHandler?verb=GetRecord&metadataPrefix=oai_ead&identifier=<access number>
Approach:
- Find the birth record: eventtype 'Geboorte', relationtype 'Kind'. Read the parents with show.json (RelationType 'Vader' and 'Moeder').
- For each couple find the marriage record with name='<man> & <woman>': eventtype 'Huwelijk' or 'Trouwen', relationtype 'Bruidegom', year before the child's birth. Read 'Vader van de bruidegom', 'Moeder van de bruidegom', 'Vader van de bruid', 'Moeder van de bruid' in it and go one generation up.
- If that fails, search on the two surnames only and check in the record whether the first names of bride and groom roughly match (Jakob and Jacob).
What you need to know:
- At most 4 requests per second per IP, otherwise HTTP 429. Wait 0.3 seconds between calls and cache everything.
- Send a descriptive User-Agent ('my-family-tree/1.0 (+you@example.com)').
- number_show at most 100; start for the next page; start above 10,000 gives HTTP 400 (no deep paging).
- A2A: Person and RelationEP are an object with one person and a list with more. Join RelationEP.PersonKeyRef to Person['@pid']. Names: PersonNameFirstName, PersonNamePatronym, PersonNamePrefixLastName ('van der'), PersonNameLastName.
- Age is text ('32 jaar'), occupation in Profession in old spelling ('hoogleeraar').
- A hit is a person in a record, not a person. The same record can be held by two archives (a regional and a municipal archive): deduplicate on date, place and names.
- Some first names are masked with '####'. Sometimes there is HTML in the data ('Internerings­kaarten'): decode entities.
- Before 1811 (church books, eventtype 'Trouwen' or 'Doop') parents are rarely named; the tree often stops there.
- National Archives: archive_code 'ghn'. In show.json the access number is in Source.SourceReference.Archive and the item number in RegistryNumber. The EAD from GetRecord can be almost 10 MB: fetch it on the server and store it. The identifier of the mention appears in the EAD as a handle (hdl.handle.net/10648/<identifier>).
Output: a tree (D3 tree or simple nested cards) with for each person name, occupation, date and place of birth or marriage, and a source line (archive, register, record number, link). At the bottom 'Other mentions at the National Archives' with the count per source type and a link to the inventory. Couples without a found record in grey, with the reason.
Try it yourself
The core of the project in a small script. Needs: Python 3.10+ en requests. Tested on 2026-10-16; below is the real output of that run.
# Stamboomzoeker: van één geboorteakte terug naar ouders, grootouders en overgrootouders.
# Bronnen: Open Archieven (records/search en records/show, A2A-model) en het Nationaal Archief (OAI-PMH). Geen sleutel.
import re, time, requests
UA = {"User-Agent": "mijn-stamboom/1.0 (+jij@voorbeeld.nl)"} # Open Archieven vraagt een beschrijvende user-agent
OA = "https://api.openarchieven.nl/1.1"
GENERATIES = 3
def oa(pad, **params): # maximaal 4 verzoeken per seconde per IP: wacht steeds 0,3 s
time.sleep(0.3)
r = requests.get(f"{OA}/{pad}", params={**params, "lang": "nl"}, headers=UA, timeout=60)
r.raise_for_status()
return r.json()
def lijst(x): # A2A: één persoon is een object, meer personen een lijst
return x if isinstance(x, list) else [x]
def naam(p):
n = p.get("PersonName", {})
return " ".join(x for x in [n.get("PersonNameFirstName"), n.get("PersonNamePatronym"),
n.get("PersonNamePrefixLastName"), n.get("PersonNameLastName")] if x).replace(" ", " ")
def rollen(doc): # haal de akte op en geef {rol: persoon}
akte = oa("records/show.json", archive=doc["archive_code"], identifier=doc["identifier"])
personen = {p["@pid"]: p for p in lijst(akte["Person"])}
return {r["RelationType"]: personen[r["PersonKeyRef"]] for r in lijst(akte["RelationEP"])}, akte
def huwelijk(man, vrouw, voor): # huwelijksakte van een paar, getrouwd uiterlijk in het jaar 'voor'
def zoek(vraag):
docs = oa("records/search.json", name=vraag, number_show=100)["response"]["docs"]
return sorted((d for d in docs if d["eventtype"] in ("Huwelijk", "Trouwen") and d["relationtype"] == "Bruidegom"
and d.get("eventdate", {}).get("year", 9999) <= voor), key=lambda d: -d["eventdate"]["year"])
# Spelling verschilt per akte (Jakob/Jacob): lukt de volledige naam niet, zoek dan op de twee achternamen
# en controleer in de akte zelf of de voornamen van bruidegom en bruid ongeveer kloppen.
for vraag in (f"{man} & {vrouw}", f"{man.split()[-1]} & {vrouw.split()[-1]}"):
for doc in zoek(vraag)[:5]:
rr, _ = rollen(doc)
if naam(rr["Bruidegom"])[:2] == man[:2] and naam(rr.get("Bruid", {}))[:2] == vrouw[:2]:
return doc, rr
return None, None
# 1. Begin bij een geboorteakte: naam, jaar en plaats maken de zoekvraag scherp.
start = oa("records/search.json", name="Johan Huizinga 1872", eventplace="Groningen")["response"]["docs"]
geboorte = next(d for d in start if d["eventtype"] == "Geboorte" and d["relationtype"] == "Kind")
r, akte = rollen(geboorte)
print(f"{naam(r['Kind'])}, geboren {geboorte['eventdate']['day']}-{geboorte['eventdate']['month']}-{geboorte['eventdate']['year']} "
f"in {geboorte['eventplace'][0]} ({geboorte['archive']}, {akte['Source']['SourceReference'].get('Book')})")
print(f" vader {naam(r['Vader'])} ({r['Vader'].get('Profession', '?')}), moeder {naam(r['Moeder'])}")
# 2. Klim per generatie omhoog via de huwelijksakten: daarin staan de ouders van bruid en bruidegom.
paren = [(naam(r["Vader"]), naam(r["Moeder"]), geboorte["eventdate"]["year"])]
for gen in range(1, GENERATIES + 1):
volgende = []
for man, vrouw, voor in paren:
doc, rr = huwelijk(man, vrouw, voor)
if not doc:
print(f"{' ' * gen}{man} x {vrouw}: geen huwelijksakte gevonden")
continue
d = doc.get("eventdate", {})
print(f"{' ' * gen}{naam(rr['Bruidegom'])} x {naam(rr['Bruid'])}: getrouwd {d.get('day', '?')}-{d.get('month', '?')}-{d.get('year', '?')} "
f"in {doc['eventplace'][0]} ({doc['archive']})")
for kant in ("bruidegom", "bruid"):
v, m = rr.get(f"Vader van de {kant}"), rr.get(f"Moeder van de {kant}")
if v and m:
print(f"{' ' * gen} ouders {kant}: {naam(v)} ({v.get('Profession', '?')}) en {naam(m)}")
volgende.append((naam(v), naam(m), d.get("year", voor)))
paren = volgende
# 3. Dezelfde achternaam in de archieven van het Nationaal Archief (archive_code ghn), per soort bron.
res = oa("records/search.json", name="Huizinga", archive_code="ghn", number_show=100)["response"]
soorten = {}
for d in res["docs"]:
soorten[d["sourcetype"]] = soorten.get(d["sourcetype"], 0) + 1
print(f"\nNationaal Archief via Open Archieven: {res['number_found']} vermeldingen van Huizinga; eerste 100 per soort:")
print(" " + ", ".join(f"{k} {v}" for k, v in sorted(soorten.items(), key=lambda x: -x[1])))
# 4. Van een vermelding naar de inventaris: het toegangsnummer staat in SourceReference.Archive.
doc = next(d for d in res["docs"] if d["sourcetype"] == "Beheersdossier")
_, akte = rollen(doc)
toegang = akte["Source"]["SourceReference"]["Archive"]
oai = requests.get("https://service.archief.nl/gaf/oai/!open_oai.OAIHandler", headers=UA, timeout=120,
params={"verb": "GetRecord", "metadataPrefix": "oai_ead", "identifier": toegang})
titel = re.search(r"<titleproper[^>]*>([^<]+)", oai.text).group(1).strip()
guid = doc["identifier"]
inv = re.search(rf"<unitid[^>]*>(\d+)</unitid>\s*<unitid[^>]*>[^<]*{guid}</unitid>\s*<unittitle>([^<]+)", oai.text)
print(f"\n{doc['personname']} ({doc['sourcetype']}): toegang {toegang}, {len(oai.content) / 1e6:.1f} MB EAD")
print(f" {titel}")
print(f" inventarisnummer {inv.group(1)}: {inv.group(2)}")
Johan Huizinga, geboren 7-12-1872 in Groningen (AlleGroningers, Geboorteregister 1872)
vader Dirk Huizinga (hoogleeraar), moeder Jacoba Tonkens
Dirk Huizinga x Jacoba Tonkens: getrouwd 14-12-1866 in Groningen (AlleGroningers)
ouders bruidegom: Jakob Huizinga (Predikant) en Aaltje Meihuizen
ouders bruid: Johannes Tonkens (hoofdonderwijzer) en Anna Jacoba Brugsma
Jacob Huizinga x Aaltje Meihuizen: getrouwd 21-8-1838 in Hoogezand (AlleGroningers)
ouders bruidegom: Dirk Huizinga (doopsgez. predikant) en Trijntje Jurjens Coolman
ouders bruid: Samuel Meihuizen (winkelier) en Grietje Romkes van der Baan
Johannes Tonkens x Anna Jacoba Brugsma: getrouwd 5-5-1836 in Groningen (AlleGroningers)
ouders bruidegom: Lammert Tonkens (?) en Jacoba van Ulphen
ouders bruid: Albert Brugsma (geregtsdienaar) en Geesje Jans Popkes
Dirk Huizinga x Trijntje Jurjens Coolman: geen huwelijksakte gevonden
Samuel Meihuizen x Grietje Romkes van der Baan: getrouwd 29-1-1814 in Sappemeer (AlleGroningers)
ouders bruidegom: Samuel Meihuizen (koopman) en Sijntje Jacobs Mulder
ouders bruid: Romke Douwes van der Baan (koopman) en Aaltje Koerts Verveld
Lammert Tonkens x Jacoba van Ulphen: getrouwd 9-11-1800 in Kerkelijke gemeente Groningen (AlleGroningers)
Albert Brugsma x Geesje Jans Popkes: geen huwelijksakte gevonden
Nationaal Archief via Open Archieven: 705 vermeldingen van Huizinga; eerste 100 per soort:
Tewerkgesteldenregistratie 31, Stamboeken 18, Verzoekschriften 11, Beheersdossier 10, CABR dossiers 7, Persoonsdossiers 6, Registratie onderscheidingen 6, Personeelsdossier 4, Staat van dienst 3, Personeelsregister 1, Stamkaarten 1, Landverhuizers 1, Internerings­kaarten 1
A. Huizinga (Beheersdossier): toegang 2.09.16.06, 9.8 MB EAD
Inventaris van het archief van het Nederlands Beheersinstituut, beheersdossiers beginnend met de letter H
inventarisnummer 94713: Huizinga, A., Zuidhorn
Where it goes wrong
- Name spelling differs per record. The groom's father is 'Jakob Huizinga' in 1866 and 'Jacob' in his own marriage record of 1838. An exact search found nothing; a search on surnames ('Huizinga & Meihuizen') did. Then check in the record whether the first names of bride and groom match, or you link the wrong Jacob.
- A hit is a person in a record, not a person. One birth record gives three hits (child, father, mother) and a marriage record six. Never count hits as people.
- In the A2A model Person and RelationEP are an object when there is one person and a list when there are more. Code that always expects a list breaks on records with one person (such as the National Archives administration files).
- Before 1811 there are only church books (eventtype 'Trouwen', 'Doop'). These rarely name the parents: the marriage of Lammert Tonkens and Jacoba van Ulphen (Groningen, 1800) was found, but without parents. That is where the tree stops.
- Open Archives allows 4 requests per second per IP (HTTP 429 above that), and start above 10,000 gives HTTP 400. A three-generation tree easily takes 20 to 40 calls: wait between calls and cache.
- A National Archives inventory can be large: GetRecord for 2.09.16.06 returned 9.8 MB of EAD with 21,791 described components. Do not fetch it in the browser for every click.
- Data are not clean everywhere: first names masked with '####', HTML entities in source types ('Internerings­kaarten'), occupations in old spelling ('hoogleeraar', 'geregtsdienaar'), patronymics inside the first name ('Grietje Romkes').
Take it further
- Also find the death record for each person (records/match.json with name and birth year returns birth and death records) and put life years in the tree.
- Put the places of all records on a map and show how the family moved (here: from Lagemeeden and Hoogezand to Groningen).
- Use related/weather.json for the weather on the wedding day and stats/familynames.json for where the surname is most common.
- Show the scans for military service records and other National Archives mentions: in the EAD, items with scans link to a METS file with the images.
More with this data
National Archives finding aids by year of last change: 2024 is the largest part, 58% in October 2026
Breakdown in October 2026: 2024 58%, 2025 31%, 2026 11%. Total: 7,411 finding aids.
The sources2
Open Archives (Open Archieven)
Open Archives by Coret Genealogie combines the genealogical data of 200 archives and societies, mostly Dutch, also Belgian and French. On 16 October 2026 the statistics API counted 368,475,032 records across 199 source types: civil registration of deaths, births and marriages, population registers, church baptism, marriage and burial registers, notarial records and more. A keyless REST API, SPARQL, OAI-PMH and file exports under CC BY 4.0.

National Archives of the Netherlands, finding aids and scans
The National Archives publish their finding aids as open data (CC0) via OAI-PMH, in EAD XML. On 16 October 2026 there were 7,411 finding aids (7,442 sets), each with the description of the archive and its inventory numbers. Where scans exist, each inventory number has a METS file linking to the images (public domain or CC0). Finding aids made by third parties (2.8 percent) are not open data.
Asylum reception dashboard: national and per municipality
A monument walk through your own neighbourhood
The Netherlands next to Europe: a comparison tool for any indicator