Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.closient.com/llms.txt

Use this file to discover all available pages before exploring further.

Closient implements GS1 EPCIS 2.0 (ISO/IEC 19987:2024) end-to-end: events captured by 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.
For querying existing events, see the sibling skill query-epcis-events.

Auth

OAuth token (or X-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 typeWhen to useRequired structural fields
ObjectEventSingle-step observation on one or more EPCs (harvest, observation, retail sale).epcList or quantityList, action.
AggregationEventParent-child container relationship (case → pallet, lot → case).parentID, childEPCs (and/or childQuantityList), action.
TransactionEventLinking EPCs to a business transaction (PO, invoice, despatch advice).bizTransactionList, epcList and/or quantityList, action.
TransformationEventInputs → outputs (kill step, cook step, repack).inputEPCList/inputQuantityList AND outputEPCList/outputQuantityList.
AssociationEventSensor / 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:
bizStepMaterialized CTE typeFSMA 204 §
harvestingHARVEST§ 1.1330(a) — first-receiver of food on the FTL.
coolingCOOLING§ 1.1330(b) — first cooling step.
packingINITIAL_PACK§ 1.1330(c) — initial packing.
acceptingLAND_RECEIVE§ 1.1335 — first land-based receive of a fishery product.
receivingRECEIVE§ 1.1345 — receiving CTE.
shippingSHIP§ 1.1340 — shipping CTE.
TransformationEvent (any bizStep)TRANSFORM§ 1.1350 — transformation CTE.
Any other 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. Two EPC encodings are accepted on epcList / 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 the ilmd block.
For 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

POST /epcis/api/2.0/capture
Authorization: Bearer <token>
Content-Type: application/json
{
  "@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
  "type": "EPCISDocument",
  "schemaVersion": "2.0",
  "creationDate": "2026-05-18T14:32:00Z",
  "epcisBody": {
    "eventList": [
      {
        "type": "ObjectEvent",
        "eventTime": "2026-05-18T14:30:00Z",
        "eventTimeZoneOffset": "+00:00",
        "epcList": [
          "https://id.gs1.org/01/00614141123456/10/LOT-2026-042"
        ],
        "action": "OBSERVE",
        "bizStep": "shipping",
        "disposition": "in_transit",
        "readPoint": {
          "id": "https://id.gs1.org/414/0614141000005"
        },
        "bizLocation": {
          "id": "https://id.gs1.org/414/0614141000005"
        }
      }
    ]
  }
}
Wrap multi-event captures in the same eventList array — the server runs them in a single DB transaction (atomic on partial failure).

Step 5 — Read the response

On success (201 Created):
{
  "captureID": "8c30f2c4-d8e5-4e3a-9b15-6f24a1b8d5fa",
  "createdEvents": 1
}
On per-event validation failure (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):
{
  "eventID": "urn:uuid:8c30f2c4-d8e5-4e3a-9b15-6f24a1b8d5fa",
  "type": "ObjectEvent",
  "...": "..."
}

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 onto ProductLot if the lot is unlocked.
  • cooling_date — written onto the CriticalTrackingEvent row.
  • expiration_date, best_before_date — backfilled onto ProductLot.
  • vessel_name, vessel_identifier, species_description — copied onto LAND_RECEIVE CTEs.
  • growing_area — informational; reserved for future structured use.
Unknown keys are silently dropped.
{
  "type": "ObjectEvent",
  "bizStep": "harvesting",
  "ilmd": {
    "cbvmda:lotNumber": "LOT-2026-042",
    "cbvmda:harvest_start_date": "2026-05-15",
    "cbvmda:growing_area": "Salinas Valley, CA"
  }
}

Required inputs

  • type — one of ObjectEvent, AggregationEvent, TransactionEvent, TransformationEvent, AssociationEvent.
  • eventTime — RFC 3339 timestamp of the real-world observation.
  • eventTimeZoneOffset — the offset of the recorder (e.g. +00:00).
  • actionADD, OBSERVE, or DELETE (NOT required on TransformationEvent).
  • 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 — see apps.epcis.vocabulary.Disposition. Notable values: in_transit, in_progress, recalled, expired, damaged, destroyed.
  • bizLocation / readPoint — required to resolve a Location-keyed CTE.
  • bizTransactionList — for TransactionEvents.
  • sourceList / destinationListowning_party, possessing_party, location source/destination triples.
  • ilmd — KDEs (Step 7).
  • sensorElementList — for cold-chain / temperature data on AssociationEvent.

Output

  • 201 Created with { "captureID": "<uuid>", "createdEvents": <n> }.
  • 400 — per-event validation failure (offending eventID/index in detail).
  • 403 — caller is not OWNER / MANAGER of 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 server cbvmda: 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 eventTypes capability first. A GET /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_selling succeeds 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 ProductLot has been used in a FSMA-relevant event, its LOCKED_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 / SHIP CTEs the server needs to match a OWNING_PARTY source/destination GLN against an existing TradingPartner.gln.gln and a bizLocation GLN against Location.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/csv rather than this endpoint.
  • AssociationEvent sensor handling is opaque. Closient persists the sensorElementList block 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 eventList fails 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.
  • 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 captured disposition=recalled events as ground truth for “what is currently under recall”.
  • check-recalls — consumer side; reads disposition=recalled to surface alerts.