Developers
Two APIs
Passport management API
/openapi.jsonFor the company that owns the passports: list models and items (by cursor, with updatedSince for synchronisation), create items, ranges and copies of models, update item data, publish (one item or in the background) and get QR codes. Authenticated with an API key.
Reference: Passport management APIDPP API (EN 18222)
/openapi-dpp.jsonLife Cycle and Fine Granular API following EN 18222: read passports at your access level, search passport IDs by product ID, record events (repair, state of health, status) with an OAuth 2.0 access token. Public data can be read without a token.
Reference: DPP API (EN 18222)
Read a passport
Every passport address answers with JSON when you ask for it – no key needed for public data. The headers carry the version, its SHA-256 and the Ed25519 signature, so you can check what you read against our public keys.
curl -i -H "Accept: application/json" \https://batterycompliance.eu/id/BG123456789/EBIKE-48V/SN0001 HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8X-Passport-Version: 3X-Passport-Access-Level: publicX-Passport-SHA256: bd4c49c7b04ac463…81146b938X-Passport-Signature: Tw0bRkvf+s3IS1MQ…MPZ7Dg==X-Passport-Key-Id: batterycompliance-2026-09-25Link: </schema/battery-passport/2.0.0>; rel="describedby" { "dppHeader": { "dppStatus": { "dppStatusValue": "active" }, … }, "identifiersAndProductData": { "batterySerialNumber": "SN0001", … }, … }How the APIs work
Authentication
API keys are created by the company owner in Company → API keys and shown once. Send them as Authorization: Bearer bcp_live_…. Scopes: items:read, items:write (also reads), items:publish, qr:read.
OAuth 2.0 clients (client credentials) are created by the company owner for its partners, or by the platform for authorities and approved third parties. Get a token with POST /oauth/token (grant_type=client_credentials); it is valid for 15 minutes. Scopes: dpp:read, dpp:search, dpp:write.
Limits and errors
60 requests per minute per API key (headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) and 120 per minute per OAuth client or, without a token, per address. Over the limit: HTTP 429 with Retry-After.
The passport management API answers errors with an error object of code, message and details; the DPP API answers statusCode, payload and result with the status codes of EN 18222.
DPP API updates accept an Idempotency-Key header: the same key with the same request within 24 hours returns the first answer and creates no second version.
Public passports
Every passport has a permanent address (GS1 Digital Link /01/{GTIN}/21/{serial} or /id/{operator}/{model}/{serial}). With Accept: application/json or ?format=json it returns the JSON of the latest version for your access level; ?version=N a given version; /versions the list.
Every version is signed: X-Passport-SHA256 carries the SHA-256 of the RFC 8785 canonical JSON of the full version, X-Passport-Signature its Ed25519 signature over that hex string and X-Passport-Key-Id the key that signed it. The public keys and the schema are listed under Machine-readable descriptions.
Webhooks
Instead of polling, add an endpoint in Company → Webhooks. Events – passport.published, publish_job.finished, item.lifecycle_recorded, access_request.created, passport.transferred, label_template.issued, dossier.ready, import_batch.assigned, import_batch.confirmed, import_batch.rejected – are POSTed as JSON with the headers X-Webhook-Id, X-Webhook-Timestamp and X-Webhook-Signature = v1= + hex HMAC-SHA256 of timestamp.body with your secret. Answer 2xx within 10 seconds; failed deliveries are retried for 24 hours.
Machine-readable descriptions
- Public signing keys (JWKS)/.well-known/batterycompliance-signing-key.json
- Passport JSON schema/schema/battery-passport/2.0.0
- OpenAPI 3.1 – passport management API/openapi.json
- OpenAPI 3.1 – DPP API/openapi-dpp.json
Get an API key
Register your company, then create a key in Company → API keys. Keys are shown once and stored only as a hash.