EPCIS 2.0 Integration
EPCIS 2.0 (Electronic Product Code Information Services) is the GS1 global standard for supply chain event data. This guide covers mapping Optropic provenance events to EPCIS 2.0 and enabling interoperability with legacy supply chain systems.
Overviewโ
What is EPCIS 2.0?โ
EPCIS 2.0 is a standardized XML/JSON framework for capturing and sharing supply chain events. It enables:
- Visibility: Track products through the entire supply chain
- Interoperability: Exchange data between different systems and trading partners
- Standards Compliance: Align with GS1 global standards
- Event Types: Object, Aggregation, Transaction, and Transformation events
Key Specifications:
- Standard: GS1 EPCIS 2.0.1 (Latest)
- Format: XML and JSON representations
- EPC Identifiers: GTIN, Serial Numbers, Batch/Lot
- Event Attributes: Timestamp, Location, Business Step, Disposition
Provenance Event Mappingโ
Optropic provenance events map to EPCIS 2.0 event types as follows:
| Optropic Event | EPCIS 2.0 Event | Business Step | Disposition | Description |
|---|---|---|---|---|
| manufactured | TransformationEvent | commissioning | active | Product created; raw materials transformed into finished product |
| labeled | ObjectEvent | encoding | encoded | DPP or serial number assigned to product |
| enrolled | ObjectEvent | commissioning | active | Product registered in DPP Registry (approximate mapping) |
| shipped | ObjectEvent | shipping | in_transit | Product handed to carrier/logistics provider |
| received | ObjectEvent | receiving | active | Product received at destination and inventory updated |
| transferred | TransactionEvent | holding | active | Ownership/custody transferred between parties (approximate) |
| verified | ObjectEvent | inspecting | active | Quality, compliance, or authenticity verified |
| recalled | ObjectEvent | holding | recalled | Product recalled due to safety/compliance issue |
| destroyed | ObjectEvent | decommissioning | destroyed | Product permanently destroyed/recycled |
| custom | ObjectEvent | holding | active | User-defined event (fallback mapping) |
Core Functionsโ
mapToEPCIS / map_to_epcisโ
Converts a single Optropic provenance event to EPCIS 2.0 format:
- TypeScript
- Python
import { ProvenanceEvent, mapToEPCIS, EventType } from '@heimdall/epcis';
const event: ProvenanceEvent = {
eventType: EventType.SHIPPED,
productId: "08714043123452",
timestamp: "2026-03-15T14:30:00Z",
location: "DE-BW-70174", // GS1 GLN (or ISO 3166-1 + postal code)
actor: "logistics.company@example.com",
metadata: {
carrier: "DPD Express",
trackingNumber: "DPD123456789",
expectedDeliveryDate: "2026-03-18"
}
};
const epcisEvent = mapToEPCIS(event);
console.log(JSON.stringify(epcisEvent, null, 2));
/* Output:
{
"type": "ObjectEvent",
"eventID": "urn:uuid:...",
"eventTime": "2026-03-15T14:30:00Z",
"recordTime": "2026-03-15T14:30:00Z",
"epcList": ["urn:epc:id:sgtin:..."],
"action": "OBSERVE",
"bizStep": "urn:epcis:vtype:BusinessStep#shipping",
"disposition": "urn:epcis:vtype:Disposition#in_transit",
"readPoint": {
"id": "urn:epc:id:sgln:...location"
},
"bizLocation": {
"id": "urn:epc:id:sgln:...location"
},
"bizTransactionList": [
{
"type": "urn:epcis:vtype:BizTransactionType#po",
"bizTransaction": "..."
}
],
"extension": {
"carrier": "DPD Express",
"trackingNumber": "DPD123456789"
}
}
*/
from heimdall.epcis import ProvenanceEvent, EventType, map_to_epcis
import json
event = ProvenanceEvent(
event_type=EventType.SHIPPED,
product_id="08714043123452",
timestamp="2026-03-15T14:30:00Z",
location="DE-BW-70174",
actor="logistics.company@example.com",
metadata={
"carrier": "DPD Express",
"tracking_number": "DPD123456789",
"expected_delivery_date": "2026-03-18"
}
)
epcis_event = map_to_epcis(event)
print(json.dumps(epcis_event, indent=2))
toEPCISEvent / to_epcis_eventโ
Lower-level function for constructing EPCIS event objects with granular control:
- TypeScript
- Python
import { toEPCISEvent, EPCISEventType } from '@heimdall/epcis';
const epcisEvent = toEPCISEvent({
type: EPCISEventType.OBJECT,
eventID: "urn:uuid:12345678-1234-5678-1234-567812345678",
eventTime: "2026-03-15T14:30:00Z",
recordTime: "2026-03-15T14:30:01Z",
epcList: [
"urn:epc:id:sgtin:0871404.312345.2026001",
"urn:epc:id:sgtin:0871404.312345.2026002"
],
action: "OBSERVE",
bizStep: "urn:epcis:vtype:BusinessStep#shipping",
disposition: "urn:epcis:vtype:Disposition#in_transit",
readPoint: {
id: "urn:epc:id:sgln:0871404.00001.0"
},
bizLocation: {
id: "urn:epc:id:sgln:0871404.00001.0"
},
extension: {
carrier: "DPD Express",
temperature: 22.5,
humidity: 45
}
});
console.log(epcisEvent);
from heimdall.epcis import to_epcis_event, EPCISEventType
epcis_event = to_epcis_event(
type=EPCISEventType.OBJECT,
event_id="urn:uuid:12345678-1234-5678-1234-567812345678",
event_time="2026-03-15T14:30:00Z",
record_time="2026-03-15T14:30:01Z",
epc_list=[
"urn:epc:id:sgtin:0871404.312345.2026001",
"urn:epc:id:sgtin:0871404.312345.2026002"
],
action="OBSERVE",
biz_step="urn:epcis:vtype:BusinessStep#shipping",
disposition="urn:epcis:vtype:Disposition#in_transit",
read_point={
"id": "urn:epc:id:sgln:0871404.00001.0"
},
biz_location={
"id": "urn:epc:id:sgln:0871404.00001.0"
},
extension={
"carrier": "DPD Express",
"temperature": 22.5,
"humidity": 45
}
)
print(epcis_event)
buildEPCISDocument / build_epcis_documentโ
Constructs a complete EPCIS document containing multiple events:
- TypeScript
- Python
import { buildEPCISDocument } from '@heimdall/epcis';
const epcisDocument = buildEPCISDocument({
version: "2.0.1",
schemaVersion: "urn:gs1:gtin:13",
creationDateTime: "2026-03-15T15:00:00Z",
sender: {
gln: "5412345000013",
name: "ACME Corporation"
},
receiver: {
gln: "4006381333931",
name: "Distributor Ltd"
},
events: [epcisEvent1, epcisEvent2, epcisEvent3],
masterData: {
epcClassList: [
{
epc: "urn:epc:class:lgtin:0871404.312345.2026",
attributes: {
productName: "Eco Battery Pack 5000mAh",
productBrand: "Green Energy"
}
}
]
}
});
// Serialize to XML
const xmlDocument = epcisDocument.toXML();
console.log(xmlDocument);
from heimdall.epcis import build_epcis_document
epcis_document = build_epcis_document(
version="2.0.1",
schema_version="urn:gs1:gtin:13",
creation_date_time="2026-03-15T15:00:00Z",
sender={
"gln": "5412345000013",
"name": "ACME Corporation"
},
receiver={
"gln": "4006381333931",
"name": "Distributor Ltd"
},
events=[epcis_event_1, epcis_event_2, epcis_event_3],
master_data={
"epc_class_list": [
{
"epc": "urn:epc:class:lgtin:0871404.312345.2026",
"attributes": {
"product_name": "Eco Battery Pack 5000mAh",
"product_brand": "Green Energy"
}
}
]
}
)
# Serialize to XML
xml_document = epcis_document.to_xml()
print(xml_document)
provenanceChainToEPCIS / provenance_chain_to_epcisโ
Converts an entire provenance chain to an EPCIS document:
- TypeScript
- Python
import { provenanceChainToEPCIS } from '@heimdall/epcis';
const provenanceChain = [
{
eventType: EventType.MANUFACTURED,
timestamp: "2026-01-10T08:00:00Z",
location: "CN-SH-200010",
actor: "factory@greenergy.cn"
},
{
eventType: EventType.LABELED,
timestamp: "2026-01-10T09:30:00Z",
location: "CN-SH-200010",
actor: "labeling@greenergy.cn"
},
{
eventType: EventType.SHIPPED,
timestamp: "2026-01-15T14:00:00Z",
location: "CN-SH-200010",
actor: "export@greenergy.cn",
metadata: { carrier: "COSCO" }
},
{
eventType: EventType.RECEIVED,
timestamp: "2026-02-20T16:30:00Z",
location: "DE-BW-70174",
actor: "warehouse@distributor.de"
}
];
const epcisDocument = provenanceChainToEPCIS(
provenanceChain,
{
gs1CompanyPrefix: "0871404",
gtin: "08714043123452",
serialNumber: "2026001"
}
);
console.log(epcisDocument.toJSON());
from heimdall.epcis import provenance_chain_to_epcis, EventType
provenance_chain = [
{
"event_type": EventType.MANUFACTURED,
"timestamp": "2026-01-10T08:00:00Z",
"location": "CN-SH-200010",
"actor": "factory@greenergy.cn"
},
{
"event_type": EventType.LABELED,
"timestamp": "2026-01-10T09:30:00Z",
"location": "CN-SH-200010",
"actor": "labeling@greenergy.cn"
},
{
"event_type": EventType.SHIPPED,
"timestamp": "2026-01-15T14:00:00Z",
"location": "CN-SH-200010",
"actor": "export@greenergy.cn",
"metadata": {"carrier": "COSCO"}
},
{
"event_type": EventType.RECEIVED,
"timestamp": "2026-02-20T16:30:00Z",
"location": "DE-BW-70174",
"actor": "warehouse@distributor.de"
}
]
epcis_document = provenance_chain_to_epcis(
provenance_chain,
{
"gs1_company_prefix": "0871404",
"gtin": "08714043123452",
"serial_number": "2026001"
}
)
print(epcis_document.to_json())
GS1 Digital Link Supportโ
EPCIS 2.0 supports GS1 Digital Links, which enable web-resolvable product URLs:
- TypeScript
- Python
import { mapToEPCIS, GenerateDigitalLinkOptions } from '@heimdall/epcis';
const event = {
eventType: EventType.SHIPPED,
productId: "08714043123452",
timestamp: "2026-03-15T14:30:00Z",
location: "DE-BW-70174"
};
const epcisEvent = mapToEPCIS(event, {
gs1CompanyPrefix: "0871404",
generateDigitalLink: true,
digitalLinkBaseUrl: "https://id.gs1.org" // Default GS1 resolver
});
console.log(epcisEvent.extension?.digitalLink);
// Output: https://id.gs1.org/01/08714043123452
from heimdall.epcis import map_to_epcis
event = {
"event_type": EventType.SHIPPED,
"product_id": "08714043123452",
"timestamp": "2026-03-15T14:30:00Z",
"location": "DE-BW-70174"
}
epcis_event = map_to_epcis(
event,
gs1_company_prefix="0871404",
generate_digital_link=True,
digital_link_base_url="https://id.gs1.org"
)
print(epcis_event.extension.get("digital_link"))
# Output: https://id.gs1.org/01/08714043123452
EPCIS Event Types Referenceโ
ObjectEventโ
Captures events where objects (products) are observed at a location:
- Common Use: Shipping, receiving, quality checks
- Action: OBSERVE, ADD, DELETE
- Disposition: active, in_transit, recalled, destroyed
TransformationEventโ
Captures events where raw materials are transformed into finished products:
- Common Use: Manufacturing, assembly
- Input/Output EPCs: Distinguish consumed vs. produced items
TransactionEventโ
Captures business transactions:
- Common Use: Purchase orders, invoices
- Party: Seller, buyer, invoice recipient
AggregationEventโ
Captures grouping of products into larger units:
- Common Use: Pallet formation, case packing
Integration Patternsโ
Pattern 1: DPP + EPCIS Workflowโ
- Create DPP metadata for product
- Generate initial
manufacturedandlabeledprovenance events - Map events to EPCIS using
mapToEPCIS - Transmit EPCIS document to GS1 network or trading partner
Pattern 2: Existing Supply Chain Systemโ
- Extract supply chain events from legacy system (ERP, WMS)
- Map to Optropic
ProvenanceEventformat - Use
provenanceChainToEPCISto generate EPCIS document - Publish to GS1 Discovery Service or internal resolver
Pattern 3: Real-Time Event Streamingโ
- Listen to supply chain events (IoT sensors, checkpoint scanning)
- Build EPCIS events incrementally
- Push to EPCIS repository or subscription service
- Enable downstream partners to query events
Best Practicesโ
1. Unique Event Identifiersโ
Always generate unique eventID (UUID v4) for each event:
urn:uuid:12345678-1234-5678-1234-567812345678
2. Timestamp Accuracyโ
Use ISO 8601 timestamps with timezone information:
2026-03-15T14:30:00Z (UTC)
2026-03-15T14:30:00+02:00 (with offset)
3. EPC Encodingโ
Use standardized EPC URIs for traceability:
- SGTIN (Serialized GTIN):
urn:epc:id:sgtin:... - SSCC (Serial Shipping Container Code):
urn:epc:id:sscc:... - GTIN (Global Trade Item Number):
urn:epc:id:gtin:...
4. Business Contextโ
Always include business step and disposition for downstream queries:
bizStep: "urn:epcis:vtype:BusinessStep#receiving"
disposition: "urn:epcis:vtype:Disposition#active"
5. Extension Dataโ
Leverage extension field for custom metadata while maintaining standard compliance:
extension: {
temperature: 22.5,
humidity: 45,
signedBy: "warehouse_manager@company.com"
}
Related Documentationโ
- Digital Product Passport โ Core DPP data structures
- DPP Access Control โ Manage visibility of DPP + EPCIS data
- GS1 EPCIS 2.0 Standard โ https://www.gs1.org/standards/epcis
- GS1 Digital Link โ https://www.gs1.org/services/how-it-works-epcis