The QR code on a Digital Product Passport looks like any other black-and-white square. It is not. It has to carry a GS1 Digital Link, survive being printed small on a curved, scuffable product, and reliably resolve to the passport for the product's whole life. Here is what actually matters when you generate one — the parts most "DPP QR code" articles skip.
It is a GS1 Digital Link, not a plain URL
A DPP QR encodes a structured GS1 URL, not example.com/product/123:
https://id.gs1.org/01/04019999999902/21/DEMO-BAT-01
01 is the GTIN, 21 the serial. Any camera opens it; a resolver returns the right representation per caller (see The GS1 Digital Link Resolver, Explained). Point the QR at your resolver and the GTIN/serial stay stable forever.
Error correction level: pick Q or H for products
QR codes have four error-correction levels — the higher, the more of the symbol can be damaged and still scan:
| Level | Recovery | Use for a DPP? |
|---|---|---|
| L | ~7 % | No — too fragile on physical products |
| M | ~15 % | Web/screen only |
| Q | ~25 % | Yes — labels, packaging |
| H | ~30 % | Yes — small, curved or harsh-wear products |
A passport label may get scratched, bent around a battery cell, or partially worn. Use Q or H so it still scans after a year in the field. Higher correction means a denser symbol, so balance against print size.
Quiet zone and minimum print size
- Quiet zone: keep a clear margin of at least 4 modules around the symbol. No logos, no text in it.
- Minimum size: rule of thumb, the module size should be ≥ 0.33 mm for close-range phone scans; bigger if scanned from a distance. On a typical 300 DPI label printer that is roughly a 2 × 2 cm symbol for a serial-bearing Digital Link — verify with your worst-case scanner and lighting.
Dynamic, not static — or it is not compliant
A static QR bakes the data into the symbol. A DPP's data changes over the product's lifetime (carbon footprint re-measured, recycled-content target reached, repair info updated). If the data is baked in, you cannot update it without reprinting every label — and an out-of-date passport is non-compliant.
So a DPP QR must be dynamic: it carries a stable resolver URL (immutable GTIN/serial), and the data behind it is updated via API. Print once, update forever.
Generate a print-ready DPP QR (code)
Creating a passport returns the QR in four formats — no separate QR step:
import { QR3 } from "@qr3/sdk";
const client = new QR3({ apiKey: process.env.QR3_API_KEY! });
const passport = await client.dpp.create({
gtin: "04019999999902",
serial: "SN-00012345",
product_name: "PowerCell 5 kWh LFP",
manufacturer: "ExampleTech GmbH",
origin_country: "DE",
category: "battery",
battery_data: { capacity_kwh: 5, carbon_footprint_kg: 62, recycled_content_pct: 12, recyclability_pct: 95, manufacturer_warranty_years: 8 },
});
console.log(passport.qr.svg); // vector — scales to any label size, no pixelation
console.log(passport.qr.pdf); // CMYK PDF for print
// qr.png for the web, qr.eps for professional label printers
Use SVG or EPS for labels (vector survives any scaling); PNG for the web. The QR already encodes the GS1 Digital Link to the passport.
Tiny products: GS1 Data Matrix
When there is no room for a QR (small electronics, jewellery), a GS1 Data Matrix carries the same Digital Link in less space and is supported by the same standards. Same URL, smaller symbol.
FAQ
Can I add my logo in the middle? Yes, within the error-correction budget — at level Q/H a small centered logo is recoverable. Keep the quiet zone clear and test-scan.
Does the QR contain the product data itself? No — it contains the GS1 Digital Link. The data lives behind the resolver and stays updatable. That is what makes the passport durable.
SVG vs PNG for labels? SVG/EPS (vector) for anything printed — it scales cleanly to any size. PNG only for fixed-size web use.
Sources
Start for free and generate a print-ready DPP QR: app.qr3.app/sign-up