Authentication
Organisation API keys, their scopes, what a key may do and how to rotate it.
Every operation of the API needs an API key of your organisation, except the public passport reads (tag
public), which need none.
Send the key
Send the key in the Authorization header with the Bearer scheme:
Authorization: Bearer bp_live_...curl -sS "$BATTERYPASS_URL/api/v1/registry" \
-H "Authorization: Bearer $BATTERYPASS_API_KEY"The API reads keys only from this header. Never put a key into a URL: query strings and paths end up in logs, browser histories and proxies.
Organisation keys
- A key belongs to the organisation, not to a member. It keeps working when the member who created it leaves.
- Owners create and revoke keys in the portal under Settings → API keys. Key management is not part of the API.
- The secret is
bp_live_followed by 43 characters. It is shown once, when the key is created. BatteryPass stores only a SHA-256 hash and shows the first 12 characters as a prefix so you can tell keys apart. - An organisation has at most 25 active keys. A revoked key stays listed with its revocation time and never works again.
- Keys have no expiry date. You end a key by revoking it (see Rotate a key).
Scopes
A key has one or more scopes. Each operation names the scope it needs in x-api-key-scope in the contract and
on its page in the API reference.
| Scope | Allows | Operations |
|---|---|---|
read | Reading what a viewer of the organisation sees: models, versions, units, values with provenance and completeness, evidence, facilities, passports with versions, diffs and exports, lifecycle events, condition data, the registry | Every operation with x-api-key-scope: read |
condition | Reporting condition data and lifecycle events | updateCondition, createLifecycleEvent |
import | Staging spreadsheet imports of units: upload, map, validate and follow them; members commit and approve them in the portal (ADR-026) | createImport, updateImportMapping, validateImport, getImport, listImports |
The scopes do not include each other. A battery management system that reports measurements and also reads
the current condition with getCondition needs both.
To list every operation with its scope, read the contract of your deployment:
curl -sS "$BATTERYPASS_URL/api/v1/openapi.json" \
| jq -r '.paths[][] | objects | select(has("operationId")) | "\(.operationId)\t\(.["x-api-key-scope"] // "public")"'What a key may do
A key acts in its organisation with the rights of a viewer. Where an operation's description names a role
("any member", "editors and above"), a key counts as a viewer. The exceptions: the two operations of the
condition scope accept a key with that scope, and the import operations of the import scope accept a key with
that one.
A key never:
- creates or changes declared data (models, units, values, documents);
- reviews, approves, publishes or withdraws anything, and never commits or approves an import, also one it staged;
- manages members, API keys or organisation settings.
These stay with members in the portal, so the four-eyes principle and the publication checks keep their
meaning. What a key reports is recorded with the source api, and the lifecycle event of the report names
the key in its api_key member.
Session and key together
A request that carries both a portal session cookie and an API key is refused with 401. This can happen when
you try requests in a browser in which you are signed in to the portal. Use a client without cookies, such as
curl or your server code.
401 or 403
| Status | code | Cause | What to do |
|---|---|---|---|
401 | unauthenticated | The header is missing or malformed, the key is unknown or revoked, or the request also carries a session cookie | Check the header and the environment variable; ask an owner for a new key if it was revoked |
403 | forbidden | The key lacks the operation's scope, or the action needs more than a viewer's rights | Use a key with the right scope; actions beyond a viewer's rights are done in the portal |
429 | rate_limited | Too many attempts with unknown or revoked keys from your client address | Stop and fix the key; see Rate limits |
Do not retry a 401 in a loop. Requests with unknown or revoked keys are limited to 30 attempts per 15
minutes per client address; after that, further attempts with such a key get 429 instead of 401 until
the window ends.
Rotate a key
Keys do not expire, so rotate them yourself: on a regular schedule, at once when a key may have leaked, and when someone who knew it leaves.
Create the new key
An owner creates a new key with the same scopes in Settings → API keys.
Deploy it
Put the new secret into your secret store and restart or reconfigure the system that uses it.
Check that the old key is idle
In the portal, the old key's "Last used" time stops changing. It is updated at most once a minute.
Revoke the old key
Revoking takes effect at once and cannot be undone.
Keep keys secret
- Use keys only in server-side systems, never in browser code, mobile apps or public repositories.
- Create one key per system, so you can revoke one without stopping the others.
- Give each key only the scopes it needs.
- The prefix
bp_live_makes leaked keys easy to find for secret scanners.
More in Secure key handling and Security.