The blog · 2026-07-31
The EANCOM DESADV: a full open-reference walkthrough with the EPCIS join
Written for ED-1 — the supply-chain ISV / traceability-vendor engineering org — the integration engineer who learned the 856 first and now faces the international lane.
One thesis: the EANCOM DESADV is the international ASN — GS1-published, freely documented, with a CPS hierarchy doing the 856's HL job — and because its content is open, this walkthrough can be complete on the page, all the way down to the compile into AggregationEvents.
The X12 856's anatomy has to stop at original prose and link out for segment detail, because X12 element content is licensed. The DESADV has no such wall: GS1 publishes the full EANCOM 2002 DESADV specification as a free PDF (gs1.org, EANCOM S4 DESADV), and the underlying EDIFACT directories are vendored here and pinned by digest. So this page does what no 856 page legally can: the whole document, then the whole compile.
The shape of a DESADV
EANCOM is GS1's implementation subset of UN/EDIFACT — the retail dialect where GTINs, GLNs, and SSCCs are native citizens rather than qualifier tricks. The envelope mechanics ride the standard EDIFACT service segments — UNA's defaults and the UNB/UNZ interchange are a page of their own — and inside them a despatch advice reads in four movements: the header (BGM identifies the document, DTM dates it, RFF ties it to the order), the parties (NAD segments carrying GLNs), the packaging hierarchy (CPS/PAC/GIN — the tree), and the lines (LIN/QTY inside the tree's leaves). A self-authored, license-clean example, one pallet with cases of one trade item:
UNH+1+DESADV:D:96A:UN:EAN005'
BGM+351+DES8560001+9' document: despatch advice DES8560001
DTM+137:20260728:102' message date
DTM+11:20260728:102' despatch date
RFF+ON:4500123' the purchase order it answers
NAD+SU+0614141000005::9' supplier, by GLN (code list 9 = GS1)
NAD+BY+0345678000007::9' buyer, by GLN
NAD+DP+0345678000168::9' delivery party, by GLN
CPS+1' consignment level
CPS+2+1' pallet, parent = CPS 1
PAC+1++201' one pallet
GIN+BJ+306141411234567891' its SSCC (qualifier BJ)
CPS+3+2' case level, parent = CPS 2
PAC+48++CT' forty-eight cartons
LIN+1++00614141123452:SRV' the trade item, by GTIN (SRV = GS1)
QTY+12:48' despatch quantity: 48
UNT+17+1'
CPS versus HL: same tree, different pointer discipline
The 856 builds its packing tree with HL segments — each carries its own id, its parent's id, and a level code, a runtime parent-pointer tree. The DESADV's CPS segment does the same job with less ceremony: each CPS carries a sequence number and the sequence number of its parent, and the levels are whatever the tree says they are — consignment, pallet, case above; deeper when reality is deeper. Everything between one CPS and the next belongs to that node: its PAC package counts, its GIN identifiers, its LIN/QTY lines.
The isomorphism that matters is not CPS-to-HL; it is both-to-aggregation. A packing tree whose nodes carry SSCCs and whose leaves carry GTINs and quantities is the EPCIS aggregation model wearing wire-format clothes — which is why the compile below invents no semantics.
The compile, node by node
The join verb walks the CPS tree and emits, for this document:
One AggregationEvent per SSCC-bearing node. The pallet's GIN+BJ becomes parentID; its child nodes' contents become children — here, a lot-grain childQuantityList because the cases carry GTIN and count rather than serials:
{ "type": "AggregationEvent",
"action": "ADD",
"parentID": "urn:epc:id:sscc:0614141.3123456789",
"childQuantityList": [
{ "epcClass": "urn:epc:idpat:sgtin:0614141.012345.*",
"quantity": 48, "uom": "EA" } ],
"bizStep": "packing",
"bizTransactionList": [
{ "type": "desadv",
"bizTransaction": "urn:epc:id:gdti:0614141.00001.DES8560001" },
{ "type": "po",
"bizTransaction": "urn:epc:id:gdti:0345678.00010.4500123" } ] }
One shipping ObjectEvent for the consignment — bizStep shipping, disposition in_transit, the same two references on bizTransactionList, eventTime from DTM+11. The despatch date is the despatch assertion; that mapping is a ruling recorded in the pinned join map, not an improvisation.
Parties land as parties. The NAD GLNs compile to CBV §7.4 source/destination — supplier GLN to source owning_party, buyer GLN to destination owning_party, the delivery-point GLN to destination location, as party and location EPC URIs. This is the same three-type vocabulary the 856's N1 loops compile to; EDIFACT just hands over the GLNs without a qualifier argument, because in EANCOM the GS1 code list is the default, not the exception. (The identifiers themselves are the family's other layer: SSCC and GLN anatomy live at barcoding.dev.)
Every emitted event validates against the pinned official EPCIS 2.0 JSON schema before it leaves the tool — superset where the document carries more than the standard models, and conformant always. The document's desadv identity is exactly the reference CBV 2.0 §7.3 defines — "Also called an 'Advanced Shipment Notice,' but the value desadv is always used regardless of local nomenclature" — so an 856, a DESADV, and a fulfillment webhook all land as the same reference type, and one reconcile query covers all three lanes.
Why this walkthrough earns its length
EANCOM is not the legacy lane it is assumed to be — GS1's own adoption numbers put it far ahead of GS1 XML, which makes the DESADV the highest- volume despatch advice on earth that can also be fully documented in public. If your product needs to say, in an RFP, exactly how an inbound despatch advice becomes conformant event context, this page is the answer you can hand over: open spec, pinned directories, worked message, validated output — every byte accounted for, and every claim checkable against a digest. And when an inbound DESADV of your own needs to land as events, bring the lane to the door — the onboarding flow asks which document sets are on your wire and which versions stamp them.
882 words. The access flow is at /get-access/; the family's event door is epcis.dev.