One thesis: the one-endpoint, every-grammar resolver is not a startup's architectural bet — the FDA's AccessGUDID has run one at government scale for a decade, accepting identifiers from three different issuing agencies, detecting which grammar it was handed, parsing identity from instance data, and answering from public-domain records. barcoding.dev is that architecture, generalized past medical devices.
If you are the engineering executive at an ISV whose customers touch medical devices, you already live inside the precedent. The FDA's UDI system accredits three issuing agencies — GS1 (whose device identifier is a GTIN), HIBCC (HIBC), and ICCBBA (ISBT 128) — and publishes the grammar of all three in one document, UDI formats by issuing agency (v1.4, September 2025). Three agencies, three syntaxes, three check-digit traditions. And one lookup door.
What AccessGUDID actually does
The AccessGUDID device lookup API accepts a device identifier, a full UDI string, or a record key — and does the work a resolver is supposed to do:
- Detects the grammar. Hand it a GS1 element string or an ISBT-128 structure; it recognizes which agency's syntax it is holding without being told.
- Splits DI from PI. The Device Identifier (which model, which labeler) is identity; the Production Identifiers (lot, serial, expiration, manufacture date) are instance data riding along in the same symbol. It parses the UDI, extracts the DI, and keys the registry on it.
- Serves public-domain data. Full database downloads, no auth on lookups, mirrored weekly into openFDA's
device/udiendpoint.
That DI/PI split should look familiar: it is exactly the GTIN-versus-AIs split that runs through every GS1 2D symbol — the stable identity key versus the per-instance attributes traveling with it. The FDA did not invent a new theory of identifiers; it recognized the same two-layer structure across three agencies and built the door at the right layer.
The same string, both doors
Take the DI the NLM's own API documentation uses, 08717648200274. Structurally it is a GTIN-14, and the check digit confirms it — first thirteen digits weighted 3,1,3,1…:
0·3+8·1+7·3+1·1+7·3+6·1+4·3+8·1+2·3+0·1+0·3+2·1+7·3 = 106
check = (10 − 106 mod 10) mod 10 = 4 ✓
Side by side:
$ curl 'https://accessgudid.nlm.nih.gov/api/v3/devices/lookup.json?di=08717648200274'
→ gudid.device: brandName, company, versionModelNumber, sterilization, …
$ barcoding resolve '(01)08717648200274(17)270331(10)LOT42' --json
{"scheme":"udi.gs1","di":"08717648200274","gtin14":"08717648200274",
"pi":{"expiry":"2027-03-31","lot":"LOT42"},"check":"mod10 pass"}
Same detection, same split, same answer grain. resolve is pure and local — it runs the grammar and the check digit with no network — and enrich on the DI cites AccessGUDID/openFDA records attribute by attribute, each value wrapped in the provenance envelope with source, dataset version, license class, and fetch time. Scale of the rail, from a live openFDA count query: 4,501,620 GS1-issued device identifiers, 687,331 HIBCC, 86 ICCBBA — roughly 4.5 million GTINs sitting in the public domain.
The license read, including the trap
openFDA's license page is close to a best case: CC0/public domain unless otherwise noted. The "otherwise noted" is real and specific — GMDN® fields carry a separate GMDN Agency license for commercial services and AI-training use. An enrichment layer has exactly two honest options: strip those columns, or license them. Ours strips them, and the registry row says so, because the alternative — serving a mostly-CC0 record with a commercially-restricted nomenclature field silently inside it — is precisely the unlabeled-blob failure this API exists to correct. Per-attribute license classes are not compliance decoration; they are what makes a mosaic like "CC0 record, restricted taxonomy column" representable at all.
Why this is the architecture argument, not an anecdote
The build-vs-buy diligence question for an identifier layer is usually framed as can a single resolver really serve heterogeneous schemes without collapsing into special cases? AccessGUDID is the empirical answer. It demonstrates, in production, under regulatory load:
- Grammar detection is tractable as data. Three agencies' syntaxes coexist behind one endpoint because detection is a registry of grammars, not a pile of heuristics.
- Identity/instance separation generalizes. DI/PI for devices, GTIN/AIs for retail, VIN/build-data for vehicles — the same cut, everywhere.
- Public-domain rails can carry a regulated vertical. Nobody had to negotiate a syndication contract to look up a device.
barcoding.dev generalizes each of those: the scheme registry extends the grammar table past three agencies to every scheme worth resolving — GTIN, GLN, SSCC, VIN, ISBN, NDC, tracking formats — with the same DI-grade identity discipline and the same per-attribute provenance on the answer layer. Where a GS1 standard governs, the behavior is conformant to the standard; where the registry extends beyond it, the extension is explicit — never implied into the standard's name. The full generalization is worked through in one resolver, every scheme; the scheme page for this row is /schemes/udi.
For your product, the delta is maintenance economics — the same arithmetic your team already runs on every conformance surface. The FDA formats document revises. openFDA fields shift. The GMDN boundary is contractual, not technical, and it moves on somebody else's schedule. Embedding a layer that pins all of that — grammar tables, check-digit vectors, per-source license manifests, printable with one pins command — is buying the maintenance tax down to a dependency bump. npx barcoding.dev resolve on a UDI from your own test corpus is the evaluation, no meeting required. And if your product needs the hosted UDI enrichment rail — the answer layer, served, with envelopes — tell us who you are.
Keys open the network half of the verb set. Get an API key — say what arrives at your door, and the provisioning order follows the list.
We answer in writing. We take at most five conversations a month, only when you ask for one, and only after you already have the written read.