decode-gs1-ai.
When to use
- A consumer-facing surface needs a QR code or URL for a product: packaging, shelf-talker, email receipt, branded resolver page.
- An ERP / PIM / TMS system has structured product+lot+serial data and needs to emit GS1 Digital Link strings to label printers or partner feeds.
- An agent received a raw GTIN and wants to construct the canonical Closient resolver URL to hand back to a user.
decode-gs1-ai.
Anatomy of a Digital Link
Step 1 — Validate inputs
Before composing anything, normalize:Step 2 — Compose the primary AI
GTIN is the common case:Step 3 — Append qualifier AIs (canonical order)
The GS1 Barcode Syntax Dictionary fixes which AIs may follow a GTIN in the path, and in what order (dlpkey=22,10,21|235):
400 Bad Request and a
JSON body naming the broken rule (non_qualifier_ai_in_path,
qualifier_out_of_order, incompatible_qualifiers,
duplicate_qualifier). It never reorders and resolves anyway, so emit
the canonical form. (A brand’s custom domain with a hosted dead-end page
sends a bad GTIN path to that page instead of the JSON body.)
Step 4 — Encode special characters in values
GS1 Digital Link values are URL path segments, so anything outside the unreserved set (A-Z a-z 0-9 - . _ ~) must be percent-encoded:
%20), + (%2B), & (%26), / (%2F), ?
(%3F), # (%23). Don’t pre-escape with \\ — that’s a different
encoding.
Step 5 — Attach data-attribute AIs (query string)
AIs that aren’t qualifiers go in the query string as<ai>=<value>:
Per the spec, query-string AIs should follow data-attribute conventions
— not used as primary IDs, never the basis for resolution decisions.
Step 6 — (Optional) attach linkType to drive resolution intent
A Digital Link URL can point at one identifier but many
destinations: product info page, recall notice, instructions, video,
loyalty enrollment. The linkType query string parameter tells the
resolver which destination the agent (or end user) wants:
https://www.gs1.org/voc/). Closient’s resolver maps these to
hosted-page destinations and the Resolver model’s
destination_type column — the resolver API
reference lists every link type Closient recognizes.
If you don’t set linkType, the resolver returns its default
destination — typically the brand’s PIP or the public Closient
product page.
Step 7 — Pick the host
Any host that implements the GS1 DL resolver protocol will serve the
same identifier. The Closient hosted pages live under
id.closient.com and *.gtin.one; the Brand.preferred_resolver_host
column stores which one to emit for that brand’s products.
Full example
Inputs:- GTIN-14:
09506000134352 - Lot:
ABC123 - Expiry:
2030-09-01(=300901YYMMDD, AI 17 → query string) - Serial:
SN9999 - Best-before:
2027-12-31(=271231YYMMDD, AI 15 → query string) - Link type: PIP (product information page)
- Host:
https://id.closient.com
YYMMDD before emitting ?17=.
For a QR Code, any query string (and any lowercase letter) forces byte
mode, which makes the symbol roughly a third larger. A code that only
needs to identify the item can drop the query string and print the path
uppercase in the scheme and host (HTTPS://ID.CLOSIENT.COM/01/...) to
stay in the compact alphanumeric mode.
Common mistakes
- Wrong qualifier order.
/01/<gtin>/21/<serial>/10/<lot>breaks the path grammar; the resolver answers400with"rule": "qualifier_out_of_order". - A date in the path.
/01/<gtin>/17/<expiry>puts a data attribute where only qualifiers go; the resolver answers400with"rule": "non_qualifier_ai_in_path". Use?17=<expiry>. - Leaving out the qualifier on a serialized item. A GTIN+serial URL
(
/01/<gtin>/21/<serial>) resolves to that specific item; a GTIN-only URL (/01/<gtin>) resolves to the class. Emit the qualifier when you have the data — class-level resolution can’t drive item-level experiences like recalls. - Encoding the AI itself. AI digits are path literals and must NOT be percent-encoded — only the value slot is.
- Wrong link-type CURIE.
linkType=gs1:pip(correct CURIE) versuslinkType=pip(bare token, ambiguous) — always emit the namespaced form. Closient’s test suite normalizes both, but partner resolvers may not. - Hardcoding
id.gs1.orgfor brand-owned products. Closient brands have their own preferred resolver host; use that so the brand owns the surface and gets the analytics. - Not URL-encoding non-ASCII or reserved characters in lot/serial.
A lot of
LOT-2024/Q1becomesLOT-2024%2FQ1.
What Closient does with the URL
Once emitted, the URL can be:- Encoded as a QR code — the
Print Digital LinkMCP tool takes any Digital Link URL and produces a print-ready QR. For a product, lot or serial you have stored,GET /products/api/v1/products/{gtin}/barcode(and.../lots/{lot_id}/barcode,.../serials/{serial_id}/barcode) renders its barcode from the record. - Hosted by Closient’s resolver — if the URL points at
id.closient.comor a*.gtin.onebrand domain, Closient serves the destination (hosted page, redirect, JSON linkset, branded video, etc.) based onlinkTypeand the brand’s resolver configuration. - Verified for serialized items — call
GET /resolver/api/v1/verify/01/{gtin}/21/{serial}to confirm an item is authentic + active.
Related skills
decode-gs1-ai— inverse: take a Digital Link URL apart into AIs.resolve-gtin— once you have the URL, fetch product detail.capture-epcis-event— emit a supply-chain event keyed on the same GTIN + serial.closient-api-quickstart— authenticate before calling/products/api/v1/products/{gtin}/barcodeor/resolver/api/v1/verify/....
Authoritative references
- GS1 Digital Link Standard 1.4 — sections 4 (URI syntax), 5 (canonicalization), 6 (link types).
- ISO/IEC 18975:2024 — formalization of GS1 Digital Link.
- GS1 link-type vocabulary:
https://www.gs1.org/voc/. - Closient API reference:
https://docs.closient.com/api-reference/overview.