Implementation Guide

Step-by-step guide for implementing a GS1-native Battery Digital Product Passport with OpenEPCIS extensions

5 min read

Masterdata and eventsmasterDataAvailableFor is GS1 Web Vocabulary (no gs1: prefix needed). It is used to carry lot- or serial-level masterdata alongside an event: production batch, declaration references, incident records, regulatory citations. It must not carry GTIN-level masterdata (product name, generic specifications) — those live on the resolver, POSTed once via POST /products/{gtin}. Extension vocabularies (battery:, eudr:, textile:, electronics:) keep their prefix; they are declared in the document's @context.

Disclaimer: This is not official GS1 guidance, but it follows official GS1 standards and best practices:

We use GLN for parties/locations, GTIN+serial for products, and the regulatoryInformation pattern from GS1 EUDR. Feedback welcome!

Prerequisites

Before implementing the Battery DPP, ensure you have:

  • GS1 Company Prefix (for GTIN assignment)
  • GLN for your organization and facilities
  • EPCIS 2.0 capable repository
  • GS1 Digital Link resolver (or access to GS1 Verified by GS1)

Step 1: Assign GS1 Identifiers

Product Identification

  1. Assign GTIN to your battery product type:
    GTIN: 09521234000013
    
  2. Assign Serial Numbers to individual units:
    Serial: BAT2024-001
    Full Digital Link: https://id.gs1.org/01/09521234000013/21/BAT2024-001
    

Organization Identification

  1. GLN for manufacturer:
    Manufacturer GLN: 9521234000006
    URI: https://id.gs1.org/417/9521234000006
    
  2. GLN for production facility:
    Facility GLN: 9521234000013
    URI: https://id.gs1.org/414/9521234000013
    

Device Identification

  1. GIAI for measurement devices (BMS, test equipment):
    BMS GIAI: 9521987BMS-001
    URI: https://id.gs1.org/8004/9521987BMS-001
    

Step 2: Create Product Master Data

Create a JSON-LD file containing static battery information:

{
  "@context": [
    {
      "gs1": "https://ref.gs1.org/voc/"
    },
    {
      "battery": "https://ref.openepcis.io/extensions/eu/battery/"
    }
  ],
  "@id": "https://id.gs1.org/01/09521234000013/21/BAT2024-001",
  "@type": ["gs1:Product"],

  "gtin": "09521234000013",
  "serialNumber": "BAT2024-001",

  "manufacturer": {
    "@id": "https://id.gs1.org/417/9521234000006",
    "@type": "gs1:Organization",
    "organizationName": "Your Company Name",
    "gln": "9521234000006"
  },

  "batteryCategory": { "@id": "battery:IndustrialBattery" },

  "battery:technicalSpecifications": {
    "@type": "battery:TechnicalSpecification",
    "battery:ratedCapacity": {
      "@type": "gs1:QuantitativeValue",
      "value": "280",
      "unitCode": "AH"
    },
    "battery:ratedEnergy": {
      "@type": "gs1:QuantitativeValue",
      "value": "14.3",
      "unitCode": "KWH"
    }
  }
}

Required Fields per EU Battery Regulation

FieldPropertyRequired
Unique Identifier@idYes
Manufacturergs1:manufacturerYes
Production Dategs1:productionDateYes
Production Placegs1:placeOfProductProvenanceYes
Battery CategorybatteryCategoryYes
Battery Weightgs1:netWeightYes
Rated Capacitybattery:ratedCapacityYes
Rated Energybattery:ratedEnergyYes
Material Compositionbattery:materialCompositionYes
Hazardous Substancesbattery:hazardousSubstancesYes
Recycled Contentbattery:recycledContentYes

Step 3: Publish the battery linkset

The battery passport is exposed as an IETF application/linkset+json document (RFC 9264). One object per anchor identifier, GS1 link relations as full-IRI keys, link descriptors as values. For a serialised battery you typically want at least the consumer Product Information Page, the EPCIS event history, the compliance certificates and the EU Battery Regulation conformity declaration:

{
  "linkset": [
    {
      "anchor": "https://id.gs1.org/01/09521234000013/21/BAT2024-001",
      "itemDescription": "EcoCell IM-500 industrial battery module",
      "https://ref.gs1.org/voc/defaultLink": [
        { "href": "https://dpp.example.com/battery/09521234000013/BAT2024-001",
          "title": "Battery passport" }
      ],
      "https://ref.gs1.org/voc/pip": [
        { "href": "https://dpp.example.com/battery/09521234000013/BAT2024-001",
          "title": "Battery passport (consumer view)",
          "type": "text/html",
          "context": ["ALL"], "public": true }
      ],
      "https://ref.gs1.org/voc/epcis": [
        { "href": "https://api.example.com/events?MATCH_anyEPC=https%3A%2F%2Fid.gs1.org%2F01%2F09521234000013%2F21%2FBAT2024-001",
          "title": "EPCIS event history (SoH, shipping, recycling)",
          "type": "application/ld+json",
          "context": ["ALL"], "public": true }
      ],
      "https://ref.gs1.org/voc/certificationInfo": [
        { "href": "https://dpp.example.com/certs/09521234000013/BAT2024-001",
          "title": "EU Battery Regulation conformity & test reports",
          "type": "application/ld+json",
          "context": ["business", "authority"] }
      ],
      "https://ref.gs1.org/voc/productSustainabilityInfo": [
        { "href": "https://dpp.example.com/sustainability/09521234000013/BAT2024-001",
          "title": "Carbon footprint and recycled-content declaration",
          "type": "application/ld+json",
          "context": ["ALL"], "public": true }
      ]
    }
  ]
}

The ?linkType= query parameter on the resolver URL takes the bare relation name (pip, epcis, certificationInfo, productSustainabilityInfo). See Resolver Setup for hosting options.

Step 4: Integrate EPCIS Event Capture

Commissioning Event

Record when a battery is created. Per GS1 Germany EUDR Guideline V1.11, use masterDataAvailableFor for product master data (not ILMD):

{
  "@context": [
    "https://ref.gs1.org/standards/epcis/epcis-context.jsonld",
    { "battery": "https://ref.openepcis.io/extensions/eu/battery/", "gs1": "https://ref.gs1.org/voc/" }
  ],
  "type": "EPCISDocument",
  "schemaVersion": "2.0",
  "epcisBody": {
    "eventList": [{
      "type": "ObjectEvent",
      "eventID": "urn:uuid:YOUR-UUID-HERE",
      "eventTime": "2024-03-15T14:30:00.000Z",
      "eventTimeZoneOffset": "+01:00",
      "epcList": ["https://id.gs1.org/01/09521234000013/21/BAT2024-001"],
      "action": "ADD",
      "bizStep": "commissioning",
      "disposition": "active",
      "readPoint": { "id": "https://id.gs1.org/414/9521234000013" },
      "sensorElementList": [{
        "sensorMetadata": {
          "deviceID": "https://id.gs1.org/8004/9521234EOL-TEST-001"
        },
        "sensorReport": [
          { "type": "battery:stateOfHealth", "value": 100, "uom": "P1" },
          { "type": "battery:stateOfCharge", "value": 50, "uom": "P1" },
          { "type": "battery:cycleCount", "value": 0 }
        ]
      }],
      "masterDataAvailableFor": [{
        "id": "https://id.gs1.org/01/09521234000013/21/BAT2024-001",
        "battery:initialCapacity": { "value": "280", "unitCode": "AH" },
        "lotNumber": "BATCH-2024-03-A"
      }]
    }]
  }
}

Integration with BMS

Configure your Battery Management System to emit EPCIS events:

// Example: BMS to EPCIS event conversion
function createSoHEvent(battery, bmsData) {
  return {
    "@type": "ObjectEvent",
    "@id": `urn:uuid:${generateUUID()}`,
    "eventTime": new Date().toISOString(),
    "epcList": [{
      "@id": battery.digitalLinkUri,
      "masterDataAvailableFor": { "@id": battery.digitalLinkUri }
    }],
    "action": "OBSERVE",
    "bizStep": "inspecting",
    "sensorElementList": [{
      "sensorMetadata": {
        "deviceID": battery.bmsUri,
        "time": new Date().toISOString()
      },
      "sensorReport": [
        { "type": "battery:stateOfHealth", "value": bmsData.soh, "uom": "P1" },
        { "type": "battery:stateOfCharge", "value": bmsData.soc, "uom": "P1" },
        { "type": "battery:cycleCount", "value": bmsData.cycles },
        { "type": "battery:internalResistance", "value": bmsData.resistance, "uom": "OHM" }
      ]
    }]
  };
}

Step 5: Handle Ownership Transfers

When battery ownership changes:

{
  "@context": "https://ref.gs1.org/standards/epcis/epcis-context.jsonld",
  "@type": "ObjectEvent",
  "action": "OBSERVE",
  "bizStep": "accepting",
  "disposition": "in_transit",
  "sourceList": [
    {
      "@type": "source",
      "type": "owning_party",
      "source": "https://id.gs1.org/417/9521234000006"
    }
  ],
  "destinationList": [
    {
      "@type": "destination",
      "type": "owning_party",
      "destination": "https://id.gs1.org/417/9521987000001"
    }
  ],
  "bizTransactionList": [
    {
      "@type": "bizTransaction",
      "type": "po",
      "bizTransaction": "https://buyer.example.com/orders/PO-2024-0089"
    }
  ]
}

Step 6: Record Negative Events

Capture accidents, damage, or safety incidents. Use masterDataAvailableFor for incident data:

{
  "@context": [
    "https://ref.openepcis.io/extensions/eu/battery/battery-context.jsonld",
    "https://ref.gs1.org/standards/epcis/epcis-context.jsonld"
  ],
  "type": "ObjectEvent",
  "action": "OBSERVE",
  "bizStep": "inspecting",
  "disposition": "damaged",
  "epcList": [
    "https://id.gs1.org/01/09521234000013/21/BAT2024-001"
  ],
  "battery:incidentSeverity": "Minor",
  "sensorElementList": [
    {
      "sensorReport": [
        {
          "type": "battery:stateOfHealth",
          "value": 93.8,
          "uom": "P1"
        }
      ]
    }
  ],
  "masterDataAvailableFor": [
    {
      "id": "https://id.gs1.org/01/09521234000013/21/BAT2024-001",
      "battery:incidentId": "INC-2025-00023",
      "battery:recommendedAction": "Continue monitoring. Schedule follow-up in 30 days."
    }
  ],
  "bizTransactionList": [
    {
      "type": "urn:epcglobal:cbv:btt:cert",
      "bizTransaction": "https://example.com/incidents/INC-2025-00023.pdf"
    }
  ]
}

Validation

  • JSON-LD shape — normalises against the EPCIS and battery contexts.
  • EPCIS events — unique event @id (UUID), correct bizStep / disposition from CBV, masterDataAvailableFor on EPCs, UN/CEFACT Rec 20 unit codes.

Next steps