EPCIS 2.0 from the Reader's Side: Which Event Fields Edge Software Can Fill
A dock-door UHF reader produces EPCs, antenna ports, signal strength and timestamps. A GS1 traceability partner wants EPCIS 2.0 events. Between the two sits a mapping most integration specs leave vague: which event fields the reader’s edge software can fill on its own, and which must come from the WMS or ERP. This guide settles it field by field against the ratified GS1 texts, with a section number on every rule, and walks GS1’s own JSON-LD examples 9.6.1 (ObjectEvent) and 9.6.3 (AggregationEvent) the way a capture application builds them. We design and build fixed and handheld readers and the software on them, so the view is from the bottom of the stack looking up.
Version pin
Every rule below is pinned to these documents, with release and date as printed on their covers.
| Document | On the face | Used for |
|---|---|---|
| EPCIS Standard | Release 2.0, Ratified, Jun 2022 | Event types, fields, section numbers |
| Core Business Vocabulary (CBV) Standard | Release 2.0, Ratified, Jun 2022 | Vocabulary values, identifier syntax, Event Hash ID |
| EPCIS and CBV Implementation Guideline | Release 2.0, Ratified, Mar 2023 | Design advice (non-normative) |
| EPC Tag Data Standard | Release 2.3, Ratified, Oct 2025 | Tag URI, filter value, SGTIN-96 layout |
| JSON-LD context, JSON Schema | Path version 2.0.0 | Expansion and validation |
EPCIS 2.1 is not yet a standard. GS1’s EPCIS repository on GitHub added a public_review_2_1 folder on 4 September 2026, holding a JSON-LD context its commit describes as a public review draft of v2.1. Build and certify against 2.0; track the draft.
Checked 22 October 2026. ref.gs1.org was serving a maintenance page that day, so the PDFs were read from Internet Archive captures of their ref.gs1.org pages and the examples from GS1’s EPCIS GitHub repository (links in the sources). EPCIS section 10.4 classes the JSON examples as non-normative; where they differ from the standard text, the text wins.
Where the reader sits: capture layer vs share layer
EPCIS 2.0 section 2.2 draws the stack every RFID integration lives in. From the bottom:
- Tag and air interface: Gen2 inventory rounds; the EPC bank plus radio facts.
- Reader, LLRP interface: raw tag reports, duplicates included.
- Filtering and collection, ALE interface: one observation per tag per event window.
- Data capture workflow, EPCIS Capture Interface: business context attached, EPCIS event emitted.
- Repository and Query Interface: events stored and shared.
Section 2.2 puts the EPCIS event a semantic level above the read: it carries business context, and it need not match any physical read (the standard’s example is a software-generated expiry event). The non-normative note in section 7.3.5 leaves logical and physical reader IDs out of events by design: swap a failed reader for an identical one and its physical ID changes, which tells a trading partner nothing.
The Implementation Guideline (section 2.6) places EPCIS Capture Applications at the edge of the enterprise, in factories, warehouses and stores, and expects them to fetch purchase-order and master data from back-end systems. On a reader that runs its own middleware, as in our post on edge RFID middleware on the reader, layers 2 and 3 are already on the device. ReaderSense Edge reports zone and direction of travel and forwards over HTTP, WebSocket or MQTT. Direction matters: section 7.3.5.1 notes that a correct business location needs both the read and the direction of movement. The mapping below is an integration pattern for the step above that, in the edge rules layer or the first service that receives the stream, whichever holds the context the event needs.
The field-ownership table
Our reading of EPCIS 2.0 and CBV 2.0. “Edge” is anything at the read point that knows its configuration (door, direction, process step) and its last reads. “Business system” is the WMS, ERP or EPCIS repository.
| Field | Spec section | Filled by edge (config + read) | Filled by business system | Notes |
|---|---|---|---|---|
type | EPCIS 7.4 | Fixed per read-point profile | — | Per business step, not per read |
eventTime | 7.4.1 | NTP-synced reader clock | — | Usually the end of the step (Guideline 4.6.2) |
eventTimeZoneOffset | 7.4.1 | Site configuration | — | Required on every event by the 2.0.0 JSON Schema |
recordTime | 7.4.1 | — | Repository | Ignored at capture |
eventID | 7.4.1; CBV 8.9 | UUID v1 or v4 (CBV 8.9.1) | Event Hash ID (CBV 8.9.2) once final | Hash covers bizTransactionList and extensions |
epcList, childEPCs | 7.4.2, 7.4.3; CBV 8.2 | Decoded EPC bank | — | Pure identity or constrained Digital Link |
parentID | 7.4.3 | When a pallet tag is read | When the SSCC or LPN is assigned | Required for ADD and DELETE |
action | 7.3.2 | Fixed per profile | — | ADD, OBSERVE or DELETE |
readPoint | 7.3.5 | Per door or antenna group; location tag for handhelds | — | SGLN recommended (CBV 8.4.1) |
bizLocation | 7.3.5 | Per door and direction | When the room is decided later | Omitted on shipping (Guideline 4.6.3) |
bizStep | 7.3.6.1; CBV 7.1 | Fixed per read point | Exceptions | Mapping table below |
disposition | 7.3.6.2.1; CBV 7.2 | Fixed for routine flows | After inspection or reconciliation | Omitted means unchanged |
persistentDisposition | 7.3.6.2.2 | — | Set and unset | Home of mismatch_ values |
bizTransactionList | 7.3.6.3; CBV 8.5 | — | PO, despatch advice, bill of lading | Guideline 2.6 |
sourceList, destinationList | 7.3.6.4 | — | Order or transfer record | Parties and locations |
quantityList, childQuantityList | 7.3.3.1; CBV 8.3 | Weight from a scale at the read point | Counts of untagged goods | uom from UN/CEFACT Rec. 20 |
ilmd | 7.3.8 | — | Lot, expiry, production data | ObjectEvent ADD or TransformationEvent |
sensorElementList | 7.3.7 | Sensor values read with the tag | — | Attach to the listed objects |
errorDeclaration | 7.4.1.2 | — | Correction workflow | Otherwise identical to the original |
Three rules the edge enforces
- Non-empty What. An ObjectEvent SHALL carry a non-empty
epcList,quantityListor both (7.4.2), the only exception being a physical-location observation with asensorElementandreadPoint. The 2.0.0 JSON Schema’sepcListbranch setsminItemsto 0, so an empty list from a silent read cycle passes the schema. Drop empty cycles at the edge. - ILMD only at birth.
ilmdSHALL NOT appear whenactionis OBSERVE or DELETE (7.4.2). A dock-door read never carries it. - Three actions, fixed. Section 7.3.2 says
actionSHALL NOT be extended by industry groups. Reader states such as “entered” and “left” are expressed throughbizStep, location and time.
From decoder output to an allowed identifier
One tag, the first EPC in GS1’s example 9.6.1, taken all the way. We encoded it as SGTIN-96 with filter value 1 (Point of Sale trade item, TDS Table 10-1) and partition 5 for a seven-digit company prefix (TDS Table 14-16).
| Form | Value | In an event? |
|---|---|---|
| EPC bank hex, after the PC word | 3034257BF468D480000007E1 | Decode first |
| EPC Tag URI | urn:epc:tag:sgtin-96:1.0614141.107346.2017 | SHALL NOT (CBV 8.1.1) |
| EPC Pure Identity URI | urn:epc:id:sgtin:0614141.107346.2017 | Allowed (CBV 8.2.1) |
| GS1 Digital Link URI | https://id.gs1.org/01/10614141073464/21/2017 | Allowed, constrained (CBV 8.2.2) |
The tag URI carries the filter value and control fields, which describe the tag; the pure identity URI keeps only what identifies the item. CBV 8.1.1 therefore bars tag URIs, pure identity pattern URIs and EPC pattern URIs from events (class-level patterns from CBV 8.3.1 excepted). For the Digital Link, the indicator digit (the leading 1 of 107346) moves to the front, then the company prefix, the rest of the item reference and a check digit: 1 0614141 07346 4. The bit arithmetic is in our SGTIN-96 walkthrough; where the 96 bits sit is in the Gen2 EPC bank post.
- Raw URIs are a fallback:
urn:epc:raw:only when the bits cannot be decoded as an EPC (CBV 8.1.1). - Locations are not objects: an SGLN or PGLN SHALL NOT be an object identifier (CBV 8.2.1); location fields SHOULD use SGLNs (CBV 8.4.1).
- Digital Link keys are constrained: CBV 8.2.2 collapses (01)(17)(21) or (01)(10)(21) element strings to
/01/{gtin}/21/{serial}forepcList. - Choose test vectors carefully: GS1’s
WithDigitalLinkIDtwin of 9.6.1 uses GTIN70614141123451, not the10614141073464the URN file converts to. Treat it as a syntax sample and build converter tests from your own encodings.
Reader mode to bizStep
A read point does one job, so its bizStep is configuration. CBV 2.0 values (section 7.1.3):
| Reader mode | Event, action | bizStep | CBV definition, in short |
|---|---|---|---|
| Dock door, inbound | Object or Aggregation, OBSERVE | receiving | Received and added to the receiver’s inventory |
| Dock door, outbound | Object or Aggregation, OBSERVE | shipping | Staging outbound, loading and departing as one step |
| Handheld shelf or zone count | ObjectEvent, OBSERVE | cycle_counting | Counting for needs other than accounting; the CBV’s examples use a handheld |
| Count for the accounts | ObjectEvent, OBSERVE | stock_taking | Counting under established rules for accounting |
| Encode-and-apply station | ObjectEvent, ADD | commissioning | Identifier associated with the object |
| Pack station | AggregationEvent, ADD | packing | Aggregation typically happens here |
| Break-down station | AggregationEvent, DELETE | unpacking | Disaggregation typically happens here |
Enforce the CBV’s exclusivity rules in the profile editor: receiving excludes arriving and accepting; shipping excludes staging_outbound, loading and departing. Pick the coarse value or the fine set per site and keep it consistent. A bureau that encodes tags without applying them uses encoding, which the CBV says SHOULD appear only in a TransactionEvent.
Two CBV 2.0 inconsistencies. Sections 7.1.1 and 7.1.2 print the web prefix as https://ref.gs1.org/cbv/Bizstep-; section 5.1, the hash rules in 8.9.2 and the 2.0.0 JSON-LD context use BizStep-. Section 7.1.2 says a CBV-Compliant event SHOULD include bizStep; the section 5.1 summary says SHALL. In JSON, send the bare string ("receiving") and let the context expand it to cbv:BizStep-receiving; if you need a full URI, the URN urn:epcglobal:cbv:bizstep:receiving is printed identically in both sections. And send bizStep on every event, which satisfies both readings.
Dispositions for warehouse reads
Values from CBV 2.0 section 7.2.3, with the business steps the CBV lists against them.
| Value | CBV example steps | Who sets it (our reading) |
|---|---|---|
active | commissioning | Edge, encode station |
in_transit | shipping, departing | Edge, outbound door |
sellable_accessible | stocking, receiving | Edge, door onto a sales floor |
sellable_not_accessible | receiving, storing, loading, holding, inspecting | Edge, backroom or warehouse receiving |
container_closed | staging_outbound (non-exclusive) | Edge or yard system, at sealing |
damaged | receiving, inspecting, others | Inspection workflow |
returned | receiving, holding, shipping | Business system, against the return authorisation |
completeness_inferred | Persistent disposition on an OBSERVE event | Business system, from upstream packing data or ASN |
completeness_verified | AggregationEvent DELETE with unpacking | Business system, after comparing children with the expected list |
- Skip
in_progress. The CBV 7.2.3 note recommends omitting disposition instead, sincein_progressadds little. GS1’s own examples use it anyway (the receiving event in 9.6.1, and 9.6.3). Omitted, the condition stays unchanged (EPCIS 7.4.2). mismatch_class,mismatch_instance,mismatch_quantitycompare arrivals with expectations (the CBV’s examples use the supplier’s packing data), and the CBV recommends recording them aspersistentDisposition. They come from the system holding the despatch advice.- Retire deprecated values (CBV 7.2.3.1):
non_sellable_expired,_damaged,_disposedand_recalledbecomeexpired,damaged,disposedandrecalled;no_pedigree_matchhas no replacement.non_sellable_otheris current.
GS1 example 9.6.1 walked line by line
Open Example_9.6.1-ObjectEvent.jsonld alongside. It holds a shipment out of one company and a receipt at another.
@context: the 2.0.0 context URL from EPCIS 10.3, plus an object binding the prefixexamplefor the extension field (Guideline 5.8.2).- Document fields: the 2.0.0 JSON Schema requires
@context,type,schemaVersion,creationDateandepcisBody. eventID: an Event Hash ID,ni:///sha-256;plus digest plus?ver=CBV2.0(CBV 8.9.2).- ObjectEvent, OBSERVE,
shipping,in_transit: bare strings the context expands to CBV web URIs (CBV 8.9.2 rule 15 does the same before hashing). epcList: two SGTIN pure identity URIs, serials 2017 and 2018.eventTime2005-04-03T20:33:31.116000-06:00has six fractional digits, the second event three; hashing normalises both to UTC milliseconds (rules 8 and 9).eventTimeZoneOffsetrepeats-06:00as business context (EPCIS 7.4.1.1).readPointis an SGLN and there is nobizLocation, as Guideline 4.6.3 prescribes for shipping.bizTransactionList: apoas an HTTP URL with a/po/path. CBV 8.5.5 wants the transaction ID as the single segment after/bt/, one of the six forms section 8.5 requires of a CBV-Compliant document.- Receiving event: another company’s SGLNs (read point
.400, business location.0), adesadvin the GLN-based form of CBV 8.5.3, and only serial 2018. Explaining the missing 2017 is reconciliation work. example:myField: a user extension. The JSON Schema and SHACL validate with an open shape, so it passes (EPCIS 10.3).
The same shipment from a reader in India
Our rewrite: an NTP-synced clock, the +05:30 offset EPCIS 7.4.1 uses as its own example, a UUID because the WMS adds the PO afterwards, and a CBV 8.5.5 transaction URL.
{
"@context": ["https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld"],
"type": "EPCISDocument",
"schemaVersion": "2.0",
"creationDate": "2026-10-22T09:14:05.250+05:30",
"epcisBody": {"eventList": [{
"type": "ObjectEvent",
"eventID": "urn:uuid:99dd98b7-ce73-44a3-9d13-5639ec27d67e",
"eventTime": "2026-10-22T09:14:03.871+05:30",
"eventTimeZoneOffset": "+05:30",
"epcList": ["urn:epc:id:sgtin:0614141.107346.2017",
"urn:epc:id:sgtin:0614141.107346.2018"],
"action": "OBSERVE",
"bizStep": "shipping",
"disposition": "in_transit",
"readPoint": {"id": "urn:epc:id:sgln:0614141.07346.1234"},
"bizTransactionList": [{"type": "po",
"bizTransaction": "https://epcis.example.com/bt/PO-4500012345"}]
}]}
}
Everything above bizTransactionList came from configuration and the last read cycle. For Event Hash IDs, hash after enrichment: the canonical property order in CBV 8.9.2 includes bizTransactionList, sources, destinations, ILMD and extensions.
Validate before sending. EPCIS 10.3: JSON SHALL validate against the JSON Schema, JSON-LD against the SHACL file, both under 2.0.0. Add two checks of your own: a non-empty What dimension, and parentID on every AggregationEvent with ADD or DELETE, a condition the schema’s AggregationEvent definition leaves out.
The dock-door AggregationEvent
GS1’s example 9.6.3 is what an inbound portal produces when it reads a pallet and its cases together.
parentIDurn:epc:id:sscc:0614141.1234567890: an EPC parent SHALL be a pure identity URI (7.4.3).childEPCs: the two SGTINs from 9.6.1.- OBSERVE,
receiving,in_progress, read point SGLN0614141.00777.0, business location0614141.00888.0. eventTimeis in UTC (Z) while the offset is+02:00: the timestamp fixes the instant, the offset records local time (7.4.1.1).childQuantityList: ten ofurn:epc:idpat:sgtin:4012345.098765.*and 200.5KGMof the LGTINurn:epc:class:lgtin:4012345.012345.998877, both class-level forms from CBV 8.3.1, the one place anidpatURI may appear in an event.
Variant: untagged or unreadable pallet
Section 7.4.3 makes parentID optional under OBSERVE, and its explanation names this exact case: a receiving process reads the cases by RFID, but the pallet has no tag or an unreadable one. Our version:
{
"type": "AggregationEvent",
"eventID": "urn:uuid:ae31a0cd-bcf9-4578-b045-fd4200832e07",
"eventTime": "2026-10-22T11:02:47.390+05:30",
"eventTimeZoneOffset": "+05:30",
"childEPCs": ["urn:epc:id:sgtin:0614141.107346.2017",
"urn:epc:id:sgtin:0614141.107346.2018"],
"action": "OBSERVE",
"bizStep": "receiving",
"readPoint": {"id": "urn:epc:id:sgln:0614141.00777.12"},
"bizLocation": {"id": "urn:epc:id:sgln:0614141.00777.0"}
}
Disposition is omitted on purpose (CBV 7.2.3). Tying these cases to the SSCC on the despatch advice is the WMS’s statement, in its own event.
Aggregation rules (EPCIS 7.4.3)
- Parent: required for ADD and DELETE, optional for OBSERVE.
- Children: non-empty
childEPCs,childQuantityListor both; under DELETE both may be empty, meaning all children are disaggregated. - Partial observation: under OBSERVE, unread children simply go unlisted.
- Containment only: objects in the same place at the same time. Two pallets in one shipment belong in a TransactionEvent.
- Re-parenting: LPN to SSCC is DELETE under the old parent, then ADD under the new.
Antenna placement and stray-read control for these doors are in the dock door portal design worksheet; the pallet process is on our RFID pallet tracking system page.
Location and design rules for the capture app
- Design from the consumer. Guideline 4.6 advises building events from what a business application needs to know, not from what the reader emits. Signal strength and antenna port stay at the edge, where they tune the portal.
- Read points from configuration or a tag. Section 7.3.5 lets fixed readers infer the read point from the logical reader, and mobile readers determine it by reading a location tag. A tag on each bay end gives every handheld count a read point with no typing.
- Doors are read points, rooms are business locations (EPCIS 7.3.5.1). You can ask for the inventory of a room, never of a doorway.
- Omit
bizLocationon shipping: location is unknown until the receiver’s event (Guideline 4.6.3). - Order simultaneous events. When commissioning and packing happen in one instant, Guideline 4.6.2 suggests timing the packing event slightly later, even by one millisecond.
- Capture fine, share coarse. Guideline 4.6.3 suggests dock-door read points internally, redacted to building level for partners (options in section 6.7). A redacted event will not reproduce its original Event Hash ID (CBV 8.9.2), and an ADD aggregation cannot lose its
parentIDand stay well formed.
Net result: each dock door needs one profile per direction, holding event type, action, bizStep, optional disposition, readPoint, inbound bizLocation, time-zone offset and an event-ID rule. Everything else is enrichment. For the reader side see our fixed UHF RFID readers; for the WMS side, the RFID warehouse management system.
Frequently asked questions
What is the difference between readPoint and bizLocation in EPCIS?
readPoint is where the objects were when the event happened; bizLocation is where they are assumed to be afterwards, until a later event says otherwise (EPCIS 2.0, section 7.3.5). At a dock door, the door is the read point and the warehouse behind it is the business location. Shipping events omit bizLocation because the goods’ location is unknown until the receiver records them (Implementation Guideline 4.6.3).
Can an RFID reader generate EPCIS events directly?
Edge software at the reader can fill most of an event: type, action, eventTime, eventTimeZoneOffset, eventID, the EPC list, readPoint, bizLocation, and a bizStep and disposition fixed per read point. EPCIS calls this an EPCIS Capture Application, which the Implementation Guideline (section 2.6) places at the edge and expects to fetch order and master data from back-end systems. Purchase orders, despatch advices, sources, destinations and lot data come from the WMS or ERP.
Which EPCIS fields must come from the ERP or WMS?
bizTransactionList, sourceList, destinationList, ilmd, persistentDisposition (including the mismatch_ values), errorDeclaration, and class-level quantities for untagged goods. recordTime is set by the EPCIS repository and ignored at capture (EPCIS 2.0, section 7.4.1). If you use Event Hash IDs, compute them after enrichment, because the hash covers bizTransactionList, sources, destinations, ILMD and extensions (CBV 2.0, section 8.9.2).
Can I use an EPC tag URI in an EPCIS event?
No. CBV 2.0 section 8.1.1 forbids EPC tag URIs (urn:epc:tag:) in EPCIS documents, along with pattern URIs other than the class-level forms listed in section 8.3.1. Use the pure identity URI (urn:epc:id:sgtin:...) or the constrained GS1 Digital Link form from section 8.2.2. Raw URIs are allowed only when the bits cannot be decoded as an EPC.
What bizStep should a dock door RFID reader use?
receiving for an inbound door and shipping for an outbound door, normally with action OBSERVE (CBV 2.0, section 7.1.3). receiving is mutually exclusive with arriving and accepting; shipping is mutually exclusive with staging_outbound, loading and departing. Choose the coarse value or the fine-grained set for the whole site and use it consistently.
How do I record a pallet without an RFID tag in EPCIS?
Use an AggregationEvent with action OBSERVE and omit parentID. EPCIS 2.0 section 7.4.3 makes the parent optional under OBSERVE, and its explanation describes a receiving process that reads the cases while the pallet has no tag or an unreadable one. List the cases you read in childEPCs. ADD and DELETE still require a parentID.
Is EPCIS 2.1 released?
As of 22 October 2026 the ratified versions are EPCIS 2.0 and CBV 2.0 (both Release 2.0, Ratified, Jun 2022). GS1’s EPCIS GitHub repository added a public_review_2_1 folder on 4 September 2026 with a JSON-LD context described as a public review draft of v2.1. Build and certify against 2.0 and track the draft.
Sources
- GS1 EPCIS Standard, Release 2.0, Ratified, Jun 2022 (ref.gs1.org)
- GS1 EPCIS Standard 2.0, Internet Archive capture of ref.gs1.org (copy read)
- GS1 Core Business Vocabulary (CBV) Standard, Release 2.0, Ratified, Jun 2022 (ref.gs1.org)
- GS1 CBV Standard 2.0, Internet Archive capture of ref.gs1.org (copy read)
- GS1 EPCIS and CBV Implementation Guideline, Release 2.0, Ratified, Mar 2023 (Internet Archive capture)
- GS1 EPC Tag Data Standard, Release 2.3, Ratified, Oct 2025 (Internet Archive capture): Table 10-1 and Table 14-16
- GS1 EPCIS example 9.6.1 ObjectEvent (ref.gs1.org)
- GS1 EPCIS example 9.6.3 AggregationEvent (ref.gs1.org)
- GS1 EPCIS GitHub: Example_9.6.1-ObjectEvent.jsonld
- GS1 EPCIS GitHub: Example_9.6.3-AggregationEvent.jsonld
- GS1 EPCIS GitHub: Digital Link versions of the examples (WithDigitalLinkID)
- EPCIS 2.0.0 JSON-LD context (ref.gs1.org)
- EPCIS 2.0.0 JSON-LD context, Internet Archive capture (copy read)
- EPCIS 2.0.0 JSON Schema (ref.gs1.org)
- EPCIS 2.0.0 JSON Schema, Internet Archive capture (copy read)
- GS1 EPCIS GitHub: public_review_2_1 folder
- GS1 EPCIS GitHub commit, 4 September 2026: public review draft v2.1 of epcis-context.jsonld