Closient implements GS1 EPCIS 2.0 (ISO/IEC 19987:2024) end-to-end: events captured byDocumentation Index
Fetch the complete documentation index at: https://docs.closient.com/llms.txt
Use this file to discover all available pages before exploring further.
POST /epcis/api/2.0/capture are persisted as
JSON-LD EPCISDocuments and — when the bizStep is FSMA 204-relevant
— materialized into a CriticalTrackingEvent row in the same DB
transaction. This skill walks an agent through composing a correct
event for each of the five EPCIS event types and posting it.
When to use
- A brand owner or 3PL needs to record a real-world supply-chain observation (harvest, pack, ship, receive, transform).
- An EDI 856 ASN or other source needs to be translated into an EPCIS event for FSMA 204 traceability.
- An agent is building chain-of-custody for a GTIN + batch and needs to seed the ledger.
query-epcis-events.
Auth
OAuth token (orX-API-Key header) where the caller holds OWNER or
MANAGER membership on the target organization. The endpoint will
return 403 for VIEWER and for users with no membership.
The API key format is csb_<token>_<crc32>. Rate limit: 300 req/min,
10,000 req/day per key (same as the rest of Closient’s APIs).
Flow
Step 1 — Choose the event type
EPCIS 2.0 defines five event types. Pick the one that matches the real-world observation:| Event type | When to use | Required structural fields |
|---|---|---|
ObjectEvent | Single-step observation on one or more EPCs (harvest, observation, retail sale). | epcList or quantityList, action. |
AggregationEvent | Parent-child container relationship (case → pallet, lot → case). | parentID, childEPCs (and/or childQuantityList), action. |
TransactionEvent | Linking EPCs to a business transaction (PO, invoice, despatch advice). | bizTransactionList, epcList and/or quantityList, action. |
TransformationEvent | Inputs → outputs (kill step, cook step, repack). | inputEPCList/inputQuantityList AND outputEPCList/outputQuantityList. |
AssociationEvent | Sensor / asset attachment to an EPC (cold-chain logger, RFID reader). | parentID, childEPCs, action. |
Step 2 — Pick a bizStep (GS1 CBV 2.0)
The full list lives in apps.epcis.vocabulary.BizStep. The FSMA
204-relevant subset that materializes a CTE in the same transaction:
bizStep | Materialized CTE type | FSMA 204 § |
|---|---|---|
harvesting | HARVEST | § 1.1330(a) — first-receiver of food on the FTL. |
cooling | COOLING | § 1.1330(b) — first cooling step. |
packing | INITIAL_PACK | § 1.1330(c) — initial packing. |
accepting | LAND_RECEIVE | § 1.1335 — first land-based receive of a fishery product. |
receiving | RECEIVE | § 1.1345 — receiving CTE. |
shipping | SHIP | § 1.1340 — shipping CTE. |
TransformationEvent (any bizStep) | TRANSFORM | § 1.1350 — transformation CTE. |
bizStep is accepted and persisted but does NOT produce a
CTE — useful for non-FSMA 204 categories (cosmetics, beauty, household).
Submit bizStep either as the bare CBV token (shipping) or the
canonical URI (urn:epcglobal:cbv:bizstep:shipping); the server
accepts both forms.
Step 3 — Encode EPCs (GS1 Digital Link preferred)
Two EPC encodings are accepted onepcList / outputEPCList /
inputEPCList:
- GS1 Digital Link (preferred):
https://id.gs1.org/01/{gtin14}/10/{lot}— AI(10) lot is extracted directly from the URI. Supports serialization via/21/{serial}. - EPCIS 1.x SGTIN URN:
urn:epc:id:sgtin:{company}.{item}.{serial}— GTIN-14 reconstructed via mod-10 check digit. The URN form does NOT carry AI(10), so the lot must come from theilmdblock.
bizLocation and readPoint, accepted forms are
https://id.gs1.org/414/{gln} or urn:epc:id:sgln:{...}. The server
matches against Location.gln.gln.
Step 4 — Compose the EPCIS document and POST
eventList array — the server
runs them in a single DB transaction (atomic on partial failure).
Step 5 — Read the response
On success (201 Created):
400): detail includes the
offending eventID (or the index in the array). On duplicate event
(409): the EPCIS event hash (§ 8.4) already exists — fetch the
existing one via GET /epcis/api/2.0/events/{event_id} rather than
retrying.
Step 6 — Provide an eventID for idempotency
EPCIS 2.0 events optionally carry an eventID (a UUID URN). Submitting
the same eventID twice produces 409 Conflict (the hash dedup
already enforces this on the wire, but an explicit eventID makes
retries on flaky networks safe):
Step 7 — Include ilmd for FSMA 204 KDEs
The ilmd (Instance/Lot Master Data) block carries the FSMA 204 Key
Data Elements. The server reads keys in either cbvmda: namespace or
bare form, case-insensitive. Canonical keys:
lot_number— overrides any AI(10) embedded in the EPC.harvest_start_date,harvest_end_date— backfilled ontoProductLotif the lot is unlocked.cooling_date— written onto theCriticalTrackingEventrow.expiration_date,best_before_date— backfilled ontoProductLot.vessel_name,vessel_identifier,species_description— copied onto LAND_RECEIVE CTEs.growing_area— informational; reserved for future structured use.
Required inputs
type— one ofObjectEvent,AggregationEvent,TransactionEvent,TransformationEvent,AssociationEvent.eventTime— RFC 3339 timestamp of the real-world observation.eventTimeZoneOffset— the offset of the recorder (e.g.+00:00).action—ADD,OBSERVE, orDELETE(NOT required onTransformationEvent).- The structural field(s) for the event type per Step 1.
Optional inputs
eventID— strongly recommended for idempotency.bizStep— required if you want a CTE materialized (Step 2 table).disposition— seeapps.epcis.vocabulary.Disposition. Notable values:in_transit,in_progress,recalled,expired,damaged,destroyed.bizLocation/readPoint— required to resolve aLocation-keyed CTE.bizTransactionList— forTransactionEvents.sourceList/destinationList—owning_party,possessing_party,locationsource/destination triples.ilmd— KDEs (Step 7).sensorElementList— for cold-chain / temperature data onAssociationEvent.
Output
201 Createdwith{ "captureID": "<uuid>", "createdEvents": <n> }.400— per-event validation failure (offendingeventID/index indetail).403— caller is notOWNER/MANAGERof the target organization, or the org’s billing tier doesn’t include EPCIS capture.409— duplicate event hash (idempotent retry succeeded; no new row).422— malformed JSON-LD envelope.429— rate limited.
Guidance for agents
- Always send the
@context. Capture parses the body as JSON-LD; the EPCIS 2.0 context is what tells the servercbvmda:keys are KDEs rather than arbitrary metadata. - Prefer GS1 Digital Link EPCs. The URN form drops AI(10), forcing
the lot to come from
ilmd. Digital Link keeps the lot inline and is the format the rest of Closient’s surfaces (resolver, QR, hosted pages) speak natively. - One event per real-world action. Don’t batch unrelated harvest
events into a single
eventList— each event is hashed and dedup’d independently, but a transaction-wide validation failure rolls all of them back. Group only when they represent one transactional business operation (e.g., shipping 12 pallets in one despatch). - Read the
eventTypescapability first. AGET /epcis/api/2.0/eventTypes(no auth required) returns the set of event types supported. If the environment doesn’t expose EPCIS at all, you’ll get a 404 — fail fast rather than thrashing on capture. - Materializer is silent on non-FSMA bizSteps. Capturing an event
with
bizStep=retail_sellingsucceeds but produces no CTE. That’s expected — don’t treat a missing CTE as a failure unless the bizStep is in the FSMA table. - Lock-aware ILMD backfill. Once a
ProductLothas been used in a FSMA-relevant event, itsLOCKED_FIELDS(lot number, harvest dates, expiration) become immutable. Subsequent captures still produce CTEs, but the ILMD KDEs are dropped on the floor for the lot itself. The captured event preserves them. - Resolve trading partners and locations up front. For
RECEIVE/SHIPCTEs the server needs to match aOWNING_PARTYsource/destination GLN against an existingTradingPartner.gln.glnand abizLocationGLN againstLocation.gln.gln. If those rows don’t exist, the EPCIS event still captures but the CTE materialization logs an INFO and skips.
Known gaps (planned)
- No streaming capture. All events are flushed synchronously on the
request. For bulk historical backfills (>1k events), use the
management CSV importer at
POST /epcis/api/v1/cte-imports/csvrather than this endpoint. AssociationEventsensor handling is opaque. Closient persists thesensorElementListblock verbatim but does not yet decompose it into a structured sensor-reading table; cold-chain alerts are filed but not actionable from query results.- No partial-success response. If one event in a batched
eventListfails validation, the whole transaction rolls back. Per-event success/failure responses would require splitting the capture into per-event sub-transactions; deferred until a customer actually hits the all-or-nothing pain. - No webhook on materialization. Materialized CTEs are not pushed back out via webhook today. Compliance dashboards refresh on demand.
Related skills
query-epcis-events— read-side counterpart for chain-of-custody reconstruction.check-fsma-204-readiness— validate that captured events have the KDEs needed for FSMA 204 export.manage-recall— uses captureddisposition=recalledevents as ground truth for “what is currently under recall”.check-recalls— consumer side; readsdisposition=recalledto surface alerts.