Skip to main content

Battery Compliance DPP API (EN 18222)

Life Cycle API and Fine Granular API for digital battery passports, following the method names and status codes of EN 18222 as described in BatteryPass-Ready “User Stories from a Technical Perspective” v1.0 (tables 1, 2, 4). DPP ID = Product ID = the permanent item URI; in paths it is URL-encoded (encodeURIComponent). Reading public data needs no token. Controlled data, search and updates need an OAuth 2.0 access token (client credentials, POST /oauth/token). Responses: { statusCode, payload?, result? }. A passport payload is { dpp, version, accessLevel, links }: dpp is the signed passport filtered to the caller's access level; links lists the Art. 77(7) links to the passports of the original batteries (predecessors) and to new passports (successors) – they are not part of the signed passport.

POST/oauth/token

Obtain an access token (OAuth 2.0 client credentials)

Request body

FieldTypeDetails
grant_typerequired
scopestringoptional – space-separated subset of dpp:read dpp:search dpp:write
client_idstringoptional
client_secretstringoptional

Example

grant_type=client_credentials&scope=dpp%3Aread

Responses

  • 200 Token
    {
      "access_token": "eyJhbGciOiJFZERTQSIs…",
      "token_type": "Bearer",
      "expires_in": 900,
      "scope": "dpp:read dpp:write"
    }
  • 400 invalid_request, unsupported_grant_type, invalid_scope
  • 401 invalid_client

curl

curl -X POST "https://batterycompliance.eu/oauth/token" \
  -d "grant_type=client_credentials&scope=dpp%3Aread"

GET/api/dpp/v1/dpps

ReadDPPByProductId – current active DPP for a Product ID

Parameters

FieldInTypeDetails
productIdquerystring (uri)required

Responses

  • 200 Active DPP filtered to the caller's access rights
    {
      "statusCode": "Success",
      "payload": {
        "dpp": {
          "dppHeader": {
            "digitalProductPassportId": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
            "dppStatus": {
              "dppStatusValue": "active"
            }
          },
          "performanceAndDurability": {
            "stateOfCharge": {
              "percentageValue": 80,
              "percentUnit": "%"
            }
          }
        },
        "version": {
          "versionNo": 3,
          "publishedAt": "2026-10-01T08:00:00.000Z",
          "sha256": "9f2c…",
          "signature": "base64…"
        },
        "accessLevel": "legitimateInterest",
        "links": {
          "predecessors": [],
          "successors": []
        }
      }
    }
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }

curl

curl -X GET "https://batterycompliance.eu/api/dpp/v1/dpps" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

POST/api/dpp/v1/dpps

CreateDPP – not provided (501 ServerNotImplemented)

Responses

  • 501 Not implemented

curl

curl -X POST "https://batterycompliance.eu/api/dpp/v1/dpps" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

GET/api/dpp/v1/dpps/{dppId}

ReadDPPById – latest version of a DPP, whatever its status

Parameters

FieldInTypeDetails
dppIdpathstringrequired – URL-encoded DPP ID (permanent URI)

Responses

  • 200 DPP
    {
      "statusCode": "Success",
      "payload": {
        "dpp": {
          "dppHeader": {
            "digitalProductPassportId": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
            "dppStatus": {
              "dppStatusValue": "active"
            }
          },
          "performanceAndDurability": {
            "stateOfCharge": {
              "percentageValue": 80,
              "percentUnit": "%"
            }
          }
        },
        "version": {
          "versionNo": 3,
          "publishedAt": "2026-10-01T08:00:00.000Z",
          "sha256": "9f2c…",
          "signature": "base64…"
        },
        "accessLevel": "legitimateInterest",
        "links": {
          "predecessors": [],
          "successors": []
        }
      }
    }
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }

curl

curl -X GET "https://batterycompliance.eu/api/dpp/v1/dpps/$DPP_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

PATCH/api/dpp/v1/dpps/{dppId}

UpdateDPPById – partial update of item-level data elements; creates a new signed version

Body: partial DPP by section. `null` removes an element. Every element must be within the client's write paths; identifiers, header and model data are immutable. Only active DPPs. All-or-nothing validation against the schema and the category profile. Optional Idempotency-Key header. Recycling (Art. 77(8)): `{"dppHeader":{"dppStatus":{"dppStatusValue":"archived"}},"identifiersAndProductData":{"batteryStatus":{"batteryStatusValues":"waste"}}}` with the scope dpp:recycle records that the battery was recycled – a last archived version is published and the passport is frozen (the "Marked for Deletion" step of BatteryPass-Ready, with the EN 18223 statuses). At most one automatic version a day per passport: a later change is stored and published when the day is over (the response gives publishAfter); the battery status, the putting into service and accidents are published at once.

Parameters

FieldInTypeDetails
dppIdpathstringrequired – URL-encoded DPP ID (permanent URI)
Idempotency-Keyheaderstringoptional

Request body

Example

{
  "identifiersAndProductData": {
    "batteryStatus": {
      "batteryStatusValues": "repurposed"
    }
  },
  "performanceAndDurability": {
    "stateOfCharge": {
      "percentageValue": 80
    }
  }
}

Responses

  • 200 Updated DPP (new version)
    {
      "statusCode": "Success",
      "payload": {
        "dpp": {
          "dppHeader": {
            "digitalProductPassportId": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
            "dppStatus": {
              "dppStatusValue": "active"
            }
          },
          "performanceAndDurability": {
            "stateOfCharge": {
              "percentageValue": 80,
              "percentUnit": "%"
            }
          }
        },
        "version": {
          "versionNo": 3,
          "publishedAt": "2026-10-01T08:00:00.000Z",
          "sha256": "9f2c…",
          "signature": "base64…"
        },
        "accessLevel": "legitimateInterest",
        "links": {
          "predecessors": [],
          "successors": []
        }
      }
    }
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }
  • 409 Status does not allow the update, or Idempotency-Key reuse
    {
      "statusCode": "ClientResourceConflict",
      "result": {
        "message": "The DPP status is archived; only active DPPs can be updated"
      }
    }

curl

curl -X PATCH "https://batterycompliance.eu/api/dpp/v1/dpps/$DPP_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"identifiersAndProductData":{"batteryStatus":{"batteryStatusValues":"repurposed"}},"performanceAndDurability":{"stateOfCharge":{"percentageValue":80}}}'

DELETE/api/dpp/v1/dpps/{dppId}

DeleteDPPById – delete a passport after the battery was recycled (Art. 77(8))

Only the economic operator's own clients with the scope dpp:delete, only after the recycling was recorded (UpdateDPPById with dpp:recycle, or in the panel); a recycling recorded by another company (a recycler) holds the deletion for 14 days (409 with `details.deletableFrom`), while the platform administrator can still reverse a wrong record. Deletes every version, its backup copies and the readings; the permanent address then answers 410 Gone and is never used for another battery. Notify the EU registry of the deletion.

Parameters

FieldInTypeDetails
dppIdpathstringrequired – URL-encoded DPP ID (permanent URI)

Responses

  • 200 Deleted
    {
      "statusCode": "Success",
      "payload": {
        "dppId": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
        "deleted": true,
        "versions": 4
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }
  • 409 Status does not allow the update, or Idempotency-Key reuse
    {
      "statusCode": "ClientResourceConflict",
      "result": {
        "message": "The DPP status is archived; only active DPPs can be updated"
      }
    }

curl

curl -X DELETE "https://batterycompliance.eu/api/dpp/v1/dpps/$DPP_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

GET/api/dpp/v1/dpps/{dppId}/versions

ReadDPPVersionByIdAndDate – the version valid at a timestamp

Parameters

FieldInTypeDetails
dppIdpathstringrequired – URL-encoded DPP ID (permanent URI)
datequerystring (date-time)required

Responses

  • 200 DPP version
    {
      "statusCode": "Success",
      "payload": {
        "dpp": {
          "dppHeader": {
            "digitalProductPassportId": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
            "dppStatus": {
              "dppStatusValue": "active"
            }
          },
          "performanceAndDurability": {
            "stateOfCharge": {
              "percentageValue": 80,
              "percentUnit": "%"
            }
          }
        },
        "version": {
          "versionNo": 3,
          "publishedAt": "2026-10-01T08:00:00.000Z",
          "sha256": "9f2c…",
          "signature": "base64…"
        },
        "accessLevel": "legitimateInterest",
        "links": {
          "predecessors": [],
          "successors": []
        }
      }
    }
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }

curl

curl -X GET "https://batterycompliance.eu/api/dpp/v1/dpps/$DPP_ID/versions" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

GET/api/dpp/v1/dpps/{dppId}/elements/{elementPath}

ReadDataElement – one data element (section.attribute[.part])

Parameters

FieldInTypeDetails
dppIdpathstringrequired – URL-encoded DPP ID (permanent URI)
elementPathpathstringrequired

Responses

  • 200 Element
    {
      "statusCode": "Success",
      "payload": {
        "dppId": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
        "elementPath": "performanceAndDurability.stateOfCharge",
        "value": {
          "percentageValue": 80,
          "percentUnit": "%"
        },
        "versionNo": 3
      }
    }
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }

curl

curl -X GET "https://batterycompliance.eu/api/dpp/v1/dpps/$DPP_ID/elements/$ELEMENT_PATH" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

PATCH/api/dpp/v1/dpps/{dppId}/elements/{elementPath}

UpdateDataElement – set or remove (value: null) one attribute; creates a new version

At most one automatic version a day per passport: a later change is stored and published when the day is over (the response gives publishAfter); the battery status, the putting into service and accidents are published at once.

Parameters

FieldInTypeDetails
dppIdpathstringrequired – URL-encoded DPP ID (permanent URI)
elementPathpathstringrequired
Idempotency-Keyheaderstringoptional

Request body

Example

{
  "value": {
    "percentageValue": 64
  }
}

Responses

  • 200 Updated element
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }
  • 409 Status does not allow the update, or Idempotency-Key reuse
    {
      "statusCode": "ClientResourceConflict",
      "result": {
        "message": "The DPP status is archived; only active DPPs can be updated"
      }
    }

curl

curl -X PATCH "https://batterycompliance.eu/api/dpp/v1/dpps/$DPP_ID/elements/$ELEMENT_PATH" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value":{"percentageValue":64}}'

POST/api/dpp/v1/dpps/search

ReadDPPIdsByProductIds – DPP IDs for up to 100 Product IDs (identifiers only)

Request body

FieldTypeDetails
productIdsarray of string (uri)required
limitintegeroptional
cursorstringoptional

Example

{
  "productIds": [
    "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123"
  ],
  "limit": 50
}

Responses

  • 200 DPP IDs; cursor present when more results exist
    {
      "statusCode": "Success",
      "payload": {
        "dppIds": [
          "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123"
        ]
      }
    }
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }

curl

curl -X POST "https://batterycompliance.eu/api/dpp/v1/dpps/search" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"productIds":["https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123"],"limit":50}'

POST/api/dpp/v1/dpps/{dppId}/readings

AddReadings – store dynamic data readings (platform extension, not an EN 18222 method); optionally apply the latest values as a new version

Paths: item-level attributes with dynamic data (state of charge, remaining capacity, cycles, temperature…) within the client's write paths. Readings do not create a version unless apply is true. Only active DPPs. With apply, at most one automatic version a day per passport: a later apply stores the values and answers with publishAfter, when the maintenance publishes them.

Parameters

FieldInTypeDetails
dppIdpathstringrequired – URL-encoded DPP ID (permanent URI)

Request body

Example

{
  "readings": [
    {
      "path": "performanceAndDurability.stateOfCharge",
      "value": {
        "percentageValue": 76
      },
      "measuredAt": "2026-10-01T08:00:00Z",
      "source": "bms"
    },
    {
      "path": "performanceAndDurability.numberOfFullChargingAndDischargingCycles",
      "value": 312,
      "measuredAt": "2026-10-01T08:00:00Z",
      "source": "bms"
    }
  ],
  "apply": true
}

Responses

  • 201 Stored
    {
      "statusCode": "SuccessCreated",
      "payload": {
        "dppId": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
        "created": 2,
        "versionNo": 4
      }
    }
  • 400 Malformed or invalid request
    {
      "statusCode": "ClientErrorBadRequest",
      "result": {
        "message": "productIds must be a non-empty array"
      }
    }
  • 401 Missing, invalid, expired or revoked access token
    {
      "statusCode": "ClientNotAuthorized",
      "result": {
        "message": "Invalid access token"
      }
    }
  • 403 No access to the DPP, element or operation
    {
      "statusCode": "ClientForbidden",
      "result": {
        "message": "No write access to these data elements"
      }
    }
  • 404 DPP or element does not exist
    {
      "statusCode": "ClientErrorResourceNotFound",
      "result": {
        "message": "No DPP with this identifier"
      }
    }
  • 409 Status does not allow the update, or Idempotency-Key reuse
    {
      "statusCode": "ClientResourceConflict",
      "result": {
        "message": "The DPP status is archived; only active DPPs can be updated"
      }
    }

curl

curl -X POST "https://batterycompliance.eu/api/dpp/v1/dpps/$DPP_ID/readings" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"readings":[{"path":"performanceAndDurability.stateOfCharge","value":{"percentageValue":76},"measuredAt":"2026-10-01T08:00:00Z","source":"bms"},{"path":"performanceAndDurability.numberOfFullChargingAndDischargingCycles","value":312,"measuredAt":"2026-10-01T08:00:00Z","source":"bms"}],"apply":true}'