Developer Docs
Sandbox · API v2PlaygroundGet API keys

Passports & versions

A Passport (DPP) is a versioned product-information artifact with defined disclosure and lifecycle. It is generated from a product, then published, and once published, a version is never mutated, only superseded.

States, three vocabularies, do not conflate

  • Product DPP-journey status (the canonical 11-state vocabulary, what generation drives): draft → validated → ready_for_dpp → dpp_pending → dpp_issued → published, plus the terminal/exception states suspended, expired, withdrawn, recalled, recycled (and voided for serialized-item tombstones).
  • Passport command-machine state (what passport commands drive): draft | submitted | rejected | approved | published | suspended | revoked | archived | recycled. A draft is publicly indistinguishable from nonexistent (404 "not found or not published").
  • EU Registry status (per passport): NOT_REQUIRED | PENDING | REGISTERED | FAILED | SYNCED | REVOKED, the passport's standing against the ESPR Art. 13 EU registry, independent of lifecycle state.

"Superseded" is not a lifecycle state, it is the version-level attribute of v(N) after a republish mints v(N+1).

Immutable versioning

Every publish mints an immutable passport_version: version number, a previous_version_id hash-chain link, and a current flag. Republishing mints v(N+1); v(N) is superseded, never edited. Read the chain at GET /passports/{id}/history.

Temporal as-of queries are live: GET /passports/{id}/as-of?date=<ISO 8601> returns the passport projection that was valid at the given instant, a pre-update timestamp returns the old value, a post-update timestamp the new one. A date before the first version returns a typed 404 NOT_FOUND ("No passport version was active at …").

Publishing

Three publish-family routes with distinct jobs, do not conflate them:

POST/api/v2/dpp/{productId}/publishmints passport content
POST/api/v2/products/{productId}/publish-dppregisters Digital Link
POST/api/v2/passports/{id}/publishbroadcasts to external registries (Catena-X / GS1 / EBSI; optional)

Publishing returns the public passportUid and, from publish-dpp, the verifiable credential plus a merkleRoot for later verification.

Lifecycle guards

Guards are real: an EDIT on a published passport returns 403 GUARD_REJECTED. Replaying a command with the same idempotencyKey returns the first result. See Passport commands.

Was this page helpful?
Thanks, noted.Feedback goes to the docs team by email.