Skip to content

Archives catalogue

A gap in a tree is only half a task. The other half is where the missing record is kept. gwt-leads --archives FILE can say that, but only from a file you write yourself, so a new user starts with nothing. And a search done in the wrong place gets counted as a negative. A city's index cannot hold a birth from the next town, and a register that starts in 1871 cannot hold a birth from 1850.

gwt-leads ships a catalogue of about 200 archives and record portals, one file per country. Each row says which places and years it covers, which record types it holds and how you reach it. Every row comes from a probe of the source's public site.

gwt-check dump tree.json.gz
gwt-leads --archives builtin:es,xx --format json tree.json.gz      # Spain, plus the sources that span countries
gwt-leads --archives builtin:all --format queue --root I0001 tree.json.gz > seeds.jsonl

builtin: takes country codes (ISO 3166, any case, comma-separated) or all. xx holds the sources that cover several countries: FamilySearch, Find a Grave, Open Archives outside the Netherlands, Matricula outside its home dioceses, and the paid tree sites. An unknown code exits 2 and lists the codes there are. A path that does not start with builtin: is read as your own file, exactly as before.

What a gap gets

The record a gap asks for is the same one as with your own file: the birth or baptism for a branch end, a birth gap or an unsupported link, and the death or burial for a death gap. A marriage gap gets no hint. Neither does an event with no place, nor a private event.

A row fits that record when all of these hold:

  • one of the names in its match cell is a level of the event's place: the place itself, the province it sits in, the country (names compare folded, the same way --archives FILE compares them). A * row (a world source) fits any place;
  • a region or place row of a country's file fits only when the place also names that country, or names no country the catalogue knows. Barcelona, Venezuela never gets the Catalan archives, and Paris, Texas never gets the Archives de Paris. Country rows only fit through the country's own names, so a place chain needs a country level (España, France, USA) before any country row can match; a tree whose places stop at the province gets only the region rows and the world rows;
  • its record_types hold the record: birth for a birth or baptism, death for a death or burial;
  • its years hold the event's year (an exact year, or an "about" or estimated one; a "before", "after" or range year is no year, so it never rules a row out);
  • its coverage_places, when it has any, include a level of the event's place.

The fitting rows are listed deepest level first (a province's archive before the country's), then the world rows. Rows of one level go by access: online first, then browser, login, paid, letter and in-person, and in file order within the same access.

  • --format json: the first fitting row is where, with the same keys as with your own file (archive, series, url, online, access). The others are also, a list in the same shape. A row that matches a named level of the place and the record but not the year or the places is listed under outside, with why: {"archive": "matchID: décès INSEE", "why": "covers 1970-, not 1930"}. A search there cannot find this record, so it is not a negative. World rows are never listed there: a death in 1890 being outside a 1939-1945 index tells nobody anything.
  • --format queue: the note's where: part lists up to three rows per record: where and the first two of also.
  • --format tsv does not change.

online is true only for a source a lane can search (access online) when the year is known. A row whose robots.txt forbids scripts is never online. It is false for any other access and null when the year is unknown.

In the url, {place} is the event's own place, {year} its year, {year_from} and {year_to} five years either side, {given} and {surname} the person's first given name and first surname, and {code} the place's code in the tree (an INSEE, INE or ISTAT code, if you keep one). Every value is URL-encoded, and a value the tree does not hold is left empty. gwt-leads never opens the url; it only writes it down.

The files

leads/archives/<CC>.tsv, UTF-8, tab-separated, one header row:

column holds
match place names separated by vertical bars: a country in its own language and in a few others, or a region and its provinces. * for a world source
match_level country, region, place, or world (only with *)
archive the archive or portal
series what it holds, in a few words
record_types some of birth, marriage, death, census, migration, military, probate, land, notarial, court, press, directory, tree, gazetteer, catalogue, other. A parish register counts as birth,marriage,death; a war-dead list as death
years the years it covers, as ranges separated by commas. An open end, 1871-, means it still runs. Empty means not known: the row fits any year
civil_start the year civil registration began there, when the row is about vital records
url where to search, with the placeholders above, or empty
access online (a lane can search it), browser (a person has to open it: a bot challenge, or robots.txt or the terms forbid scripts), login (a free account), paid, letter (by request) or in-person
robots what its robots.txt or front door said: ok, disallow (robots.txt or the terms forbid scripts), challenge (a bot check), or empty when not known
coverage_places places separated by vertical bars, when the source holds less than its match: the Archives de Paris match the old Seine département but hold only Paris
tested the date a probe last got a 2xx or 3xx answer from the url, or empty
notes rate limits, closures, terms

A source that forbids scripts stays in the catalogue as access browser, so a gap still points a person there. The files are checked when they load, and again by leads/test_archives_data.py. A wrong column, an unknown value, years that are not ranges, a repeated name or an unknown placeholder stops the run with exit 2 and the file and line.

Countries

code country rows
ad Andorra 1
ar Argentina 2
at Austria 3
au Australia 2
ba Bosnia and Herzegovina 1
be Belgium 1
bg Bulgaria 1
bo Bolivia 1
br Brazil 2
by Belarus 1
ca Canada 6
ch Switzerland 3
cl Chile 1
cn China 1
co Colombia 1
cr Costa Rica 1
cu Cuba 3
cy Cyprus 1
cz Czech Republic 5
de Germany 9
dk Denmark 3
do Dominican Republic 1
dz Algeria 1
ec Ecuador 1
ee Estonia 2
eg Egypt 1
es Spain 18
fi Finland 4
fr France 11
gb United Kingdom 11
gg Guernsey 1
gr Greece 1
gt Guatemala 1
hr Croatia 1
ht Haiti 1
hu Hungary 2
ie Ireland 5
il Israel 1
im Isle of Man 1
in India 1
is Iceland 2
it Italy 2
je Jersey 1
jm Jamaica 1
jp Japan 1
lb Lebanon 1
li Liechtenstein 2
lt Lithuania 1
lu Luxembourg 3
lv Latvia 2
ma Morocco 1
mc Monaco 1
md Moldova 1
mt Malta 1
mx Mexico 2
nl Netherlands 4
no Norway 2
nz New Zealand 2
pe Peru 1
ph Philippines 1
pl Poland 5
pr Puerto Rico 1
pt Portugal 2
py Paraguay 1
ro Romania 1
rs Serbia 1
ru Russia 1
se Sweden 2
si Slovenia 1
sk Slovakia 1
sm San Marino 1
tr Turkey 1
ua Ukraine 1
us United States 7
uy Uruguay 2
va Vatican City 1
ve Venezuela 1
za South Africa 2
xx several countries 19

Checking the urls (maintainers)

leads/gwt-leads archives probe --country nl     # one country; no --country: every file

The probe fills each url with invented values (the surname Example, the year 1900), never a real person. It reads each host's robots.txt first (following its redirects, as RFC 9309 says) and skips a path it forbids; a robots.txt that errors or does not answer forbids the whole host. A forbidden url prints robots - when robots.txt itself says no, and robots robots.txt 503 (or the network error) when robots.txt could not be read, so you can tell the two apart. Then it sends a HEAD request, or a GET when the server refuses HEAD, waiting two seconds before each request (--delay, never less than one). It does not follow redirects. A 2xx or 3xx answer writes today's date into tested, and nothing else in the file changes. Any other answer leaves tested as it was and prints FAIL with the status, and the command exits 1. It sends the User-Agent gramps-web-toolkit archives probe. It is a maintainer's command, run from a clone, never in CI. A row whose url keeps failing keeps its access and an empty tested; say what happened in notes. Many sites answer a script with 403 (a bot check) while a browser gets in, which is why access browser exists.

To add a source, add a row to the country's file (or a new <CC>.tsv), run the tests in leads/, probe that country, and name in the pull request where the facts come from.