The 214 is not an event record — and that's fine

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.

One thesis: *the X12 214's carrier statuses are evidence about transport, not custody events — they carry no item-grain identifiers and no performer — so the correct compile is thin: a bol business-transaction reference plus corroborating context on transport-adjacent events, and never a fabricated ObjectEvent.*

This is a post about a compile we refuse to do. If you are evaluating this layer for your product, that refusal is the most useful thing on this page, because a pipeline that manufactures events from documents that never observed anything is a pipeline whose output you cannot defend later.

What a 214 actually asserts

The 214 — Transportation Carrier Shipment Status Message — is the carrier telling the shipper or consignee where a shipment stands: picked up, arrived at a terminal, out for delivery, delivered, exception. Structurally it hangs reference numbers off the shipment identification (the carrier's PRO, the shipper's ID, the bill of lading), then delivers status assertions with a code, a date-time, and a coarse geography. Segment-level detail is licensed X12 content, so per our standing rule it stays where it is legal and canonical: Stedi's 214 reference documents the structure; everything on this page is original prose over a self-authored synthetic fragment.

B10*4950532888*SHP20260728*SCAC~
L11*BM8842001*BM~
LX*1~
AT7*X6*NS***20260728*1433*ET~
MS1*CHICAGO*IL*US~

Read as claims: carrier SCAC, tracking PRO 4950532888, against shipment SHP20260728 and bill of lading BM8842001, reports status "arrived at delivery location" at 2026-07-28 14:33 ET, near Chicago. That is a real, useful assertion. Now look at what it does not contain.

The missing dimensions

An EPCIS event answers what, when, where, why — and the capture interface adds who observed it. Hold the 214 against that:

  • No what-grain. There are no SSCCs, no GTINs, no serials. The 214 talks about "the shipment" as an opaque unit named by reference numbers. You cannot populate an epcList or a quantityList from it without inventing contents it never asserted.
  • No performer. Nobody scanned anything. There is no attested observer — no who — and who is never faked from a document. (Neither is it ever collapsed into capturedBy, which is the warrantor account that stamps a capture job — a different fact entirely.)
  • Org-grain parties only. The parties are companies and a SCAC — the grain of a document header, not the grain of a dock door.

A compile that emits an ObjectEvent from this input is asserting an observation that never happened, performed by no one, about items it cannot name. Every downstream consumer — a reconcile job, a trace query, a counterparty auditor — inherits that fabrication.

Two candidate compiles, one refused

The wrong one, flagged so you recognize it in other people's pipelines:

// REFUSED — fabricates an observation
{ "type": "ObjectEvent",
  "action": "OBSERVE",
  "bizStep": "arriving",
  "epcList": [],
  "readPoint": { "id": "??" } }

An empty epcList because the document names no items; a guessed readPoint because "Chicago, IL" is not a read point; no observer because there was none. The event validates against nothing worth validating against.

The right one — thin by design:

// The compile: the document becomes a reference, not an event
{ "type": "bol",
  "bizTransaction": "urn:epc:id:gdti:0M8842001" }

The bol type is core CBV 2.0 §7.3 vocabulary, sitting beside po and desadva core field, not a custom extension. The reference lands on the events that do exist for this shipment: the shipping ObjectEvent and the AggregationEvent tree that the ASN compiled to, where item-grain identifiers and real capture provenance already live. The 214's status assertions ride as corroborating transport context against those events — evidence attached to the record, dated and attributed to the carrier document that made the claim.

Evidence-for versus record-of

That distinction is the design law, stated plainly: a document that reports on the world is evidence for the record; only an observation is the record. The ASN is a promise, the events are observations, the reconcile between them is a typed verdict — and the 214 is a third thing, a counterparty's narrative about the gap between shipping and receiving. The record stays defensible precisely because each of these keeps its own epistemic weight. When the exception views on visibility.cloud show a shipment stalled at a terminal, the underlying answer is honest about its source: the carrier said so, on this date, in this document — not we observed it.

Where real transport events come from

None of this means transport is invisible to the event record. Where the carrier's own systems emit genuine equipment events — DCSA-standard track and trace on the ocean side is the clean example, with defined event types, equipment identifiers, and timestamps published as an API standard — those compile as what they are: transport events from the party that performed them, with their provenance intact (the eBL post walks that lane). Parcel-carrier webhooks sit under the same law: rich enough to be excellent evidence, item-grain only when they genuinely carry the identifier, never laundered into observations. The rule is uniform, and it is the same rule that keeps the whole layer's output superset where a document carries more than the standard models and conformant always.

The engine's join verb enforces this ruling mechanically: a 214 in produces references and context out, and there is no flag to make it manufacture an ObjectEvent, because a flag like that is how a record stops being one. If your pipeline needs a carrier's word attached to a defensible event spine — rather than dressed up as the spine itself — that is exactly the compile this layer ships. If 214s are on your wire today, say so at the door — the onboarding flow asks which rails moved your freight last quarter and which of them reported on it.

Get access.

The engine runs from npx today with no key. The hosted layer opens from the access list.