Skip to main content

List, import, update and publish battery items (digital battery passports under Regulation (EU) 2023/1542). Authenticate with an API key created by the company owner: Authorization: Bearer bcp_live_…. Limit: 60 requests per minute per key. Errors: { "error": { "code", "message", "details"? } }. Plan limits answer 403 with details.code: no_subscription (the company has no subscription), expired (the paid plan ended or stopped for late payment – the limits of Free apply; limit is Free's), models_limit, items_limit, items_unlocked (monthly Business unlocks a twelfth of its passports per paid month), open_items_limit (a manufacturer outside the EU above its cap of open items – drafts and batteries in batches not confirmed yet), files_quota (no room left in the company's files; limit, used, remaining in bytes).

GET/api/v1/models

List the company's models

Scope: items:read or items:write. Sorted by model code. Pages: pass `nextCursor` of the response as `cursor` until it is null.

Parameters

FieldInTypeDetails
limitqueryintegeroptional – Page size (default 100; items up to 1000, models up to 500).
cursorquerystringoptional – `nextCursor` of the previous page.

Responses

  • 200 Models
    {
      "models": [
        {
          "id": "cmu4a0z9y0000model1234abc",
          "code": "KS-16X",
          "name": "KS-16X Pack 1500 Wh",
          "category": "LMT",
          "status": "published",
          "gtin": "03850012345678",
          "schemaVersion": "2.0.0",
          "createdAt": "2026-09-16T09:00:00.000Z",
          "updatedAt": "2026-09-18T12:30:00.000Z"
        }
      ],
      "nextCursor": null
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/models" \
  -H "Authorization: Bearer $BCP_API_KEY"

POST/api/v1/models/{modelId}/duplicate

Copy a model with its documents as a new draft

Scope: items:write. The model attributes and own copies of the documents (links in the attributes point to the copies); items and versions are not copied. GTIN required for operators with GS1 identifiers, within the verified company prefix. The copies of the documents count towards the company's files: a manufacturer outside the EU keeps up to 2 GB, otherwise 403 with `details.code = files_quota` (`limit`, `used`, `remaining` in bytes) and nothing is copied.

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Request body

FieldTypeDetails
codestring (^[A-Za-z0-9._-]{1,50}$)required
namestringrequired
gtinstringoptional – GTIN-14 (or 8/12/13 digits, normalised)

Example

{
  "code": "KS-16X-1800",
  "name": "KS-16X Pack 1800 Wh",
  "gtin": "03850012345685"
}

Responses

  • 201 Created
    {
      "id": "cmu7q2d3e0000copy1234abcd",
      "code": "KS-16X-1800",
      "name": "KS-16X Pack 1800 Wh",
      "gtin": "03850012345685",
      "category": "LMT",
      "status": "draft",
      "documents": 4
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 409 Error
  • 422 Error
  • 429 Error

curl

curl -X POST "https://batterycompliance.eu/api/v1/models/$MODEL_ID/duplicate" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"KS-16X-1800","name":"KS-16X Pack 1800 Wh","gtin":"03850012345685"}'

GET/api/v1/models/{modelId}/items

List the items of a model

Scope: items:read or items:write. Sorted by serial number, up to 1000 per page. Pages: pass `nextCursor` of the response as `cursor` until it is null; every item is returned once, also when items are added meanwhile. Synchronisation: `updatedSince` returns only items created or changed at or after that time (store the time before you start and use it next time).

Parameters

FieldInTypeDetails
modelIdpathstringrequired
limitqueryintegeroptional – Page size (default 100; items up to 1000, models up to 500).
cursorquerystringoptional – `nextCursor` of the previous page.
updatedSincequerystring (date-time)optional – RFC 3339 date-time with a time zone, e.g. 2026-09-21T08:00:00Z.

Responses

  • 200 Items
    {
      "items": [
        {
          "id": "cmu4a1b2c0000abcd1234efgh",
          "serial": "KS16X-2026-000123",
          "uri": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123",
          "status": "original",
          "dppStatus": "active",
          "manufacturingDate": "2026-08",
          "putIntoServiceDate": null,
          "facilityCode": "SOF1",
          "attributes": {
            "performanceAndDurability": {
              "stateOfCharge": {
                "percentageValue": 80
              }
            }
          },
          "latestVersion": {
            "versionNo": 2,
            "publishedAt": "2026-09-18T12:31:04.512Z"
          },
          "changedSincePublication": false,
          "transferredTo": null,
          "createdAt": "2026-09-16T09:05:00.000Z",
          "updatedAt": "2026-09-18T12:31:04.530Z"
        }
      ],
      "nextCursor": "S1MxNlgtMjAyNi0wMDAxMjM"
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/models/$MODEL_ID/items" \
  -H "Authorization: Bearer $BCP_API_KEY"

POST/api/v1/models/{modelId}/items

Create items (all-or-nothing, up to 1000 per request)

Scope: items:write. Items are created with a permanent URI (GS1 Digital Link or own scheme). Plan limit: 403 with `details.code = items_limit | items_unlocked | expired | no_subscription`, or `open_items_limit` for a manufacturer outside the EU (it prepares free on every plan up to its cap of open items; its passports are counted when its importers confirm their batches).

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Request body

FieldTypeDetails
itemsarray of objectrequired

Example

{
  "items": [
    {
      "serial": "KS16X-2026-000123",
      "manufacturingDate": "2026-08",
      "facilityCode": "SOF1",
      "status": "original",
      "attributes": {
        "performanceAndDurability": {
          "stateOfCharge": {
            "percentageValue": 80,
            "percentUnit": "%"
          }
        }
      }
    }
  ]
}

Responses

  • 201 Created
    {
      "created": [
        {
          "id": "cmu4a1b2c0000abcd1234efgh",
          "serial": "KS16X-2026-000123",
          "uri": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123"
        }
      ],
      "errors": []
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 409 Error
  • 422 Error
  • 429 Error

curl

curl -X POST "https://batterycompliance.eu/api/v1/models/$MODEL_ID/items" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"serial":"KS16X-2026-000123","manufacturingDate":"2026-08","facilityCode":"SOF1","status":"original","attributes":{"performanceAndDurability":{"stateOfCharge":{"percentageValue":80,"percentUnit":"%"}}}}]}'

POST/api/v1/models/{modelId}/items/range

Create a range of items with consecutive serial numbers (all-or-nothing, up to 20,000)

Scope: items:write. Serial numbers are prefix + the number padded to `digits` + suffix, e.g. KS16X-2026-00001 … KS16X-2026-05000. Existing serial numbers → 409 with their count and examples; nothing is created. Plan limit: as for POST /items – 403 with `details.code = items_limit | items_unlocked | expired | no_subscription | open_items_limit`.

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Request body

FieldTypeDetails
prefixstring (^[A-Za-z0-9._-]{0,40}$)required
suffixstring (^[A-Za-z0-9._-]{0,40}$)optional
startintegerrequired
countintegerrequired
digitsintegerrequired
manufacturingDatestring (^[0-9]{4}-(0[1-9]|1[0-2])$)required
facilityCodestringoptional
status"original" | "waste"optional – repurposed, reused and remanufactured are set through the link to the original passport (Art. 77(7))
putIntoServiceDatestring (^[0-9]{4}-(0[1-9]|1[0-2])$)optional

Example

{
  "prefix": "KS16X-2026-",
  "start": 1,
  "count": 5000,
  "digits": 5,
  "manufacturingDate": "2026-09",
  "facilityCode": "SOF1",
  "status": "original"
}

Responses

  • 201 Created
    {
      "created": 5000,
      "first": "KS16X-2026-00001",
      "last": "KS16X-2026-05000"
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 409 Error
  • 422 Error
  • 429 Error

curl

curl -X POST "https://batterycompliance.eu/api/v1/models/$MODEL_ID/items/range" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prefix":"KS16X-2026-","start":1,"count":5000,"digits":5,"manufacturingDate":"2026-09","facilityCode":"SOF1","status":"original"}'

POST/api/v1/models/{modelId}/import-batches

Assign batteries of a model to an importer as a batch (manufacturer outside the EU)

Scope: items:publish. The operator that places the battery on the EU market pays (docs/35): the passports of a batch count in full in the payer's plan when the importer confirms the batch – the importer, unless the manufacturer pays. Who pays is the link's choice (Company → Importers; the importer by default) and is recorded on the batch when it is assigned; it does not change after the confirmation. `billedTo: "manufacturer"` makes the manufacturer pay for this batch, as "Pay for this batch" in the panel: its plan must have room for the batch's passports, otherwise 403 with `details.code = plan_limit` (`items`, `limit`, `used`, `unlocked`) and nothing is assigned. Only the importer confirms the batch, in its panel (there is no API for it); then it is the responsible economic operator in the passports and they are published – the manufacturer never publishes them by itself. The confirmation is refused with `link_pending` until the importer has accepted the link (its written authorisation, Art. 77(4)), with `brand_declaration` without the declaration that the batteries are placed on the market under the manufacturer's name or trademark and are not modified, and with `plan_limit` when the payer's plan has no room – the batch then waits and the manufacturer is told by e-mail. The link must be active, or the importer one not on the platform yet (entered in Company → Importers and invited by e-mail): the batch waits until it registers, accepts the link and confirms. Until then the batch can be withdrawn in the panel. Registering the batch through the EU registry's API on the importer's behalf needs a paid plan of the payer in force (otherwise `payer_plan`: prepare the registry file, which works on every plan).

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Request body

FieldTypeDetails
importerstringrequired – The importer's operator code: an active link, or an importer not on the platform yet that the manufacturer invited by e-mail (Company → Importers).
serialsarray of stringoptional
rangeobjectoptional – Serial numbers compared as text, both included.
allUnassignedtrueoptional
codestringoptional – Batch code; default {model}-{YYYYMMDD}-{n}. Sent to the EU registry as the batch identifier.
expectedArrivalstring (date)optional
notestringoptional
billedTo"manufacturer"optional – The manufacturer pays for this batch (optional; default: the link's choice). Checked against its plan: 403 with details.code = plan_limit when it has no room.

Example

{
  "importer": "BG206000000",
  "range": {
    "from": "KS16X-2026-00001",
    "to": "KS16X-2026-00500"
  },
  "code": "CONT-MSKU1234567",
  "expectedArrival": "2026-11-20",
  "billedTo": "manufacturer"
}

Responses

  • 201 Assigned
    {
      "id": "cm…",
      "code": "CONT-MSKU1234567",
      "status": "assigned",
      "items": 500,
      "billedTo": "manufacturer",
      "skipped": []
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 409 Error
  • 422 Error
  • 429 Error

curl

curl -X POST "https://batterycompliance.eu/api/v1/models/$MODEL_ID/import-batches" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"importer":"BG206000000","range":{"from":"KS16X-2026-00001","to":"KS16X-2026-00500"},"code":"CONT-MSKU1234567","expectedArrival":"2026-11-20","billedTo":"manufacturer"}'

GET/api/v1/import-batches/{batchId}

A batch for an importer with its serial numbers (the manufacturer's or the importer's key)

Scope: items:read. `billedTo` – who pays for the passports of the batch: the importer, or the manufacturer; they count in the payer's plan when the importer confirms the batch (`status = confirmed`).

Parameters

FieldInTypeDetails
batchIdpathstringrequired

Responses

  • 200 The batch
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/import-batches/$BATCH_ID" \
  -H "Authorization: Bearer $BCP_API_KEY"

POST/api/v1/models/{modelId}/publish-jobs

Publish items of a model in the background

Scope: items:publish. Publishes the not yet published items (includeUnpublished) and/or those changed since their last version (includeChanged); both by default, the body may be empty. One queued or running job per model (409). Poll the job with GET until status is done or failed. For a manufacturer outside the EU only the batteries of batches its importers confirmed are candidates; without such batteries 422 (nothing to publish). A job started through the API publishes like POST /items/{itemId}/publish: at most one version a day per passport from the company's systems – a later change waits and is published when the day is over (counted in `deferred`); a first publication is never held back.

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Request body

FieldTypeDetails
includeUnpublishedbooleanoptional
includeChangedbooleanoptional

Example

{
  "includeUnpublished": true,
  "includeChanged": true
}

Responses

  • 202 Accepted; Location header points to the job
    {
      "id": "cmu7p0b1c0000pjob1234abcd",
      "status": "queued",
      "total": 5000
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 409 Error
  • 422 Error
  • 429 Error

curl

curl -X POST "https://batterycompliance.eu/api/v1/models/$MODEL_ID/publish-jobs" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"includeUnpublished":true,"includeChanged":true}'

GET/api/v1/models/{modelId}/publish-jobs/{jobId}

Progress of a publishing job

Scope: items:publish. `failures` lists the first 1000 items that could not be published (incomplete or invalid data).

Parameters

FieldInTypeDetails
modelIdpathstringrequired
jobIdpathstringrequired

Responses

  • 200 Job
    {
      "id": "cmu7p0b1c0000pjob1234abcd",
      "status": "done",
      "total": 5000,
      "published": 4997,
      "deferred": 0,
      "failed": 3,
      "failures": [
        {
          "serial": "KS16X-2026-00042",
          "code": "incomplete",
          "missing": 2
        }
      ],
      "error": null,
      "createdAt": "2026-09-18T10:00:00.000Z",
      "startedAt": "2026-09-18T10:00:00.120Z",
      "finishedAt": "2026-09-18T10:00:41.700Z"
    }
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/models/$MODEL_ID/publish-jobs/$JOB_ID" \
  -H "Authorization: Bearer $BCP_API_KEY"

PATCH/api/v1/items/{itemId}

Update an item

Scope: items:write. `attributes` are merged into the existing item attributes; only item-level fields of the catalogue are accepted.

Parameters

FieldInTypeDetails
itemIdpathstringrequired

Request body

FieldTypeDetails
status"original" | "repurposed" | "reused" | "remanufactured" | "waste"optional
putIntoServiceDateoptional
attributesobjectoptional – Item-level passport attributes by section, as in https://batterycompliance.eu/schema/battery-passport/2.0.0

Example

{
  "status": "repurposed",
  "putIntoServiceDate": "2026-10",
  "attributes": {
    "performanceAndDurability": {
      "stateOfCharge": {
        "percentageValue": 64
      }
    }
  }
}

Responses

  • 200 Updated item
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 422 Error
  • 429 Error

curl

curl -X PATCH "https://batterycompliance.eu/api/v1/items/$ITEM_ID" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"repurposed","putIntoServiceDate":"2026-10","attributes":{"performanceAndDurability":{"stateOfCharge":{"percentageValue":64}}}}'

POST/api/v1/items/{itemId}/publish

Publish a new passport version

Scope: items:publish. Validates against the JSON schema and the category profile; missing fields mandatory from 02/2027 block publication (422). A new version is made only when the content changed. At most one automatic version (API key or OAuth client) a day per passport: a later change is stored and published when the day is over – the response gives publishAfter (docs/32, task 118). 200 with unchanged: true when nothing changed; 202 with publishAfter when the change waits. A manufacturer outside the EU never publishes by itself (docs/35): 409 with `details.code = importer_required` when the battery is in no batch, `import_pending` when its batch is not confirmed by the importer yet. A battery of a confirmed batch was counted at the confirmation and is not counted again. First publication of a draft above the plan in force: 403 with `details.code = items_limit`.

Parameters

FieldInTypeDetails
itemIdpathstringrequired

Responses

  • 201 Published
    {
      "versionNo": 2,
      "sha256": "9f2c…",
      "url": "https://batterycompliance.eu/01/03850012345678/21/KS16X-2026-000123?version=2",
      "backupConfirmed": true
    }
  • 401 Error
  • 403 Error
  • 404 Error
  • 422 Not publishable
    {
      "error": {
        "code": "unprocessable",
        "message": "Mandatory fields are missing",
        "details": {
          "missing": [
            "identifiersAndProductData.batteryMass"
          ]
        }
      }
    }
  • 429 Error

curl

curl -X POST "https://batterycompliance.eu/api/v1/items/$ITEM_ID/publish" \
  -H "Authorization: Bearer $BCP_API_KEY"

GET/api/v1/items/{itemId}/qr

QR code of the item URI

Scope: qr:read. Error correction level M. Recommended minimum printed size 15 × 15 mm.

Parameters

FieldInTypeDetails
itemIdpathstringrequired
formatquery"svg" | "png"optional
sizequeryintegeroptional – PNG width in pixels (64–2048)
captionquery"1"optional – 1 – adds "Battery passport" below the code (not required by Annex VI Part C; tells the holder what the code opens)

Responses

  • 200 QR code
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/items/$ITEM_ID/qr" \
  -H "Authorization: Bearer $BCP_API_KEY"

GET/api/v1/documents

Generated documents of the operator

Scope: documents:read. Documents issued by the compliance assistants (labels, declarations, policies, reports) with their signed versions. Public kinds also have a verification page at verifyUrl.

Parameters

FieldInTypeDetails
kindquery"label_template" | "capacity_label" | "carbon_label" | "transport_label" | "packaging_label" | "eu_doc" | "packaging_doc" | "carbon_declaration" | "dd_policy" | "dd_report" | "dossier_manifest" | "packaging_report"optional – One of the document kinds
modelIdquerystringoptional – Documents of one battery model

Responses

  • 200 Documents
    {
      "documents": [
        {
          "id": "cmgd1",
          "kind": "eu_doc",
          "title": "EU declaration of conformity – KS-16X",
          "modelId": "cmmodel1",
          "labelProductId": null,
          "variant": "",
          "createdAt": "2026-09-23T10:00:00.000Z",
          "versions": [
            {
              "versionNo": 1,
              "issuedAt": "2026-09-23T10:00:00.000Z",
              "sha256": "9f86…",
              "keyId": "batterycompliance-2026-1",
              "pdfSize": 48213,
              "verifyUrl": "https://batterycompliance.eu/verify/document/cmgd1/1",
              "modelDocumentId": "cmmd1",
              "backedUp": true
            }
          ]
        }
      ]
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/documents" \
  -H "Authorization: Bearer $BCP_API_KEY"

GET/api/v1/documents/{documentId}/{versionNo}

One version of a generated document: signed data or PDF

Scope: documents:read. JSON with the signed envelope (data), its SHA-256 (over the canonical JSON, RFC 8785), the Ed25519 signature and the key id. With format=pdf (or Accept: application/pdf) the PDF is returned; its metadata and footer carry the same hash and key.

Parameters

FieldInTypeDetails
documentIdpathstringrequired
versionNopathintegerrequired
formatquery"json" | "pdf"optional

Responses

  • 200 Document version
    {
      "document": {
        "id": "cmgd1",
        "kind": "eu_doc",
        "title": "EU declaration of conformity – KS-16X",
        "modelId": "cmmodel1",
        "labelProductId": null,
        "variant": ""
      },
      "version": {
        "versionNo": 1,
        "issuedAt": "2026-09-23T10:00:00.000Z",
        "sha256": "9f86…",
        "signature": "base64…",
        "keyId": "batterycompliance-2026-1",
        "pdfSha256": "ab12…",
        "pdfSize": 48213,
        "verifyUrl": "https://batterycompliance.eu/verify/document/cmgd1/1",
        "modelDocumentId": "cmmd1",
        "backedUp": true,
        "data": {
          "kind": "eu_doc",
          "documentId": "cmgd1",
          "versionNo": 1,
          "issuedAt": "2026-09-23T10:00:00Z",
          "title": "EU declaration of conformity – KS-16X",
          "operator": {
            "name": "Kingsong Europe EOOD",
            "eoCode": "BG206000000"
          },
          "subject": {
            "type": "model",
            "code": "KS-16X"
          },
          "content": {}
        }
      }
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/documents/$DOCUMENT_ID/$VERSION_NO" \
  -H "Authorization: Bearer $BCP_API_KEY"

GET/api/v1/models/{modelId}/label-templates

Issued label templates of a model

Scope: documents:read or items:read. The general label (Annex VI Part A), the capacity label (Art. 13(2)), the carbon footprint class label (Art. 7) and the transport labels (one per shipment mode, `mode`: alone – UN 3480/3090, in_equipment – UN 3481/3091 packed in equipment, with_equipment – packed with equipment) issued by the label assistant, with their versions and file addresses. Use the file addresses as listed: those of a transport label carry its mode.

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Responses

  • 200 Templates
    {
      "templates": [
        {
          "id": "cmgd2",
          "kind": "label_template",
          "title": "Battery label – KS-16X",
          "versions": [
            {
              "versionNo": 1,
              "issuedAt": "2026-09-23T10:00:00.000Z",
              "sha256": "9f86…",
              "keyId": "batterycompliance-2026-1",
              "verifyUrl": "https://batterycompliance.eu/verify/document/cmgd2/1",
              "files": [
                "/api/v1/models/cmmodel1/label-templates/1.svg?kind=label_template",
                "/api/v1/models/cmmodel1/label-templates/1.pdf?kind=label_template",
                "/api/v1/models/cmmodel1/label-templates/1.png?kind=label_template"
              ]
            }
          ]
        }
      ]
    }
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/models/$MODEL_ID/label-templates" \
  -H "Authorization: Bearer $BCP_API_KEY"

GET/api/v1/models/{modelId}/label-templates/{file}

SVG, PDF or PNG of an issued label version

Scope: documents:read or items:read. `{file}` is `{versionNo}.svg`, `{versionNo}.pdf` (the stored sample) or `{versionNo}.png` (600 dpi by default). With `serial` the general label is rendered for that item (serial number, month/year, its passport QR).

Parameters

FieldInTypeDetails
modelIdpathstringrequired
filepathstringrequired
kindquery"label_template" | "capacity_label" | "carbon_label" | "transport_label"optional
modequery"alone" | "in_equipment" | "with_equipment"optional – A transport label: the shipment mode it was issued for (the `mode` of the template in the list)
serialquerystringoptional
batchquerystringoptional
dpiqueryintegeroptional

Responses

  • 200 Label file
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/models/$MODEL_ID/label-templates/$FILE" \
  -H "Authorization: Bearer $BCP_API_KEY"

GET/api/v1/models/{modelId}/items/labels.pdf

Sheets of item labels from an issued template

Scope: items:read or documents:read. Each item gets the general label of template version `template` with its serial number, month/year and passport QR; on A4 unless `paper` chooses another sheet or a custom size (`orientation=landscape` turns it); as many labels per sheet as fit inside 8 mm margins, or the grid of `columns`, `rows`, `marginTopMm`, `marginLeftMm`, `gapXMm`, `gapYMm` (400 if it does not fit the sheet). Up to 5 000 labels per file.

Parameters

FieldInTypeDetails
modelIdpathstringrequired
templatequeryintegerrequired – Version number of the issued general label template
prefixquerystringoptional – Serial number starts with
fromqueryintegeroptional – Position in the list sorted by serial number
limitqueryintegeroptional
batchquerystringoptional – Value of the {batch} field
paperquery"A4" | "A5" | "A3" | "Letter" | "Legal" | "custom"optional – Sheet size; `custom` takes paperWidthMm and paperHeightMm
orientationquery"portrait" | "landscape"optional – Landscape swaps the sheet's width and height
paperWidthMmquerynumberoptional – Width of a custom sheet (mm)
paperHeightMmquerynumberoptional – Height of a custom sheet (mm)
columnsqueryintegeroptional – Labels per row (with a grid; 1–20)
rowsqueryintegeroptional – Labels per column (with a grid; 1–40)
marginTopMmquerynumberoptional – Top margin of the grid (mm)
marginLeftMmquerynumberoptional – Left margin of the grid (mm)
gapXMmquerynumberoptional – Horizontal gap between labels (mm)
gapYMmquerynumberoptional – Vertical gap between labels (mm)

Responses

  • 200 PDF
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/models/$MODEL_ID/items/labels.pdf" \
  -H "Authorization: Bearer $BCP_API_KEY"

GET/api/v1/models/{modelId}/packaging

Packaging specification of a model (Regulation (EU) 2025/40)

Scope: packaging:read or packaging:write. Components, volumes, summary by material and the checks (problem / attention / information, each with the article and the date it applies from). See docs/24.

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Responses

  • 200 Specification
    {
      "status": "issued",
      "version": 1,
      "issuedAt": "2026-09-23T10:00:00.000Z",
      "packagingVolumeCm3": 4000,
      "productVolumeCm3": 2600,
      "minimisationJustified": true,
      "minimisationNote": "Annex IV assessed",
      "designForRecyclingNote": null,
      "components": [
        {
          "level": "sales",
          "type": "box",
          "material": "paperCardboard",
          "materialCode": "PAP 20",
          "massG": 180,
          "recycledContentPct": 80,
          "reusable": false,
          "heavyMetalsDeclared": true,
          "supplier": "Cartons Ltd",
          "inksAdhesivesNote": null,
          "note": null,
          "id": "cmpc1"
        }
      ],
      "summary": {
        "totalMassG": 180,
        "byMaterial": [
          {
            "material": "paperCardboard",
            "massG": 180,
            "share": 100
          }
        ],
        "byLevel": [
          {
            "level": "sales",
            "massG": 180
          }
        ],
        "reusableMassG": 0,
        "recycledMassG": 144
      },
      "checks": [
        {
          "code": "recyclability",
          "severity": "info",
          "article": "Art. 6",
          "appliesFrom": "2030-01-01"
        }
      ]
    }
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/models/$MODEL_ID/packaging" \
  -H "Authorization: Bearer $BCP_API_KEY"

PUT/api/v1/models/{modelId}/packaging

Update the packaging specification

Scope: packaging:write; feature packaging (Business/Enterprise). Volumes and notes are merged; `components` replaces all components (up to 10 000). The specification returns to draft.

Parameters

FieldInTypeDetails
modelIdpathstringrequired

Request body

Example

{
  "packagingVolumeCm3": 4000,
  "productVolumeCm3": 2600,
  "minimisationJustified": true,
  "components": [
    {
      "level": "sales",
      "type": "box",
      "material": "paperCardboard",
      "materialCode": "PAP 20",
      "massG": 180,
      "recycledContentPct": 80,
      "reusable": false,
      "heavyMetalsDeclared": true,
      "supplier": "Cartons Ltd",
      "inksAdhesivesNote": null,
      "note": null
    },
    {
      "level": "transport",
      "type": "film",
      "material": "plastic",
      "materialCode": "LDPE 4",
      "massG": 25,
      "heavyMetalsDeclared": true
    }
  ]
}

Responses

  • 200 Specification after the update (same shape as GET)
  • 400 Error
  • 401 Error
  • 403 Error
  • 404 Error
  • 429 Error

curl

curl -X PUT "https://batterycompliance.eu/api/v1/models/$MODEL_ID/packaging" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"packagingVolumeCm3":4000,"productVolumeCm3":2600,"minimisationJustified":true,"components":[{"level":"sales","type":"box","material":"paperCardboard","materialCode":"PAP 20","massG":180,"recycledContentPct":80,"reusable":false,"heavyMetalsDeclared":true,"supplier":"Cartons Ltd","inksAdhesivesNote":null,"note":null},{"level":"transport","type":"film","material":"plastic","materialCode":"LDPE 4","massG":25,"heavyMetalsDeclared":true}]}'

GET/api/v1/registrations

Producer registrations by country

Scope: registrations:read. The markets of the company, its registrations as a producer of batteries (Art. 55) and packaging (Art. 44–45 of Regulation (EU) 2025/40) by country, with the status applied to the validity date, and the warnings (markets without registration, expiring within 90 days, expired). Not the EU battery passport registry.

Responses

  • 200 Registrations
    {
      "markets": [
        "BG",
        "DE"
      ],
      "registrations": [
        {
          "id": "cmr1",
          "country": "DE",
          "countryName": "Germany",
          "scheme": "batteries",
          "status": "registered",
          "registrationNumber": "WEEE-Reg.-Nr. DE 12345678",
          "organisation": "stiftung ear",
          "representativeName": null,
          "representativeCountry": null,
          "validUntil": "2027-06-30",
          "documentUrl": null,
          "note": null,
          "updatedAt": "2026-09-23T10:00:00.000Z"
        }
      ],
      "warnings": {
        "marketsWithoutRegistration": [
          {
            "country": "DE",
            "scheme": "packaging"
          }
        ],
        "expiring": [],
        "expired": []
      }
    }
  • 401 Error
  • 403 Error
  • 429 Error

curl

curl -X GET "https://batterycompliance.eu/api/v1/registrations" \
  -H "Authorization: Bearer $BCP_API_KEY"

POST/api/v1/verify

Bulk verification of passports

Scope: verify:read; feature verify_bulk (Business and Enterprise). For importers and distributors (Art. 41–42): up to 10 000 permanent passport addresses of any operator on the platform, or serial numbers together with a model address. For each: status (published, archived, suspended, deleted 410, moved, not_found, invalid), the latest version and its date, the model code and whether the model has an issued label template and EU declaration of conformity – facts that are public on the passport page. Drafts never published count as not found. The request is one entry in the access log (with the count) and a run in the operator's history. Body: JSON, or text/csv (first column; model address in ?model=). 200 checks per operator and hour.

Request body

Example

{
  "items": [
    "https://batterycompliance.eu/01/04012345678901/21/SN0001",
    "SN0002"
  ],
  "model": "https://batterycompliance.eu/01/04012345678901"
}

Responses

  • 200 Results in the order of the input
    {
      "runId": "cmv1",
      "summary": {
        "total": 2,
        "found": 1,
        "published": 1,
        "archived": 0,
        "suspended": 0,
        "deleted": 0,
        "moved": 0,
        "notFound": 1,
        "invalid": 0
      },
      "results": [
        {
          "input": "https://batterycompliance.eu/01/04012345678901/21/SN0001",
          "uri": "https://batterycompliance.eu/01/04012345678901/21/SN0001",
          "status": "published",
          "httpStatus": 200,
          "versionNo": 3,
          "publishedAt": "2026-09-23T08:00:00.000Z",
          "model": "KS-16X",
          "labelTemplate": true,
          "euDeclaration": true
        },
        {
          "input": "SN0002",
          "uri": "https://batterycompliance.eu/01/04012345678901/21/SN0002",
          "status": "not_found",
          "httpStatus": 404,
          "versionNo": null,
          "publishedAt": null,
          "model": null,
          "labelTemplate": null,
          "euDeclaration": null
        }
      ]
    }
  • 400 Error
  • 401 Error
  • 403 Error
  • 422 Error
  • 429 Error

curl

curl -X POST "https://batterycompliance.eu/api/v1/verify" \
  -H "Authorization: Bearer $BCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items":["https://batterycompliance.eu/01/04012345678901/21/SN0001","SN0002"],"model":"https://batterycompliance.eu/01/04012345678901"}'