Developers · Reference

Error code index

Every error code the Battery Passport API returns — top-level and per row in bulk responses — with its HTTP status, what it means and how to fix it.

Version
v1.0.0
Base URL
https://dppapi-production.up.railway.app/v1
Format
JSON · OpenAPI 3.1
FeedbackLast updated
On this page400 · Bad request

Every value of error the API answers with — 36 in all — grouped by HTTP status. Each has a stable link, so a log line or a support ticket can point straight at it. Most are snake_case codes; a few older routes answer with a short English message such as Not found, listed here under its own spelling. For the error shape, validation details and request IDs, see Errors.

422 Unprocessable Entity
{"error": "idempotency_key_reused","message": "This Idempotency-Key was already used for a different request. Use a new key for a new request.","request_id": "3f1c2a9e-8d4b-4c6f-9e2a-7b5d1c0e8f34"}

400 Bad request

401 Unauthorised

  • The API key is missing, malformed, unknown or revoked.

    FixSend Authorization: Bearer dpp_live_… (or dpp_test_…). A revoked key never comes back — create a new one under Organisation → API keys.

    Every /v1 endpoint except GET /openapi.json

402 Payment required

403 Forbidden

  • The key is valid but lacks the scope this call needs: read for GET (and POST /models/validate), write for everything else.

    FixUse a key with the write scope for writes. Scopes are fixed when a key is created; see Authentication.

    Any write (POST, PATCH, PUT)
  • A DELETE was sent with an API key. Records are never deleted over the API — a passport must stay available for ten years.

    FixRecycle or change the status instead, or delete in the app, where deletions are audited. See Why there is no DELETE.

    Any DELETE

404 Not found

409 Conflict

  • The organisation is frozen and read-only. Published passports keep resolving and data stays exportable.

    FixfrozenAt and reason say when and why. Reads and exports keep working; contact us to reactivate.

    Extra properties: frozenAt reason

    Any write (POST, PATCH, PUT)
  • The uniqueIdentifier you brought over already exists. An identifier resolves to exactly one battery and is never reused.

    FixLook the battery up with GET /passports?unique_identifier=… instead of creating it again.

  • The first request with this Idempotency-Key is still running.

    FixRetry shortly with the same key; you will get the stored answer once the first request finishes.

    Any write (POST, PATCH, PUT)
  • The battery was recycled, so its passport has ceased (Art. 77(8)) and can no longer be published or change status.

    FixNothing to retry. A recycled passport is final; the resolver answers 410 for it.

  • The supplier request is not attached to a model, so there is nowhere to accept its values into.

    FixCreate supplier requests with a modelId when you mean to accept values into a model.

410 Gone

413 · 415 Payload too large, unsupported type

422 Unprocessable

  • The passport cannot be published yet: the battery has no place of manufacture, or the model is missing required data for its category.

    Fixblockers lists each reason (missing_place_of_manufacture, model_incomplete with the missing fields). Fill them, then publish again. Check ahead with GET /models/{id}/completeness.

    Extra properties: blockers

  • A uniqueIdentifier you brought over breaks the identifier rules (characters, length, format).

    Fixviolations lists each broken rule and message explains them. Omit uniqueIdentifier to have one minted for you.

    Extra properties: violations

  • The putInService lifecycle event needs an in-service date.

    FixAdd date (ISO 8601) to the request.

  • The webhook URL is not acceptable: not https, credentials in the URL, a host that does not resolve, or one that resolves to a private address.

    Fixmessage names the problem. Use a public https URL; authenticate deliveries with the signature, not the URL.

  • This Idempotency-Key was already used, within 24 hours, for a request with a different method, path or body.

    FixUse a new key for a new request. Reuse a key only to retry the exact same request.

    Any write (POST, PATCH, PUT)
  • None of the fields you asked to accept were proposed by the supplier on this request.

    FixRead the request first (GET /upload-links) and accept only fields it carries.

429 · 5xx Rate limits and server errors

  • More requests than the key’s per-minute limit: 600 for live keys, 60 for test keys.

    FixWait for the seconds in retry-after, then retry. See Rate limits.

    Every endpoint
  • Something failed on our side.

    FixRetry with backoff and the same Idempotency-Key — a 5xx is never stored, so the retry runs again. Quote request_id if you contact us.

    Every endpoint

207 Per-row codes in bulk responses

Bulk endpoints answer for every row. When any row fails the response is 207, and each failed row carries ok: false and one of these codes in error. not_found is also used per row; it is documented above.

Cookie preferences

You choose which cookies are used. You can change your choice at any time with “Cookie settings” in the footer. Privacy policy

Necessary

Always on

Needed for the site to work: your light/dark theme and this cookie choice are stored in your browser. They do not track you.

Analytics

Google Analytics 4 measures how pages are used through statistics, which helps us improve the site. If you accept, it sets cookies and measures your visit in full. If you decline, it sets no cookies, but Google may still receive technical data such as the page viewed, your browser type and IP address.

_ga, _ga_* · up to 2 years · Google