Skip to main content
The GS1 Digital Link standard (v1.4 / ISO/IEC 18975) encodes Application Identifiers in URL paths instead of barcode element strings, so the same identifier can drive a barcode scan, a deep link, and a web resolver. This skill teaches an agent how to compose a correct Digital Link URI from structured input — the inverse of 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.
For the inverse — taking a Digital Link URI and parsing it — see decode-gs1-ai.

Step 1 — Validate inputs

Before composing anything, normalize:
Reject silently-malformed GTINs at this step rather than building a URI that fails resolution downstream.

Step 2 — Compose the primary AI

GTIN is the common case:
For other primary identifiers:

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):
Each of 22, 10 and 21 is optional but their order is mandatory, and 235 stands alone. Expiry (17) is not a qualifier: it is a data attribute and goes in the query string (Step 5). Closient’s resolver answers any other path with 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:
In practice, lot/serial characters that show up in real life and need encoding: space (%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>:
Useful examples: 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:
The IANA-registered link-type vocabulary is the source of truth (see 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 (= 300901 YYMMDD, AI 17 → query string)
  • Serial: SN9999
  • Best-before: 2027-12-31 (= 271231 YYMMDD, AI 15 → query string)
  • Link type: PIP (product information page)
  • Host: https://id.closient.com
Canonical URL:
Compose the path segments in the order shown, percent-encode only the value slots, and convert ISO dates to 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 answers 400 with "rule": "qualifier_out_of_order".
  • A date in the path. /01/<gtin>/17/<expiry> puts a data attribute where only qualifiers go; the resolver answers 400 with "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) versus linkType=pip (bare token, ambiguous) — always emit the namespaced form. Closient’s test suite normalizes both, but partner resolvers may not.
  • Hardcoding id.gs1.org for 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/Q1 becomes LOT-2024%2FQ1.

What Closient does with the URL

Once emitted, the URL can be:
  1. Encoded as a QR code — the Print Digital Link MCP 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.
  2. Hosted by Closient’s resolver — if the URL points at id.closient.com or a *.gtin.one brand domain, Closient serves the destination (hosted page, redirect, JSON linkset, branded video, etc.) based on linkType and the brand’s resolver configuration.
  3. Verified for serialized items — call GET /resolver/api/v1/verify/01/{gtin}/21/{serial} to confirm an item is authentic + active.
  • 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}/barcode or /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.