303,525 datasets indexed1,419 publishers
Open Data IndexThe index of open data about the Netherlands
Open Data Index›Build›Family tree finder: from one record to your great-grandparents

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.

Your AI assistantOpen Data Index MCP on
The Open Data Index MCP server is on in your chat, so the assistant reads this project and its sources itself.
You paste this project's prompt
The assistant fetches from Open Data Index
  • geef_project("stamboomzoeker")
  • geef_bron("open-archieven")
  • geef_bron("nationaal-archief")
The assistant

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.

Follow the steps
wortelwerk.jouwsite.nl/boom?naam=Johan+Huizinga&jaar=1872
WortelwerknameJohan Huizingayear1872placeGroningen
JJohan Huizingaborn 7 December 1872, GroningenBirth register 1872
record 1277 · AlleGroningers
4 generations in ±10 s
ParentsGrandparentsGreat-grandparents
Dirk HuizingahoogleeraarJacoba Tonkens⚭14-12-1866Groningen
Jacob HuizingaPredikantAaltje Meihuizen⚭21-8-1838Hoogezand
Dirk Huizingadoopsgez. predikantTrijntje Jurjens Coolmanno record found
Samuel MeihuizenwinkelierGrietje Romkes van der Baan⚭29-1-1814Sappemeer
Johannes TonkenshoofdonderwijzerAnna Jacoba Brugsma⚭5-5-1836Groningen
Lammert TonkensJacoba van Ulphen⚭9-11-1800Groningenchurch
Albert BrugsmageregtsdienaarGeesje Jans Popkesno record found
Nationaal Archief · 705 mentions of HuizingaLabour deployment register 31Service registers 18Petitions 11Administration files 10
access 2.09.16.06inv. no. 94713Huizinga, A., Zuidhorn
Mockup

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.

Source: Open Archieven, API v1.1 (stats/records en stats/archives) · opgehaald 25 oktober 2026 · selection: archieven met een ISIL-code NL- of een homepage op .nlOpen the table Single block

How you could start6 steps

  1. 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. 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. 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. 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. 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. 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

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&shy;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)}")
Output
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&shy;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&shy;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.

Source: Nationaal Archief, OAI-PMH (archiefinventarissen als EAD) · opgehaald 25 oktober 2026 · selection: datestamp per jaar, 2024–2026Open the table Single block

The sources2

Open Archives (Open Archieven)

Coret Genealogie, met gegevens van de deelnemende archievenNetherlands, person in a record

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.

OpenAPIDownloadSearch serviceHeritage and culturePopulation
Up to date
updated in August 2026

National Archives of the Netherlands, finding aids and scans

Nationaal Archief (agentschap van het ministerie van OCW)Netherlands, inventory number

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.

OpenAPIDownloadHeritage and cultureGovernment
Up to date
updated 1 hours ago

More to build