Skip to content

Quickstart

Create an API key, make your first request and read a passport in a few minutes.

You need:

  • the BatteryPass address of your organisation, for example https://batterypass.example.com;
  • the owner role in that organisation, or an owner who creates the key for you;
  • curl and jq, or Node.js 20+ (the TypeScript samples are ES modules, e.g. npx tsx quickstart.mts), Python 3 with requests, or Go.

Create an API key

An owner signs in to the BatteryPass portal, opens Settings → API keys and chooses Create API key. Give the key a name that says which system uses it, and select the scope Read (read). The scope Report condition data (condition) is only for systems that report measurements and lifecycle events.

The secret starts with bp_live_ and is shown only once. Copy it into your secret store right away; it cannot be displayed again. Keys are managed only in the portal, not through the API.

Set two environment variables

Shell
export BATTERYPASS_URL="https://batterypass.example.com"
export BATTERYPASS_API_KEY="bp_live_..."

BATTERYPASS_URL is your organisation's BatteryPass address without a trailing slash. Every sample on this site reads these two variables. More in Environments and base URL.

Make your first request

List the first five battery models of your organisation with listBatteryModels:

cURL
curl -sS "$BATTERYPASS_URL/api/v1/battery-models?limit=5" \
  -H "Authorization: Bearer $BATTERYPASS_API_KEY"
200
{
  "items": [
    {
      "id": "0192f0a1-6c2e-7d4b-9a10-3e5f7b2c8d41",
      "name": "SolarVolt Home 10",
      "sku": "SV-H10",
      "gtin": "04012345000023",
      "category": "stationary",
      "archived_at": null,
      "row_version": 3,
      "created_at": "2026-01-08T09:12:44Z",
      "updated_at": "2026-03-02T15:40:10Z"
    }
  ],
  "next_cursor": null
}

A 401 means the header is missing or the key is unknown or revoked; a 403 means the key lacks the read scope. See Authentication and Errors.

List battery models in code

const res = await fetch(`${process.env.BATTERYPASS_URL}/api/v1/battery-models?limit=50`, {
  headers: { Authorization: `Bearer ${process.env.BATTERYPASS_API_KEY}` },
});
if (!res.ok) throw new Error(`listBatteryModels: ${res.status} ${await res.text()}`);

const page: { items: { id: string; name: string; gtin: string | null }[]; next_cursor: string | null } =
  await res.json();
for (const model of page.items) console.log(model.name, model.gtin ?? '(no GTIN)', model.id);
if (page.next_cursor) console.log('More models on the next page.');

Lists return at most limit items and a next_cursor; Pagination shows how to read all pages.

Read the passport of a unit

Find a unit with a published passport with listBatteries, then read its passport with getPassport:

BATTERY_ID=$(curl -sS "$BATTERYPASS_URL/api/v1/batteries?passport_status=published&limit=1" \
  -H "Authorization: Bearer $BATTERYPASS_API_KEY" | jq -r '.items[0].id')

curl -sS "$BATTERYPASS_URL/api/v1/batteries/$BATTERY_ID/passport" \
  -H "Authorization: Bearer $BATTERYPASS_API_KEY"
200
{
  "battery_id": "0192f0a3-1b7c-7e2a-8f45-6a9d0c3e5b12",
  "status": "published",
  "serial_number": "SV2027-000001",
  "gtin": "04012345000023",
  "passport_id": "urn:dpp:0192f3c4-7e1a-7b2c-9d3e-5f6a7b8c9d0e",
  "gs1_digital_link": "https://batterypass.example.com/01/04012345000023/21/SV2027-000001",
  "public_url": "https://batterypass.example.com/pass/0192f3c4-7e1a-7b2c-9d3e-5f6a7b8c9d0e",
  "first_published_at": "2026-03-10T08:30:00Z",
  "identifiers_locked_at": "2026-03-10T08:30:00Z",
  "row_version": 4
}

The response also carries current_version with the version number, the hashes and the signing key of the current version. A unit that was never published has a passport in status draft without passport_id.

Read the public passport without a key

The public tier of a published passport needs no key. getPublicPassport takes the UUID part of passport_id, without the prefix urn:dpp::

PASSPORT_UUID=$(curl -sS "$BATTERYPASS_URL/api/v1/batteries/$BATTERY_ID/passport" \
  -H "Authorization: Bearer $BATTERYPASS_API_KEY" | jq -r '.passport_id | sub("^urn:dpp:"; "")')

curl -sS "$BATTERYPASS_URL/api/v1/public/passports/$PASSPORT_UUID" | jq '{passport_id, status, links}'

document is the signed public projection of the current version; verification holds its Ed25519 signature. Passports that are not public (for example withdrawn) answer with their status and no document. Public reads are cached for five minutes and limited to 300 requests per minute per client address.

Next steps

On this page