# transactions.dev · by visibility.cloud > The business-transaction layer of the visibility.cloud family: X12, EDIFACT/EANCOM, and > API-native business documents (purchase orders, ASNs, invoices, receiving advices) compiled to > CBV bizTransaction context on conformant EPCIS 2.0 events. A CLI, a library, and an MCP door — > one core, re-dispatched. Not an EDI network, not a VAN, not a mapping consultancy: the join only. The compile target is core-spec machinery: CBV 2.0 §7.3 business-transaction types (po, desadv, inv, recadv, bol, rma, prodorder), bizTransactionList on every EPCIS event type (§8.5), source/destination party GLNs (§7.4), and the 856 HL hierarchy compiled to AggregationEvents. Superset always paired with conformant: every emitted event validates against the pinned official EPCIS 2.0 JSON schema. X12 element detail is licensed content: this surface links the canonical public reference (stedi.com/edi/x12) and never republishes it; EDIFACT/EANCOM directories are open content, vendored and pinned by digest. ## Pages - [The landing page](https://transactions.dev/): the verbs (parse, emit, validate, ack, translate, join, reconcile, pins), the eight laws, one worked run - [The blog](https://transactions.dev/blog/): one thesis per post, a proof artifact in each - [Amazon's Vendor API is the EDI cycle wearing REST](https://transactions.dev/blog/amazon-vendor-api-is-edi-in-rest/): getPurchaseOrders is an 850 analog, SubmitShipmentConfirmations is an 856 analog, submitInvoices is an 810 analog — Amazon's vendor surface re-skins the EDI transaction cycle as JSON. And its catalog is the industry's largest free ASIN-to-GTIN oracle, which makes it a connector and an identifier bridge at once. - [The 856 is a tree, a manifest, and a promise — anatomy of the ASN](https://transactions.dev/blog/anatomy-of-an-856/): The 856 is three claims at once — a packing tree, a shipment manifest, and a promise against a purchase order. Reading it claim by claim beats reading it segment by segment, and survives partner-guide variation. - [bizTransaction is a core field, not a custom extension](https://transactions.dev/blog/biztransaction-is-a-core-field/): CBV 2.0 ships po, desadv, inv, and recadv as first-class bizTransaction types, and bizTransactionList rides on every EPCIS event type. Carrying a customer's PO numbers needs zero extension namespaces. - [Business Central put item.gtin in the standard API — and forgot the webhook](https://transactions.dev/blog/business-central-gtin-standard-api/): Dynamics 365 Business Central exposes the full document cycle — purchaseOrders, salesShipments, purchaseReceipts, invoices — with a real GTIN field in the standard v2.0 API. Its webhook entity list just doesn't cover half of it, so the honest intake design is webhook-where-possible, poll-where-not, stated per entity. - [Byte 4 is the law — X12 delimiters are self-describing](https://transactions.dev/blog/byte-4-is-the-law/): An X12 interchange declares its own delimiters — element separator at byte 4, component separator at ISA16, terminator after ISA16, repetition separator at ISA11 in 005010. Three delimiter sets, one identical canonical JSON. - [One pivot, many faces — the canonical JSON contract](https://transactions.dev/blog/canonical-json-the-lossless-pivot/): Every segment, element, component, and delimiter choice survives into one canonical JSON form, published as JSON Schema. Friendly shapes, event compiles, and re-emission are pure derivations from that pivot. - [The bill of lading went digital and brought an event model with it](https://transactions.dev/blog/dcsa-ebl-compiles-to-bol/): DCSA's Apache-2.0 OpenAPI standards give ocean freight an open event vocabulary and a canonical eBL that compiles to CBV bol — and UN/CEFACT's multimodal track-and-trace standard explicitly adopted the EPCIS event model. Freight's open rails already lean on the record's native grammar. - [A delivered webhook is evidence, not a receiving advice](https://transactions.dev/blog/delivered-webhook-is-evidence/): Parcel aggregators are the cheapest event feed in the landscape and the poorest in identifiers — tracking number and carrier, no GTIN, no GLN, no SSCC. So a delivered webhook compiles to corroborating evidence on the record, and the pipeline refuses to mint a recadv or a receiving event from it. - [desadv is the ASN — the spec says so in its own words](https://transactions.dev/blog/desadv-is-the-asn/): CBV 2.0 defines desadv with the sentence "Also called an 'Advanced Shipment Notice'" and rules that the value desadv is used regardless of local nomenclature. Every 856, every EANCOM DESADV, and every fulfillment webhook compiles to the same reference type. - [The EANCOM DESADV: a full open-reference walkthrough with the EPCIS join](https://transactions.dev/blog/eancom-desadv-walkthrough/): The EANCOM DESADV is the international ASN — GS1-published and freely documented — so this is the one despatch-advice walkthrough that can be complete on the page, from BGM to the CPS tree to validated AggregationEvents. - [The retail dialect nobody blogs about: EANCOM, GS1 XML, and where volume lives](https://transactions.dev/blog/eancom-is-the-bigger-rail/): GS1's own adoption numbers put EANCOM at roughly 126,000 companies against GS1 XML's 47,000 — so an EDIFACT/EANCOM-first pipeline covers the larger installed base, and GS1 XML becomes a cheap add because both share one GS1 semantic dictionary. - [Ecommerce has orders and shipments — and no invoice, anywhere](https://transactions.dev/blog/ecommerce-has-no-invoice-object/): Shopify's Admin API sources po-analog orders, desadv-grade fulfillments with tracking, and rma-shaped returns. What it cannot source — like every ecommerce platform — is an invoice, and its barcode field is free text. What an ecommerce-sourced record can and cannot claim, stated exactly. - [The directory you can actually vendor: UNTDID, sha256-pinned](https://transactions.dev/blog/edifact-is-open-we-pinned-it/): UNECE publishes the complete UN/EDIFACT directories free of charge, so the transactions.dev reference goes dictionary-deep on EDIFACT and EANCOM — every vendored file pinned by digest, with the license reading journaled and dated. - [The EDIFACT ORDERS message, and what po looks like from Brussels](https://transactions.dev/blog/edifact-orders-the-open-purchase-order/): ORDERS is the open-content purchase order — same commercial semantics as the 850, fully documentable from the pinned UNTDID directories — and its BGM document number is the po reference every later document in the cycle echoes. - [Every wire format is a dialect. The transaction is the noun.](https://transactions.dev/blog/every-wire-format-is-a-dialect/): X12, EDIFACT, and API-native JSON are three surface syntaxes for the same small CBV vocabulary. transactions.dev compiles all three to bizTransaction references that ride on EPCIS 2.0 events — conformant, and a superset only where the document carries more than the standard models. - [From 856 to EPCIS document: every byte accounted for](https://transactions.dev/blog/from-856-to-epcis-document/): A complete ASN compiles to a shipping ObjectEvent plus an AggregationEvent tree — desadv, po, and bol on bizTransactionList, party GLNs on source and destination — and the output validates against the pinned official EPCIS 2.0 schema. The full fixture pair, inline. - [Grammars are data, and data has provenance — GRAMMAR-PINS.json](https://transactions.dev/blog/grammars-are-data-grammar-pins/): Every (transaction set × version) grammar is a self-authored data file with a provenance block, pinned by sha256, changed only by journaled human ruling — and the verify gate refuses a tampered file. - [Shipment, Order, Pack, Item: where the HL mapping stops being derivation](https://transactions.dev/blog/hl-loop-to-aggregation-events/): Nearly every step from the 856's HL loop to an AggregationEvent is a derivation an engineer can check against the file. Exactly one step is a ruling — tare-versus-pack SSCC nesting — and a governed pipeline names it, pins it, and changes it only by journal. - [INVOIC to inv: billing context on the record, disputes left where they belong](https://transactions.dev/blog/invoic-to-inv/): The EDIFACT INVOIC and its 810 twin compile to an inv reference that answers "which billing document covers this movement" — while payment status, disputes, and AP workflow stay deliberately out of the record's scope. - [The ISA segment is 106 characters of load-bearing whitespace](https://transactions.dev/blog/isa-is-106-characters/): X12's interchange header is fixed-width in a delimited format — padding is significant, byte 4 defines the element separator, and most real-world parse failures are envelope failures. The byte ruler, annotated. - [N1 loops are your sourceList: party GLNs land in core fields](https://transactions.dev/blog/n1-loops-are-your-sourcelist/): CBV 2.0 §7.4 defines exactly three source/destination types — owning_party, possessing_party, location — and the 856's GLN-qualified N1 loops map onto them without extensions. Seller to source, buyer to destination, ship-from and ship-to as locations. - [Naming the document itself — GDTI, Digital Link, and the hash fallback](https://transactions.dev/blog/naming-the-document-itself/): CBV 2.0 gives bizTransaction references a complete identifier discipline — GDTI EPC URIs, GS1 Digital Link URIs, and a hash-URI fallback for documents with no issuer-assigned identity. Every reference the pipeline emits is checkable. - [NetSuite is the one system that already has all four documents](https://transactions.dev/blog/netsuite-has-the-full-cycle/): purchaseOrder, itemFulfillment, itemReceipt, invoice — NetSuite's REST record set carries the entire transaction cycle as first-class objects, which makes it the highest-strategic-weight connector in the matrix despite real friction. - [A thousand private PDFs — partner rules as an overlay you own](https://transactions.dev/blog/partner-guides-as-overlays/): Every hub constrains the 856 differently, in implementation guides no corpus can cover. Partner rules are a user-authored JSON overlay on the base grammar — validated like the grammar, pinned like the grammar, never a code fork. - [The network that already uses GS1 party identity: Peppol, EAS 0088, and the invoice rail](https://transactions.dev/blog/peppol-puts-a-gln-on-the-envelope/): Peppol participant addressing supports GLN as a first-class endpoint scheme — ISO 6523 code 0088 — and carries GTINs at line level, making it the richest GS1-identifier rail in the landscape and the way inv coverage arrives without bilateral EDI. - [The document nobody sends: recadv, the 861, and the close of the cycle](https://transactions.dev/blog/recadv-closes-the-loop/): The receiving advice is the least-implemented, most spec-supported document in the transaction cycle. CBV defines recadv beside po, desadv, and inv — and its natural modern source is not an 861 but a WMS goods-receipt object compiled to the same reference. - [RECADV in full: the open receiving advice, and the reconcile it encodes](https://transactions.dev/blog/recadv-in-full/): RECADV is the discrepancy-bearing document of the cycle — received versus accepted versus rejected, per line — and because it is UNTDID-open it can be fully documented, making it the natural output format for a reconcile verdict. - [Reconcile is a verdict, not a report](https://transactions.dev/blog/reconcile-is-a-verdict/): Shipped-versus-seen is only useful as a machine verdict — a typed diff between what the ASN claimed and what the events observed, with an exit code an integrator can wire a go-live gate to. - [SAP still speaks IDoc, and IDoc is our home game](https://transactions.dev/blog/sap-still-speaks-idoc/): S/4HANA's OData catalog and its IDoc traffic are two faces of one transaction cycle. ORDERS05, DELVRY03, and INVOIC02 are EDI semantics in SAP syntax, and the same compile that lands an 856 as events lands them too — beside the strongest GS1 identifier posture of any ERP. - [The only 3PL that hands you GTIN, lot, and a receiving object](https://transactions.dev/blog/shipbob-wro-is-a-receiving-advice/): ShipBob's Warehouse Receiving Order is the rarest document in the API landscape — a first-class receiving object that compiles to recadv — next to product-level gtin, upc, barcodes, and lot support, behind self-serve keys and a full sandbox. The receiving side of the record, without asking anyone's permission. - [If you're leaving Stedi's EDI platform, your Guides still work here](https://transactions.dev/blog/stedi-guide-json-as-a-door/): Stedi's Guide JSON is a proven JSON-Schema-first representation of X12, and transactions.dev accepts it as an input format — a migration bridge stated as interop, not a fork. - [The 214 is not an event record — and that's fine](https://transactions.dev/blog/the-214-is-not-an-event-record/): Carrier status messages carry no EPCs and no performer, so the honest compile is thin — a bol reference plus transport context on the record, never a fabricated ObjectEvent. Both candidate compiles shown, one of them refused. - [The 850 asks, the 810 settles — anatomy of the commercial bookends](https://transactions.dev/blog/the-850-asks-the-810-settles/): BEG03's purchase-order number is the reference every later document echoes, and the three-way match — ordered versus shipped versus billed — is a join across po, desadv, and inv references the event record can hold on one spine. - [The 856 is already an aggregation tree](https://transactions.dev/blog/the-856-is-already-an-aggregation-tree/): The ASN's HL hierarchy — Shipment, Order, Tare, Pack, Item — is structurally an EPCIS aggregation tree. Compiling one into AggregationEvents is a projection, not an interpretation. - [940 and 945 — the warehouse speaks a different dialect of shipping](https://transactions.dev/blog/the-940-945-cycle/): The warehouse-fulfillment pair compiles to picking and shipping ObjectEvents, but which date becomes eventTime and what a 945 means are semantic rulings — so the mapping itself is pinned data, changed only by journaled ruling. - [The ASN said 48 cases. The dock saw 47. Now what?](https://transactions.dev/blog/the-asn-said-48-the-dock-saw-47/): Once both sides speak GTIN and SSCC, reconciling an ASN against captured events is a deterministic set comparison — matched, missing, unexpected, lot-mismatch — and its typed output is precisely the input a receiving advice needs. - [The envelope must agree with itself — control numbers and counts](https://transactions.dev/blog/the-envelope-must-agree-with-itself/): X12's three-level envelope carries redundant self-checks — control-number echoes and segment and group counts. Validating them catches truncation, splicing, and duplication before any grammar work begins. - [Almost nothing on the wire carries a GLN — the identifier gap is the product](https://transactions.dev/blog/the-gtin-gap/): We audited thirty-seven developer surfaces across ecommerce, parcel, freight, WMS, ERP, and POS against one question — what GS1 identity actually rides the API? The census — zero commercial APIs carry SSCC, two carry GLN — is the verified finding that makes an enrichment layer necessary rather than nice-to-have. - [The GTIN is the join key: attaching ASN lines to serial-level events](https://transactions.dev/blog/the-gtin-is-the-join-key/): An ASN line's GTIN matches the GTIN inside sgtin EPCs and lot-level epcClass URIs, so PO-line and ASN-line context attaches to each shipped serial by a deterministic join, not a heuristic match. The anatomy, the normalization traps, and what honestly refuses to join. - [Everyone shipped an MCP server that stops at parse](https://transactions.dev/blog/the-mcp-edi-vacuum/): Every MCP-EDI repo in the field census stops at parse/validate/997. The transactions.dev MCP door re-dispatches the same verbs through the same core, and its output is a conformant event record with trading-partner context. - [emit(parse(x)) === x, byte for byte, or the job says why not](https://transactions.dev/blog/the-round-trip-law/): Every parse ships with an emit-and-diff fidelity report. Byte-exact is the baseline; the two legal normalizations are recorded as canonical-equal with diff positions, never silently passed. - [The standard already named your paperwork: a §7.3 close reading](https://transactions.dev/blog/the-standard-already-named-your-paperwork/): The CBV business-transaction vocabulary was written with EDI document types as first-class values — po, desadv, inv, recadv, bol, prodorder, rma. Joining EDI context onto events is core spec machinery, not a vendor extension, and this post reads the enumeration line by line. - [Stedi went to healthcare. The supply-chain layer is open ground.](https://transactions.dev/blog/the-supply-chain-layer-is-open-ground/): The best EDI reference on the internet belongs to a healthcare clearinghouse now, and our audit of five developer-EDI vendors found no EPCIS product anywhere. The EDI-to-events layer is verifiably unoccupied. - [When there's no official test suite, make the parsers vote](https://transactions.dev/blog/the-three-parser-differential-harness/): X12 publishes no conformance suite and runs no certification program. Ground truth here is what independent open parsers agree on — disagreements go to a journaled adjudication queue, and the agreement rate is a published number. - [Exit 0, exit 1, exit 2 — a CLI contract agents can bet on](https://transactions.dev/blog/the-verb-contract/): Every verb honors one contract — exit 0 ok, exit 1 negative domain verdict, exit 2 usage; payload-only stdout; typed errors on stderr — because a negative verdict is a result, not a failure, and an agent must tell the difference mechanically. - [The why dimension has a field on every event type](https://transactions.dev/blog/the-why-dimension-rides-on-every-event/): CBV 2.0 §8.5 puts bizTransactionList on every EPCIS event type — Object, Aggregation, Transaction, Transformation, Association. Business-document context is an event field, not a side system you reconcile against at night. - [997, 999, CONTRL — three acknowledgments, one question](https://transactions.dev/blog/three-acknowledgments-one-question/): The 997, the 999, and EDIFACT's CONTRL all answer the same layered question — received, syntactically valid, accepted. Generating them is a pure function of a validation result, which is why acknowledging a bad document is a successful operation. - [Order, DespatchAdvice, Invoice, ReceiptAdvice: UBL's four are CBV's four](https://transactions.dev/blog/ubl-already-speaks-cbv/): OASIS UBL 2.3's document library maps one-to-one onto the CBV core four — Order to po, DespatchAdvice to desadv, Invoice to inv, ReceiptAdvice to recadv — with royalty-free schemas, making UBL the cleanest standards bridge in the landscape. - [UNA is a courtesy, not a mystery — the EDIFACT envelope for people who learned X12 first](https://transactions.dev/blog/una-is-a-courtesy/): EDIFACT's service segments — optional UNA advice, UNB/UNZ interchange, UNH/UNT message — do the same envelope work as ISA, GS, and ST with defaulted delimiters and one less nesting level. The differences fit on one page. - [Lot, expiry, and the header — where ASN master data lands in an EPCIS document](https://transactions.dev/blog/where-asn-master-data-lands/): EPCIS 2.0 gives master data two spec-sanctioned homes — ILMD on events at object creation, and epcisHeader → epcisMasterData → vocabularyList at document level. The ASN's attributes ship beside its events in one conformant document. - [The full document cycle exists in exactly one place, and it isn't your storefront](https://transactions.dev/blog/where-the-document-cycle-lives/): Only the top ERPs carry po, desadv, inv, and recadv as API objects. Ecommerce stops at order plus fulfillment; small-business accounting stops at po plus inv with no shipment or receipt objects at all. Intake architecture is decided by where each reference type actually lives — a decision brief with the coverage matrix. - [The record knows a case arrived. It should know who received it.](https://transactions.dev/blog/who-at-the-dock-door/): A receiving event that names its ASN and PO answers the auditor's first question and not the second. EPCIS 2.0's five dimensions carry no performer — so the record carries who, the attested observer, permanently distinct from capturedBy, the warrantor account, beside the same bizTransactionList. - [The reference we won't clone: X12 licensing, stated plainly](https://transactions.dev/blog/x12-licensing-stated-plainly/): X12's copyright regime makes a free segment dictionary legally unbuildable without a negotiated partner deal — Stedi has one; we don't pretend to. Our X12 pages are original prose plus deep links, and the constraint is stated on the page. - [Get access](https://transactions.dev/get-access/): the access list. EMAIL FIRST — the form takes an address and nothing else; a short branching set of optional past-behaviour questions follows, and the final step locks. The list stores, on this origin, exactly what the visitor gives the form — an address, a timestamp, and the answers they choose to give. Nothing request-derived is stored: no referrer, no user-agent, no analytics. The promise, in full: access is provisioned from the list, in order; one email when the seat is ready; nothing else, ever — no newsletter, no sequence; if the work stops, one message says so and the address is deleted. ## Content negotiation The landing page, the blog listing and every post carry a markdown twin on the SAME route: request with an Accept header naming text/markdown and the route answers markdown (Vary: Accept). ## The family - [epcis.dev](https://epcis.dev): the event door — capture, translate, validate, hash; the pinned GS1 artifacts this layer validates its emitted events against - [barcoding.dev](https://barcoding.dev): the barcode resolution layer — GS1, VIN, ISBN, UDI - [visibility.cloud](https://visibility.cloud): the executive side of the same spine GS1 is the standards body; this project is not affiliated with, endorsed by, or certified by GS1. X12 is a registered trademark of X12 Incorporated. No customers are claimed on this surface, and no conformance attestation is implied.