/api/v1/passports/{id}/registrationRecord the EU DPP Registry result for a battery passport
Records what the economic operator reports from the EU DPP Registry website for one published **battery** passport. TracePass records the operator's statement and does not verify it with the Registry. The body takes one of two shapes, chosen by `environment`.
**`environment: "production"`** — the passport is registered in the production Registry. Sets `placeOnMarketStatus: "placed"`, `registrationMode: "website"`, `placedOnMarketAt` and, if you send it, `registrationId` (the Registry's registration identifier, at most 200 characters). `placedOnMarketAt` is the date of placing on the market as `YYYY-MM-DD`: today by default, not in the future and not before the passport was first published. The operator and facility parties lock (a party write that would change a stored identifier answers 409 `operator_locked`), the passport's backup copy is queued and the `passport.placed_on_market` webhook fires.
**`environment: "acceptance"`** — a test in the Registry's acceptance environment: `result` is `passed` or `failed`, with the Registry's `errorCode` for a failure (at most 100 characters, e.g. `SEMANTIC_VALIDATION_UNAVAILABLE`). A test has no legal effect and changes nothing on the passport but `registryAcceptanceTest`.
**Refusals:** `400` for a body that fails validation or a refused date (`invalid_date` when it is not `YYYY-MM-DD`, `date_in_future`, `date_before_publication`, `registration_id_too_long`); `409` for `not_a_battery`, `not_published` or, for production, `already_registered` (the passport is already placed or being sent to an EN 18222 registry). A mistaken record is undone with `DELETE /api/v1/passports/{id}/registration`.
**Paid plans only** (`402` on Free). OAuth callers must act for an admin or owner. Returns the passport after the record. Counts as one v1 write, and only when the call succeeds. Honours `Idempotency-Key`.
Path parameters
- idrequired
string (24 hex chars)
Passport ID of a published battery passport.
Headers
- Authorizationrequired
string
`Bearer <token>` — either a `tp_` API key (Developer → API Keys; simplest, for server-to-server) or an OAuth 2.0 access token (Developer → OAuth Apps; for user-authorized apps, scoped + revocable). The Authentication page has the full OAuth flow and scope list.
e.g. Bearer tp_REDACTED_xxxxxxxxxxxx
- Idempotency-Key
string
UUID v4.
Body fields
- environmentrequired
"production" | "acceptance"
Which Registry environment the result comes from. `acceptance` is a test with no legal effect.
e.g. production
- placedOnMarketAt
string (YYYY-MM-DD)
Production only. The date of placing on the market. Defaults to today; not in the future, not before the passport was first published.
e.g. 2027-03-01
- registrationId
string (≤ 200 chars)
Production only. The Registry's registration identifier, if you have it.
e.g. URI-000-00-000
- result
"passed" | "failed"
Acceptance only, and required there. The outcome of the test.
e.g. failed
- errorCode
string (≤ 100 chars)
Acceptance only. The Registry's error code for a failed test.
e.g. SEMANTIC_VALIDATION_UNAVAILABLE
Request
curl -sS -X POST \
https://app.tracepass.eu/api/v1/passports/6650b2c3d4e5f6a7b8c9d0e1/registration \
-H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9e3b6c28-1f7a-4d52-b0e4-6a8c2d1f5b97" \
-d '{ "environment": "production", "placedOnMarketAt": "2027-03-01", "registrationId": "URI-000-00-000" }'Response
{
"passport": {
"_id": "6650b2c3d4e5f6a7b8c9d0e1",
"status": "published",
"placeOnMarketStatus": "placed",
"registrationMode": "website",
"placedOnMarketAt": "2027-03-01T00:00:00.000Z",
"registrationId": "URI-000-00-000",
"registryUpi": "https://id.tracepass.eu/01/04012345000016/21/A1B2C3",
"registrationPreparedAt": "2027-02-26T09:12:00.000Z",
"registrationPreparedVia": "form"
}
}