In EPCIS, the Who is a company. Every event has a performer.
Post the event.
The door does the rest.
The door is epcis.dev: an EPCIS 2.0 capture gateway.
EPCIS is GS1's standard for supply-chain events — what, when, where, why, how — and its Who is a company: the GLN of the legal entity involved.
id.org.ai — Agent. Human. Thing. — extends that Who to the actual performer, the human, agent, or robot that took the action, and the event still validates against GS1's own pinned schema.
npx epcis.dev is the one-line local door — translate, validate, hash, capture, MCP, the same engine this origin hosts at POST /translate, /validate and /hash.
We answer in writing. We take at most five conversations a month, only when you ask for one, and only after you already have the written read.
Proof, not adjectives. The gateway's conformance tests pass against GS1's normative artefacts — verified by this build: 716/716 tests green, 2026-07-31. Try the doors from the terminal you are reading this in — no key, no account: POST /translate, /validate, /hash. The dated ledger is What ships today.
- sim · authored scenarios of the event model
scenario 01 · cold chain, watched across an ocean
- commissioning · sscc:…5501 · 2–8°C · who: human · line lead · capturedBy: mfr acct
- sensorReport ×3 · temp in_range · who: thing · logger (id.org.ai) · capturedBy: carrier acct
- receiving · sensor: in_range · who: human · dock 4 · capturedBy: distributor acct
Sealed, watched, received — and at every hop the record carries who, the attested observer, distinct from capturedBy, the warrantor account.
sim · authored scenarios · event model · not live data · no customers
who resolves via id.org.ai · Agent. Human. Thing.
“The rest,” row by row.
Every capture goes through the same six moves, enforced on every event; the laws behind them are further down this page.
- 01Validates.
Every event, against GS1's own pinned official schema — digests on the pins page.
- 02Refuses in the standard's own exception types.
Non-conformance comes back as RFC 7807 problem+json, never a vendor error string.
- 03Stamps recordTime, capturedBy and the attestation grade.
Caller-supplied values in those fields are stripped. who — the observer — stays the caller's assertion, graded, never collapsed into capturedBy.
- 04Hashes by CBV 2.0 §8.9.
The standard's own event identity, checked against pinned reference vectors.
- 05Appends, only.
No service identity holds UPDATE or DELETE. Corrections are declared events, never edits.
- 06One door for people and for agents.
Same interface, same key, over MCP.
The interface, and what the door does to what you send.
You POST an EPCIS 2.0 document. The gateway validates it against GS1's official JSON schema, strips the fields it is going to stamp, stamps them, computes the standard event hash, and appends. A capture that does not validate is refused as problem+json carrying the standard's own exception types.
npx epcis.dev capture \
golden-corpus/valid-standard/object-event-shipping.json
accepted captureID={captureID} events=1
eventID urn:uuid:6f9b62a2-5c1e-4c39-9e2b-1a2b3c4d5e6f
The whole run is on Run it yourself. The write half opens with a capture key; the calculators — /translate, /validate, /hash — answer on this origin without one.
Eight laws, not eight features.
The gateway underneath epcis.dev is written, and these are the parts that cannot be renegotiated later. The first two carry the Who past company grain, at the door — the part the standard leaves to the GLN. The rest are conformance you can check without asking us.
-
01
Stamped by the gateway, not the sender.
recordTime, spine:capturedBy and spine:attestationGrade are applied at the door. Whatever you sent in those fields is stripped. The scriber is not the part being scribed.
-
02
Two grains, never collapsed.
who is the attested observer — a human, an agent, or an embodied agent — asserted by the caller and graded by the door. capturedBy is the warrantor: the account whose key opened the door, stamped by the gateway. Never the same thing, never merged; one is stamped, the other is graded. Party and org grain are derived at read time from grant chains, never stamped on an event — the record survives your reorg and your revocations.
-
03
Conforms to EPCIS 2.0 and CBV 2.0.
Implemented against GS1's official OpenAPI description, pinned by digest and re-checked in CI. The spine speaks What/Who/When/Where/Why/How natively; EPCIS 2.0 is its projection, and the projection always validates.
-
04
Validated on every capture.
Each event is machine-checked against the official GS1 EPCIS 2.0 JSON schema before it is accepted. A capture that does not validate is refused as RFC 7807 problem+json, carrying the standard's own exception types — not a vendor error string. The digests are on the pins page.
-
05
Identified by the standard's own hash.
The standardized EPCIS event hash from CBV 2.0 §8.9, with GS1 Digital Link normalisation, checked against the pinned reference vectors — so the same event captured twice is the same event, and a changed event is a different one.
-
06
Append-only, by construction.
No service identity anywhere holds an UPDATE or DELETE grant; the write path has exactly one writer. You can add an event. You cannot un-write one. Corrections are declared events, never edits.
-
07
Minimally scoped on read.
You see your own scope. What is outside it is absent, not greyed out and not redacted — there is no shape left behind to argue about.
-
08
Ten years of vendor XML, translated.
EPCIS 1.1, 1.2 and 2.0 XML in; EPCIS 2.0 JSON-LD out; a round-trip fidelity report per job, so the translation is reviewable rather than trusted. The translation door is a page of its own.
Everyone in this market has built a network that is authoritative because you joined it. The spine makes a record that is verifiable whether or not you joined anything — and it carries, in the record itself, an attested answer to who observed the event, including when the observer was an agent.
Every law above is enforced in code and verified by the spine's own test run this build. The executive lens on the same spine is visibility.cloud.
Two grains. One stamped, one graded.
Every event carries two attributions, and the door owns a different half of each. capturedBy is the warrantor — the account whose key opened the door — and the gateway STAMPS it, together with recordTime and the attestation grade: whatever the caller sent in those three fields is stripped and replaced. who is the attested observer — a human, an agent, or an embodied agent — and it is the caller's assertion, which the door GRADES: an asserted observer reaches only the grade claimed until identity attestation lands. The standard's own Who — the company, a GLN — stays exactly where EPCIS puts it: party and org grain are derived from grant chains at read time, never stamped in. who is the grain beneath it — the performer — named in id.org.ai terms: Agent. Human. Thing.
// stamped: the key that posted
"spine:capturedBy": "acct:acme-3pl",
// asserted by the caller, graded
"who": "did:agent:router-7",
// the door's grade of that assertion
"spine:attestationGrade": "claimed",
// stamped: the door clock
"recordTime": "2026-07-29T14:20:07Z"
The stamped half is never the caller's; the asserted half is never silently upgraded — one is stamped, the other is graded, and the two never collapse. The envelope carries both grains, and the resolve tool refuses rather than fakes — a typed tool error, never a fabricated identity.
One door for people and for agents.
An agent gets the same door as a person: the same interface, the same key, over MCP — JSON-RPC re-dispatched through the same worker fetch. A door, not a second path. Two tools refuse loudly instead of faking, because an honest tool error is a feature.
| tool | what it does | readOnlyHint | state |
|---|---|---|---|
| capture | POST an EPCIS document through the gateway laws: strip → validate → project-check → stamp → append | no | shipped |
| query | SimpleEventQuery over whatever was captured | yes | shipped |
| get_event | one event, by its CBV §8.9 hash identity | yes | shipped |
| trace_epc | the full event chain for one EPC | yes | shipped |
| translate | EPCIS 1.1 / 1.2 / 2.0 XML → 2.0 JSON-LD, with a per-job fidelity report | yes | shipped |
| resolve | refuses honestly: returns a typed tool error, never a fabricated resolution — identity resolution lives at id.org.ai (Agent. Human. Thing.) | — | honest refusal |
| subscribe | refuses honestly: a typed tool error, never a silent downgrade to a one-shot pull | — | honest refusal |
The machine face of this site is first-class: /llms.txt for summarisers, /icp.json and /agent-classes.json as the derivation contract an arriving agent reads — built from the same frozen enumeration a runtime selector must use, so the published contract and the selection cannot drift. The door is POST /mcp on this origin, and npx epcis.dev mcp runs the same server on your bench.
Four ways people arrive at this door.
Each of these is a different evaluation, and the site does not pretend they are one audience. None of them requires a conversation; each ends at an artifact you can check.
-
ISV
The build is cheap. The conformance tax is forever.
Every engineer spent tracking schema and CBV revisions is a feature not shipped. Run your own decade of 1.1/1.2 XML through the translation engine — POST /translate on this origin, no key, no account. The round-trip fidelity report is the evaluation. For the RFP checkbox, not “we support EPCIS” but evidence an auditor can recompute: the pinned digests and the advisory suite.
-
SI
“And where does the data go?” Stop losing the account to whoever answers it.
Every reader deployment ends with that question, and today a software vendor answers it and the account follows. This is the layer you build with and put in a bid — open source, a reader-feed → validated-event path you can run against a deployment you already did. There is no partner programme and nothing to resell; the record layer is the product.
-
PLT
You were handed “make traceability work” and a date. Not a year to build a conformant repository.
You will disqualify on a broken command faster than on a bad price, so the message is the working command and the defensibility kit for the architecture review: pinned EPCIS 2.0.1 with sha256 provenance, OpenEPCIS-gated hashes, RFC 7807 bodies, the append-only law, and an open-source escape hatch (the repository is the escape hatch). The security reviewer's questionnaire, answered before it is sent.
-
AGT
Equip your agent to capture, verify, and transact under a mandate you wrote.
The agent classes are matched, never persuaded: typed verbs, complete descriptions, deterministic answers, readOnlyHint set where true. The free zone is structural — translate, validate, hash, and capture at $0/event (intent, until published terms bind it) — and the gate lands on durable state, authority and licensed data, never on compute. Start at the agent door.
$0 per event. It stays that way.
Not a trial. Not a tier. Not a meter you watch. The allowance is abuse governance, never a bill.
Recording an event will never cost money. That is a policy, not an introductory price, and it holds because the cost structure underneath capture is object storage and a catalogue, which is cheap enough to carry permanently. It will never appear in the interface as a counter.
Revenue attaches to answers, at the human door on the executive side: traces, custody evidence, exception review, partner grants, seats, retention. The capture door stays free, because an event stream that charges per event is one you stop feeding the month the bill grows with volume.
Our intent is that recording an event never costs money. Until published terms bind it, that is a commitment we make, not a contract you hold. When prices are published, this page carries them — or says we changed our mind.
Ten years of vendor XML, translated.
EPCIS 1.1, 1.2 and 2.0 XML goes in; EPCIS 2.0 JSON-LD comes out; and a round-trip fidelity report comes with every job, so the translation is something you review rather than something you trust. CBV migration and extension unwrapping are handled by a zero-dependency, namespace-aware parser. The door is on this origin — no key, no account:
curl -X POST https://epcis.dev/translate \
-H 'content-type: application/xml' \
--data-binary @legacy-1.2.xml
200 OK
Spine-Translation-Fidelity: round-trip-clean
→ EPCIS 2.0 JSON-LD + the per-job fidelity report
What ships today, and what does not.
Shipped
- Hosted on this origin: POST /translate, POST /validate and POST /hash — the stateless engine doors, no key required
- Validation against the official GS1 EPCIS 2.0 JSON schema, on every capture
- Gateway stamping, with caller-supplied values stripped
- An MCP door: capture / query / get_event / trace_epc / translate as tools
Open in the launch ledger
- The hosted capture/query/MCP spine at api.epcis.dev — cloud provisioning and deploy (P0-14)
- Issued capture keys — provisioned from the key list, in order, when the spine's door opens (P0-14/P0-18)
- The public repository host — the clone URL ships on this site the day the publication ruling lands (P0-24)
- The business-transaction layer’s EDIFACT track — parse of EDIFACT answers a typed SYNTAX_UNSUPPORTED refusal while this row is open (biztx ledger, EDIFACT P6)
Four lines from each column. The ledger in full, dated, is a page of its own.
Who builds this.
epcis.dev is built to be judged the way open source is judged: by the repository, not by a biography. Every provenance claim on this site is one a reader can check — the pinned digests, the reference-vector gates, the test counts, and the live doors on this origin. Where a claim cannot be checked, it does not ship.
GS1 has not reviewed, certified or approved this project, and nothing here should be read as a GS1 position. The contract is straightforward: the standard is implemented as written, its exception types and its event hash included, and where we have made a choice the standard leaves open, the conformance suite records it.
epcis.dev is stewarded under The Org.AI Foundation.
Get a capture key.
A capture key opens the write half of the door — capture, query, MCP. Keys are provisioned from the list, in order: say what you will capture, and you get one email when yours is ready. One, not a drip campaign.
We answer in writing. We take at most five conversations a month, only when you ask for one, and only after you already have the written read.