01 = GTIN, 10 = batch/lot, 21 =
serial, 00 = SSCC, 8003 = GRAI, and so on. This skill teaches an
agent how to take an element string off a barcode scan and unpack it
into structured data the rest of the system can query.
When to use
- A scanner / OCR / EDI feed produced a raw element string and you need structured fields (GTIN, lot, expiry, serial, SSCC, GRAI, GIAI).
- The agent received a GS1 Digital Link (
https://id.gs1.org/01/...) and needs to extract the AIs the path encodes. - A user pasted a GS1-128 barcode payload and asked “what does this mean?”.
build-gs1-digital-link.
The two encodings
Both encode the same data; bracketed form just makes the AI boundaries
visible. The unbracketed form uses FNC1 (
\x1d, also written
<GS> or ASCII 29) to mark the end of a variable-length value.
Step 1 — Detect the variant
(01)09506000134352(17)270101(10)ABC123→ bracketed010950600013435217270101\x1d10ABC123→ unbracketedhttps://id.gs1.org/01/09506000134352/10/ABC123→ Digital Link path
Step 2 — Know the fixed-length AIs
These AIs have a predefined length; the parser jumps that many characters and continues. No separator needed.Step 3 — Know the variable-length AIs
These accept up to a maximum number of characters and must be terminated by FNC1 (\x1d) when followed by another AI. If the
variable-length value is the last element in the string, no separator
is needed.
Step 4 — Parse, bracketed → structured
Step 5 — Parse, unbracketed → structured
This is where most agents trip up. The algorithm:- Read 2-4 leading digits and try them against the AI table. Try the
longest prefix that matches a known AI (so
8003is preferred over80+03). - If the AI is fixed-length, slice
lengthcharacters as the value. - If it’s variable-length, slice up to the next
\x1d(or end of string, if there’s no separator). - Repeat from the position after the value.
- Normalize bracketed input by stripping brackets and re-emitting an unbracketed string with FNC1 separators inserted, then run the unbracketed algorithm. One code path is easier to maintain than two.
- Validate the Mod-10 check digit on AI
01(GTIN). The Closientapps.core.types.GTIN.from_raw()does this — reuse if you’re in Python. - Accept the literal characters
^or~as FNC1 sentinels (some scanners emit those instead of\x1d).
Step 6 — Parse, GS1 Digital Link → structured
Digital Link path is path-based AI encoding:/{AI}/{value}/{AI}/{value}/…
apps.products.gs1_digital_link.parse_gs1_digital_link)
returns a typed dataclass with gtin, lot_number, expiry_date, and
serial_number already broken out — call that directly if you’re
running inside the monorepo.
Step 7 — Validate
Beyond the AI table, two checks matter:- GTIN check digit (AI 01). Mod-10; the last digit is computed from the first 13. Reject silently-malformed scans rather than continuing with a corrupt GTIN.
- Date plausibility (AI 17 in particular).
YYMMDDwithMMin 01-12,DDin 00-31 (where00is sentinel for “last day of month”). The Closient scanner emits structuredfreshness_metafor AI 17 — seeapps.scanner.services.gs1_dates.
Example end-to-end
Input (off a meat-case label):01→ fixed 14 →09506000134352(GTIN).17→ fixed 6 →300901(expiry2030-09-01).10→ variable, up to FNC1 →45454GH(lot).21→ variable, no separator left →SN0001(serial).
Common mistakes
- Forgetting FNC1 after a variable-length AI before another AI
starts — produces a corrupted parse where
10ABC12321SN0001is read as a 20-character lot ending in21SN0001. - Not zero-padding GTIN-8 or GTIN-12 to GTIN-14 before lookups — Closient stores GTINs as GTIN-14 internally; pad with leading zeros.
- Treating
(01)from a Digital Link query string as the SSCC AI 00 because the parser was eager about 2-digit prefixes; always try the longest AI prefix first. - Trusting
YYas 4-digit year. GS1 saysYYin 00-49 → 20YY, 50-99 → 19YY (sliding window). Don’t hardcode the century.
Related skills
build-gs1-digital-link— inverse: given GTIN + AIs, emit a valid Digital Link URI.resolve-gtin— fetch product detail once you have the GTIN.check-product-availability— find local stock for a GTIN.capture-epcis-event— once you have GTIN + lot + serial, record a supply-chain event.closient-api-quickstart— authenticate before calling any of the above.
Authoritative references
- GS1 General Specifications (v25 or later) — section 3 (AIs) and section 7 (data carriers).
- GS1 Digital Link Standard 1.4.
- ISO/IEC 15418 — GS1 Application Identifiers.
- Closient internal:
backend/apps/products/gs1_digital_link.py(parser) andbackend/apps/core/types/_gs1.py(typed value objects).