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.

EPCIS 2.0’s SimpleEventQuery (§ 8.2.7 / § 8.2.8) is the standard way to ask “what happened to this EPC?” across the captured ledger. Closient implements it at GET /epcis/api/2.0/events, scoped to the authenticated organization. This skill walks an agent through building filter combinations that reconstruct chain-of-custody, verify a recall, or audit a transformation step.

When to use

  • A brand owner asks “where did batch X go?” — walk forward from bizStep=shipping events.
  • A retailer needs to confirm a receive against the supplier’s shipping CTE — walk backward from bizStep=receiving.
  • A compliance audit needs every CTE-relevant event for a GTIN in a date window for FSMA 204 § 1.1455(c) records request.
  • Verify a recall: does the recalled batch have a corresponding disposition=recalled event in the ledger?
For full chain traversal with downstream impact counts, prefer the dedicated traversal endpoints: GET /epcis/api/2.0/traceability/lots/{lot_id}/fda-export (FDA Sortable Spreadsheet export) and GET /epcis/api/2.0/traceability/lots/{lot_id}/blast-radius (quantified downstream footprint). This skill is for raw event-level queries.

Auth

OAuth token (or X-API-Key) with OWNER or MANAGER membership on the organization. Results are scoped to events captured by that organization — cross-org leakage is blocked by the org filter on the server, not by client-side filtering.

Flow

Step 1 — Pick filter dimensions

The endpoint accepts the GS1 EPCIS 2.0 SimpleEventQuery parameter set. Most agents need one or two dimensions:
ParamTypeUse case
eventTypeone of ObjectEvent / AggregationEvent / TransactionEvent / TransformationEvent / AssociationEventLimit to e.g. only transformations.
GE_eventTimeRFC 3339 timestamp”Since when?” lower bound (inclusive).
LT_eventTimeRFC 3339 timestamp”Up to when?” upper bound (exclusive).
EQ_bizStepCBV BizStep token or canonical URI”Show me all shipping events”.
EQ_dispositionCBV Disposition token or canonical URI”Show me everything currently in_transit” or recalled.
EQ_readPointGS1 Digital Link /414/{gln} or urn:epc:id:sgln:Events observed at one location.
EQ_bizLocationsameEvents whose business location is one site.
MATCH_epcsingle EPC URI (Digital Link or SGTIN URN)All events touching one EPC.
MATCH_anyEPCcomma-separated EPC URIsEvents touching any of N EPCs.
EQ_actionADD / OBSERVE / DELETENarrow to a single action verb.
perPageintegerPage size (server default applies).
nextPageTokenopaque cursorCursor pagination (Step 4).

Step 2 — Issue the query

GET /epcis/api/2.0/events?MATCH_epc=https%3A%2F%2Fid.gs1.org%2F01%2F00614141123456%2F10%2FLOT-2026-042&EQ_bizStep=shipping
Authorization: Bearer <token>
URL-encode EPC URIs — the ? / / / % in Digital Link forms are ambiguous without percent encoding.

Step 3 — Read the response

The body is a JSON-LD EPCISQueryDocument (GS1 EPCIS 2.0 § 8.2.5):
{
  "@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
  "type": "EPCISQueryDocument",
  "epcisBody": {
    "queryResults": {
      "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"}
        }
      ]
    }
  },
  "GS1-Next-Page-Token": "<opaque>"
}
Headers include GS1-EPCIS-Version: 2.0.0 and GS1-CBV-Version: 2.0.0.

Step 4 — Walk the cursor

Pass the body’s GS1-Next-Page-Token back as the nextPageToken query parameter to fetch the next page. When the field is absent, the result set is exhausted.
GET /epcis/api/2.0/events?MATCH_epc=...&nextPageToken=<opaque>

Step 5 — Fetch a single event by ID

GET /epcis/api/2.0/events/{event_id}
event_id is the 36-char canonical UUID assigned at capture (echoed back as eventID on each event). Other organizations receive 404 — no leak of existence.

Required inputs

None at the protocol level (an empty query returns the org’s events in -eventTime order, paginated). Practically: at least one filter (MATCH_epc or GE_eventTime) to keep results bounded.

Optional inputs

All SimpleEventQuery params per the Step 1 table.

Output

200 OK JSON-LD EPCISQueryDocument with:
  • @context — EPCIS 2.0 context URI.
  • type — always EPCISQueryDocument.
  • epcisBody.queryResults.eventList — array of events (newest first).
  • GS1-Next-Page-Token — present when more pages exist.
Error responses follow RFC 9457 Problem Details (application/problem+json):
  • 401 — missing or invalid auth.
  • 403 — caller is not OWNER / MANAGER.
  • 422 — malformed query parameters (e.g. unparsable timestamp).
  • 429 — rate limited (300 req/min, 10k req/day per key).

Guidance for agents

  • Read bizStep like a verb. The CBV vocabulary is human-readable on purpose: commissioning (born), harvesting (picked), cooling, packing, shipping, receiving, retail_selling, dispensing, destroying. Reconstruct narrative by sorting events by eventTime and reading the bizStep column.
  • Disposition is current-state, bizStep is verb. A shipping event with disposition=in_transit means “we shipped it; it’s currently in transit.” A subsequent receiving with disposition=available means “the receiver took possession; it’s now available at their location.” A disposition=recalled event is what check-recalls looks for when answering “is this lot under recall?”.
  • MATCH_epc is exact-string. The server matches the full EPC URI literally — https://id.gs1.org/01/00614141123456/10/LOT-A and https://id.gs1.org/01/00614141123456/10/LOT-A/21/0001 are different EPCs. Use MATCH_anyEPC (comma-separated) when you have multiple serialization candidates.
  • Time windows narrow first. A query with no time bound has to scan the whole org’s event table. Always include GE_eventTime (and LT_eventTime when chasing a specific incident window) before fanning out to other dimensions.
  • Chain reconstruction is sort-then-walk. EPCIS doesn’t natively give you the parent/child traversal that FSMA 204 expects (that lives on the materialized CTE rows). For a single-lot story, sort the returned events by eventTime and read the bizStep column; for full traversal of a CTE chain, use the /traceability/lots/{lot_id}/fda-export endpoint.
  • Don’t reconstruct blast radius from this endpoint. Use GET /epcis/api/2.0/traceability/lots/{lot_id}/blast-radius — it walks the materialized CTE graph and returns aggregate counts in one call. Doing it by hand from event-level data is brittle (no parent/child linkage on raw events) and wastes API quota.

Known gaps (planned)

  • No MASTER_DATA query. EPCIS 2.0 § 8.2.9 defines a master-data query (vocabulary lookup for biz locations, read points, etc.) — Closient does not implement it. Use the management API (/epcis/api/v1/trading-partners, /epcis/api/v1/reference-documents) for master data CRUD instead.
  • No subscription / poll endpoint. EPCIS 2.0 § 8.3 standing-query subscription is not implemented. Agents must poll.
  • No MATCH_epcClass filter. Class-level matches (all events on any EPC sharing a GTIN, regardless of lot/serial) require a pre-filter by MATCH_anyEPC or a post-query group-by on epcList. Planned alongside FSMA 204 GTIN-keyed dashboards.
  • No EQ_quantity filter. Quantity-list-based filtering (events involving > N units) is out of scope for the standard SimpleEventQuery and not supported.
  • Cursor opacity is server-internal. The GS1-Next-Page-Token is not the GS1-suggested base64-encoded eventID|eventTime form — it’s a Closient-internal opaque cursor. Tokens are not durable across schema migrations.
  • capture-epcis-event — write-side; produces the rows this skill reads.
  • check-fsma-204-readiness — uses query results to determine which KDEs are present per lot.
  • manage-recall — checks for disposition=recalled events when reviewing a recall record.
  • check-recalls — consumer side; resolves “is GTIN X under recall right now?” via disposition=recalled (joined with the regulator recall feed).