diff --git a/guides/authentication.md b/guides/authentication.md index 0aa45ef..0b15e5c 100644 --- a/guides/authentication.md +++ b/guides/authentication.md @@ -8,7 +8,7 @@ tags: - api keys - tenancy - security -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Authenticate with a tenant **API key** sent as a Bearer token: diff --git a/guides/conformance.md b/guides/conformance.md index ba2bcba..27aecb0 100644 --- a/guides/conformance.md +++ b/guides/conformance.md @@ -7,7 +7,7 @@ tags: - conformance - standards - honesty -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- OpenDPP is deliberately precise about what it claims. In short: diff --git a/guides/errors.md b/guides/errors.md index b9a506b..f157065 100644 --- a/guides/errors.md +++ b/guides/errors.md @@ -7,7 +7,7 @@ tags: - errors - validation - troubleshooting -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Authenticated endpoints return `{ success: false, error, message }` (some endpoints, and all diff --git a/guides/interop-aas-untp.md b/guides/interop-aas-untp.md index 0bed7da..a7c71a5 100644 --- a/guides/interop-aas-untp.md +++ b/guides/interop-aas-untp.md @@ -9,7 +9,7 @@ tags: - IDTA - UNTP - data integrity -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Public resolution is **content-negotiated**: one URL serves several representations, so a passport diff --git a/guides/public-access-tiers.md b/guides/public-access-tiers.md index cf7bf1b..ef9fe55 100644 --- a/guides/public-access-tiers.md +++ b/guides/public-access-tiers.md @@ -8,7 +8,7 @@ tags: - tiers - capability tokens - legitimate interest -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Public resolution endpoints serve **tiered** views of the same URL: diff --git a/guides/rate-limits.md b/guides/rate-limits.md index df7e395..cbc15ce 100644 --- a/guides/rate-limits.md +++ b/guides/rate-limits.md @@ -7,7 +7,7 @@ tags: - rate limits - throttling - headers -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- | Surface | Limit | Headers | diff --git a/guides/sealing-and-verification.md b/guides/sealing-and-verification.md index a30d682..30b7ff4 100644 --- a/guides/sealing-and-verification.md +++ b/guides/sealing-and-verification.md @@ -9,7 +9,7 @@ tags: - eIDAS - merkle - RFC 3161 -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- OpenDPP passport seals are **eIDAS advanced electronic seals**: an ECDSA P-256 signature over a diff --git a/index.md b/index.md index 242522a..db87e23 100644 --- a/index.md +++ b/index.md @@ -4,7 +4,7 @@ okf_version: "0.1" # OpenDPP Integration API — Knowledge Bundle -> An OKF (Open Knowledge Format) projection of the public [OpenDPP Integration API](https://opendpp-node.eu/api-reference), for ingestion by AI agents and humans alike. Generated from [`/openapi.json`](https://opendpp-node.eu/openapi.json) (API v1.5.0). +> An OKF (Open Knowledge Format) projection of the public [OpenDPP Integration API](https://opendpp-node.eu/api-reference), for ingestion by AI agents and humans alike. Generated from [`/openapi.json`](https://opendpp-node.eu/openapi.json) (API v1.6.0). # Concepts diff --git a/log.md b/log.md index 59dbb3b..3775694 100644 --- a/log.md +++ b/log.md @@ -1,5 +1,5 @@ # Log -## 2026-06-19 +## 2026-06-20 -**Update** — Knowledge bundle generated for OpenDPP Integration API v1.5.0. For the full per-version API contract history see [`/openapi.json`](https://opendpp-node.eu/openapi.json) and the project CHANGELOG. +**Update** — Knowledge bundle generated for OpenDPP Integration API v1.6.0. For the full per-version API contract history see [`/openapi.json`](https://opendpp-node.eu/openapi.json) and the project CHANGELOG. diff --git a/manifest.json b/manifest.json index a4a0d89..bdea4be 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { "okfVersion": "0.1", - "apiVersion": "1.5.0", - "generated": "2026-06-19T00:00:00Z", - "conceptCount": 196, + "apiVersion": "1.6.0", + "generated": "2026-06-20T00:00:00Z", + "conceptCount": 202, "concepts": [ { "path": "overview.md", @@ -116,6 +116,13 @@ "description": "Unauthenticated, content-negotiated passport resolution: GS1 Digital Link paths, passport and unit pages.", "resource": "https://opendpp-node.eu/api-reference" }, + { + "path": "tags/verifiable-credentials.md", + "type": "Reference", + "title": "Verifiable Credentials", + "description": "Issuer trust endpoints that back the UNTP Verifiable Credential representations: the workspace's did:web DID document (public keys only) and its W3C Bitstring Status List for revocation.", + "resource": "https://opendpp-node.eu/api-reference" + }, { "path": "tags/schemas-vocabulary.md", "type": "Reference", @@ -445,11 +452,18 @@ "description": "Get the ESPR metadata schema for a product category", "resource": "https://opendpp-node.eu/api/v1/schemas/{category}" }, + { + "path": "operations/getDppJsonLdContext.md", + "type": "API Endpoint", + "title": "Canonical resolvable JSON-LD context for passport & unit documents", + "description": "Canonical resolvable JSON-LD context for passport & unit documents", + "resource": "https://opendpp-node.eu/contexts/dpp/v1" + }, { "path": "operations/getJsonLdContext.md", "type": "API Endpoint", - "title": "W3C JSON-LD context document for passport terms", - "description": "W3C JSON-LD context document for passport terms", + "title": "W3C JSON-LD context document for passport terms (secondary, fixed term list)", + "description": "W3C JSON-LD context document for passport terms (secondary, fixed term list)", "resource": "https://opendpp-node.eu/context/v1" }, { @@ -515,6 +529,20 @@ "description": "Publicly verify a passport's eIDAS seal, certificate chain and timestamp", "resource": "https://opendpp-node.eu/api/v1/audit/verify" }, + { + "path": "operations/getTenantDidDocument.md", + "type": "API Endpoint", + "title": "Resolve a tenant's did:web DID document", + "description": "Resolve a tenant's did:web DID document", + "resource": "https://opendpp-node.eu/tenants/{tenantId}/did.json" + }, + { + "path": "operations/getTenantRevocationStatusList.md", + "type": "API Endpoint", + "title": "Tenant revocation status list (W3C Bitstring Status List)", + "description": "Tenant revocation status list (W3C Bitstring Status List)", + "resource": "https://opendpp-node.eu/tenants/{tenantId}/status/revocation" + }, { "path": "operations/listWebhookSubscriptions.md", "type": "API Endpoint", @@ -718,6 +746,13 @@ "description": "DeleteOperatorResponse", "resource": "https://opendpp-node.eu/openapi.json#/components/schemas/DeleteOperatorResponse" }, + { + "path": "schemas/DidWebDocument.md", + "type": "Schema", + "title": "DidWebDocument", + "description": "A tenant's did:web DID document (public-key material only).", + "resource": "https://opendpp-node.eu/openapi.json#/components/schemas/DidWebDocument" + }, { "path": "schemas/DppJsonLdContextDocument.md", "type": "Schema", @@ -725,6 +760,13 @@ "description": "The fixed W3C JSON-LD context document served by GET /context/v1: maps DigitalProductPassport, economicOperator, metadata, digitalSeal, signingPublicKey and proof to https://opendpp-node.eu/ns/dpp#… IRIs, and createdAt/updatedAt to schema.…", "resource": "https://opendpp-node.eu/openapi.json#/components/schemas/DppJsonLdContextDocument" }, + { + "path": "schemas/DppVocabContextDocument.md", + "type": "Schema", + "title": "DppVocabContextDocument", + "description": "The canonical resolvable JSON-LD context served by GET /contexts/dpp/v1 — the context every public passport and battery-unit document references in its @context.", + "resource": "https://opendpp-node.eu/openapi.json#/components/schemas/DppVocabContextDocument" + }, { "path": "schemas/EconomicOperatorNode.md", "type": "Schema", diff --git a/operations/approveGrantRequest.md b/operations/approveGrantRequest.md index 0253ad7..28d5f28 100644 --- a/operations/approveGrantRequest.md +++ b/operations/approveGrantRequest.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/grants/{id}/approve tags: - POST - access-grants -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/grants/{id}/approve` diff --git a/operations/auditEventLineage.md b/operations/auditEventLineage.md index 492c12d..9276ba0 100644 --- a/operations/auditEventLineage.md +++ b/operations/auditEventLineage.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/events/{id}/audit tags: - POST - traceability-audit -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/events/{id}/audit` diff --git a/operations/bulkIngestPassports.md b/operations/bulkIngestPassports.md index aea6172..2d86f21 100644 --- a/operations/bulkIngestPassports.md +++ b/operations/bulkIngestPassports.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/bulk tags: - POST - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/passports/bulk` diff --git a/operations/createFacility.md b/operations/createFacility.md index 7f6ae3f..f0902e3 100644 --- a/operations/createFacility.md +++ b/operations/createFacility.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/facilities tags: - POST - facilities -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/facilities` diff --git a/operations/createGrant.md b/operations/createGrant.md index 6450ae3..719967a 100644 --- a/operations/createGrant.md +++ b/operations/createGrant.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/grants tags: - POST - access-grants -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/grants` diff --git a/operations/createPassport.md b/operations/createPassport.md index 1b98256..8efbf2c 100644 --- a/operations/createPassport.md +++ b/operations/createPassport.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports tags: - POST - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/passports` diff --git a/operations/createWebhookSubscription.md b/operations/createWebhookSubscription.md index 3a59f6b..0971a88 100644 --- a/operations/createWebhookSubscription.md +++ b/operations/createWebhookSubscription.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/webhooks/subscriptions tags: - POST - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/webhooks/subscriptions` diff --git a/operations/deleteBatteryUnit.md b/operations/deleteBatteryUnit.md index 16e816b..42c2a7f 100644 --- a/operations/deleteBatteryUnit.md +++ b/operations/deleteBatteryUnit.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/units/{id} tags: - DELETE - battery-units -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `DELETE /api/v1/units/{id}` diff --git a/operations/deleteDraftPassport.md b/operations/deleteDraftPassport.md index b1e6ec2..f29bbc9 100644 --- a/operations/deleteDraftPassport.md +++ b/operations/deleteDraftPassport.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{id} tags: - DELETE - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `DELETE /api/v1/passports/{id}` diff --git a/operations/deleteFacility.md b/operations/deleteFacility.md index 3d57ec4..7a6cf72 100644 --- a/operations/deleteFacility.md +++ b/operations/deleteFacility.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/facilities/{id} tags: - DELETE - facilities -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `DELETE /api/v1/facilities/{id}` diff --git a/operations/deleteOperator.md b/operations/deleteOperator.md index 4ed2c47..b438b15 100644 --- a/operations/deleteOperator.md +++ b/operations/deleteOperator.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/operators/{id} tags: - DELETE - economic-operators -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `DELETE /api/v1/operators/{id}` diff --git a/operations/deleteWebhookSubscription.md b/operations/deleteWebhookSubscription.md index a24e0b1..82021d3 100644 --- a/operations/deleteWebhookSubscription.md +++ b/operations/deleteWebhookSubscription.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/webhooks/subscriptions/{id} tags: - DELETE - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `DELETE /api/v1/webhooks/subscriptions/{id}` diff --git a/operations/denyGrantRequest.md b/operations/denyGrantRequest.md index d5ec0fb..03762a5 100644 --- a/operations/denyGrantRequest.md +++ b/operations/denyGrantRequest.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/grants/{id}/deny tags: - POST - access-grants -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/grants/{id}/deny` diff --git a/operations/getApiVersion.md b/operations/getApiVersion.md index 4b6b972..7ad31a3 100644 --- a/operations/getApiVersion.md +++ b/operations/getApiVersion.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/version tags: - GET - service -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/version` diff --git a/operations/getBatteryUnit.md b/operations/getBatteryUnit.md index 3ecbe0d..77b6c17 100644 --- a/operations/getBatteryUnit.md +++ b/operations/getBatteryUnit.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/units/{id} tags: - GET - battery-units -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/units/{id}` diff --git a/operations/getBatteryUnitQrCode.md b/operations/getBatteryUnitQrCode.md index 1f4f29c..6fcd7ce 100644 --- a/operations/getBatteryUnitQrCode.md +++ b/operations/getBatteryUnitQrCode.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/units/{id}/qr tags: - GET - qr-codes -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/units/{id}/qr` diff --git a/operations/getDppJsonLdContext.md b/operations/getDppJsonLdContext.md new file mode 100644 index 0000000..9d0c404 --- /dev/null +++ b/operations/getDppJsonLdContext.md @@ -0,0 +1,37 @@ +--- +type: API Endpoint +title: Canonical resolvable JSON-LD context for passport & unit documents +description: Canonical resolvable JSON-LD context for passport & unit documents +resource: https://opendpp-node.eu/contexts/dpp/v1 +tags: + - GET + - schemas-vocabulary +timestamp: 2026-06-20T00:00:00Z +--- + +`GET /contexts/dpp/v1` + +**Domain:** [Schemas & Vocabulary](/tags/schemas-vocabulary.md) +**Authentication:** **Public** — no authentication required. + +Serves the stable, resolvable W3C JSON-LD `@context` (`application/ld+json`) that **every** public passport and battery-unit JSON-LD document references in its `@context` array — this is the context to dereference when expanding OpenDPP JSON-LD. It declares `@vocab: https://opendpp-node.eu/ns/dpp#` (so even dynamic metadata keys expand under the OpenDPP namespace and are never silently dropped by a strict JSON-LD processor) plus explicit term mappings for the core DPP/unit vocabulary (`DigitalProductPassport`, `BatteryUnit`, `economicOperator`, `manufacturingFacility`, `metadata`, `digitalSeal`, `signingPublicKey`, `proof`, `status`, `MerkleTreeAttestationProof`). Cacheable (`Cache-Control: public, max-age=86400`). + +(The separate `/context/v1` serves an older, fixed term-only list and is **not** the context emitted documents point to.) + +No authentication, no permission (public endpoint). No custom rate limiter — only the global platform limit applies (100 req/min/IP, standard `x-ratelimit-*` headers). + +## Responses + +- **200** — The canonical @vocab-based JSON-LD context document (fixed content). → [DppVocabContextDocument](/schemas/DppVocabContextDocument.md) +- **429** — Global rate limit exceeded (100 requests/min per IP). + +## Example + +```bash +curl -s \ + -X GET 'https://opendpp-node.eu/contexts/dpp/v1' +``` + +## See also + +Schemas: [DppVocabContextDocument](/schemas/DppVocabContextDocument.md). diff --git a/operations/getEventLineage.md b/operations/getEventLineage.md index 7fca3e6..7ea657a 100644 --- a/operations/getEventLineage.md +++ b/operations/getEventLineage.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/events/{id}/lineage tags: - GET - traceability-audit -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/events/{id}/lineage` diff --git a/operations/getFacility.md b/operations/getFacility.md index f08196c..b51e6af 100644 --- a/operations/getFacility.md +++ b/operations/getFacility.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/facilities/{id} tags: - GET - facilities -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/facilities/{id}` diff --git a/operations/getHealth.md b/operations/getHealth.md index 338f982..fca2ef9 100644 --- a/operations/getHealth.md +++ b/operations/getHealth.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/health tags: - GET - service -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /health` diff --git a/operations/getJsonLdContext.md b/operations/getJsonLdContext.md index 0d958aa..cde7eb4 100644 --- a/operations/getJsonLdContext.md +++ b/operations/getJsonLdContext.md @@ -1,12 +1,12 @@ --- type: API Endpoint -title: W3C JSON-LD context document for passport terms -description: W3C JSON-LD context document for passport terms +title: W3C JSON-LD context document for passport terms (secondary, fixed term list) +description: W3C JSON-LD context document for passport terms (secondary, fixed term list) resource: https://opendpp-node.eu/context/v1 tags: - GET - schemas-vocabulary -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /context/v1` @@ -14,7 +14,7 @@ timestamp: 2026-06-19T00:00:00Z **Domain:** [Schemas & Vocabulary](/tags/schemas-vocabulary.md) **Authentication:** **Public** — no authentication required. -Serves a static W3C JSON-LD `@context` document (`application/ld+json`) for the core Digital Product Passport term vocabulary: maps the DPP terms to `https://opendpp-node.eu/ns/dpp#…` IRIs and `createdAt`/`updatedAt` to schema.org `dateCreated`/`dateModified`. (Passport/unit JSON-LD documents carry these term mappings inline and reference the resolvable context published at `/contexts/dpp/v1`.) +Serves a static W3C JSON-LD `@context` document (`application/ld+json`) for the core Digital Product Passport term vocabulary: maps the DPP terms to `https://opendpp-node.eu/ns/dpp#…` IRIs and `createdAt`/`updatedAt` to schema.org `dateCreated`/`dateModified`. This is a **secondary** fixed term list — the context that public passport/unit JSON-LD documents actually reference is the `@vocab`-based one at `GET /contexts/dpp/v1`; dereference that when expanding OpenDPP JSON-LD. No authentication, no permission (public endpoint). No custom rate limiter — only the global platform limit applies (100 req/min/IP, standard `x-ratelimit-*` headers). Like every documented path except `/health`, a request on an unknown tenant workspace host receives a platform-level JSON 404 before this handler runs. diff --git a/operations/getOperator.md b/operations/getOperator.md index cae126a..55f7703 100644 --- a/operations/getOperator.md +++ b/operations/getOperator.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/operators/{id} tags: - GET - economic-operators -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/operators/{id}` diff --git a/operations/getPassport.md b/operations/getPassport.md index 8cfc609..39e7aca 100644 --- a/operations/getPassport.md +++ b/operations/getPassport.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{id} tags: - GET - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/passports/{id}` @@ -18,7 +18,7 @@ Owner-side alias of the public resolver. Accepts either the passport **UUID** or **Permission:** `passport:read` (read-only — no subscription/402 gate). -**Content negotiation** (substring match on `Accept`): `application/aas+json` → role-filtered AAS environment; `text/html` → SSR passport page; anything else (including `application/json`, `*/*`, or no header) → JSON-LD with `Content-Type: application/ld+json` (the default). +**Content negotiation** (substring match on `Accept`): `application/aas+json` → role-filtered AAS environment; `application/vc+jwt` → enveloping UNTP Verifiable Credential; `application/vc+ld+json` → the same credential with an embedded `ecdsa-jcs-2019` W3C Data Integrity proof; `application/dc+sd-jwt` (legacy `vc+sd-jwt` accepted) → SD-JWT-VC selective disclosure (these three return `406 Not Acceptable` when the passport has no manufacturing facility with a country of production); `text/html` → SSR passport page; anything else (including `application/json`, `*/*`, or no header) → JSON-LD with `Content-Type: application/ld+json` (the default). The VC and SD-JWT representations are forwarded verbatim from `GET /passport/{id}` — see that operation for the full credential semantics. **Access-tier caveat (privilege is resolved from the *forwarded* headers, not the already-authenticated context):** only **database API keys** (`Authorization: Bearer op_dpp_token_…`) of the owning or operator-bound tenant are recognized as owner by the inner resolver. Those callers get the **owner-tier** document: `facilityDetails` and battery restricted keys unmasked, `manufacturingFacility` includes `streetAddress`/`city`/`postalCode`, and DRAFT passports are visible. Callers authenticated with a **JWT session** (login cookie or bearer JWT) receive the **public-redacted** tier instead, and DRAFT passports answer 404 with the forwarded public body (no `success` field). @@ -38,6 +38,7 @@ Every successful resolution records an anonymized-IP access audit entry. - **401** — Missing, invalid, revoked or expired credentials. → [Error](/schemas/Error.md) - **403** — Authenticated but not allowed: the key lacks the required permission, the request crosses workspaces, or an MFA-gated write was attempted without an MFA sessio… → [Error](/schemas/Error.md) - **404** — Two distinct bodies. → [Error](/schemas/Error.md) +- **406** — The requested representation cannot be produced for this resource. → [Error](/schemas/Error.md) - **429** — Two possible sources. - **500** — Unexpected failure. → [Error](/schemas/Error.md) diff --git a/operations/getPassportQrCode.md b/operations/getPassportQrCode.md index 3796612..fc8d028 100644 --- a/operations/getPassportQrCode.md +++ b/operations/getPassportQrCode.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{id}/qr tags: - GET - qr-codes -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/passports/{id}/qr` diff --git a/operations/getSealCaCertificate.md b/operations/getSealCaCertificate.md index 7d96c44..f2b59da 100644 --- a/operations/getSealCaCertificate.md +++ b/operations/getSealCaCertificate.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/.well-known/opendpp-seal-ca.pem tags: - GET - eidas-keys -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /.well-known/opendpp-seal-ca.pem` diff --git a/operations/getSectorSchema.md b/operations/getSectorSchema.md index 0291d65..f2c31b7 100644 --- a/operations/getSectorSchema.md +++ b/operations/getSectorSchema.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/schemas/{category} tags: - GET - schemas-vocabulary -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/schemas/{category}` diff --git a/operations/getTenantDidDocument.md b/operations/getTenantDidDocument.md new file mode 100644 index 0000000..1f67e04 --- /dev/null +++ b/operations/getTenantDidDocument.md @@ -0,0 +1,44 @@ +--- +type: API Endpoint +title: Resolve a tenant's did:web DID document +description: Resolve a tenant's did:web DID document +resource: https://opendpp-node.eu/tenants/{tenantId}/did.json +tags: + - GET + - verifiable-credentials +timestamp: 2026-06-20T00:00:00Z +--- + +`GET /tenants/{tenantId}/did.json` + +**Domain:** [Verifiable Credentials](/tags/verifiable-credentials.md) +**Authentication:** **Public** — no authentication required. + +Resolves the issuing workspace's `did:web` DID document (`application/did+json`). The DID is `did:web:opendpp-node.eu:tenants:{tenantId}`, which per the did:web method dereferences here. The document exposes **only public key material** — the workspace's eIDAS public key(s) as `JsonWebKey2020` verification methods, each with a stable `#key-` id matching the `kid` of the credentials it signs. + +Use it to verify any OpenDPP-issued Verifiable Credential (`Accept: application/vc+jwt`, `application/vc+ld+json`, or `application/dc+sd-jwt` on the public resolution endpoints) without out-of-band key exchange. Both current and retired keys are published and listed in `assertionMethod`/`authentication`, so credentials issued before a key rotation still verify; new credentials always use the current key. The optional `name` is the issuer's authoritative legal name (the same value used in every credential's `issuer.name`). + +No authentication, no permission (public endpoint). Subject only to the global platform rate limit (100 req/min/IP). A workspace that has never provisioned a signing key returns 404. Never returns private key material. + +## Parameters + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `tenantId` | path | yes | string | The issuing workspace (tenant) id — the {tenantId} of its did:web:opendpp-node.eu:tenants:{tenantId} DID. | + +## Responses + +- **200** — The tenant's did:web DID document (public keys only). → [DidWebDocument](/schemas/DidWebDocument.md) +- **404** — No DID document for this tenant (the workspace has not provisioned a signing key). → [Error](/schemas/Error.md) +- **429** — Global rate limit exceeded (100 requests/min per IP). + +## Example + +```bash +curl -s \ + -X GET 'https://opendpp-node.eu/tenants/{tenantId}/did.json' +``` + +## See also + +Schemas: [DidWebDocument](/schemas/DidWebDocument.md), [Error](/schemas/Error.md). diff --git a/operations/getTenantRevocationStatusList.md b/operations/getTenantRevocationStatusList.md new file mode 100644 index 0000000..7bf1e9f --- /dev/null +++ b/operations/getTenantRevocationStatusList.md @@ -0,0 +1,42 @@ +--- +type: API Endpoint +title: Tenant revocation status list (W3C Bitstring Status List) +description: Tenant revocation status list (W3C Bitstring Status List) +resource: https://opendpp-node.eu/tenants/{tenantId}/status/revocation +tags: + - GET + - verifiable-credentials +timestamp: 2026-06-20T00:00:00Z +--- + +`GET /tenants/{tenantId}/status/revocation` + +**Domain:** [Verifiable Credentials](/tags/verifiable-credentials.md) +**Authentication:** **Public** — no authentication required. + +Serves the workspace's W3C **Bitstring Status List** as a signed enveloping `vc+jwt` (`application/vc+jwt`) — a `BitstringStatusListCredential` whose GZIP+base64 encoded bitstring sets the bit of every passport whose status is RECALLED or DECOMMISSIONED. An OpenDPP-issued DPP credential's `credentialStatus.statusListCredential` points here; a verifier fetches this list and checks the bit at the credential's `statusListIndex` to determine whether it has been revoked. Signed by the workspace's current key (stable `kid`), verifiable via the DID document at `/tenants/{tenantId}/did.json`. + +No authentication, no permission (public endpoint). Subject only to the global platform rate limit (100 req/min/IP). A workspace with no signing key returns 404. + +## Parameters + +| Name | In | Required | Type | Description | +|------|----|----------|------|-------------| +| `tenantId` | path | yes | string | The issuing workspace (tenant) id. | + +## Responses + +- **200** — The signed BitstringStatusListCredential as a compact vc+jwt (JWS string). +- **404** — No status list for this tenant (unknown workspace or no signing key). → [Error](/schemas/Error.md) +- **429** — Global rate limit exceeded (100 requests/min per IP). + +## Example + +```bash +curl -s \ + -X GET 'https://opendpp-node.eu/tenants/{tenantId}/status/revocation' +``` + +## See also + +Schemas: [Error](/schemas/Error.md). diff --git a/operations/index.md b/operations/index.md index fdc1798..8169fd3 100644 --- a/operations/index.md +++ b/operations/index.md @@ -71,10 +71,16 @@ * [GET /8003/{grai}](resolveGs1Grai.md) - GS1 Digital Link resolution by GRAI (AI 8003) * [GET /unit/{id}](resolvePublicBatteryUnit.md) - Resolve an individual serialised battery unit +# Verifiable Credentials + +* [GET /tenants/{tenantId}/did.json](getTenantDidDocument.md) - Resolve a tenant's did:web DID document +* [GET /tenants/{tenantId}/status/revocation](getTenantRevocationStatusList.md) - Tenant revocation status list (W3C Bitstring Status List) + # Schemas & Vocabulary * [GET /api/v1/schemas/{category}](getSectorSchema.md) - Get the ESPR metadata schema for a product category -* [GET /context/v1](getJsonLdContext.md) - W3C JSON-LD context document for passport terms +* [GET /contexts/dpp/v1](getDppJsonLdContext.md) - Canonical resolvable JSON-LD context for passport & unit documents +* [GET /context/v1](getJsonLdContext.md) - W3C JSON-LD context document for passport terms (secondary, fixed term list) * [GET /api/v1/materials](listMaterials.md) - List the platform-curated material vocabulary # QR Codes diff --git a/operations/ingestPassportFromAas.md b/operations/ingestPassportFromAas.md index 3211c57..08fcbd1 100644 --- a/operations/ingestPassportFromAas.md +++ b/operations/ingestPassportFromAas.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/aas/ingest tags: - POST - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/passports/aas/ingest` diff --git a/operations/listBatteryUnitEvents.md b/operations/listBatteryUnitEvents.md index 73762f7..69c8245 100644 --- a/operations/listBatteryUnitEvents.md +++ b/operations/listBatteryUnitEvents.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/units/{id}/events tags: - GET - battery-units -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/units/{id}/events` diff --git a/operations/listBatteryUnits.md b/operations/listBatteryUnits.md index 4f8eecb..d61ed76 100644 --- a/operations/listBatteryUnits.md +++ b/operations/listBatteryUnits.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{passportId}/units tags: - GET - battery-units -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/passports/{passportId}/units` diff --git a/operations/listFacilities.md b/operations/listFacilities.md index 973822f..fd62765 100644 --- a/operations/listFacilities.md +++ b/operations/listFacilities.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/facilities tags: - GET - facilities -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/facilities` diff --git a/operations/listGrants.md b/operations/listGrants.md index 9376922..0df5d6a 100644 --- a/operations/listGrants.md +++ b/operations/listGrants.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/grants tags: - GET - access-grants -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/grants` @@ -31,7 +31,7 @@ Paginated with `?page` (default 1) and `?limit` (default 100, max 200), grouped ## Responses -- **200** — The workspace's grants and requests (most recent 500). → [GrantListResponse](/schemas/GrantListResponse.md) +- **200** — The workspace's grants and requests, paginated newest-first — a { success, count, page, limit, total, totalPages, grants } envelope. → [GrantListResponse](/schemas/GrantListResponse.md) - **401** — Missing, invalid, revoked or expired credentials. → [Error](/schemas/Error.md) - **403** — Authenticated but not allowed: the key lacks the required permission, the request crosses workspaces, or an MFA-gated write was attempted without an MFA sessio… → [Error](/schemas/Error.md) - **429** — Global rate limit exceeded (100 requests/min per IP). diff --git a/operations/listMaterials.md b/operations/listMaterials.md index eecd715..0c500a5 100644 --- a/operations/listMaterials.md +++ b/operations/listMaterials.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/materials tags: - GET - schemas-vocabulary -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/materials` diff --git a/operations/listOperators.md b/operations/listOperators.md index 3885f43..66084f5 100644 --- a/operations/listOperators.md +++ b/operations/listOperators.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/operators tags: - GET - economic-operators -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/operators` diff --git a/operations/listPassports.md b/operations/listPassports.md index f13b7cb..3096dce 100644 --- a/operations/listPassports.md +++ b/operations/listPassports.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports tags: - GET - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/passports` diff --git a/operations/listWebhookDeliveries.md b/operations/listWebhookDeliveries.md index 9cf685f..1949ca6 100644 --- a/operations/listWebhookDeliveries.md +++ b/operations/listWebhookDeliveries.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/webhooks/deliveries tags: - GET - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/webhooks/deliveries` diff --git a/operations/listWebhookSubscriptions.md b/operations/listWebhookSubscriptions.md index 55a0236..d88f53a 100644 --- a/operations/listWebhookSubscriptions.md +++ b/operations/listWebhookSubscriptions.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/webhooks/subscriptions tags: - GET - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/webhooks/subscriptions` diff --git a/operations/recordBatteryUnitEvent.md b/operations/recordBatteryUnitEvent.md index 51c9cfb..3c71550 100644 --- a/operations/recordBatteryUnitEvent.md +++ b/operations/recordBatteryUnitEvent.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/units/{id}/events tags: - POST - battery-units -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/units/{id}/events` diff --git a/operations/registerOperator.md b/operations/registerOperator.md index 66c3114..1b434c7 100644 --- a/operations/registerOperator.md +++ b/operations/registerOperator.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/operators tags: - POST - economic-operators -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/operators` diff --git a/operations/registerTraceabilityEvent.md b/operations/registerTraceabilityEvent.md index f17b544..b2eab98 100644 --- a/operations/registerTraceabilityEvent.md +++ b/operations/registerTraceabilityEvent.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/events tags: - POST - traceability-audit -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/events` diff --git a/operations/resolveGs1Grai.md b/operations/resolveGs1Grai.md index 4abcc00..c321128 100644 --- a/operations/resolveGs1Grai.md +++ b/operations/resolveGs1Grai.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/8003/{grai} tags: - GET - public-resolution -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /8003/{grai}` @@ -30,6 +30,7 @@ An additional `/21/{serial}` AI pair after the GRAI behaves exactly like `GET /0 - **200** — The matched passport in the negotiated representation (same envelope as GET /passport/{id}). → [AasEnvironment](/schemas/AasEnvironment.md), [PublicPassportJsonLd](/schemas/PublicPassportJsonLd.md) - **400** — Invalid GRAI (format / check digit) or — without tenant scope and AI-21 serial — an ambiguous lookup. → [Error](/schemas/Error.md) - **404** — No passport matches (content-negotiated HTML/JSON, Vary: Accept), DRAFT hidden from non-owner, or unknown tenant subdomain (JSON only). → [Error](/schemas/Error.md) +- **406** — The requested representation cannot be produced for this resource. → [Error](/schemas/Error.md) - **429** — Public-resolution rate limit exceeded (30 requests/min per IP; no rate-limit headers). → [Error](/schemas/Error.md) - **500** — Unexpected server error. → [Error](/schemas/Error.md) diff --git a/operations/resolveGs1Gtin.md b/operations/resolveGs1Gtin.md index ede0b9c..093e81b 100644 --- a/operations/resolveGs1Gtin.md +++ b/operations/resolveGs1Gtin.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/01/{gtin14} tags: - GET - public-resolution -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /01/{gtin14}` @@ -34,6 +34,7 @@ The gateway also accepts additional GS1 AI key/value path pairs after the GTIN; - **200** — The matched passport in the negotiated representation (same envelope as GET /passport/{id}). → [AasEnvironment](/schemas/AasEnvironment.md), [PublicPassportJsonLd](/schemas/PublicPassportJsonLd.md) - **400** — Invalid GTIN-14 (must be 14 digits with a valid modulo-10 check digit) or — when no tenant scope is in play and no AI-21 serial was given — an ambiguous lookup… → [Error](/schemas/Error.md) - **404** — No passport matches the identifier (content-negotiated: HTML page for Accept: text/html, JSON otherwise; Vary: Accept set), a DRAFT match was hidden from a non… → [Error](/schemas/Error.md) +- **406** — The requested representation cannot be produced for this resource. → [Error](/schemas/Error.md) - **429** — Public-resolution rate limit exceeded (30 requests/min per IP; no rate-limit headers). → [Error](/schemas/Error.md) - **500** — Unexpected server error. → [Error](/schemas/Error.md) diff --git a/operations/resolveGs1GtinSerial.md b/operations/resolveGs1GtinSerial.md index ea8b587..926cfcf 100644 --- a/operations/resolveGs1GtinSerial.md +++ b/operations/resolveGs1GtinSerial.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/01/{gtin14}/21/{serial} tags: - GET - public-resolution -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /01/{gtin14}/21/{serial}` diff --git a/operations/resolvePublicBatteryUnit.md b/operations/resolvePublicBatteryUnit.md index a1583f7..f1d1c07 100644 --- a/operations/resolvePublicBatteryUnit.md +++ b/operations/resolvePublicBatteryUnit.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/unit/{id} tags: - GET - public-resolution -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /unit/{id}` @@ -35,6 +35,7 @@ Every resolution is access-audit-logged with an anonymized IP. **Rate limit:** 3 - **200** — The unit document in the negotiated representation. → [PublicBatteryUnitJsonLd](/schemas/PublicBatteryUnitJsonLd.md) - **404** — No unit with that id (a malformed UUID also resolves to this 404). → [Error](/schemas/Error.md) +- **406** — The requested representation cannot be produced for this resource. → [Error](/schemas/Error.md) - **410** — Gone — the unit was RECYCLED (or ceasedAt is set): the battery passport has ceased to exist (Art. → [BatteryUnitTombstoneJsonLd](/schemas/BatteryUnitTombstoneJsonLd.md) - **429** — Public-resolution rate limit exceeded (30 requests/min per IP; no rate-limit headers). → [Error](/schemas/Error.md) - **500** — Unexpected server error. → [Error](/schemas/Error.md) diff --git a/operations/resolvePublicPassport.md b/operations/resolvePublicPassport.md index e51d062..4a659c2 100644 --- a/operations/resolvePublicPassport.md +++ b/operations/resolvePublicPassport.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/passport/{id} tags: - GET - public-resolution -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /passport/{id}` @@ -39,6 +39,7 @@ DRAFT passports are hidden from everyone but the owner (404 with a body identica - **200** — The passport in the negotiated representation. → [AasEnvironment](/schemas/AasEnvironment.md), [PublicPassportJsonLd](/schemas/PublicPassportJsonLd.md) - **400** — Passport identifier missing. → [Error](/schemas/Error.md) - **404** — No passport with that UUID — or the passport is a DRAFT and the caller is not owner-tier (identical body, deliberate). → [Error](/schemas/Error.md) +- **406** — The requested representation cannot be produced for this resource. → [Error](/schemas/Error.md) - **429** — Public-resolution rate limit exceeded (30 requests/min per IP; no rate-limit headers). → [Error](/schemas/Error.md) - **500** — Unexpected server error. → [Error](/schemas/Error.md) diff --git a/operations/restoreOperator.md b/operations/restoreOperator.md index 27ddc70..0453ae2 100644 --- a/operations/restoreOperator.md +++ b/operations/restoreOperator.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/operators/{id}/restore tags: - POST - economic-operators -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/operators/{id}/restore` diff --git a/operations/revokeGrant.md b/operations/revokeGrant.md index 25ef415..8029129 100644 --- a/operations/revokeGrant.md +++ b/operations/revokeGrant.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/grants/{id} tags: - DELETE - access-grants -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `DELETE /api/v1/grants/{id}` diff --git a/operations/rotateTenantKeys.md b/operations/rotateTenantKeys.md index 36ca944..ab3a03d 100644 --- a/operations/rotateTenantKeys.md +++ b/operations/rotateTenantKeys.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/tenants/rotate-keys tags: - POST - eidas-keys -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/tenants/rotate-keys` diff --git a/operations/rotateWebhookSecret.md b/operations/rotateWebhookSecret.md index 1baaaba..35e2b2d 100644 --- a/operations/rotateWebhookSecret.md +++ b/operations/rotateWebhookSecret.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/webhooks/subscriptions/{id}/rotate-secr tags: - POST - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/webhooks/subscriptions/{id}/rotate-secret` diff --git a/operations/sealPassport.md b/operations/sealPassport.md index b4fdc34..8335273 100644 --- a/operations/sealPassport.md +++ b/operations/sealPassport.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{id}/seal tags: - POST - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/passports/{id}/seal` diff --git a/operations/serializeBatteryUnits.md b/operations/serializeBatteryUnits.md index d9b7bd0..d077e8f 100644 --- a/operations/serializeBatteryUnits.md +++ b/operations/serializeBatteryUnits.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{passportId}/units tags: - POST - battery-units -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/passports/{passportId}/units` diff --git a/operations/testWebhookSubscription.md b/operations/testWebhookSubscription.md index 9dedfaa..c3a225b 100644 --- a/operations/testWebhookSubscription.md +++ b/operations/testWebhookSubscription.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/webhooks/subscriptions/{id}/test tags: - POST - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/webhooks/subscriptions/{id}/test` diff --git a/operations/updateFacility.md b/operations/updateFacility.md index fdc7658..a1f3c48 100644 --- a/operations/updateFacility.md +++ b/operations/updateFacility.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/facilities/{id} tags: - PUT - facilities -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `PUT /api/v1/facilities/{id}` diff --git a/operations/updateOperator.md b/operations/updateOperator.md index 0faa85b..482c008 100644 --- a/operations/updateOperator.md +++ b/operations/updateOperator.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/operators/{id} tags: - PATCH - economic-operators -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `PATCH /api/v1/operators/{id}` diff --git a/operations/updatePassport.md b/operations/updatePassport.md index baf78a1..e82db93 100644 --- a/operations/updatePassport.md +++ b/operations/updatePassport.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{id} tags: - PUT - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `PUT /api/v1/passports/{id}` @@ -22,7 +22,7 @@ Replaces the passport's `metadata` (the Merkle root and leaf hashes are recomput **Draft semantics (`draft` flag):** - `draft: true` **skips ESPR validation entirely** and forces `status: "DRAFT"` — note this also demotes an already-published (ACTIVE/RECALLED/DECOMMISSIONED) passport back to DRAFT. -- `draft` absent/false: `metadata` is validated against the ESPR category rules (400 on failure — see below). If the passport was a DRAFT it is **published**: status becomes `ACTIVE`, a `passport.ingested` webhook is enqueued transactionally (public-redacted JSON-LD payload) and an in-app notification is created best-effort afterwards. Live statuses are left untouched. +- `draft` absent/false: `metadata` is validated against the ESPR category rules (400 on failure — see below). If the passport was a DRAFT it is **published**: status becomes `ACTIVE`, a `passport.ingested` webhook is enqueued transactionally (public-redacted JSON-LD payload) and an in-app notification is created best-effort afterwards. Editing an already-published (live) passport leaves its status untouched and enqueues a `passport.updated` webhook instead (same public-redacted JSON-LD payload). **Validation divergence:** the 400 validation body here contains `errors` but — unlike `POST /api/v1/passports` — **never a `warnings` array**. `friendlyMessage` is localized via the `lang` query parameter or `Accept-Language` (28 languages, default `en`; unsupported values silently fall back). diff --git a/operations/updatePassportStatus.md b/operations/updatePassportStatus.md index 785e8c4..ed67183 100644 --- a/operations/updatePassportStatus.md +++ b/operations/updatePassportStatus.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/{id}/status tags: - PUT - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `PUT /api/v1/passports/{id}/status` diff --git a/operations/updateWebhookSubscription.md b/operations/updateWebhookSubscription.md index cf8c5d3..05a6137 100644 --- a/operations/updateWebhookSubscription.md +++ b/operations/updateWebhookSubscription.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/webhooks/subscriptions/{id} tags: - PATCH - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `PATCH /api/v1/webhooks/subscriptions/{id}` diff --git a/operations/validatePassport.md b/operations/validatePassport.md index 1bb8937..8894ab9 100644 --- a/operations/validatePassport.md +++ b/operations/validatePassport.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/validate-only tags: - POST - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/passports/validate-only` diff --git a/operations/validatePassportPublic.md b/operations/validatePassportPublic.md index 87bc886..614d443 100644 --- a/operations/validatePassportPublic.md +++ b/operations/validatePassportPublic.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/passports/validate-only-public tags: - POST - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/passports/validate-only-public` diff --git a/operations/verifyPassportSeal.md b/operations/verifyPassportSeal.md index 68bf0d7..525166a 100644 --- a/operations/verifyPassportSeal.md +++ b/operations/verifyPassportSeal.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/audit/verify tags: - POST - traceability-audit -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `POST /api/v1/audit/verify` diff --git a/operations/whoami.md b/operations/whoami.md index 7dd21ce..c129200 100644 --- a/operations/whoami.md +++ b/operations/whoami.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api/v1/whoami tags: - GET - account -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- `GET /api/v1/whoami` diff --git a/overview.md b/overview.md index ce603ea..b2ce8d7 100644 --- a/overview.md +++ b/overview.md @@ -8,7 +8,7 @@ tags: - getting started - ESPR - EU Battery Regulation -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- OpenDPP is a B2B platform for **EU Digital Product Passports (DPPs)**, aligned with the data diff --git a/schemas/AasEnvironment.md b/schemas/AasEnvironment.md index 7228ba9..b3c68d9 100644 --- a/schemas/AasEnvironment.md +++ b/schemas/AasEnvironment.md @@ -5,7 +5,7 @@ description: An Asset Administration Shell (AAS) v3.0 environment export of the resource: https://opendpp-node.eu/openapi.json#/components/schemas/AasEnvironment tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- An Asset Administration Shell (AAS) v3.0 environment export of the passport, served as `application/aas+json`. Three top-level keys: `assetAdministrationShells` (asset identity — `urn:opendpp:aas:{passportId}` / `urn:opendpp:asset:{operatorId}:{productId}`, GS1 GLN-qualified specific asset ids), `submodels`, and `conceptDescriptions` (semantic concept records from the admin-curated registry, `urn:opendpp:concept:…`; empty array when the registry is empty). Submodels: a `GeneralProductInformation` submodel (`urn:opendpp:submodel:general:{passportId}`), a `ComplianceMetadata` submodel (`urn:opendpp:submodel:compliance`) mapping the passport metadata through the concept registry, an IDTA Digital Nameplate submodel (idShort `Nameplate`) whenever manufacturer/product identity is available — carrying `ManufacturerName` / `ManufacturerProductDesignation` for EU-index (CIRPASS-2) discoverability — one or more additive per-category submodel views (ESPR-category views such as CarbonFootprint / TechnicalData, id prefix `urn:opendpp:submodel:category:`), and — whenever the issuing tenant's eIDAS signing key is provisioned (the normal case) — an `eidasVerificationSeal` submodel (`urn:opendpp:submodel:security-seal:{passportId}`) carrying `digitalSealHash`, `cryptographicSignature`, `pemPublicKey` and an optional `x509CertificateChain`. The seal submodel is present for EVERY access tier. Role filtering strips restricted and commercial owner-only elements from the `ComplianceMetadata` submodel before sending: owner credentials are filtered by their API-key role, grant holders by the `legitimate_interest` tier, anonymous callers by the `public` tier. Submodel internals are intentionally not enumerated in this specification. diff --git a/schemas/AasEnvironmentInput.md b/schemas/AasEnvironmentInput.md index 7bc40ae..09ad79e 100644 --- a/schemas/AasEnvironmentInput.md +++ b/schemas/AasEnvironmentInput.md @@ -5,7 +5,7 @@ description: An Asset Administration Shell (AAS) JSON Environment — the format resource: https://opendpp-node.eu/openapi.json#/components/schemas/AasEnvironmentInput tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- An Asset Administration Shell (AAS) JSON Environment — the format produced by OpenDPP's AAS export of a passport. MUST contain a submodel with `idShort: "ComplianceMetadata"` whose `submodelElements` (AAS `Property` elements and `SubmodelElementCollection`s) are parsed back into the passport metadata object; absence fails 400 `Ingestion Failed`. MAY contain an `eidasVerificationSeal` submodel (elements `digitalSealHash`, `cryptographicSignature`, `pemPublicKey`) — when present, the seal is verified against the tenant's SERVER-HELD eIDAS public key (the embedded `pemPublicKey` is never trusted as the verification key). Body limit 256 KiB. diff --git a/schemas/AasIngestCreated.md b/schemas/AasIngestCreated.md index eca87f0..65da76c 100644 --- a/schemas/AasIngestCreated.md +++ b/schemas/AasIngestCreated.md @@ -5,7 +5,7 @@ description: 201 envelope of POST /api/v1/passports/aas/ingest. resource: https://opendpp-node.eu/openapi.json#/components/schemas/AasIngestCreated tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 201 envelope of `POST /api/v1/passports/aas/ingest`. Returned for both newly created passports and in-place updates of existing UNSEALED passports. No webhook event is emitted by this endpoint. diff --git a/schemas/ApproveGrantRequest.md b/schemas/ApproveGrantRequest.md index 9b7184f..106ffb8 100644 --- a/schemas/ApproveGrantRequest.md +++ b/schemas/ApproveGrantRequest.md @@ -5,7 +5,7 @@ description: Approval body — only the final expiry is supplied; everything els resource: https://opendpp-node.eu/openapi.json#/components/schemas/ApproveGrantRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Approval body — only the final expiry is supplied; everything else comes from the original request. diff --git a/schemas/BatteryUnitCreateItem.md b/schemas/BatteryUnitCreateItem.md index b67fad7..daa0448 100644 --- a/schemas/BatteryUnitCreateItem.md +++ b/schemas/BatteryUnitCreateItem.md @@ -5,7 +5,7 @@ description: One unit to serialise. resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitCreateItem tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One unit to serialise. Validation is per-item: an invalid item is skipped (its error string collected) without failing the rest of the batch. diff --git a/schemas/BatteryUnitCurrentState.md b/schemas/BatteryUnitCurrentState.md index 09fe999..b8767e6 100644 --- a/schemas/BatteryUnitCurrentState.md +++ b/schemas/BatteryUnitCurrentState.md @@ -5,7 +5,7 @@ description: Latest recorded measurement of the unit (owner/grant tiers only). resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitCurrentState tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Latest recorded measurement of the unit (owner/grant tiers only). All measurement fields are `null` when the latest event did not carry them. diff --git a/schemas/BatteryUnitDeleteResponse.md b/schemas/BatteryUnitDeleteResponse.md index ebffead..d1c7ce6 100644 --- a/schemas/BatteryUnitDeleteResponse.md +++ b/schemas/BatteryUnitDeleteResponse.md @@ -5,7 +5,7 @@ description: BatteryUnitDeleteResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitDeleteResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/BatteryUnitDynamicDataEvent.md b/schemas/BatteryUnitDynamicDataEvent.md index 048825e..9663ff4 100644 --- a/schemas/BatteryUnitDynamicDataEvent.md +++ b/schemas/BatteryUnitDynamicDataEvent.md @@ -5,7 +5,7 @@ description: One telemetry event in the JSON-LD dynamicData history (privileged resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitDynamicDataEvent tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One telemetry event in the JSON-LD `dynamicData` history (privileged view only). diff --git a/schemas/BatteryUnitEventListResponse.md b/schemas/BatteryUnitEventListResponse.md index b4c0c24..9fdcd5e 100644 --- a/schemas/BatteryUnitEventListResponse.md +++ b/schemas/BatteryUnitEventListResponse.md @@ -5,7 +5,7 @@ description: BatteryUnitEventListResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitEventListResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/BatteryUnitEventNode.md b/schemas/BatteryUnitEventNode.md index 70be768..afc8f17 100644 --- a/schemas/BatteryUnitEventNode.md +++ b/schemas/BatteryUnitEventNode.md @@ -5,7 +5,7 @@ description: One append-only telemetry event (owner/grant tiers only). resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitEventNode tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One append-only telemetry event (owner/grant tiers only). diff --git a/schemas/BatteryUnitEventRow.md b/schemas/BatteryUnitEventRow.md index 95442c9..6778176 100644 --- a/schemas/BatteryUnitEventRow.md +++ b/schemas/BatteryUnitEventRow.md @@ -5,7 +5,7 @@ description: One immutable per-unit telemetry record (raw persisted row). resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitEventRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One immutable per-unit telemetry record (raw persisted row). Append-only: no update or delete path exists. diff --git a/schemas/BatteryUnitEventType.md b/schemas/BatteryUnitEventType.md index 2413982..479aefc 100644 --- a/schemas/BatteryUnitEventType.md +++ b/schemas/BatteryUnitEventType.md @@ -5,7 +5,7 @@ description: Per-unit dynamic-data event category (Annex XIII / Art. resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitEventType tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Per-unit dynamic-data event category (Annex XIII / Art. 77 telemetry). diff --git a/schemas/BatteryUnitJsonLd.md b/schemas/BatteryUnitJsonLd.md index 5b88ae5..c27262d 100644 --- a/schemas/BatteryUnitJsonLd.md +++ b/schemas/BatteryUnitJsonLd.md @@ -5,7 +5,7 @@ description: "JSON-LD document for one serialised battery unit, privileged tenan resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitJsonLd tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- JSON-LD document for one serialised battery unit, **privileged tenant view** (`isPrivileged=true`): includes `currentState` + `dynamicData` telemetry (restricted to legitimate-interest holders/authorities on the public view, where a `restrictedData` marker appears instead — never on this endpoint). diff --git a/schemas/BatteryUnitLineageRef.md b/schemas/BatteryUnitLineageRef.md index 0e131b0..8c9e281 100644 --- a/schemas/BatteryUnitLineageRef.md +++ b/schemas/BatteryUnitLineageRef.md @@ -5,7 +5,7 @@ description: Public lineage pointer between battery units (Art. resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitLineageRef tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Public lineage pointer between battery units (Art. 77(7)). diff --git a/schemas/BatteryUnitListResponse.md b/schemas/BatteryUnitListResponse.md index 35279d5..0c92659 100644 --- a/schemas/BatteryUnitListResponse.md +++ b/schemas/BatteryUnitListResponse.md @@ -5,7 +5,7 @@ description: BatteryUnitListResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitListResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/BatteryUnitRestrictedDataNotice.md b/schemas/BatteryUnitRestrictedDataNotice.md index 4612a60..172c5ce 100644 --- a/schemas/BatteryUnitRestrictedDataNotice.md +++ b/schemas/BatteryUnitRestrictedDataNotice.md @@ -5,7 +5,7 @@ description: Marker replacing per-unit telemetry in anonymous (public-tier) resp resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitRestrictedDataNotice tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Marker replacing per-unit telemetry in anonymous (public-tier) responses, with a pointer for requesting legitimate-interest access (Reg. (EU) 2023/1542, Annex XIII(2)-(4)). diff --git a/schemas/BatteryUnitRow.md b/schemas/BatteryUnitRow.md index 9d86c04..27059c0 100644 --- a/schemas/BatteryUnitRow.md +++ b/schemas/BatteryUnitRow.md @@ -5,7 +5,7 @@ description: One physical serialised battery (raw persisted row — these routes resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One physical serialised battery (raw persisted row — these routes declare no Fastify response schema, so all model fields are returned as-is). A `BatteryUnit` is an individual instance of a SKU/type-level passport, carrying its real serial in GS1 AI-21. diff --git a/schemas/BatteryUnitSerialisationFailedError.md b/schemas/BatteryUnitSerialisationFailedError.md index 8be475b..96903ff 100644 --- a/schemas/BatteryUnitSerialisationFailedError.md +++ b/schemas/BatteryUnitSerialisationFailedError.md @@ -5,7 +5,7 @@ description: 400 body when every item in the serialisation batch failed. resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitSerialisationFailedError tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 400 body when **every** item in the serialisation batch failed. Note: `errors` is an array of plain strings and there is **no `message` field** (unlike the standard error triple). diff --git a/schemas/BatteryUnitStatus.md b/schemas/BatteryUnitStatus.md index 11784b7..b01f36d 100644 --- a/schemas/BatteryUnitStatus.md +++ b/schemas/BatteryUnitStatus.md @@ -5,7 +5,7 @@ description: Annex XIII battery-status vocabulary (Battery Reg. resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitStatus tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Annex XIII battery-status vocabulary (Battery Reg. (EU) 2023/1542). `RECYCLED` means the passport has ceased to exist (Art. 77(8)): the public unit view answers 410 Gone whenever `status` is `RECYCLED` **or** `ceasedAt` is set. Terminality is enforced via `ceasedAt`, which only the events-route transition stamps (and never clears): the predecessor-refusal check keys on `ceasedAt` alone, so a unit *created* with initial status `RECYCLED` (no `ceasedAt`) is already a public 410 tombstone yet can still be referenced as a predecessor; conversely, once `ceasedAt` is set the events endpoint will still accept later `status` values, but the 410 tombstone and the predecessor refusal persist. diff --git a/schemas/BatteryUnitTombstoneJsonLd.md b/schemas/BatteryUnitTombstoneJsonLd.md index 0c4ec49..372af89 100644 --- a/schemas/BatteryUnitTombstoneJsonLd.md +++ b/schemas/BatteryUnitTombstoneJsonLd.md @@ -5,7 +5,7 @@ description: Art. resource: https://opendpp-node.eu/openapi.json#/components/schemas/BatteryUnitTombstoneJsonLd tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Art. 77(8) tombstone (HTTP 410): once a battery is recycled its passport has ceased to exist. This minimal record confirms the unit existed, that it was recycled and when, plus the (still living) model-passport link. Grants and owner credentials do not override the tombstone on the public URL; the underlying data is retained internally for the statutory retention window. diff --git a/schemas/CreateGrantRequest.md b/schemas/CreateGrantRequest.md index f1484df..9fb93a3 100644 --- a/schemas/CreateGrantRequest.md +++ b/schemas/CreateGrantRequest.md @@ -5,7 +5,7 @@ description: Direct-issuance body. resource: https://opendpp-node.eu/openapi.json#/components/schemas/CreateGrantRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Direct-issuance body. Over-length strings are silently truncated to the documented maximum, not rejected; unknown fields are ignored. The grant kind is always `LEGITIMATE_INTEREST` — there is no `kind`/`type` field. diff --git a/schemas/DeleteOperatorResponse.md b/schemas/DeleteOperatorResponse.md index f5adbf7..0296c87 100644 --- a/schemas/DeleteOperatorResponse.md +++ b/schemas/DeleteOperatorResponse.md @@ -5,7 +5,7 @@ description: DeleteOperatorResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/DeleteOperatorResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/DidWebDocument.md b/schemas/DidWebDocument.md new file mode 100644 index 0000000..ad1feba --- /dev/null +++ b/schemas/DidWebDocument.md @@ -0,0 +1,104 @@ +--- +type: Schema +title: DidWebDocument +description: A tenant's did:web DID document (public-key material only). +resource: https://opendpp-node.eu/openapi.json#/components/schemas/DidWebDocument +tags: + - schema +timestamp: 2026-06-20T00:00:00Z +--- + +A tenant's `did:web` DID document (public-key material only). Verification methods are `JsonWebKey2020` entries with stable `#key-` ids; current and retired keys are both listed so pre-rotation credentials still verify. + +## Schema + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `@context` | array | yes | JSON-LD contexts: the DID core context plus the JWS-2020 suite. | +| `id` | string | yes | The workspace DID, did:web:opendpp-node.eu:tenants:{tenantId}. | +| `name` | string | no | The issuer's authoritative legal name (present when the workspace has a company name). | +| `verificationMethod` | array | yes | Public verification keys. | +| `assertionMethod` | array | yes | Verification-method ids authorized to assert credentials (current + retired keys). | +| `authentication` | array | yes | — | + +## JSON Schema + +```json +{ + "type": "object", + "description": "A tenant's `did:web` DID document (public-key material only). Verification methods are `JsonWebKey2020` entries with stable `#key-` ids; current and retired keys are both listed so pre-rotation credentials still verify.", + "required": [ + "@context", + "id", + "verificationMethod", + "assertionMethod", + "authentication" + ], + "properties": { + "@context": { + "type": "array", + "items": { + "type": "string" + }, + "description": "JSON-LD contexts: the DID core context plus the JWS-2020 suite." + }, + "id": { + "type": "string", + "description": "The workspace DID, `did:web:opendpp-node.eu:tenants:{tenantId}`." + }, + "name": { + "type": "string", + "description": "The issuer's authoritative legal name (present when the workspace has a company name)." + }, + "verificationMethod": { + "type": "array", + "description": "Public verification keys.", + "items": { + "type": "object", + "required": [ + "id", + "type", + "controller", + "publicKeyJwk" + ], + "properties": { + "id": { + "type": "string", + "description": "`#key-` — matches the credential `kid`." + }, + "type": { + "type": "string", + "enum": [ + "JsonWebKey2020" + ] + }, + "controller": { + "type": "string" + }, + "publicKeyJwk": { + "type": "object", + "description": "The public key as a JWK (EC P-256, `alg: ES256`, `use: sig`). Public material only." + } + } + } + }, + "assertionMethod": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Verification-method ids authorized to assert credentials (current + retired keys)." + }, + "authentication": { + "type": "array", + "items": { + "type": "string" + } + } + } +} +``` + +## Used by + +- [getTenantDidDocument](/operations/getTenantDidDocument.md) (`GET /tenants/{tenantId}/did.json`) diff --git a/schemas/DppJsonLdContextDocument.md b/schemas/DppJsonLdContextDocument.md index 36aaeb4..9a1564c 100644 --- a/schemas/DppJsonLdContextDocument.md +++ b/schemas/DppJsonLdContextDocument.md @@ -5,7 +5,7 @@ description: "The fixed W3C JSON-LD context document served by GET /context/v1: resource: https://opendpp-node.eu/openapi.json#/components/schemas/DppJsonLdContextDocument tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- The fixed W3C JSON-LD context document served by `GET /context/v1`: maps `DigitalProductPassport`, `economicOperator`, `metadata`, `digitalSeal`, `signingPublicKey` and `proof` to `https://opendpp-node.eu/ns/dpp#…` IRIs, and `createdAt`/`updatedAt` to schema.org `dateCreated`/`dateModified`. diff --git a/schemas/DppVocabContextDocument.md b/schemas/DppVocabContextDocument.md new file mode 100644 index 0000000..ef668ee --- /dev/null +++ b/schemas/DppVocabContextDocument.md @@ -0,0 +1,40 @@ +--- +type: Schema +title: DppVocabContextDocument +description: The canonical resolvable JSON-LD context served by GET /contexts/dpp/v1 — the context every public passport and battery-unit document references in its @context. +resource: https://opendpp-node.eu/openapi.json#/components/schemas/DppVocabContextDocument +tags: + - schema +timestamp: 2026-06-20T00:00:00Z +--- + +The canonical resolvable JSON-LD context served by `GET /contexts/dpp/v1` — the context every public passport and battery-unit document references in its `@context`. Declares `@vocab` (so unknown terms expand under the OpenDPP namespace) plus core term mappings; `@version` is the numeric JSON-LD 1.1 marker, so `@context` values are a mix of strings and that number. + +## Schema + +| Property | Type | Required | Description | +|----------|------|----------|-------------| +| `@context` | object | yes | Term map: @vocab + @version (1.1) + the core DPP/unit term → dpp: CURIE mappings. | + +## JSON Schema + +```json +{ + "type": "object", + "description": "The canonical resolvable JSON-LD context served by `GET /contexts/dpp/v1` — the context every public passport and battery-unit document references in its `@context`. Declares `@vocab` (so unknown terms expand under the OpenDPP namespace) plus core term mappings; `@version` is the numeric JSON-LD 1.1 marker, so `@context` values are a mix of strings and that number.", + "additionalProperties": false, + "required": [ + "@context" + ], + "properties": { + "@context": { + "type": "object", + "description": "Term map: `@vocab` + `@version` (1.1) + the core DPP/unit term → `dpp:` CURIE mappings." + } + } +} +``` + +## Used by + +- [getDppJsonLdContext](/operations/getDppJsonLdContext.md) (`GET /contexts/dpp/v1`) diff --git a/schemas/EconomicOperatorNode.md b/schemas/EconomicOperatorNode.md index 7340a18..eb8dd43 100644 --- a/schemas/EconomicOperatorNode.md +++ b/schemas/EconomicOperatorNode.md @@ -5,7 +5,7 @@ description: Embedded economic-operator JSON-LD node (public in all tiers). resource: https://opendpp-node.eu/openapi.json#/components/schemas/EconomicOperatorNode tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Embedded economic-operator JSON-LD node (public in all tiers). diff --git a/schemas/Error.md b/schemas/Error.md index 684f137..b298848 100644 --- a/schemas/Error.md +++ b/schemas/Error.md @@ -5,7 +5,7 @@ description: Standard error body. resource: https://opendpp-node.eu/openapi.json#/components/schemas/Error tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Standard error body. Authenticated-API errors include `success: false`; some endpoints (and all public resolution errors) omit `success` and return only `error` + `message`. @@ -83,6 +83,8 @@ Standard error body. Authenticated-API errors include `success: false`; some end - [registerTraceabilityEvent](/operations/registerTraceabilityEvent.md) (`POST /api/v1/events`) - [getEventLineage](/operations/getEventLineage.md) (`GET /api/v1/events/{id}/lineage`) - [auditEventLineage](/operations/auditEventLineage.md) (`POST /api/v1/events/{id}/audit`) +- [getTenantDidDocument](/operations/getTenantDidDocument.md) (`GET /tenants/{tenantId}/did.json`) +- [getTenantRevocationStatusList](/operations/getTenantRevocationStatusList.md) (`GET /tenants/{tenantId}/status/revocation`) - [listWebhookSubscriptions](/operations/listWebhookSubscriptions.md) (`GET /api/v1/webhooks/subscriptions`) - [createWebhookSubscription](/operations/createWebhookSubscription.md) (`POST /api/v1/webhooks/subscriptions`) - [updateWebhookSubscription](/operations/updateWebhookSubscription.md) (`PATCH /api/v1/webhooks/subscriptions/{id}`) diff --git a/schemas/FacilityCreateRequest.md b/schemas/FacilityCreateRequest.md index b4cb58d..8436778 100644 --- a/schemas/FacilityCreateRequest.md +++ b/schemas/FacilityCreateRequest.md @@ -5,7 +5,7 @@ description: FacilityCreateRequest resource: https://opendpp-node.eu/openapi.json#/components/schemas/FacilityCreateRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/FacilityCreatedEnvelope.md b/schemas/FacilityCreatedEnvelope.md index 980312b..a64b311 100644 --- a/schemas/FacilityCreatedEnvelope.md +++ b/schemas/FacilityCreatedEnvelope.md @@ -5,7 +5,7 @@ description: FacilityCreatedEnvelope resource: https://opendpp-node.eu/openapi.json#/components/schemas/FacilityCreatedEnvelope tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/FacilityDeletedEnvelope.md b/schemas/FacilityDeletedEnvelope.md index d7599af..99deaaf 100644 --- a/schemas/FacilityDeletedEnvelope.md +++ b/schemas/FacilityDeletedEnvelope.md @@ -5,7 +5,7 @@ description: FacilityDeletedEnvelope resource: https://opendpp-node.eu/openapi.json#/components/schemas/FacilityDeletedEnvelope tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/FacilityEnvelope.md b/schemas/FacilityEnvelope.md index e18338d..5c62620 100644 --- a/schemas/FacilityEnvelope.md +++ b/schemas/FacilityEnvelope.md @@ -5,7 +5,7 @@ description: FacilityEnvelope resource: https://opendpp-node.eu/openapi.json#/components/schemas/FacilityEnvelope tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/FacilityListEnvelope.md b/schemas/FacilityListEnvelope.md index 9b147ce..d733c0b 100644 --- a/schemas/FacilityListEnvelope.md +++ b/schemas/FacilityListEnvelope.md @@ -5,7 +5,7 @@ description: FacilityListEnvelope resource: https://opendpp-node.eu/openapi.json#/components/schemas/FacilityListEnvelope tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/FacilityRow.md b/schemas/FacilityRow.md index 322b5fb..f20bd3f 100644 --- a/schemas/FacilityRow.md +++ b/schemas/FacilityRow.md @@ -5,7 +5,7 @@ description: A facility (GS1 GLN) master-data row, exactly as stored. resource: https://opendpp-node.eu/openapi.json#/components/schemas/FacilityRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- A facility (GS1 GLN) master-data row, exactly as stored. Returned in full to the owning tenant. Public exposure in passport documents differs by format: the *JSON-LD* document exposes `id`, `gln`, `name`, `activity` and `country` of a linked facility; the *AAS* export emits only the GLN, name and country (`manufacturingFacilityGln`/`Name`/`Country`). `streetAddress`, `city` and `postalCode` are emitted only to the owning/bound tenant in both formats. diff --git a/schemas/FacilityUpdateRequest.md b/schemas/FacilityUpdateRequest.md index 47c1c21..82ad594 100644 --- a/schemas/FacilityUpdateRequest.md +++ b/schemas/FacilityUpdateRequest.md @@ -5,7 +5,7 @@ description: Partial update. resource: https://opendpp-node.eu/openapi.json#/components/schemas/FacilityUpdateRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Partial update. `gln` and `operatorId` are immutable — if present they are silently ignored, as is any unknown key. For `activity`/`streetAddress`/`city`/`postalCode` the *presence* of the key matters: the value is stringified and trimmed, and anything that trims to empty (null, "", or a whitespace-only string) clears the field to null — the same normalization as POST. diff --git a/schemas/FastifyDefaultBadRequest.md b/schemas/FastifyDefaultBadRequest.md index 97ddbf5..281edb7 100644 --- a/schemas/FastifyDefaultBadRequest.md +++ b/schemas/FastifyDefaultBadRequest.md @@ -5,7 +5,7 @@ description: Fastify's default 400 error body, returned when a syntactically mal resource: https://opendpp-node.eu/openapi.json#/components/schemas/FastifyDefaultBadRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Fastify's default 400 error body, returned when a syntactically malformed JSON request body is rejected by the framework **before the handler runs** (so none of the handler-built `{success:false, ...}` shapes apply). diff --git a/schemas/GrantDecisionResponse.md b/schemas/GrantDecisionResponse.md index b711cf1..52a674d 100644 --- a/schemas/GrantDecisionResponse.md +++ b/schemas/GrantDecisionResponse.md @@ -5,7 +5,7 @@ description: "Returned by deny and revoke: the updated grant, no token." resource: https://opendpp-node.eu/openapi.json#/components/schemas/GrantDecisionResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Returned by deny and revoke: the updated grant, no token. diff --git a/schemas/GrantIssuedResponse.md b/schemas/GrantIssuedResponse.md index 328a77e..3c9a802 100644 --- a/schemas/GrantIssuedResponse.md +++ b/schemas/GrantIssuedResponse.md @@ -5,7 +5,7 @@ description: Returned by direct issuance (201) and request approval (200). resource: https://opendpp-node.eu/openapi.json#/components/schemas/GrantIssuedResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Returned by direct issuance (201) and request approval (200). `token` is the raw capability token — shown ONCE here (and, on approval, in the grantee's inspection-link e-mail); only its SHA-256 hash is persisted. diff --git a/schemas/GrantListResponse.md b/schemas/GrantListResponse.md index 5a635ed..5b4f317 100644 --- a/schemas/GrantListResponse.md +++ b/schemas/GrantListResponse.md @@ -5,7 +5,7 @@ description: List envelope for GET /api/v1/grants (paginated). resource: https://opendpp-node.eu/openapi.json#/components/schemas/GrantListResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- List envelope for `GET /api/v1/grants` (paginated). diff --git a/schemas/GrantRouteError.md b/schemas/GrantRouteError.md index 08060c1..9a7a045 100644 --- a/schemas/GrantRouteError.md +++ b/schemas/GrantRouteError.md @@ -5,7 +5,7 @@ description: Error body used by the grants endpoints' route-level errors (400/40 resource: https://opendpp-node.eu/openapi.json#/components/schemas/GrantRouteError tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Error body used by the grants endpoints' route-level errors (400/403/404/409). Unlike the standard error envelope, it has NO `success` field. diff --git a/schemas/GrantRow.md b/schemas/GrantRow.md index 370a59b..3e7a07a 100644 --- a/schemas/GrantRow.md +++ b/schemas/GrantRow.md @@ -5,7 +5,7 @@ description: Tenant-facing projection of an access grant. resource: https://opendpp-node.eu/openapi.json#/components/schemas/GrantRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Tenant-facing projection of an access grant. The token hash, issuer user id, revoking actor and request IP are never exposed; raw capability tokens appear only in the one-time issuance/approval responses. All fields are always present (nullable ones serialize as `null`). diff --git a/schemas/HealthStatus.md b/schemas/HealthStatus.md index 53b9eaa..4ecba8c 100644 --- a/schemas/HealthStatus.md +++ b/schemas/HealthStatus.md @@ -5,7 +5,7 @@ description: Health-check body of GET /health. resource: https://opendpp-node.eu/openapi.json#/components/schemas/HealthStatus tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Health-check body of `GET /health`. Carries the running build identity (`apiVersion`/`commit`/`builtAt`) in addition to the liveness fields. diff --git a/schemas/MaterialVocabularyListResponse.md b/schemas/MaterialVocabularyListResponse.md index f30c0e4..b172f0e 100644 --- a/schemas/MaterialVocabularyListResponse.md +++ b/schemas/MaterialVocabularyListResponse.md @@ -5,7 +5,7 @@ description: Envelope of GET /api/v1/materials. resource: https://opendpp-node.eu/openapi.json#/components/schemas/MaterialVocabularyListResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Envelope of `GET /api/v1/materials`. Caveat: unlike most authenticated endpoints there is NO `success` field. diff --git a/schemas/MaterialVocabularyRow.md b/schemas/MaterialVocabularyRow.md index 2cacfaf..e27668a 100644 --- a/schemas/MaterialVocabularyRow.md +++ b/schemas/MaterialVocabularyRow.md @@ -5,7 +5,7 @@ description: One entry of the platform-curated material vocabulary. resource: https://opendpp-node.eu/openapi.json#/components/schemas/MaterialVocabularyRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One entry of the platform-curated material vocabulary. Entries are unique per (`kind`, `name`). diff --git a/schemas/MerkleTreeAttestationProof.md b/schemas/MerkleTreeAttestationProof.md index 274b88a..8fbf874 100644 --- a/schemas/MerkleTreeAttestationProof.md +++ b/schemas/MerkleTreeAttestationProof.md @@ -5,7 +5,7 @@ description: "OpenDPP's own proof type — an eIDAS ADVANCED electronic seal: an resource: https://opendpp-node.eu/openapi.json#/components/schemas/MerkleTreeAttestationProof tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- OpenDPP's own proof type — an eIDAS ADVANCED electronic seal: an ECDSA prime256v1 signature over a SHA-256 Merkle root of the key-sorted metadata (one leaf per top-level metadata key). Deliberately NOT a W3C DataIntegrityProof / `ecdsa-jcs-2019` Verifiable Credential (no RFC 8785 JCS canonicalization). Verifiable offline: rebuild the Merkle root from `metadata` — substituting each `redactedLeaves` hash for its placeholder-masked key, and EXCLUDING any placeholder-masked key that has no `redactedLeaves` entry (such a key was never present in the sealed metadata; the serializer injects the owner-only placeholder unconditionally) — then verify `signatureValue` with `publicKeyPem`; the `x5c` chain validates against the platform seal CA (`GET /.well-known/opendpp-seal-ca.pem`) and the `rfc3161` token via `openssl ts -verify`. diff --git a/schemas/OperatorGetResponse.md b/schemas/OperatorGetResponse.md index 04d9090..4495b53 100644 --- a/schemas/OperatorGetResponse.md +++ b/schemas/OperatorGetResponse.md @@ -5,7 +5,7 @@ description: OperatorGetResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/OperatorGetResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/OperatorListResponse.md b/schemas/OperatorListResponse.md index 9e7cc7b..b1c42b9 100644 --- a/schemas/OperatorListResponse.md +++ b/schemas/OperatorListResponse.md @@ -5,7 +5,7 @@ description: OperatorListResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/OperatorListResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/OperatorMinimalError.md b/schemas/OperatorMinimalError.md index a41a6ef..d5d001a 100644 --- a/schemas/OperatorMinimalError.md +++ b/schemas/OperatorMinimalError.md @@ -5,7 +5,7 @@ description: Minimal error envelope used by the operator/key self-service handle resource: https://opendpp-node.eu/openapi.json#/components/schemas/OperatorMinimalError tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Minimal error envelope used by the operator/key self-service handlers — note the standard `error` key is ABSENT (unlike the shared Error schema). diff --git a/schemas/OperatorRow.md b/schemas/OperatorRow.md index 65da60c..63df9e1 100644 --- a/schemas/OperatorRow.md +++ b/schemas/OperatorRow.md @@ -5,7 +5,7 @@ description: An economic-operator record (EconomicOperator). resource: https://opendpp-node.eu/openapi.json#/components/schemas/OperatorRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- An economic-operator record (`EconomicOperator`). Operators are scoped to your workspace (each workspace keeps its own row for a given `regId`). Returned verbatim from the database (no field stripping); nullable fields are serialized as `null`. diff --git a/schemas/PassportAasEnvironment.md b/schemas/PassportAasEnvironment.md index c768357..939d22c 100644 --- a/schemas/PassportAasEnvironment.md +++ b/schemas/PassportAasEnvironment.md @@ -5,7 +5,7 @@ description: IDTA Asset Administration Shell environment (returned when Accept c resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportAasEnvironment tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- IDTA Asset Administration Shell environment (returned when `Accept` contains `application/aas+json`), role-filtered for the caller's access tier. Identifiers use `urn:opendpp:*` forms: the shell id is `urn:opendpp:aas:` with idShort `AAS_` and `globalAssetId` `urn:opendpp:asset::` (plus `specificAssetIds` carrying the productId and, when a facility is assigned, its GLN). The environment contains, at minimum, a `GeneralProductInformation` submodel (`urn:opendpp:submodel:general:`) and a `ComplianceMetadata` submodel (`urn:opendpp:submodel:compliance`); for a manufacturer/product-identified passport it also carries an IDTA Digital Nameplate submodel (idShort `Nameplate`) and one or more additive per-category submodel views (ESPR-category views such as CarbonFootprint / TechnicalData, id prefix `urn:opendpp:submodel:category:`). An `eidasVerificationSeal` submodel is appended when the tenant has signing keys configured. Loose schema — the full AAS document structure is documented with the public resolution endpoints. diff --git a/schemas/PassportBulkFailure.md b/schemas/PassportBulkFailure.md index 236a462..2abd13e 100644 --- a/schemas/PassportBulkFailure.md +++ b/schemas/PassportBulkFailure.md @@ -5,7 +5,7 @@ description: 400 body of POST /api/v1/passports/bulk when EVERY row failed. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportBulkFailure tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 400 body of `POST /api/v1/passports/bulk` when EVERY row failed. Note: `errors` is an array of STRINGS (not objects) and there is NO `message` field. diff --git a/schemas/PassportBulkRequest.md b/schemas/PassportBulkRequest.md index f4811e0..98bf8f7 100644 --- a/schemas/PassportBulkRequest.md +++ b/schemas/PassportBulkRequest.md @@ -5,7 +5,7 @@ description: PassportBulkRequest resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportBulkRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/PassportBulkResult.md b/schemas/PassportBulkResult.md index 2ad0f78..25088ae 100644 --- a/schemas/PassportBulkResult.md +++ b/schemas/PassportBulkResult.md @@ -5,7 +5,7 @@ description: 201 partial-success envelope of POST /api/v1/passports/bulk. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportBulkResult tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 201 partial-success envelope of `POST /api/v1/passports/bulk`. Returned whenever at least one row was inserted, even if other rows failed. diff --git a/schemas/PassportBulkRow.md b/schemas/PassportBulkRow.md index fef6d3d..738dcf6 100644 --- a/schemas/PassportBulkRow.md +++ b/schemas/PassportBulkRow.md @@ -5,7 +5,7 @@ description: One bulk-ingestion row. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportBulkRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One bulk-ingestion row. The HTTP layer only requires each row to be an object; rows missing `productId` or `metadata`, failing ESPR validation, referencing unbound operators/unknown facilities, or duplicating an existing `(productId, operatorId)` pair are SKIPPED and reported as strings in the response `errors[]` — they never fail the whole request (unless every row fails). Bulk rows do not support `draft` or `enrichment`, are always created with `status: "ACTIVE"`, skip the EPCIS traceability audit, and do NOT get `metadata.gtin`/`metadata.grai` auto-injected. diff --git a/schemas/PassportCreateRequest.md b/schemas/PassportCreateRequest.md index 36f002d..31376a5 100644 --- a/schemas/PassportCreateRequest.md +++ b/schemas/PassportCreateRequest.md @@ -5,7 +5,7 @@ description: PassportCreateRequest resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportCreateRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/PassportEnrichmentInput.md b/schemas/PassportEnrichmentInput.md index fd4ea93..81d0ac4 100644 --- a/schemas/PassportEnrichmentInput.md +++ b/schemas/PassportEnrichmentInput.md @@ -5,7 +5,7 @@ description: Optional presentational (non-regulatory) marketing enrichment, stor resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportEnrichmentInput tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Optional presentational (non-regulatory) marketing enrichment, stored OUTSIDE the ESPR-validated metadata and the Merkle seal; it never appears in the JSON-LD passport document. Server-side it is whitelist-sanitized rather than rejected: unknown keys are dropped; `tagline` is trimmed and capped at 200 chars, `description` at 4000, image `caption` at 200, link `label` at 120; at most 24 `images` and 24 `links` are kept; URLs must be http, https, or mailto (any other scheme, e.g. `javascript:` or `data:`, is silently dropped). An enrichment that sanitizes down to nothing is stored as null. diff --git a/schemas/PassportIngestCreated.md b/schemas/PassportIngestCreated.md index 6ac2e47..054e76f 100644 --- a/schemas/PassportIngestCreated.md +++ b/schemas/PassportIngestCreated.md @@ -5,7 +5,7 @@ description: 201 envelope of POST /api/v1/passports. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportIngestCreated tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 201 envelope of `POST /api/v1/passports`. Only these four top-level keys are ever emitted. diff --git a/schemas/PassportListItem.md b/schemas/PassportListItem.md index 95a6467..58491ff 100644 --- a/schemas/PassportListItem.md +++ b/schemas/PassportListItem.md @@ -5,7 +5,7 @@ description: One JSON-LD passport document as it appears in GET /api/v1/passport resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportListItem tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One JSON-LD passport document as it appears in `GET /api/v1/passports` list responses. Same shape as `PublicPassportJsonLd` with list-specific divergences imposed by the route's declared response serialization: `economicOperator` never carries `role`; `manufacturingFacility` is always `null`; the `@context` term map (second array element) is emptied to `{}`; and `proof` is emptied to `{}` on sealed items (`null` on unsealed) — fetch the single passport for the verifiable proof block. diff --git a/schemas/PassportListResponse.md b/schemas/PassportListResponse.md index 1679907..3dbac8d 100644 --- a/schemas/PassportListResponse.md +++ b/schemas/PassportListResponse.md @@ -5,7 +5,7 @@ description: Envelope of GET /api/v1/passports. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportListResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Envelope of GET /api/v1/passports. The response is serialized against a declared response schema: top-level keys other than these four are stripped. There is NO total count. diff --git a/schemas/PassportMetadataInput.md b/schemas/PassportMetadataInput.md index 893e851..93cef3c 100644 --- a/schemas/PassportMetadataInput.md +++ b/schemas/PassportMetadataInput.md @@ -5,7 +5,7 @@ description: The ESPR product metadata payload. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportMetadataInput tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- The ESPR product metadata payload. For non-draft ingestion and for the validate-only endpoints, `category` is mandatory and must be one of the 9 ESPR categories; each category then mandates its own field set (e.g. textiles require `fiberComposition`, `careInstructions`, `size`; batteries require `batteryCategory`, `chemistry`, `electrochemicalCapacity`, `durability`, `recycledContentShare`, `carbonFootprint`). For five categories — textiles, batteries, electronics, chemicals, construction — the authoritative per-category JSON Schema (required fields, value constraints, field help) is served live at `GET /api/v1/schemas/{category}`; the other four (cosmetics, toys, iron-steel, aluminium) are validated by built-in server-side rules and `GET /api/v1/schemas/{category}` returns 404 for them. Cross-field rules are enforced on top: `materialComposition` (and textile `fiberComposition`) percentages must sum to 100 ±0.1, `originCountry` must be a real ISO 3166-1 alpha-2 code, textile hazardous-substance concentrations are checked against REACH ppm limits. A documented set of supplementary objects (e.g. `technicalProperties`, `environmentalFootprint`, `circularityAttributes`, `esgDueDiligence`, `detailedPerformance`) produce non-blocking `warnings` instead of `errors` when malformed. With `draft: true` (single ingestion only) validation is skipped entirely and any object is accepted. diff --git a/schemas/PassportSealResponse.md b/schemas/PassportSealResponse.md index df8b2f8..85ea42e 100644 --- a/schemas/PassportSealResponse.md +++ b/schemas/PassportSealResponse.md @@ -5,7 +5,7 @@ description: 200 envelope of POST /api/v1/passports/{id}/seal. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportSealResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 200 envelope of POST /api/v1/passports/{id}/seal. `digitalSeal` is duplicated inside `passport.digitalSeal` and `passport.proof.signatureValue`. The passport document is serialized at the PUBLIC redaction tier; masked keys keep their true leaf hashes in `proof.redactedLeaves`. Note: despite the message wording, this endpoint does not change the passport's `status`. diff --git a/schemas/PassportStatusUpdateRequest.md b/schemas/PassportStatusUpdateRequest.md index 5e527ad..e55ab85 100644 --- a/schemas/PassportStatusUpdateRequest.md +++ b/schemas/PassportStatusUpdateRequest.md @@ -5,7 +5,7 @@ description: Body of PUT /api/v1/passports/{id}/status. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportStatusUpdateRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Body of PUT /api/v1/passports/{id}/status. Only `status` is read; any other keys are ignored (there is no `reason` field). diff --git a/schemas/PassportStatusUpdateResponse.md b/schemas/PassportStatusUpdateResponse.md index 50bb3c1..16c92bb 100644 --- a/schemas/PassportStatusUpdateResponse.md +++ b/schemas/PassportStatusUpdateResponse.md @@ -5,7 +5,7 @@ description: 200 envelope of PUT /api/v1/passports/{id}/status. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportStatusUpdateResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 200 envelope of PUT /api/v1/passports/{id}/status. The passport document is serialized at the PUBLIC redaction tier. diff --git a/schemas/PassportUpdateRequest.md b/schemas/PassportUpdateRequest.md index 1f98dc1..1872d32 100644 --- a/schemas/PassportUpdateRequest.md +++ b/schemas/PassportUpdateRequest.md @@ -5,7 +5,7 @@ description: Body of PUT /api/v1/passports/{id}. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportUpdateRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Body of PUT /api/v1/passports/{id}. Unknown keys are ignored. diff --git a/schemas/PassportUpdateResponse.md b/schemas/PassportUpdateResponse.md index 7b41be9..f6913d2 100644 --- a/schemas/PassportUpdateResponse.md +++ b/schemas/PassportUpdateResponse.md @@ -5,7 +5,7 @@ description: 200 envelope of PUT /api/v1/passports/{id}. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportUpdateResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 200 envelope of PUT /api/v1/passports/{id}. The passport document is serialized at the PUBLIC redaction tier (owner-only/restricted metadata keys masked) even for the owner. diff --git a/schemas/PassportUpdateValidationError.md b/schemas/PassportUpdateValidationError.md index a9dbfb7..580a907 100644 --- a/schemas/PassportUpdateValidationError.md +++ b/schemas/PassportUpdateValidationError.md @@ -5,7 +5,7 @@ description: 400 ESPR validation failure body of PUT /api/v1/passports/{id}. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportUpdateValidationError tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 400 ESPR validation failure body of PUT /api/v1/passports/{id}. DIVERGENCE from POST /api/v1/passports: there is never a `warnings` array on this route. diff --git a/schemas/PassportValidateOnlyError.md b/schemas/PassportValidateOnlyError.md index c811ab8..836df69 100644 --- a/schemas/PassportValidateOnlyError.md +++ b/schemas/PassportValidateOnlyError.md @@ -5,7 +5,7 @@ description: 400 envelope of the validate-only endpoints. resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportValidateOnlyError tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 400 envelope of the validate-only endpoints. Three variants: ESPR validation failure (`error: "Validation Failed"`, with `success`, `category`, `errors[]`, optional `warnings[]` — omitted when none; category-validity error items carry no `friendlyMessage`); whitespace-only `productId` (`error: "Bad Request"`, `category: "unknown"`, `errors: []`, no `warnings`); and structural request rejections (body-schema violations, malformed JSON), which return only `error` + `message`. diff --git a/schemas/PassportValidateOnlyRequest.md b/schemas/PassportValidateOnlyRequest.md index 660ca29..08b24bc 100644 --- a/schemas/PassportValidateOnlyRequest.md +++ b/schemas/PassportValidateOnlyRequest.md @@ -5,7 +5,7 @@ description: PassportValidateOnlyRequest resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportValidateOnlyRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/PassportValidateOnlyResult.md b/schemas/PassportValidateOnlyResult.md index 59195e0..e349cb4 100644 --- a/schemas/PassportValidateOnlyResult.md +++ b/schemas/PassportValidateOnlyResult.md @@ -5,7 +5,7 @@ description: 200 envelope of the validate-only endpoints (only the declared keys resource: https://opendpp-node.eu/openapi.json#/components/schemas/PassportValidateOnlyResult tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 200 envelope of the validate-only endpoints (only the declared keys are emitted). diff --git a/schemas/PublicBatteryUnitJsonLd.md b/schemas/PublicBatteryUnitJsonLd.md index 8156226..53a526c 100644 --- a/schemas/PublicBatteryUnitJsonLd.md +++ b/schemas/PublicBatteryUnitJsonLd.md @@ -5,7 +5,7 @@ description: Public JSON-LD document for one individual serialised battery unit resource: https://opendpp-node.eu/openapi.json#/components/schemas/PublicBatteryUnitJsonLd tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Public JSON-LD document for one individual serialised battery unit (Reg. (EU) 2023/1542 Art. 77(2)). The listed required keys are always present. EXACTLY ONE of two tier-dependent groups is added: anonymous (public) responses carry `restrictedData` (Annex XIII(2)-(4) notice) and OMIT `currentState`/`dynamicData` entirely; owner/grant (privileged) responses carry `currentState` (latest measurement or `null`) and `dynamicData` (up to 500 events, newest first) and omit `restrictedData`. The embedded `ofModel` passport is masked by the caller's tier like `GET /passport/{id}`. diff --git a/schemas/PublicFacilityNode.md b/schemas/PublicFacilityNode.md index 0b31c2c..1f58686 100644 --- a/schemas/PublicFacilityNode.md +++ b/schemas/PublicFacilityNode.md @@ -5,7 +5,7 @@ description: Embedded manufacturing-facility JSON-LD node — the GS1 GLN-backed resource: https://opendpp-node.eu/openapi.json#/components/schemas/PublicFacilityNode tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Embedded manufacturing-facility JSON-LD node — the GS1 GLN-backed Unique Facility Identifier (UFI, EN 18219). The five listed fields are public; `streetAddress`/`city`/`postalCode` appear ONLY in owner-tier responses (never via legitimate-interest grants). diff --git a/schemas/PublicPassportJsonLd.md b/schemas/PublicPassportJsonLd.md index 73a9ea1..1f04d48 100644 --- a/schemas/PublicPassportJsonLd.md +++ b/schemas/PublicPassportJsonLd.md @@ -5,7 +5,7 @@ description: The public, redacted JSON-LD Digital Product Passport document (app resource: https://opendpp-node.eu/openapi.json#/components/schemas/PublicPassportJsonLd tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- The public, redacted JSON-LD Digital Product Passport document (`application/ld+json`). All listed top-level keys are ALWAYS present (`null` where not applicable). Additionally, every key of the (masked) `metadata` object — except the reserved document keys (`@context`, `@type`, `@id`, `id`, `productId`, `digitalLinkUri`, `digitalSeal`, `signingPublicKey`, `status`, `archivedAt`, `retentionUntil`, `proof`, `createdAt`, `updatedAt`, `economicOperator`, `manufacturingFacility`, `metadata`) — is ALSO flattened onto the document root for direct semantic-graph querying (hence `additionalProperties: true`); flattened values are identical to the corresponding `metadata` values, including redaction placeholders. Tier-masked metadata keys are replaced (in both places) with the literal string `[REDACTED - Privileged Access Required]`. Masking by tier: anonymous public callers lose the per-category restricted keys (category `batteries`: `detailedPerformance`, `lifecycleAndInUse`, `circularityAndDisassembly` — masked only when actually present) AND the owner-only key `facilityDetails`; legitimate-interest/authority grant holders lose only `facilityDetails`; owner-tier responses are unmasked and additionally include the facility street address fields. Note: `facilityDetails` is placeholder-masked in EVERY non-owner response, even when the underlying metadata never contained the key — in that case it has no entry in `proof.redactedLeaves`. Each masked key that exists in the sealed metadata keeps its true Merkle leaf hash in `proof.redactedLeaves`, so the eIDAS seal stays verifiable offline after redaction (see `MerkleTreeAttestationProof` for the reconstruction rule). diff --git a/schemas/RecordBatteryUnitEventRequest.md b/schemas/RecordBatteryUnitEventRequest.md index 4551248..c178cea 100644 --- a/schemas/RecordBatteryUnitEventRequest.md +++ b/schemas/RecordBatteryUnitEventRequest.md @@ -5,7 +5,7 @@ description: One telemetry record. resource: https://opendpp-node.eu/openapi.json#/components/schemas/RecordBatteryUnitEventRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One telemetry record. All measurements are optional and independently nullable; numeric ranges are enforced with 400 on violation. diff --git a/schemas/RecordBatteryUnitEventResponse.md b/schemas/RecordBatteryUnitEventResponse.md index 6a48a87..36cca9c 100644 --- a/schemas/RecordBatteryUnitEventResponse.md +++ b/schemas/RecordBatteryUnitEventResponse.md @@ -5,7 +5,7 @@ description: RecordBatteryUnitEventResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/RecordBatteryUnitEventResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/RegisterOperatorRequest.md b/schemas/RegisterOperatorRequest.md index 020b90c..0d46342 100644 --- a/schemas/RegisterOperatorRequest.md +++ b/schemas/RegisterOperatorRequest.md @@ -5,7 +5,7 @@ description: RegisterOperatorRequest resource: https://opendpp-node.eu/openapi.json#/components/schemas/RegisterOperatorRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/RegisterOperatorResponse.md b/schemas/RegisterOperatorResponse.md index edd1dfa..46a507d 100644 --- a/schemas/RegisterOperatorResponse.md +++ b/schemas/RegisterOperatorResponse.md @@ -5,7 +5,7 @@ description: RegisterOperatorResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/RegisterOperatorResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/RestoreOperatorResponse.md b/schemas/RestoreOperatorResponse.md index 23ef09f..09f8f6f 100644 --- a/schemas/RestoreOperatorResponse.md +++ b/schemas/RestoreOperatorResponse.md @@ -5,7 +5,7 @@ description: RestoreOperatorResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/RestoreOperatorResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/RotateTenantKeysResponse.md b/schemas/RotateTenantKeysResponse.md index 92fcd54..45c46fa 100644 --- a/schemas/RotateTenantKeysResponse.md +++ b/schemas/RotateTenantKeysResponse.md @@ -5,7 +5,7 @@ description: RotateTenantKeysResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/RotateTenantKeysResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/SealCertificateReport.md b/schemas/SealCertificateReport.md index e54a47b..c3ae39c 100644 --- a/schemas/SealCertificateReport.md +++ b/schemas/SealCertificateReport.md @@ -5,7 +5,7 @@ description: "Present only for x5c-carrying proofs AND only when verification pr resource: https://opendpp-node.eu/openapi.json#/components/schemas/SealCertificateReport tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Present only for x5c-carrying proofs AND only when verification proceeds past the key-registration and operator-binding gates (the two policy `verified: false` responses omit it): the certified legal identity of the seal creator (eIDAS Art. 36(1)(b)). On an unparseable chain only `chainValid: false` and `error` are present. diff --git a/schemas/SealTimestampReport.md b/schemas/SealTimestampReport.md index 1d1cc3b..60ab869 100644 --- a/schemas/SealTimestampReport.md +++ b/schemas/SealTimestampReport.md @@ -5,7 +5,7 @@ description: "Present only when payload.proof.rfc3161.token was supplied AND ver resource: https://opendpp-node.eu/openapi.json#/components/schemas/SealTimestampReport tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Present only when `payload.proof.rfc3161.token` was supplied AND verification proceeds past the key-registration and operator-binding gates (the two policy `verified: false` responses omit it). Reports presence and the TSA-asserted genTime from the token's TSTInfo — full cryptographic TSR validation is the verifier's own step. diff --git a/schemas/SealVerifyRequest.md b/schemas/SealVerifyRequest.md index 31a0f62..076d106 100644 --- a/schemas/SealVerifyRequest.md +++ b/schemas/SealVerifyRequest.md @@ -5,7 +5,7 @@ description: Verification request. resource: https://opendpp-node.eu/openapi.json#/components/schemas/SealVerifyRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Verification request. Only `payload` is strictly required: `signature` and `publicKey` are extracted from `payload.proof` (proofValue/signatureValue, publicKeyPem, or the x5c leaf SPKI) when omitted, and the request fails 400 only if either is still missing after extraction. diff --git a/schemas/SealVerifyResponse.md b/schemas/SealVerifyResponse.md index 9c6cf0f..71020bb 100644 --- a/schemas/SealVerifyResponse.md +++ b/schemas/SealVerifyResponse.md @@ -5,7 +5,7 @@ description: Always HTTP 200 once the request is well-formed. resource: https://opendpp-node.eu/openapi.json#/components/schemas/SealVerifyResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Always HTTP 200 once the request is well-formed. `verified: false` covers both cryptographic failure and the two registration/binding policy failures — the policy failures add a `message` and OMIT `certificate`/`timestamp` even when an x5c chain or RFC 3161 token was supplied. diff --git a/schemas/SectorJsonSchemaDocument.md b/schemas/SectorJsonSchemaDocument.md index 7ff8ad8..77db5e9 100644 --- a/schemas/SectorJsonSchemaDocument.md +++ b/schemas/SectorJsonSchemaDocument.md @@ -5,7 +5,7 @@ description: A JSON Schema draft-07 document describing the ESPR metadata payloa resource: https://opendpp-node.eu/openapi.json#/components/schemas/SectorJsonSchemaDocument tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- A JSON Schema **draft-07** document describing the ESPR `metadata` payload for one product category, served as `application/schema+json`. Each known field is annotated server-side with a plain-English `description` from the platform's field-help registry (annotations are AJV-ignored; validation behavior is identical to the raw schema). The same schema (without annotations) validates `metadata` on `POST /api/v1/passports` and the validate-only endpoints. diff --git a/schemas/SectorVocabularyContext.md b/schemas/SectorVocabularyContext.md index 6e9de4d..f3de0c9 100644 --- a/schemas/SectorVocabularyContext.md +++ b/schemas/SectorVocabularyContext.md @@ -5,7 +5,7 @@ description: Per-category JSON-LD vocabulary context, returned by GET /api/v1/sc resource: https://opendpp-node.eu/openapi.json#/components/schemas/SectorVocabularyContext tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Per-category JSON-LD vocabulary context, returned by `GET /api/v1/schemas/{category}` when `Accept` contains `application/ld+json`. Fixed shape: `@vocab` is `https://w3id.org/opendpp/schemas/{category}#` plus mappings for `id`, `type`, `category`, `materialComposition`, `originCountry`, `facilityDetails` and `regulatoryCompliance`. diff --git a/schemas/SerializeBatteryUnitsRequest.md b/schemas/SerializeBatteryUnitsRequest.md index 71b39f1..507406e 100644 --- a/schemas/SerializeBatteryUnitsRequest.md +++ b/schemas/SerializeBatteryUnitsRequest.md @@ -5,7 +5,7 @@ description: "Either a single unit object, or a batch wrapper {units: [...]}." resource: https://opendpp-node.eu/openapi.json#/components/schemas/SerializeBatteryUnitsRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Either a single unit object, or a batch wrapper `{units: [...]}`. Precedence: when `units` is present **and is an array** it is used; otherwise the whole body is treated as one unit. (`anyOf`, not `oneOf`: a body carrying both a top-level `serialNumber` and a `units` array matches both shapes and is accepted by the server — `units` wins.) diff --git a/schemas/SerializeBatteryUnitsResponse.md b/schemas/SerializeBatteryUnitsResponse.md index 242bc71..bb7936f 100644 --- a/schemas/SerializeBatteryUnitsResponse.md +++ b/schemas/SerializeBatteryUnitsResponse.md @@ -5,7 +5,7 @@ description: Returned (201) when at least one unit was created. resource: https://opendpp-node.eu/openapi.json#/components/schemas/SerializeBatteryUnitsResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Returned (201) when at least one unit was created. Partial success is possible: skipped items are reported in `errors` while `units` holds the created rows. diff --git a/schemas/ServiceVersion.md b/schemas/ServiceVersion.md index ddecec8..06eaf86 100644 --- a/schemas/ServiceVersion.md +++ b/schemas/ServiceVersion.md @@ -5,7 +5,7 @@ description: Running API contract version and source build identity, returned by resource: https://opendpp-node.eu/openapi.json#/components/schemas/ServiceVersion tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Running API contract version and source build identity, returned by `GET /api/v1/version`. The `apiVersion` MAJOR is the safe thing to pin an integration or generated SDK to. diff --git a/schemas/TraceComplianceAuditResponse.md b/schemas/TraceComplianceAuditResponse.md index cbe3773..63569bc 100644 --- a/schemas/TraceComplianceAuditResponse.md +++ b/schemas/TraceComplianceAuditResponse.md @@ -5,7 +5,7 @@ description: TraceComplianceAuditResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/TraceComplianceAuditResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/TraceComplianceCertificate.md b/schemas/TraceComplianceCertificate.md index ef2dd61..ee5950d 100644 --- a/schemas/TraceComplianceCertificate.md +++ b/schemas/TraceComplianceCertificate.md @@ -5,7 +5,7 @@ description: TraceComplianceCertificate resource: https://opendpp-node.eu/openapi.json#/components/schemas/TraceComplianceCertificate tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/TraceEventRegistered.md b/schemas/TraceEventRegistered.md index 92c08f4..cc6aa4a 100644 --- a/schemas/TraceEventRegistered.md +++ b/schemas/TraceEventRegistered.md @@ -5,7 +5,7 @@ description: 201 envelope of POST /api/v1/events. resource: https://opendpp-node.eu/openapi.json#/components/schemas/TraceEventRegistered tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- 201 envelope of POST /api/v1/events. Note: `status: "success"` (string), not the usual `success: true` boolean. diff --git a/schemas/TraceLineageNode.md b/schemas/TraceLineageNode.md index eebd262..6219bd6 100644 --- a/schemas/TraceLineageNode.md +++ b/schemas/TraceLineageNode.md @@ -5,7 +5,7 @@ description: One node of the recursive upstream lineage DAG. resource: https://opendpp-node.eu/openapi.json#/components/schemas/TraceLineageNode tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One node of the recursive upstream lineage DAG. All keys are always present; `location`, `readPoint` and `issuerDid` are null when unset. `location` mirrors the stored `bizLocation`. A shared ancestor reached through multiple downstream paths appears once under each path (the DAG is expanded into a tree). diff --git a/schemas/TraceLineageResponse.md b/schemas/TraceLineageResponse.md index a8f997e..990a464 100644 --- a/schemas/TraceLineageResponse.md +++ b/schemas/TraceLineageResponse.md @@ -5,7 +5,7 @@ description: TraceLineageResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/TraceLineageResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/UntpEventCredential.md b/schemas/UntpEventCredential.md index 0510614..00422d1 100644 --- a/schemas/UntpEventCredential.md +++ b/schemas/UntpEventCredential.md @@ -5,7 +5,7 @@ description: A UNTP/EPCIS 2.0 traceability event wrapped as a VC-shaped credenti resource: https://opendpp-node.eu/openapi.json#/components/schemas/UntpEventCredential tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- A UNTP/EPCIS 2.0 traceability event wrapped as a VC-shaped credential (a vendor proof, not a conformant W3C VC). The only hard structural requirement is `credentialSubject`; a missing or unverifiable `proof` is rejected with the 400 `Cryptographic Verification Failed` body. Extra properties are permitted — the entire credential (with `proof.proofValue` blanked) is what the signature covers. diff --git a/schemas/UntpEventCredentialSubject.md b/schemas/UntpEventCredentialSubject.md index a280a94..55e07b3 100644 --- a/schemas/UntpEventCredentialSubject.md +++ b/schemas/UntpEventCredentialSubject.md @@ -5,7 +5,7 @@ description: The EPCIS event payload. resource: https://opendpp-node.eu/openapi.json#/components/schemas/UntpEventCredentialSubject tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- The EPCIS event payload. `eventType` is effectively required: it is persisted into a server-side enum, and a missing or unknown value is rejected at the persistence layer (surfacing as the 500 `Database Persistence Failed` body, not a 400). diff --git a/schemas/UntpEventProof.md b/schemas/UntpEventProof.md index df0eda0..2c11531 100644 --- a/schemas/UntpEventProof.md +++ b/schemas/UntpEventProof.md @@ -5,7 +5,7 @@ description: Credential proof. resource: https://opendpp-node.eu/openapi.json#/components/schemas/UntpEventProof tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Credential proof. Verified with ECDSA P-256 / SHA-256 over OpenDPP's deterministic key-sorted JSON canonicalization of the credential with `proofValue` blanked (NOT RFC 8785 JCS — not a conformant W3C Data Integrity suite). diff --git a/schemas/UntpVerificationMethod.md b/schemas/UntpVerificationMethod.md index 7e840a8..50f0bb2 100644 --- a/schemas/UntpVerificationMethod.md +++ b/schemas/UntpVerificationMethod.md @@ -5,7 +5,7 @@ description: Embedded verification-method object. resource: https://opendpp-node.eu/openapi.json#/components/schemas/UntpVerificationMethod tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Embedded verification-method object. The `x5c` chain (base64 DER, leaf first) is honoured ONLY when the node has eIDAS trust anchors configured, every certificate is currently valid, each link verifies against the next, the top is anchored, and the leaf attests the credential issuer — otherwise it is ignored and the registered tenant key is used instead. diff --git a/schemas/UpdateOperatorRequest.md b/schemas/UpdateOperatorRequest.md index 35ab16e..b0dbd21 100644 --- a/schemas/UpdateOperatorRequest.md +++ b/schemas/UpdateOperatorRequest.md @@ -5,7 +5,7 @@ description: Both fields are optional. resource: https://opendpp-node.eu/openapi.json#/components/schemas/UpdateOperatorRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Both fields are optional. Values must be non-empty strings after trimming; anything else (missing, non-string, whitespace-only) is silently ignored. `regId` and `regIdScheme` cannot be changed. An omitted body or an empty object `{}` is accepted and returns the unchanged row. diff --git a/schemas/UpdateOperatorResponse.md b/schemas/UpdateOperatorResponse.md index 65e6158..c341e15 100644 --- a/schemas/UpdateOperatorResponse.md +++ b/schemas/UpdateOperatorResponse.md @@ -5,7 +5,7 @@ description: UpdateOperatorResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/UpdateOperatorResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/ValidationErrorItem.md b/schemas/ValidationErrorItem.md index 5c02654..b5b7625 100644 --- a/schemas/ValidationErrorItem.md +++ b/schemas/ValidationErrorItem.md @@ -5,7 +5,7 @@ description: One field-level finding from ESPR category validation. resource: https://opendpp-node.eu/openapi.json#/components/schemas/ValidationErrorItem tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One field-level finding from ESPR category validation. `path` uses dot/bracket notation into the metadata object (e.g. `materialComposition[0].percentage`). diff --git a/schemas/WebhookDeliveriesResponse.md b/schemas/WebhookDeliveriesResponse.md index 155a0b1..8f0da3a 100644 --- a/schemas/WebhookDeliveriesResponse.md +++ b/schemas/WebhookDeliveriesResponse.md @@ -5,7 +5,7 @@ description: WebhookDeliveriesResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookDeliveriesResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WebhookDeliveryRow.md b/schemas/WebhookDeliveryRow.md index 202b290..61c3a71 100644 --- a/schemas/WebhookDeliveryRow.md +++ b/schemas/WebhookDeliveryRow.md @@ -5,7 +5,7 @@ description: One outbox delivery record (event-level). resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookDeliveryRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- One outbox delivery record (event-level). The payload is not included. diff --git a/schemas/WebhookEnvelope.md b/schemas/WebhookEnvelope.md index 3e5621d..98d37b8 100644 --- a/schemas/WebhookEnvelope.md +++ b/schemas/WebhookEnvelope.md @@ -5,7 +5,7 @@ description: The signed body of every webhook delivery. resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookEnvelope tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- The signed body of every webhook delivery. `data` is the public (redacted) JSON-LD passport document; `type` is the concrete event name (also in the `X-OpenDPP-Event` header); `id` is the stable delivery id (also in the `X-OpenDPP-Delivery` header) and is CONSTANT across all retries of the same event, so deduplicate on it for exactly-once processing; `created` is the event time (stable across retries, distinct from the per-attempt `X-OpenDPP-Timestamp`). diff --git a/schemas/WebhookEventFilter.md b/schemas/WebhookEventFilter.md index 1cdc140..516f919 100644 --- a/schemas/WebhookEventFilter.md +++ b/schemas/WebhookEventFilter.md @@ -5,7 +5,7 @@ description: Subscribable event filter values. resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookEventFilter tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Subscribable event filter values. `*` matches every emitted event. `passport.status_updated` (decommission/reactivate) and `passport.updated` (in-place edit of a published passport) are now first-class subscribable filters. diff --git a/schemas/WebhookSecretRotateResponse.md b/schemas/WebhookSecretRotateResponse.md index 674ca6c..e0787c8 100644 --- a/schemas/WebhookSecretRotateResponse.md +++ b/schemas/WebhookSecretRotateResponse.md @@ -5,7 +5,7 @@ description: WebhookSecretRotateResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSecretRotateResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WebhookSubscriptionCreateRequest.md b/schemas/WebhookSubscriptionCreateRequest.md index 44b39f2..eeb962d 100644 --- a/schemas/WebhookSubscriptionCreateRequest.md +++ b/schemas/WebhookSubscriptionCreateRequest.md @@ -5,7 +5,7 @@ description: WebhookSubscriptionCreateRequest resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionCreateRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WebhookSubscriptionCreateResponse.md b/schemas/WebhookSubscriptionCreateResponse.md index cbc58b6..c46fa97 100644 --- a/schemas/WebhookSubscriptionCreateResponse.md +++ b/schemas/WebhookSubscriptionCreateResponse.md @@ -5,7 +5,7 @@ description: WebhookSubscriptionCreateResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionCreateResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WebhookSubscriptionDeleteResponse.md b/schemas/WebhookSubscriptionDeleteResponse.md index dd02476..1f02747 100644 --- a/schemas/WebhookSubscriptionDeleteResponse.md +++ b/schemas/WebhookSubscriptionDeleteResponse.md @@ -5,7 +5,7 @@ description: WebhookSubscriptionDeleteResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionDeleteResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WebhookSubscriptionListResponse.md b/schemas/WebhookSubscriptionListResponse.md index b211d4e..a2ce8ad 100644 --- a/schemas/WebhookSubscriptionListResponse.md +++ b/schemas/WebhookSubscriptionListResponse.md @@ -5,7 +5,7 @@ description: WebhookSubscriptionListResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionListResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WebhookSubscriptionRow.md b/schemas/WebhookSubscriptionRow.md index 801803e..2a460a0 100644 --- a/schemas/WebhookSubscriptionRow.md +++ b/schemas/WebhookSubscriptionRow.md @@ -5,7 +5,7 @@ description: A webhook subscription row with the HMAC signing secret stripped (i resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionRow tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- A webhook subscription row with the HMAC signing `secret` stripped (it is shown exactly once, in the 201 create response). diff --git a/schemas/WebhookSubscriptionUpdateRequest.md b/schemas/WebhookSubscriptionUpdateRequest.md index 468a35b..543e704 100644 --- a/schemas/WebhookSubscriptionUpdateRequest.md +++ b/schemas/WebhookSubscriptionUpdateRequest.md @@ -5,7 +5,7 @@ description: All fields optional; include only what you want to change. resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionUpdateRequest tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- All fields optional; include only what you want to change. The secret is not editable here. diff --git a/schemas/WebhookSubscriptionUpdateResponse.md b/schemas/WebhookSubscriptionUpdateResponse.md index 07fc823..559200b 100644 --- a/schemas/WebhookSubscriptionUpdateResponse.md +++ b/schemas/WebhookSubscriptionUpdateResponse.md @@ -5,7 +5,7 @@ description: WebhookSubscriptionUpdateResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionUpdateResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WebhookSubscriptionWithSecret.md b/schemas/WebhookSubscriptionWithSecret.md index b478fab..d0c9755 100644 --- a/schemas/WebhookSubscriptionWithSecret.md +++ b/schemas/WebhookSubscriptionWithSecret.md @@ -5,7 +5,7 @@ description: The full subscription row as returned ONLY by the 201 create respon resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookSubscriptionWithSecret tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- The full subscription row as returned ONLY by the 201 create response — includes the HMAC-SHA256 signing secret. diff --git a/schemas/WebhookTestResult.md b/schemas/WebhookTestResult.md index bd32d7a..306fa55 100644 --- a/schemas/WebhookTestResult.md +++ b/schemas/WebhookTestResult.md @@ -5,7 +5,7 @@ description: WebhookTestResult resource: https://opendpp-node.eu/openapi.json#/components/schemas/WebhookTestResult tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/WhoamiResponse.md b/schemas/WhoamiResponse.md index 45bbb43..20cef45 100644 --- a/schemas/WhoamiResponse.md +++ b/schemas/WhoamiResponse.md @@ -5,7 +5,7 @@ description: WhoamiResponse resource: https://opendpp-node.eu/openapi.json#/components/schemas/WhoamiResponse tags: - schema -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- ## Schema diff --git a/schemas/index.md b/schemas/index.md index a33b6f1..9bfaa58 100644 --- a/schemas/index.md +++ b/schemas/index.md @@ -22,7 +22,9 @@ * [BatteryUnitTombstoneJsonLd](BatteryUnitTombstoneJsonLd.md) - Art. * [CreateGrantRequest](CreateGrantRequest.md) - Direct-issuance body. * [DeleteOperatorResponse](DeleteOperatorResponse.md) +* [DidWebDocument](DidWebDocument.md) - A tenant's did:web DID document (public-key material only). * [DppJsonLdContextDocument](DppJsonLdContextDocument.md) - The fixed W3C JSON-LD context document served by GET /context/v1: maps DigitalProductPassport, economicOperator, metadata, digitalSeal, sig… +* [DppVocabContextDocument](DppVocabContextDocument.md) - The canonical resolvable JSON-LD context served by GET /contexts/dpp/v1 — the context every public passport and battery-unit document refer… * [EconomicOperatorNode](EconomicOperatorNode.md) - Embedded economic-operator JSON-LD node (public in all tiers). * [Error](Error.md) - Standard error body. * [FacilityCreateRequest](FacilityCreateRequest.md) diff --git a/tags/access-grants.md b/tags/access-grants.md index 4fc6c3f..0d66a09 100644 --- a/tags/access-grants.md +++ b/tags/access-grants.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - access-grants -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Capability tokens implementing tiered access (Battery Regulation Art. 77(9) legitimate-interest access): issue, approve, deny and revoke `dpp_li_…` / `dpp_auth_…` tokens. Third parties request access via the hosted request page; granted tokens unlock restricted fields on the public resolution endpoints (Bearer or `?grant=`). diff --git a/tags/account.md b/tags/account.md index 2fad160..ed7bcc0 100644 --- a/tags/account.md +++ b/tags/account.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - account -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Identity of the authenticated API key / session: workspace, role, permissions, operator scope, and passport usage against the tier quota — the integration-facing counterpart to the console's profile endpoints. diff --git a/tags/battery-units.md b/tags/battery-units.md index 9c29700..4025d0a 100644 --- a/tags/battery-units.md +++ b/tags/battery-units.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - battery-units -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Per-unit battery serialization (real serials, GS1 AI 21) under a SKU-level passport, plus append-only telemetry events (state of health, charge cycles, status changes) per the EU Battery Regulation. diff --git a/tags/economic-operators.md b/tags/economic-operators.md index eb67dd2..0ada63c 100644 --- a/tags/economic-operators.md +++ b/tags/economic-operators.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - economic-operators -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Register and manage the economic operators (manufacturers/brands, identified by EORI or national registry id) that passports are issued on behalf of. Operators with passports are archived — never hard-deleted — to preserve passport resolvability (ESPR Art. 9(2)). diff --git a/tags/eidas-keys.md b/tags/eidas-keys.md index e43113e..b92b3ee 100644 --- a/tags/eidas-keys.md +++ b/tags/eidas-keys.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - eidas-keys -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Tenant signing-key management. Keys are generated and held server-side in an encrypted vault; private key material is never returned by any endpoint. diff --git a/tags/facilities.md b/tags/facilities.md index 522d9de..99a96f6 100644 --- a/tags/facilities.md +++ b/tags/facilities.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - facilities -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Manufacturing facility master data, identified by GS1 GLN-13 (the Unique Facility Identifier). GLN, name, activity and country are public in passport documents; street addresses are never published. diff --git a/tags/index.md b/tags/index.md index 2a3349c..6a1d401 100644 --- a/tags/index.md +++ b/tags/index.md @@ -8,6 +8,7 @@ * [Webhooks](webhooks.md) - Subscribe HTTPS endpoints to passport lifecycle events. * [Traceability & Audit](traceability-audit.md) - UNTP/EPCIS supply-chain traceability events, lineage queries, and the public seal verifier. * [Public Resolution](public-resolution.md) - Unauthenticated, content-negotiated passport resolution: GS1 Digital Link paths, passport and unit pages. +* [Verifiable Credentials](verifiable-credentials.md) - Issuer trust endpoints that back the UNTP Verifiable Credential representations: the workspace's did:web DID document (public keys only) and its W3C Bitstring… * [Schemas & Vocabulary](schemas-vocabulary.md) - Machine-readable contracts: per-category ESPR JSON Schemas, the W3C JSON-LD context, and the curated materials vocabulary. * [QR Codes](qr-codes.md) - Export GS1-Digital-Link QR codes (PNG/SVG, 128–2048 px, GS1 quiet zone) for passports and battery units. * [eIDAS Keys](eidas-keys.md) - Tenant signing-key management. diff --git a/tags/passports.md b/tags/passports.md index 54eafbd..21e3681 100644 --- a/tags/passports.md +++ b/tags/passports.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - passports -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Create, validate, read, update, seal and manage the lifecycle of Digital Product Passports. Passport metadata is category-specific: machine-readable JSON Schemas are served live at `GET /api/v1/schemas/{category}` for textiles, batteries, electronics, chemicals and construction; the remaining categories (cosmetics, toys, iron-steel, aluminium) are validated by built-in rules — use the dry-run validators to check payloads for any category. diff --git a/tags/public-resolution.md b/tags/public-resolution.md index 7b7feb7..7c7cf67 100644 --- a/tags/public-resolution.md +++ b/tags/public-resolution.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - public-resolution -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Unauthenticated, content-negotiated passport resolution: GS1 Digital Link paths, passport and unit pages. One URL serves JSON-LD (default), an AAS environment (`Accept: application/aas+json`), a signed UNTP Verifiable Credential (`Accept: application/vc+jwt` enveloping, `application/vc+ld+json` embedded `ecdsa-jcs-2019` Data Integrity, or `application/dc+sd-jwt` SD-JWT-VC selective disclosure; the first two also item-level on `/unit/:id`), or HTML (`Accept: text/html`). Tiered by optional credentials or grant tokens. Rate limit: 30 requests/min per IP. diff --git a/tags/qr-codes.md b/tags/qr-codes.md index b6f8e3a..f64e5e5 100644 --- a/tags/qr-codes.md +++ b/tags/qr-codes.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - qr-codes -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Export GS1-Digital-Link QR codes (PNG/SVG, 128–2048 px, GS1 quiet zone) for passports and battery units. diff --git a/tags/schemas-vocabulary.md b/tags/schemas-vocabulary.md index 2c0a0d4..e1bed9c 100644 --- a/tags/schemas-vocabulary.md +++ b/tags/schemas-vocabulary.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - schemas-vocabulary -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Machine-readable contracts: per-category ESPR JSON Schemas, the W3C JSON-LD context, and the curated materials vocabulary. @@ -14,5 +14,6 @@ Machine-readable contracts: per-category ESPR JSON Schemas, the W3C JSON-LD cont ## Operations - [getSectorSchema](/operations/getSectorSchema.md) — `GET /api/v1/schemas/{category}` — Get the ESPR metadata schema for a product category -- [getJsonLdContext](/operations/getJsonLdContext.md) — `GET /context/v1` — W3C JSON-LD context document for passport terms +- [getDppJsonLdContext](/operations/getDppJsonLdContext.md) — `GET /contexts/dpp/v1` — Canonical resolvable JSON-LD context for passport & unit documents +- [getJsonLdContext](/operations/getJsonLdContext.md) — `GET /context/v1` — W3C JSON-LD context document for passport terms (secondary, fixed term list) - [listMaterials](/operations/listMaterials.md) — `GET /api/v1/materials` — List the platform-curated material vocabulary diff --git a/tags/service.md b/tags/service.md index 494fb6b..6c81af9 100644 --- a/tags/service.md +++ b/tags/service.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - service -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Service metadata and liveness. diff --git a/tags/traceability-audit.md b/tags/traceability-audit.md index 0685400..e139131 100644 --- a/tags/traceability-audit.md +++ b/tags/traceability-audit.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - traceability-audit -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- UNTP/EPCIS supply-chain traceability events, lineage queries, and the public seal verifier. The verifier checks the cryptographic seal AND that the signing workspace is bound to the economic operator declared in the payload. diff --git a/tags/verifiable-credentials.md b/tags/verifiable-credentials.md new file mode 100644 index 0000000..bd5dc5b --- /dev/null +++ b/tags/verifiable-credentials.md @@ -0,0 +1,17 @@ +--- +type: Reference +title: Verifiable Credentials +description: "Issuer trust endpoints that back the UNTP Verifiable Credential representations: the workspace's did:web DID document (public keys only) and its W3C Bitstring Status List for revocation." +resource: https://opendpp-node.eu/api-reference +tags: + - api domain + - verifiable-credentials +timestamp: 2026-06-20T00:00:00Z +--- + +Issuer trust endpoints that back the UNTP Verifiable Credential representations: the workspace's `did:web` DID document (public keys only) and its W3C Bitstring Status List for revocation. Unauthenticated; resolve these to verify and revocation-check any OpenDPP-issued credential. + +## Operations + +- [getTenantDidDocument](/operations/getTenantDidDocument.md) — `GET /tenants/{tenantId}/did.json` — Resolve a tenant's did:web DID document +- [getTenantRevocationStatusList](/operations/getTenantRevocationStatusList.md) — `GET /tenants/{tenantId}/status/revocation` — Tenant revocation status list (W3C Bitstring Status List) diff --git a/tags/webhooks.md b/tags/webhooks.md index f2cf729..aa38981 100644 --- a/tags/webhooks.md +++ b/tags/webhooks.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/api-reference tags: - api domain - webhooks -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Subscribe HTTPS endpoints to passport lifecycle events. Deliveries are HMAC-SHA256-signed POSTs with retry/backoff — see the webhooks section of this document for the signature scheme and payloads. diff --git a/webhooks/passport.ingested.md b/webhooks/passport.ingested.md index 6b9e256..9c8a8f8 100644 --- a/webhooks/passport.ingested.md +++ b/webhooks/passport.ingested.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/openapi.json#/webhooks/passport.ingested tags: - webhook - event -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Sent when a passport becomes active for the first time: a non-draft `POST /api/v1/passports` create, the **first publish** of a draft via `PUT /api/v1/passports/{id}`, or each successfully ingested row of `POST /api/v1/passports/bulk`. Draft creation does NOT emit it, non-publish updates and deletes emit nothing, and **AAS ingestion (`POST /api/v1/passports/aas/ingest`) emits no webhook events at all**. The payload is the freshly created passport: `status: "ACTIVE"` with `digitalSeal` and `proof` still `null` (unless a previously sealed draft is re-published). Emission is enqueued transactionally with the passport write (outbox pattern) and delivered asynchronously to every active subscription whose filter contains `passport.ingested` or `*`. diff --git a/webhooks/passport.recalled.md b/webhooks/passport.recalled.md index b8f7037..5960bdd 100644 --- a/webhooks/passport.recalled.md +++ b/webhooks/passport.recalled.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/openapi.json#/webhooks/passport.recalled tags: - webhook - event -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Sent when `PUT /api/v1/passports/{id}/status` transitions a passport to `RECALLED`, transactionally with the status write. The payload is the public JSON-LD passport with `status: "RECALLED"` (seal/proof fields reflect whatever state the passport was in when recalled). Delivered to every active subscription whose filter contains `passport.recalled` or `*`. diff --git a/webhooks/passport.sealed.md b/webhooks/passport.sealed.md index a20a5d5..4edbd97 100644 --- a/webhooks/passport.sealed.md +++ b/webhooks/passport.sealed.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/openapi.json#/webhooks/passport.sealed tags: - webhook - event -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Sent when a passport is sealed via `POST /api/v1/passports/{id}/seal`, transactionally with the seal write. The payload carries the populated `digitalSeal`, `signingPublicKey`, and the `proof` block: `merkleRoot` always; an `x5c` certificate chain binding the signing key to the tenant's legal identity **when the tenant's signing key has an issued chain**; an **optional** `rfc3161` trusted timestamp; and `redactedLeaves` hashes **when the passport carries masked metadata keys**. Delivered to every active subscription whose filter contains `passport.sealed` or `*`. diff --git a/webhooks/passport.status_updated.md b/webhooks/passport.status_updated.md index ad51532..0209c25 100644 --- a/webhooks/passport.status_updated.md +++ b/webhooks/passport.status_updated.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/openapi.json#/webhooks/passport.status_updated tags: - webhook - event -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Sent when `PUT /api/v1/passports/{id}/status` performs a non-recall transition: decommissioning (`DECOMMISSIONED`, which also sets `retentionUntil` and starts the retention clock) or reactivation back to `ACTIVE`. Subscribe to it directly with the `passport.status_updated` filter (or `*`). diff --git a/webhooks/passport.updated.md b/webhooks/passport.updated.md index 057b97e..f205f27 100644 --- a/webhooks/passport.updated.md +++ b/webhooks/passport.updated.md @@ -6,7 +6,7 @@ resource: https://opendpp-node.eu/openapi.json#/webhooks/passport.updated tags: - webhook - event -timestamp: 2026-06-19T00:00:00Z +timestamp: 2026-06-20T00:00:00Z --- Sent when an already-published (non-draft) passport's content is edited in place via `PUT /api/v1/passports/{id}`, transactionally with the update write. This is **distinct from first publish** (that emits `passport.ingested`, not this event) and is **never** emitted for sealed passports — in-place edits of a sealed passport are rejected with `403`. The payload is the updated public JSON-LD passport with `status: "ACTIVE"`. Delivered to every active subscription whose filter contains `passport.updated` or `*`.