Most explainers about Digital Product Passport QR codes stop at "scan the code, open a website." That misses the interesting part. The QR code on a compliant product encodes a GS1 Digital Link, and the component that makes it useful is the resolver — the service that turns one product identifier into many different, context-aware responses.
This article shows what the resolver actually does, with a live passport you can call right now (no signup, no key).
What a GS1 Digital Link actually is
A GS1 Digital Link is a normal HTTPS URL that embeds GS1 identifiers as path segments, each tagged with an Application Identifier (AI):
https://id.gs1.org/01/04019999999902/21/DEMO-BAT-01
└─01─┘ └──GTIN───┘ └21┘ └─serial─┘
01→ GTIN (Global Trade Item Number) — which product21→ serial — which individual unit10→ batch/lot (alternative to serial)
Because it is a plain URL, any phone camera opens it. Because it is structured, machines can parse it. That dual nature is the whole point.
The resolver: one URI, many answers
A dumb QR code returns one fixed page. A resolver inspects the request and returns the representation that fits the caller:
- a consumer with a phone browser gets a human-readable HTML page;
- a recycler's system asks for JSON-LD and gets machine-readable structured data;
- an authority can request the full linkset — every typed link the product exposes.
Same URL, different responses, decided by the Accept header (or a ?format= override).
A live resolver you can call right now
qr3.app hosts a public demo battery passport. Open it in a browser:
You will see the consumer page for EcoMax 5000 (Demo) by GreenPower GmbH. Now ask the same URL for machine-readable JSON-LD:
curl "https://qr3.app/dpp/04019999999902/DEMO-BAT-01?format=jsonld"
{
"@context": ["https://schema.org", "https://gs1.org/voc/"],
"@type": "Product",
"gtin": "04019999999902",
"name": "EcoMax 5000 (Demo)"
}
That is the resolver doing its job: one identifier, a human page and a JSON-LD document built on schema.org + the GS1 web vocabulary. Other representations are available the same way — ?format=json (raw passport), ?format=linkset (all typed links), ?format=dcat-ap — or via standard Accept negotiation (Accept: application/ld+json).
Validate identifiers before you mint links
A resolver is only as trustworthy as the identifiers behind it. Validate a GTIN before you build a Digital Link for it:
import { QR3 } from "@qr3/sdk";
const client = new QR3({ apiKey: process.env.QR3_API_KEY! });
const result = await client.gs1.validateGs1({
identifier_type: "gtin",
value: "04019999999902",
});
console.log(result.valid); // true
console.log(result.detail); // "Valid GTIN-14"
Register your GTINs
Keep the identifiers you use under management so every Digital Link traces back to a known product:
const gtin = await client.gs1.createGs1Identifier({
identifier_type: "gtin", // or "gln" | "company_prefix"
value: "04019999999902",
label: "EcoMax 5000",
});
Using qr3 as your resolver
You do not have to build and operate a resolver yourself. Point your product QR code at the Digital Link, host the passport on qr3.app, and the resolver serves the right representation per request. The GTIN/serial in the URL stay stable forever (so printed labels never break), while the data behind them stays updatable.
FAQ
Is the QR code itself different from a normal one? No — it is a standard QR (or Data Matrix) carrying a GS1 Digital Link URL. Any camera opens it; the intelligence is in the resolver, not the symbol.
Do consumers and recyclers really get different content?
Yes — that is content negotiation. The browser gets HTML; a system requesting application/ld+json (or ?format=jsonld) gets structured data from the same URL.
Can I keep my own product page and still be compliant?
Yes. The Digital Link can expose multiple typed links (a linkset) — your marketing page, the official passport, a recycling datasheet — each tagged with a link type.
Sources
Try the live passport above, then start for free and resolve your own.