Skip to main content
Back to research

Research note · 28 August 2026

An open ontology for biodiversity registers, tested against the Biodiversity Heritage Library, ZooBank, and the Natural History Museum Data Portal

Biodiversity informatics is entering its extraction era. Programmes on both sides of the Atlantic are turning tens of millions of pages of natural history literature into machine-readable knowledge, and every one of those pipelines ends the same way: an extracted name, linked to a register, under a licence. We measured that last mile. This note reports a census of the identifier and rights layer beneath biodiversity AI, run on 28 August 2026 against complete harvests of the Biodiversity Heritage Library bulk export, the Natural History Museum Data Portal, and ZooBank with its public mirrors, with WoRMS and IPNI as controls. Everything ships as an open OWL 2, SKOS and SHACL ontology with every headline number computed two ways, in the same programme as our earlier bank, insurance, scholarly-record and learning-standards register studies.

The repository, including the full build report with every caveat and everything we could not obtain, is public: github.com/fabio-rovai/biodiversity-register-ontology .

Finding one: the register of record for animal names refuses un-whitelisted machine clients with a 404

Since the 2012 amendment to the International Code of Zoological Nomenclature, a new animal name published electronically must be registered in ZooBank to be available at all. ZooBank is therefore not a convenience database; it is the register of record. On 28 August 2026, at two observation times, every route on zoobank.org except the homepage returned HTTP 404. That includes the About and Api pages linked from its own navigation, the documented JSON API, the LSID URN form that decades of taxonomic papers embed, and all 50 canonical act URLs we sampled from the register content itself. Those are the exact URLs that GBIF's copy of the register publishes in its references field, so this is the register failing its own published pointers, not our guess at a URL scheme.

The machine-readable supply chain behind it is in no better state. The register's declared publication endpoint, an IPT instance at the Bishop Museum, returns 404. GBIF's crawl of 23 August 2026 ended in ABORT, and the freshest copy GBIF holds dates from 28 March 2025, 518 days before our census. ChecklistBank's copy dates from 9 January 2023, 1,327 days stale, and the two mirrors disagree with each other by 79,420 records. The mirror content also contains 50 identifiers that do not match the register's own UUID pattern. The operational consequence is concrete: any entity-normalisation pipeline built today, including the LLM-extraction platforms now being commissioned over the BHL corpus, cannot link to any zoological name registered in the last seventeen months, and most will silently pin to a mirror without recording which snapshot they pinned to.

The controls put the failure in context. The World Register of Marine Species resolved 10 of 10 sampled records the same day, and IPNI, the botanical names index at Kew, resolved 5 of 5, so this is a register-specific failure, not a property of biodiversity infrastructure. And our resolution observations are two timestamps on one day: if zoobank.org recovers tomorrow, the resolution finding shrinks to an outage report, while the mirror staleness, the aborted crawls and the dead publication endpoint survive any recovery. We found no announcement of the outage anywhere, and we looked.

Same-day resolution of sampled canonical records, 28 August 2026
ZooBank canonical act URLs
0 / 50
World Register of Marine Species
10 / 10
IPNI (Kew)
5 / 5

Measured from an address ZooBank had not whitelisted. The zero is an access refusal served as a 404, not an absent record, and the correction below sets out how we established that. The marine and botanical registers operate no equivalent gate.

Update, 30 August 2026: the publication endpoint recovered

On 29 August 2026, one day after we wrote to the ZooBank registrar and after the outage was raised on GBIF's tracker, the Bishop Museum IPT was rebuilt from scratch. We re-ran the census against the recovered archive on 30 August at 09:12 UTC rather than take the recovery on trust, and the paragraphs above now need reading in two halves.

The half that recovered: all three IPT endpoints return 200, and the republished archive carries 527,127 records against the 478,746 GBIF still serves and the 399,326 in ChecklistBank's copy. It is 48,381 records ahead of the freshest copy that existed anywhere when we published, and its content runs to 23 August 2026.

The half we thought had not: all 50 sampled canonical act URLs still returned 404 at 09:12 UTC, as did the Api, About and Search routes. Every one of those 527,127 records publishes such a URL in its own references field. GBIF had not re-crawled at that point, so its API still served the March 2025 copy, which it no longer does. We concluded from this that the register's content was back and its identity layer was not. That conclusion was wrong, and the correction below explains what those 404s actually were. The measurements in this box stand; the inference drawn from them does not.

Re-running the census also let us measure the register's content properly for the first time, and the result cuts both ways. The identity layer is clean: 527,127 distinct identifiers with no duplicates, no self-parenting, no cycles in the parent chain, every identifier a well-formed UUID, and CC0 asserted on every row with no variant spellings. The 50 malformed identifiers we found in the ChecklistBank snapshot are gone. Against that, 347 internal references name a record absent from the same archive, 41,274 records carry the author and year inside the name string while the atomised authorship and year fields sit empty, and five records have no scientific name at all. All three were reported to the registrar the day we found them, and the row-level lists are in the repository.

We said above that if zoobank.org recovered the resolution finding would shrink to an outage report while the staleness and the dead publication endpoint survived. The publication endpoint recovered. What we then called a surviving resolution failure turned out to be something else, which the next section sets out.

Correction, 30 August 2026: the 404s were an access gate, not a broken resolver

Hours after we published the update above, the ZooBank registrar told us the mechanism behind the 404s, and it is not the one we assumed. zoobank.org sits behind an anti-DDoS system that combines a reCAPTCHA challenge with an IP whitelist, built in response to what he described as years of semi-DDoS attacks. A client whose address is not on the whitelist is refused, and the refusal is served as HTTP 404. That is the same status the register returns for a name that was never registered.

He added this machine's address to the whitelist at approximately 20:45 UTC the same day, which turned the question into a controlled test. The 50 canonical act URLs sampled at 09:12 that morning were on file, the register's content had not changed in between, and the only thing that differed was whether our address was on the list. We re-probed the identical 50 URLs from the same machine using the same command as the original census, a plain curl with redirects followed and no browser user agent.

The same 50 canonical act URLs, same machine, same command, 30 August 2026
Before the whitelist entry, 09:12 UTC
0 / 50
After the whitelist entry, 22:52 UTC
50 / 50

One variable changed between the two observations, and it was a property of our client rather than anything about the register.

All 50 returned 404 before, all 50 return 200 after, and every one of them lands on the canonical /NomenclaturalActs/ path for its UUID. Two of the fifty stopped on the redirect from http to https on the first pass and returned 200 on an immediate re-probe; the report records both statuses rather than smoothing the first one away. The resolver was never broken. We reported a resolution failure and what we had measured was an access refusal wearing a resolution failure's status code. Our first correction, written before we knew this, compounded the error by treating the persistence of the 404s as confirmation.

What survives is narrower than the finding we published. All 527,127 records publish a zoobank.org URL in their references field. A citation checker, a crawler or an entity-normalisation pipeline that follows one of those URLs without being whitelisted receives a 404, and 404 is also the status the register returns for a name that was never registered. A client that branches on the status code, which is what link checkers and crawlers do, therefore records a live identifier as dead. A 403 would carry the information a 404 destroys.

ZooBank does communicate the gate, which is worth stating plainly. A notice on every page we checked, the 404 page included, says the site is testing a system to block high-volume robot traffic, that first-time users are asked once per internet connection to confirm they are not a robot, and that anyone having trouble should write to the address it gives. The 404 page for an unregistered identifier also names that identifier and says in words that it does not exist in ZooBank. The gap is not that the register keeps any of this quiet. It is that the status code carries none of it, and automated clients read status codes. What we cannot tell you is whether the 404 an un-whitelisted client received carried the same notice, because we recorded status codes rather than response bodies before we were whitelisted, and we can no longer issue a request from an address the list does not cover.

The inverse error is confirmed. A well-formed UUID that was never registered returns 200 to a whitelisted client in the published bare form, because the site redirects an unrecognised UUID to a search page rather than answering 404, so a link checker following a references value records a dead identifier as healthy. The registrar has confirmed that behaviour as a known defect he intends to repair.

One limit on this result is worth stating. We could not reproduce the refusal from a second, un-whitelisted address ourselves. zoobank.org publishes no AAAA record, so our only other egress, an IPv6 address the whitelist does not cover, cannot reach the host at all. The mechanism therefore rests on the registrar's account of his own system together with the before-and-after measurement above, rather than on our having seen the gate refuse a second client. The measurement itself is in reports/zoobank_whitelist_retest.json in the repository, with the status of all 50 URLs on both observations, and it is emitted as a graph and recomputed over that graph in SPARQL, so this correction meets the same two-ways bar as every other headline here. Representing it required an additive change to the ontology. The model had assumed an observation date was enough to identify a dereference, and the same URL returning 404 and 200 on one date with only the client differing falsified that. Resolution is a property of the pair rather than of the resource, so version 0.3.0 makes the client's whitelist status part of observation identity.

Update, 31 August 2026: the recovery reached GBIF

GBIF re-crawled the ZooBank dataset on 30 August 2026 at 22:39 UTC and the attempt finished NORMAL. That ended a run of 64 consecutive crawls finishing in ABORT, going back to 26 April 2025. The last crawl to ingest data ran on 29 March 2025, which is where the 28 March 2025 snapshot we measured at census came from, and the three attempts after it reported NOT_MODIFIED before the aborts began. So GBIF's crawler had been failing against this dataset roughly once a week for sixteen months, and the dataset page carried no staleness signal through any of it. The count GBIF serves has moved from 478,746 usages to 527,163, so 48,417 names that were reachable only through a stale mirror when we published are now in the index most downstream biodiversity pipelines actually read.

Names served by GBIF for the ZooBank dataset
Before, the 28 March 2025 snapshot
478,746
After the 30 August 2026 crawl
527,163

The archive itself was rebuilt on 29 August. The figures here are what GBIF served before and after its 30 August crawl.

Two things about that number are worth stating rather than rounding off. GBIF serves 527,163 while the source archive contains 527,127, and the Bishop Museum IPT still declares 527,127 records with an EML datestamp of 29 August, so the archive has not been republished in the interval. We first published that 36 record excess as unexplained. It is now explained, and the explanation reaches back into our own defect list. GBIF's origin facet splits its count into 527,124 usages taken from the source and 39 it synthesised from classification fields naming higher taxa that are not present as rows. The source figure is three short of the archive's 527,127 because GBIF rejected three records, and those three are among the five blank scientific name records we reported as finding R3. So 527,127 minus 3 rejected plus 39 synthesised is 527,163 exactly, with no residual.

The two R3 records GBIF did not reject are worth a look. Both are in the index now as accepted genera whose scientific name is a single full stop, GBIF keys 208757575 and 337071860, flagged SCIENTIFIC_NAME_ASSEMBLED and BACKBONE_MATCH_NONE. GBIF's parser took the genus field, which contains a full stop, assembled a name from it and typed the result SCIENTIFIC. A record with no name in the source is therefore an accepted genus in the aggregator, which is a smaller defect than the ones above but the same kind: a validation step that answers rather than refuses.

ChecklistBank has not moved at all: it still serves version 2023-01-09 with 399,326 records and its most recent import finished on 17 August, which now leaves it 127,837 records behind the register it mirrors.

On who caused what, the sequence is worth setting out plainly because it is easy to overclaim. We raised the aborted crawls and the dead endpoints on GBIF's tracker on 28 August. A GBIF developer brought the ZooBank registrar into that thread on 29 August. The registrar rebuilt the IPT from scratch the same day and has said the rebuild was already in train and not prompted by the ticket. GBIF's crawler then ran on its ordinary weekly schedule and succeeded because the endpoint it had been failing against was back. We reported a problem and the people who own the infrastructure fixed it, which is the whole of what we are claiming.

Finding two: 86.0 per cent of the world's largest biodiversity library carries no machine-actionable licence

The Biodiversity Heritage Library is the corpus underneath most biodiversity text mining, and its bulk export is admirably open and complete. In the export stamped 1 August 2026, 283,090 of 329,129 distinct digitised items, 86.0 per cent, carry no machine-actionable licence. 283,006 have a blank LicenseType field, and 84 carry a Creative Commons IRI with an invisible Unicode character appended, U+FFA0, halfwidth hangul filler, which defeats exact matching against any licence registry while looking identical to a human. A further 108,509 items, 33.0 per cent, carry the copyright status "Not provided. Contact Holding Institution to verify copyright status." The status field itself is uncontrolled prose: the same legal position appears as NOT_IN_COPYRIGHT, NOT IN COPYRIGHT, and several punctuation and whitespace variants of the same sentence, and where a licence IRI exists it appears in http, https, and trailing-slash variants of the same licence.

Licence and rights metadata across the BHL bulk export, 1 August 2026
All distinct digitised items
329,129
No machine-actionable licence
283,090
Copyright status "Not provided"
108,509
CC IRI with invisible Unicode appended
84

86.0% of the corpus carries no machine-actionable licence, and 84 items carry a Creative Commons IRI defeated by an invisible Unicode character.

The consequence lands on anyone trying to license content or train models at corpus scale. A platform that needs to answer "which of these 329,129 items may I redistribute, and under what terms" can answer it mechanically for roughly one item in seven. For the rest the answer is a phone call to a holding institution. The table answering it is not even keyed cleanly: 9,118 ItemIDs recur with a different parent title per row, a collision our verification gate caught when its two independent computations refused to reconcile. Rights readiness, not OCR quality, is the binding constraint on making this corpus a commercial or AI-training data product.

Finding three: identifier hygiene, including a DOI called Array

The export's DOI table holds 306,173 assignments. Thirteen values are not DOIs at all: ten titles carry the literal string Array, the fingerprint of a serialisation bug that wrote a programming-language artefact into a register field, one carries a volume designation, and two carry the https://doi.org/ resolver prefix, which the DOI display guidelines define as a display form rather than the identifier. 171 DOI values are asserted for more than one entity, six of them for both a title and an article, so the identifier cannot resolve to its referent. Among title-level identifiers, 912 of 5,607 ISBNs fail validation, 896 of them through MARC-style qualifier contamination such as 0804700036 (v. 1), eight through genuine checksum failure; 6 of 2,814 ISSNs fail; and 2,652 of 170,766 OCLC numbers are malformed, dominated by a pattern consistent with a control number concatenated with a six-digit date.

Fairness again, and prominently: BHL's own DOI minting practice is clean. Forty of forty sampled DOIs under its 10.5962 prefix are registered at doi.org, as are 24 of 25 sampled externally minted DOIs. Every defect above lives in the metadata export layer, where a per-scheme validation pass at deposit time, the kind of pipeline this study ships, would have caught each class.

Finding four: the NHM Data Portal is best in class on identifiers and thin on product metadata

The Natural History Museum's portal is the strongest catalogue we have measured in this programme on the axis most catalogues fail. Every one of its 294 public datasets carries a DOI, and 25 of 25 sampled resolve. For comparison, across the eleven Nordic national catalogues we measured in our health-data study, identifier coverage was 62.65 per cent. Descriptions are present on all 294 datasets. That deserves saying first, because the museum built the hard part.

The gap is in the fields a licensing platform or data marketplace reads. Eight of 294 datasets simultaneously carry a licence URL, a DOI, a contact email, a description of at least 100 characters, and a declared update frequency, the minimal bundle a data-product listing needs. 108 datasets have no licence URL and 51 no usable licence statement at all. The licence field mixes CKAN identifiers, SPDX-style identifiers and free text for the same licences, eighteen distinct values in total. Author email is empty on every dataset, update frequency is missing on 207, and spatial coverage is present on exactly one dataset in a collection whose specimens span the planet. At the file level, of 1,293 resources, 243 lack a format, 634 lack a size and 460 lack a description. None of this is hard to fix, which is the point: it is a bounded, enumerable backlog, and this census is the backlog list.

The model: registers make claims, and claims have dates

The ontology is deliberately small and reuses the design that has now survived six register domains: status and identity are never properties of a thing, they are dated claims by a named register. An IdentifierAssertion records which register published which identifier for which resource, with conformance judged against the scheme's own declared rules. A RightsAssertion retains the verbatim rights string, because normalising NOT_IN_COPYRIGHT into a tidy code destroys the evidence of vocabulary drift. A ResolutionObservation records what happened when a canonical URL was dereferenced, with a date, so today's 404 and next month's recovery can coexist as facts. A RegisterSnapshot records how stale each mirror is, which for ZooBank is currently the whole story. The scheme registry is SKOS data, not code: each identifier scheme declares its syntax pattern, checksum algorithm and resolution template, and the pipeline validates every identifier against its declared scheme.

Verification is the same discipline as the rest of the programme. Every headline number is computed twice, set-based in Python over the raw exports and via SPARQL over the emitted graph, by a gate that exits non-zero on any disagreement. SHACL runs in three layers with one shape per defect class, so the validation report enumerates the findings. Our own open-ontologies engine validates and lints every artefact as a third path. The build report states the sampling seeds, the caching, the partitioning, and everything we could not obtain, including the two Wayback timeouts that left the start date of the ZooBank outage unknown.

Prior art, credited by name

TDWG's standards family, Darwin Core and Latimer Core above all, defines what biodiversity data should say. The NOMEN ontology models nomenclatural acts formally. OpenBiodiv, by Viktor Senderov and Lyubomir Penev, built a knowledge graph over biodiversity literature, and Plazi extracts taxonomic treatments at scale. GBIF, ChecklistBank and the Catalogue of Life operate the aggregation layer this study reads, and the Biodiversity Heritage Library's open bulk export is what made the census possible at all. None of that work measures whether the registers' published identifiers conform to their own schemes, resolve, or agree across mirrors, and that assurance layer is the only claim this study makes for itself.

The transferable method, and a bounded offer

The method transfers to any register-shaped system: verify the sources by hand, harvest completely or state the sample, declare each identifier scheme's rules as data, reify claims instead of overwriting them, dereference a seeded sample with dates, and compute every number twice. We have now run it on fund data, insurance, banking, the scholarly record, learning standards, health-data catalogues and biodiversity, and the defect classes repeat across domains with remarkable regularity.

If you run a collections catalogue, a nomenclature register, or an extraction pipeline that has to trust one of these, the first measurement pass on one register is free: write to fabio@thetesseractacademy.com with a pointer to the catalogue or register, and you will get back the conformance, resolution and rights-readiness table for it, in the open format this repository defines.

Built and published 28 August 2026. All numbers are reproducible from the public repository; the build report records every caveat, every seed, and everything that could not be obtained. Corrections, when needed, are stated on this page rather than applied silently.