{
  "openapi": "3.1.0",
  "info": {
    "title": "Itemoo Public Product Data API",
    "version": "1.0.0",
    "description": "Read-only product data published by producers on Itemoo — no key needed. The same QR code serves a person (HTML page) and a machine (JSON). Every fact points to the document that proves it; machine data is never richer or poorer than the page a person sees.\n\n**Languages.** `?lang=xx` or `Accept-Language`; texts fall back to the brand default language.\n\n**Errors.** `{ statusCode, error, code, params?, message }` — rely on `code`. A code of a product that is no longer maintained returns `410`.\n\n**Limits.** Calls are rate-limited per IP address (`429` when exceeded); responses are cacheable — respect `Cache-Control`.",
    "x-major-version": "v1"
  },
  "servers": [
    {
      "url": "https://itemoo.eu"
    }
  ],
  "tags": [
    {
      "name": "Product data"
    },
    {
      "name": "Passport"
    },
    {
      "name": "GS1 Digital Link"
    }
  ],
  "paths": {
    "/q/{code}/data": {
      "get": {
        "operationId": "product.data",
        "tags": [
          "Product data"
        ],
        "summary": "Product data with provenance",
        "description": "Everything the human page shows, for machines: identity (GTIN, LOT, serial), product, facts with the document behind each, documents, FAQ, recall status and a trust section. Only the published version of the page is exposed. CORS is open (`Access-Control-Allow-Origin: *`); responses are cached for 5 minutes.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Two-letter language; without it the Accept-Language header decides",
            "schema": {
              "type": "string"
            },
            "example": "en"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductData"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/q/{code}/schema.json": {
      "get": {
        "operationId": "product.schema",
        "tags": [
          "Product data"
        ],
        "summary": "schema.org Product (JSON-LD)",
        "description": "The same product as schema.org `Product` in JSON-LD — for search engines and standard agents. Facts become `additionalProperty` with `valueReference` to the source document; the recall status is the first property (`recallStatus`).",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Two-letter language; without it the Accept-Language header decides",
            "schema": {
              "type": "string"
            },
            "example": "en"
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/ld+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "@context": {
                      "type": "string",
                      "const": "https://schema.org"
                    },
                    "@type": {
                      "type": "string",
                      "const": "Product"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "@context",
                    "@type",
                    "name"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/q/{code}/dpp.jsonld": {
      "get": {
        "operationId": "product.dpp",
        "tags": [
          "Passport"
        ],
        "summary": "Digital Product Passport (JSON-LD)",
        "description": "The passport in JSON-LD with the Itemoo context (`https://itemoo.eu/ns/dpp/1.1/context.jsonld`; version 1.0 stays published): fields map to the CIRPASS-2 ontology (`https://w3id.org/eudpp#`, battery modules) where the meaning matches, the rest to the Itemoo vocabulary. The product node is the unit, batch or model of the code; the passport node carries the version hash, backup copy, predecessor and successors, components and lifecycle status. The same document is returned by `/q/{code}` and the GS1 Digital Link addresses for `Accept: application/ld+json` (with `Content-Location`). With a recipient token or session it shows that level (then never cached). The CIRPASS-2 ontology is a project recommendation, not an EU data model; conformity with the EU semantic repository (Implementing Regulation (EU) 2026/1778) is not claimed. Only products with a passport have it — the brand added the “Digital product passport” block or the product is under a passport obligation (e.g. EV, LMT and industrial batteries above 2 kWh); other products answer 404 `PASSPORT_NONE` and publish their data in `/q/{code}/data`. A closed passport has `lifecycle.status` = `closed` and shows the state as of the closing date.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Two-letter language; without it the Accept-Language header decides",
            "schema": {
              "type": "string"
            },
            "example": "en"
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "description": "`Bearer ipa_…` — optional recipient token",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/ld+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "@context": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string",
                      "const": "Product"
                    },
                    "passport": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "DigitalProductPassport"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "@context",
                    "id",
                    "type",
                    "passport"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "401": {
            "description": "Error — code: PASSPORT_GRANT_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_GRANT_INVALID"
            ]
          },
          "404": {
            "description": "Error — code: unknownCode, PASSPORT_NONE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode",
              "PASSPORT_NONE"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/ns/dpp/{version}/context.jsonld": {
      "get": {
        "operationId": "dpp.context",
        "tags": [
          "Passport"
        ],
        "summary": "JSON-LD context of Itemoo passports",
        "description": "Immutable, versioned context (`@protected`). A change of content means a new version; documents name the version they use.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Context version",
            "schema": {
              "type": "string"
            },
            "example": "1.0"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/ld+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "@context": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {}
                    }
                  },
                  "required": [
                    "@context"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "version": "1.0"
          }
        }
      }
    },
    "/ns/dpp/{version}/vocab": {
      "get": {
        "operationId": "dpp.vocab",
        "tags": [
          "Passport"
        ],
        "summary": "Itemoo passport vocabulary",
        "description": "RDFS terms (`itm:`) used by the context for fields without a CIRPASS-2 equivalent, with labels in Polish and English; mapped fields are listed as equivalent properties.",
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Vocabulary version",
            "schema": {
              "type": "string"
            },
            "example": "1.0"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/ld+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "@id": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "@id"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "version": "1.0"
          }
        }
      }
    },
    "/.well-known/dpp": {
      "get": {
        "operationId": "dpp.catalog",
        "tags": [
          "Passport"
        ],
        "summary": "Data model catalogue (DCAT-AP)",
        "description": "DCAT-AP description of the Itemoo passport data models (context, vocabulary, ontologies they build on) and of the resolver service. No index of products or brands.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/ld+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "@id": {
                      "type": "string"
                    },
                    "@type": {
                      "type": "string",
                      "const": "dcat:Catalog"
                    }
                  },
                  "required": [
                    "@id",
                    "@type"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/q/{code}/passport": {
      "get": {
        "operationId": "product.passport",
        "tags": [
          "Passport"
        ],
        "summary": "Digital Product Passport",
        "description": "Public passport data; with a recipient token issued by the producer (legitimate interest or authority) also the fields, documents and unit history of that level. Send the token as `Authorization: Bearer ipa_…`. Never cached. A browser (`Accept: text/html` without a token) gets a readable passport page at the same address; `format=json` returns JSON anyway. Only products with a passport have it — the brand added the “Digital product passport” block or the product is under a passport obligation (e.g. EV, LMT and industrial batteries above 2 kWh); other products answer 404 `PASSPORT_NONE` and publish their data in `/q/{code}/data`. A closed passport has `lifecycle.status` = `closed` and shows the state as of the closing date.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Two-letter language; without it the Accept-Language header decides",
            "schema": {
              "type": "string"
            },
            "example": "en"
          },
          {
            "name": "at",
            "in": "query",
            "required": false,
            "description": "The passport as it was at that moment, from the version history (a stable address of a version): ISO 8601 with a time zone (`Z` or `±hh:mm`) or a plain date (start of the day, UTC). Without a time zone — 400 `DATE_INVALID`; in the future (over 60 s) — 400 `DATE_IN_FUTURE`",
            "schema": {
              "type": "string"
            },
            "example": "2027-03-01T10:00:00Z"
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "`json` — JSON even for a browser; `html` — the passport page. Without it the `Accept` header decides.",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "html"
              ]
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "description": "`Bearer ipa_…` — optional recipient token",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Passport"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: DATE_INVALID, DATE_IN_FUTURE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DATE_INVALID",
              "DATE_IN_FUTURE"
            ]
          },
          "401": {
            "description": "Error — code: PASSPORT_GRANT_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_GRANT_INVALID"
            ]
          },
          "404": {
            "description": "Error — code: unknownCode, PASSPORT_NONE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode",
              "PASSPORT_NONE"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/q/{code}/passport/part-of": {
      "get": {
        "operationId": "product.partOf",
        "tags": [
          "Passport"
        ],
        "summary": "Products this component is part of",
        "description": "Reverse component links: models whose bill of components lists this code and units where it is currently installed. A link is returned only when the reader has its access level AT THE BRAND OF THE PARENT product (a recipient token of that brand, or a market surveillance authority) — the component maker does not learn who uses its parts. Non-public reads are logged in the read log of the parent brand. Only products with a passport have it — the brand added the “Digital product passport” block or the product is under a passport obligation (e.g. EV, LMT and industrial batteries above 2 kWh); other products answer 404 `PASSPORT_NONE` and publish their data in `/q/{code}/data`. A closed passport has `lifecycle.status` = `closed` and shows the state as of the closing date.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "description": "`Bearer ipa_…` — optional recipient token",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartOf"
                }
              }
            }
          },
          "401": {
            "description": "Error — code: PASSPORT_GRANT_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_GRANT_INVALID"
            ]
          },
          "404": {
            "description": "Error — code: unknownCode, PASSPORT_NONE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode",
              "PASSPORT_NONE"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/b/{slug}/passport/feed.json": {
      "get": {
        "operationId": "brand.passportFeed",
        "tags": [
          "Passport"
        ],
        "summary": "Brand passport feed (JSON Feed)",
        "description": "Public feed of a brand for dealers, recyclers, marketplaces and authorities, without registering an address: recalls, safety notices and new versions of product and batch passports (names of the changed public fields; values are at the code address). No unit data. JSON Feed 1.1, ETag and 5-minute caching. The same entries as Atom: `/b/{slug}/passport/feed.atom`.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Brand identifier from the brand app address",
            "schema": {
              "type": "string"
            },
            "example": "acme"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/feed+json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "string",
                      "const": "https://jsonfeed.org/version/1.1"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "url"
                        ],
                        "additionalProperties": {}
                      }
                    }
                  },
                  "required": [
                    "version",
                    "items"
                  ],
                  "additionalProperties": {}
                }
              }
            }
          },
          "404": {
            "description": "Error — code: BRAND_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "BRAND_NOT_FOUND"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "slug": "acme"
          }
        }
      }
    },
    "/b/{slug}/passport/feed.atom": {
      "get": {
        "operationId": "brand.passportFeedAtom",
        "tags": [
          "Passport"
        ],
        "summary": "Brand passport feed (Atom)",
        "description": "The brand passport feed as Atom 1.0 (see the JSON Feed variant).",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Brand identifier",
            "schema": {
              "type": "string"
            },
            "example": "acme"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/atom+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: BRAND_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "BRAND_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "slug": "acme"
          }
        }
      }
    },
    "/q/{code}/passport/history": {
      "get": {
        "operationId": "product.passportHistory",
        "tags": [
          "Passport"
        ],
        "summary": "Passport version history",
        "description": "Every change of passport fields (model, variant, batch, unit) is an append-only version chained by SHA-256 hashes. The response lists versions with the changes of fields visible at the reader's level (public without a token) and, for the authority level, the leaf hashes needed to recompute each version hash. Redacted values (personal data removed by the platform) keep their hash and show `redacted: true`. Only products with a passport have it — the brand added the “Digital product passport” block or the product is under a passport obligation (e.g. EV, LMT and industrial batteries above 2 kWh); other products answer 404 `PASSPORT_NONE` and publish their data in `/q/{code}/data`. A closed passport has `lifecycle.status` = `closed` and shows the state as of the closing date.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "description": "`Bearer ipa_…` — optional recipient token",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassportHistory"
                }
              }
            }
          },
          "401": {
            "description": "Error — code: PASSPORT_GRANT_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_GRANT_INVALID"
            ]
          },
          "404": {
            "description": "Error — code: unknownCode, PASSPORT_NONE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode",
              "PASSPORT_NONE"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/q/{code}/passport/anchor": {
      "get": {
        "operationId": "product.passportAnchor",
        "tags": [
          "Passport"
        ],
        "summary": "Proof of existence of the current passport versions",
        "description": "Every day (UTC) Itemoo builds a Merkle tree (RFC 6962 hashing: leaf = SHA-256(0x00 ‖ hash), node = SHA-256(0x01 ‖ left ‖ right), sorted unique leaves) of all passport version hashes and unit event hashes recorded that day and, when enabled, obtains an RFC 3161 timestamp for SHA-256(root). For each current layer version (and the head of the unit event chain) the response gives the day, the root and the inclusion path; `anchor: null` until the day is anchored. Verify the token with `openssl ts -verify -digest <timestamp.digest> -in <token>`. Only products with a passport have it — the brand added the “Digital product passport” block or the product is under a passport obligation (e.g. EV, LMT and industrial batteries above 2 kWh); other products answer 404 `PASSPORT_NONE` and publish their data in `/q/{code}/data`. A closed passport has `lifecycle.status` = `closed` and shows the state as of the closing date.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassportAnchorProofs"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode, PASSPORT_NONE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode",
              "PASSPORT_NONE"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/q/{code}/passport/access-request": {
      "post": {
        "operationId": "product.passportAccessRequest",
        "tags": [
          "Passport"
        ],
        "summary": "Request access to an archived passport",
        "description": "After the contract of the brand ends, regulated passports (batteries with the full passport) stay available in the Itemoo Passport Archive, but the brand no longer issues recipient tokens. Authorities and persons with a legitimate interest (Regulation (EU) 2023/1542 Annex XIII) request access here; a platform operator reviews the request and another one approves it (four eyes) and sends the token. Outside the archive the route answers 404 — ask the brand.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "level": {
                    "type": "string",
                    "enum": [
                      "legit",
                      "authority"
                    ]
                  },
                  "organization": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Authority, service, recycler…"
                  },
                  "email": {
                    "type": "string",
                    "description": "Contact e-mail for the token (deleted 180 days after the decision)"
                  },
                  "justification": {
                    "type": "string",
                    "minLength": 20,
                    "maxLength": 2000,
                    "description": "Why the access is needed and on what basis"
                  }
                },
                "required": [
                  "level",
                  "organization",
                  "email",
                  "justification"
                ]
              },
              "example": {
                "level": "legit",
                "organization": "Recycling Sp. z o.o.",
                "email": "office@example.com",
                "justification": "Dismantling and recycling of the battery received as waste."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassportAccessRequestCreated"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: PASSPORT_GRANT_LEVEL, PASSPORT_REQUEST_ORGANIZATION, PASSPORT_REQUEST_JUSTIFICATION, EMAIL_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_GRANT_LEVEL",
              "PASSPORT_REQUEST_ORGANIZATION",
              "PASSPORT_REQUEST_JUSTIFICATION",
              "EMAIL_INVALID"
            ]
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "409": {
            "description": "Error — code: PASSPORT_REQUEST_PENDING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_REQUEST_PENDING"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          }
        }
      }
    },
    "/q/{code}/passport/documents/{versionId}": {
      "get": {
        "operationId": "product.passportDocument",
        "tags": [
          "Passport"
        ],
        "summary": "Restricted passport document file",
        "description": "The file of a document outside the public level (e.g. dismantling information, test reports — Annex XIII points 2–3 of Regulation (EU) 2023/1542). Its address comes from `documents[].url` of `GET /q/{code}/passport` read with a token; the public file address of such a document returns 404. Requires `Authorization: Bearer ipa_…` with a level that sees the document; every download is recorded in the producer's access log. Never cached.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "description": "Document version id from the passport",
            "schema": {
              "type": "string"
            },
            "example": "clx0doc0version0001"
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "description": "`Bearer ipa_…` — recipient token (required)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Document file",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string"
                }
              },
              "application/octet-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Error — code: PASSPORT_GRANT_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_GRANT_INVALID"
            ]
          },
          "404": {
            "description": "Error — code: DOCUMENT_NOT_FOUND, unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DOCUMENT_NOT_FOUND",
              "unknownCode"
            ]
          },
          "410": {
            "description": "Error — code: codeRetired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "codeRetired"
            ],
            "x-error-params": {
              "codeRetired": [
                "brand"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4",
            "versionId": "clx0doc0version0001"
          }
        }
      }
    },
    "/q/{code}/profile": {
      "get": {
        "operationId": "product.profile",
        "tags": [
          "Product data"
        ],
        "summary": "Parameter profile file",
        "description": "One parameter profile of the product (e.g. print settings for a resin) as a file: `format=json` gives `{ product, profile, params: [{ name, value }] }`, `ini` (default) and `cfg` give `key = value` text for slicers.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code from the QR label (unit, batch, variant or product)",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          },
          {
            "name": "i",
            "in": "query",
            "required": false,
            "description": "Profile index, 0 by default",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "ini",
                "cfg"
              ]
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profile file (attachment)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode, profileNotFound",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode",
              "profileNotFound"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "A1B2C3D4"
          },
          "query": {
            "format": "json"
          }
        }
      }
    },
    "/01/{gtin}": {
      "get": {
        "operationId": "gs1.product",
        "tags": [
          "GS1 Digital Link"
        ],
        "summary": "Resolve a GTIN",
        "description": "GS1 Digital Link resolver. With `linkType=linkset` or `Accept: application/linkset+json` it returns the linkset (RFC 9264) built from the published page: product page, instructions, certificates, passport and recall status. With `linkType=gs1:<type>` it redirects (307) to the first link of that type. Without either it shows the product page (HTML). One GTIN used by several brands returns a choice of their pages.",
        "parameters": [
          {
            "name": "gtin",
            "in": "path",
            "required": true,
            "description": "GTIN (8–14 digits)",
            "schema": {
              "type": "string"
            },
            "example": "05901234123457"
          },
          {
            "name": "linkType",
            "in": "query",
            "required": false,
            "description": "\"linkset\" = the whole linkset (also with Accept: application/linkset+json); \"gs1:pip\" etc. = 307 redirect to the first link of that type",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "`application/linkset+json` returns the linkset without `linkType`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/linkset+json": {
                "schema": {
                  "$ref": "#/components/schemas/Linkset"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "gtin": "05901234123457"
          },
          "query": {
            "linkType": "linkset"
          }
        }
      }
    },
    "/01/{gtin}/10/{lot}": {
      "get": {
        "operationId": "gs1.batch",
        "tags": [
          "GS1 Digital Link"
        ],
        "summary": "Resolve a GTIN with a batch",
        "description": "GS1 Digital Link resolver. With `linkType=linkset` or `Accept: application/linkset+json` it returns the linkset (RFC 9264) built from the published page: product page, instructions, certificates, passport and recall status. With `linkType=gs1:<type>` it redirects (307) to the first link of that type. Without either it shows the product page (HTML). One GTIN used by several brands returns a choice of their pages.",
        "parameters": [
          {
            "name": "gtin",
            "in": "path",
            "required": true,
            "description": "GTIN (8–14 digits)",
            "schema": {
              "type": "string"
            },
            "example": "05901234123457"
          },
          {
            "name": "lot",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "linkType",
            "in": "query",
            "required": false,
            "description": "\"linkset\" = the whole linkset (also with Accept: application/linkset+json); \"gs1:pip\" etc. = 307 redirect to the first link of that type",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "`application/linkset+json` returns the linkset without `linkType`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/linkset+json": {
                "schema": {
                  "$ref": "#/components/schemas/Linkset"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "gtin": "05901234123457",
            "lot": "L2026-10"
          },
          "query": {
            "linkType": "linkset"
          }
        }
      }
    },
    "/01/{gtin}/21/{serial}": {
      "get": {
        "operationId": "gs1.serial",
        "tags": [
          "GS1 Digital Link"
        ],
        "summary": "Resolve a GTIN with a serial number",
        "description": "GS1 Digital Link resolver. With `linkType=linkset` or `Accept: application/linkset+json` it returns the linkset (RFC 9264) built from the published page: product page, instructions, certificates, passport and recall status. With `linkType=gs1:<type>` it redirects (307) to the first link of that type. Without either it shows the product page (HTML). One GTIN used by several brands returns a choice of their pages.",
        "parameters": [
          {
            "name": "gtin",
            "in": "path",
            "required": true,
            "description": "GTIN (8–14 digits)",
            "schema": {
              "type": "string"
            },
            "example": "05901234123457"
          },
          {
            "name": "serial",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "linkType",
            "in": "query",
            "required": false,
            "description": "\"linkset\" = the whole linkset (also with Accept: application/linkset+json); \"gs1:pip\" etc. = 307 redirect to the first link of that type",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "`application/linkset+json` returns the linkset without `linkType`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/linkset+json": {
                "schema": {
                  "$ref": "#/components/schemas/Linkset"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "gtin": "05901234123457",
            "serial": "SN-0001"
          },
          "query": {
            "linkType": "linkset"
          }
        }
      }
    },
    "/01/{gtin}/10/{lot}/21/{serial}": {
      "get": {
        "operationId": "gs1.batchSerial",
        "tags": [
          "GS1 Digital Link"
        ],
        "summary": "Resolve a GTIN with a batch and a serial number",
        "description": "GS1 Digital Link resolver. With `linkType=linkset` or `Accept: application/linkset+json` it returns the linkset (RFC 9264) built from the published page: product page, instructions, certificates, passport and recall status. With `linkType=gs1:<type>` it redirects (307) to the first link of that type. Without either it shows the product page (HTML). One GTIN used by several brands returns a choice of their pages.",
        "parameters": [
          {
            "name": "gtin",
            "in": "path",
            "required": true,
            "description": "GTIN (8–14 digits)",
            "schema": {
              "type": "string"
            },
            "example": "05901234123457"
          },
          {
            "name": "lot",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "serial",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "linkType",
            "in": "query",
            "required": false,
            "description": "\"linkset\" = the whole linkset (also with Accept: application/linkset+json); \"gs1:pip\" etc. = 307 redirect to the first link of that type",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "description": "Preferred language of the texts (fact names, description) when `lang` is missing.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Accept",
            "in": "header",
            "required": false,
            "description": "`application/linkset+json` returns the linkset without `linkType`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/linkset+json": {
                "schema": {
                  "$ref": "#/components/schemas/Linkset"
                }
              }
            }
          },
          "404": {
            "description": "Error — code: unknownCode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "unknownCode"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "gtin": "05901234123457",
            "lot": "L2026-10",
            "serial": "SN-0001"
          },
          "query": {
            "linkType": "linkset"
          }
        }
      }
    },
    "/.well-known/gs1resolver": {
      "get": {
        "operationId": "gs1.resolver",
        "tags": [
          "GS1 Digital Link"
        ],
        "summary": "Resolver description",
        "description": "GS1 resolver description: supported keys and link types, for scanners and passport registries.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": {}
                }
              }
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        }
      }
    },
    "/.well-known/agent-interface.json": {
      "get": {
        "operationId": "agent.interface",
        "tags": [
          "Product data"
        ],
        "summary": "Capabilities for AI agents",
        "description": "Entry point for an agent that landed on the domain: the endpoints above and the evidence policy.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "endpoints": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "method": {
                            "type": "string"
                          },
                          "returns": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "method",
                          "returns",
                          "description"
                        ]
                      }
                    },
                    "evidencePolicy": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name",
                    "description",
                    "version",
                    "endpoints",
                    "evidencePolicy"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer",
            "examples": [
              400
            ]
          },
          "error": {
            "type": "string",
            "examples": [
              "Bad Request"
            ]
          },
          "code": {
            "type": "string",
            "description": "Stable error code — use it in your integration",
            "examples": [
              "ERP_ITEMS_EXPECTED"
            ]
          },
          "params": {
            "description": "Values inserted into the message, if any. Names per code are listed in `x-error-params` of each error response; a nested message is `{ code, params? }`",
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "message": {
            "type": "string",
            "description": "Human-readable text in the Accept-Language language (default: English)",
            "examples": [
              "Send a list of items"
            ]
          }
        },
        "required": [
          "statusCode",
          "error",
          "code",
          "message"
        ],
        "description": "Every error response has this shape."
      },
      "ProductData": {
        "type": "object",
        "properties": {
          "identity": {
            "$ref": "#/components/schemas/ProductIdentity"
          },
          "product": {
            "$ref": "#/components/schemas/ProductSummary"
          },
          "manufacturer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ],
            "description": "Manufacturer with postal address and contact; null when the brand has not filled it in"
          },
          "responsiblePerson": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ],
            "description": "Responsible person in the EU; null when none is given"
          },
          "importer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ],
            "description": "Importer (Regulation (EU) 2024/1781 Annex III point (j)); for a batch or unit code the batch importer"
          },
          "authorisedRepresentative": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authorised representative of the manufacturer"
          },
          "facility": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ],
            "description": "Manufacturing facility (Annex III point (i)); publicly only the town and country unless the brand made the full address public"
          },
          "passportFields": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {},
            "description": "Model passport fields with the public access level (empty until the page is published)"
          },
          "language": {
            "type": "string",
            "description": "Language of the texts (requested one when the brand has it)"
          },
          "published": {
            "type": "boolean",
            "description": "false = the product page is not published yet; facts are empty"
          },
          "machineTranslated": {
            "type": "boolean"
          },
          "passport": {
            "type": "boolean",
            "description": "The product has a Digital Product Passport: the brand added the “Digital product passport” block or the product is under a passport obligation. Public passport data fields (`passportFields`) are published for every product"
          },
          "passportStatus": {
            "type": "string",
            "enum": [
              "NONE",
              "ACTIVE",
              "CLOSED"
            ],
            "description": "Passport state: NONE — no passport; ACTIVE; CLOSED — closed by the brand after the product was placed on the market (the passport shows the state as of the closing date)"
          },
          "recall": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Recall"
              },
              {
                "type": "null"
              }
            ]
          },
          "facts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProvenanceFact"
            }
          },
          "offers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "price": {
                  "type": "number"
                },
                "currency": {
                  "type": "string"
                }
              },
              "required": [
                "name",
                "price",
                "currency"
              ]
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Document"
            }
          },
          "faq": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "question": {
                  "type": "string"
                },
                "answer": {
                  "type": "string"
                }
              },
              "required": [
                "question",
                "answer"
              ]
            }
          },
          "trust": {
            "type": "object",
            "properties": {
              "assertedBy": {
                "type": "string"
              },
              "publishedVia": {
                "type": "string",
                "const": "Itemoo"
              },
              "evidencePolicy": {
                "type": "string"
              },
              "factsWithProvenance": {
                "type": "integer"
              },
              "factsTotal": {
                "type": "integer"
              },
              "lastUpdated": {
                "type": "string",
                "format": "date-time",
                "examples": [
                  "2026-10-16T08:30:00.000Z"
                ]
              }
            },
            "required": [
              "assertedBy",
              "publishedVia",
              "evidencePolicy",
              "factsWithProvenance",
              "factsTotal",
              "lastUpdated"
            ]
          }
        },
        "required": [
          "identity",
          "product",
          "manufacturer",
          "responsiblePerson",
          "importer",
          "authorisedRepresentative",
          "facility",
          "passportFields",
          "language",
          "published",
          "machineTranslated",
          "passport",
          "passportStatus",
          "recall",
          "facts",
          "offers",
          "documents",
          "faq",
          "trust"
        ],
        "description": "Published product data with provenance — the same data the human page shows."
      },
      "ProductIdentity": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Itemoo code from the QR label"
          },
          "level": {
            "type": "string",
            "enum": [
              "unit",
              "batch",
              "variant",
              "model"
            ]
          },
          "gtin": {
            "type": [
              "string",
              "null"
            ]
          },
          "sku": {
            "type": [
              "string",
              "null"
            ]
          },
          "variant": {
            "type": "object",
            "properties": {
              "label": {
                "type": "string"
              },
              "catalogNo": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "label",
              "catalogNo"
            ]
          },
          "lot": {
            "type": [
              "string",
              "null"
            ]
          },
          "serial": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "examples": [
                  "2026-10-16T08:30:00.000Z"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "description": "Batch status: ACTIVE | RECALLED | …"
          },
          "uniqueProductIdentifier": {
            "type": "string",
            "description": "Unique product identifier of this code (EN 18219:2026): GS1 Digital Link with the batch and serial number of the code level, or the code address `/q/{code}` without a GTIN"
          }
        },
        "required": [
          "code",
          "level",
          "gtin",
          "sku",
          "lot",
          "serial",
          "expiresAt",
          "status",
          "uniqueProductIdentifier"
        ]
      },
      "ProductSummary": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "brand": {
            "type": "string"
          },
          "category": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "chemicals",
                  "cosmetics",
                  "medical",
                  "food",
                  "supplements",
                  "electronics",
                  "appliances",
                  "batteries",
                  "textiles",
                  "furniture",
                  "toys",
                  "construction",
                  "other"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Regulatory product type — decides the mandatory information: chemicals | cosmetics | medical | food | supplements | electronics | appliances | batteries | textiles | furniture | toys | construction | other"
          },
          "description": {
            "type": "string"
          },
          "image": {
            "type": "string"
          },
          "translations": {
            "description": "Name and description in every language the brand provides (ISO 639-1 code → text); `name` and `description` above are in the language of the response",
            "type": "object",
            "properties": {
              "name": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "string"
                }
              },
              "description": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "string"
                }
              }
            },
            "required": [
              "name",
              "description"
            ]
          }
        },
        "required": [
          "name",
          "brand",
          "category",
          "description"
        ]
      },
      "EconomicOperator": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "address": {
            "type": "object",
            "properties": {
              "street": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "postalCode": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "city": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "country": {
                "description": "ISO 3166-1 alpha-2",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "street",
              "postalCode",
              "city",
              "country"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "description": "Shown only at the access level the brand chose for it (default: persons with a legitimate interest)",
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "company",
              "registry"
            ],
            "description": "company = the brand company data; registry = an operator from the company operator register designated in the passport"
          },
          "tradeName": {
            "description": "Registered trade name or trade mark (Regulation (EU) 2024/1781 Art. 27(6), 29(3))",
            "type": [
              "string",
              "null"
            ]
          },
          "identifiers": {
            "description": "Unique operator or facility identifiers (Regulation (EU) 2024/1781 Annex III points (g)–(k), Art. 12; EN 18219:2026 Clause 6 — ISO/IEC 6523 or ISO/IEC 15459)",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "scheme": {
                  "type": "string",
                  "enum": [
                    "gln",
                    "duns",
                    "lei",
                    "vat",
                    "iso15459"
                  ],
                  "description": "gln = GS1 GLN, duns = D-U-N-S, lei = Legal Entity Identifier (ISO 17442), vat = EU VAT number with country prefix, iso15459 = identifier of another ISO/IEC 15459 issuing agency"
                },
                "iac": {
                  "description": "Issuing agency code (ISO/IEC 15459-2 register): 0–9 for GS1, UN for D&B, otherwise the registered agency code; absent for lei and vat",
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              },
              "required": [
                "scheme",
                "value"
              ]
            }
          },
          "eori": {
            "description": "EORI number (importer, Annex III point (j)) — shown only at the access level the brand chose for it (default: legitimate interest)",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "name",
          "address",
          "email",
          "phone",
          "source"
        ]
      },
      "Recall": {
        "type": "object",
        "properties": {
          "active": {
            "type": "boolean",
            "const": true
          },
          "certain": {
            "type": "boolean",
            "description": "true = this exact code is recalled; false = the batch is unknown and may be affected"
          },
          "scope": {
            "type": "string",
            "enum": [
              "product",
              "batch",
              "lotRange"
            ],
            "description": "product = the whole product; batch = one batch; lotRange = a range of batch numbers (lotFrom–lotTo)"
          },
          "reason": {
            "type": "string"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ]
          },
          "lotFrom": {
            "type": [
              "string",
              "null"
            ]
          },
          "lotTo": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "description": "recall = the product is recalled; notice = safety notice, the product is not withdrawn",
            "type": "string",
            "enum": [
              "recall",
              "notice"
            ]
          }
        },
        "required": [
          "active",
          "certain",
          "scope",
          "reason",
          "instructions",
          "lotFrom",
          "lotTo"
        ],
        "description": "Active safety recall or safety notice that applies to the code; null when none."
      },
      "ProvenanceFact": {
        "type": "object",
        "properties": {
          "key": {
            "description": "Stable English key of a standard fact (origin, materials, battery.capacityAh, chemical.ufi, …); absent for parameters defined by the brand — match on it, not on the translated name",
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "Fact name in the response language"
          },
          "value": {
            "type": "string"
          },
          "provenance": {
            "type": "object",
            "properties": {
              "source": {
                "type": "string",
                "description": "Document or block the fact comes from"
              },
              "version": {
                "type": "string"
              },
              "documentUrl": {
                "type": "string"
              },
              "assertedBy": {
                "type": "string",
                "description": "Brand that published the fact"
              },
              "assertedAt": {
                "type": "string"
              }
            },
            "required": [
              "source",
              "assertedBy"
            ]
          }
        },
        "required": [
          "name",
          "value"
        ],
        "description": "A product fact with the document that proves it."
      },
      "Document": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "description": "certificate | declaration | repair | dpp | manual | sds | …"
          },
          "version": {
            "type": "string"
          },
          "access": {
            "description": "public | legit | authority — present on documents beyond the public level",
            "type": "string"
          },
          "docId": {
            "description": "Library document identifier — the same as in `{ docId }` values of document fields",
            "type": "string"
          },
          "language": {
            "description": "Language of the file (ISO 639-1 code, e.g. `de`), set by the brand at the document version; absent — multilingual file or not specified",
            "type": "string"
          }
        },
        "required": [
          "title",
          "url",
          "kind"
        ]
      },
      "Passport": {
        "type": "object",
        "properties": {
          "level": {
            "type": "string",
            "enum": [
              "public",
              "legit",
              "authority"
            ]
          },
          "recipient": {
            "description": "Name of the access grant used",
            "type": "string"
          },
          "version": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PassportVersion"
              },
              {
                "type": "null"
              }
            ]
          },
          "backup": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string"
                  },
                  "url": {
                    "type": "string"
                  }
                },
                "required": [
                  "provider",
                  "url"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Backup copy of the passport kept by a DPP service provider (Regulation (EU) 2024/1781 Annex III point (l)), when the brand designated one"
          },
          "identity": {
            "$ref": "#/components/schemas/ProductIdentity"
          },
          "product": {
            "$ref": "#/components/schemas/ProductSummary"
          },
          "manufacturer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ]
          },
          "responsiblePerson": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ]
          },
          "importer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ]
          },
          "authorisedRepresentative": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ]
          },
          "facility": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EconomicOperator"
              },
              {
                "type": "null"
              }
            ]
          },
          "language": {
            "type": "string"
          },
          "published": {
            "type": "boolean"
          },
          "recall": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Recall"
              },
              {
                "type": "null"
              }
            ]
          },
          "facts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProvenanceFact"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Document"
            }
          },
          "components": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PassportComponent"
            },
            "description": "Components with their own passport visible at this level (Regulation (EU) 2024/1781 Art. 2(4); CIRPASS-2 D4.1 recommendation 5)"
          },
          "lifecycle": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "active",
                  "recalled",
                  "end_of_life",
                  "archived",
                  "closed"
                ]
              },
              "since": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time",
                    "examples": [
                      "2026-10-16T08:30:00.000Z"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "status",
              "since"
            ],
            "description": "Lifecycle status of the passport: recalled — an active recall covers the code (a safety notice does not); end_of_life — the unit was recycled or became waste; archived — the brand left Itemoo and the passport is kept read-only; closed — the brand closed the passport after the product was placed on the market (the passport shows the state as of the closing date, `since`). A passport is never deleted: removal is a status (CIRPASS-2 D4.1 recommendation 3); a retired code answers 410"
          },
          "model": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {},
            "description": "Model passport fields visible at this level"
          },
          "unit": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "serial": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "data": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "state": {
                    "type": "object",
                    "properties": {
                      "status": {
                        "description": "original | repurposed | re-used | remanufactured | waste | recycled (Regulation (EU) 2023/1542 Annex XIII point 4(c); recycled ends the passport). null — not visible at this access level (a battery status is for persons with a legitimate interest only)",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "soh": {
                        "description": "State of health, 0–100 (SoH, or SOCE / remaining capacity when only that is recorded)",
                        "type": [
                          "number",
                          "null"
                        ]
                      },
                      "sohAt": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date-time",
                            "examples": [
                              "2026-10-16T08:30:00.000Z"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "cycles": {
                        "type": [
                          "number",
                          "null"
                        ]
                      },
                      "incidents": {
                        "type": "integer"
                      }
                    },
                    "required": [
                      "status",
                      "soh",
                      "sohAt",
                      "cycles",
                      "incidents"
                    ]
                  },
                  "history": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string"
                        },
                        "data": {},
                        "occurredAt": {
                          "type": "string",
                          "format": "date-time",
                          "examples": [
                            "2026-10-16T08:30:00.000Z"
                          ]
                        },
                        "source": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "data",
                        "occurredAt"
                      ]
                    }
                  },
                  "links": {
                    "type": "object",
                    "properties": {
                      "predecessor": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "code",
                              "url"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Passport before remanufacturing or repurposing (Art. 77(7))"
                      },
                      "successors": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string"
                            },
                            "url": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "code",
                            "url"
                          ]
                        },
                        "description": "New passports created from this battery"
                      }
                    },
                    "required": [
                      "predecessor",
                      "successors"
                    ]
                  },
                  "custodian": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string"
                          },
                          "since": {
                            "type": "string",
                            "format": "date-time",
                            "examples": [
                              "2026-10-16T08:30:00.000Z"
                            ]
                          }
                        },
                        "required": [
                          "name",
                          "role",
                          "since"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Operator responsible for the passport of a waste battery after a transfer (producer, PRO or waste management operator — Art. 77(7))"
                  }
                },
                "required": [
                  "serial",
                  "data",
                  "state",
                  "history",
                  "links",
                  "custodian"
                ]
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "level",
          "version",
          "backup",
          "identity",
          "product",
          "manufacturer",
          "responsiblePerson",
          "importer",
          "authorisedRepresentative",
          "facility",
          "language",
          "published",
          "recall",
          "facts",
          "documents",
          "components",
          "lifecycle",
          "model",
          "unit"
        ]
      },
      "PassportVersion": {
        "type": "object",
        "properties": {
          "hash": {
            "type": "string",
            "description": "SHA-256 of the canonical (RFC 8785) composition of layer versions and the unit event chain head"
          },
          "layers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "subject": {
                  "type": "string",
                  "enum": [
                    "product",
                    "variant",
                    "batch",
                    "unit"
                  ]
                },
                "version": {
                  "type": "integer"
                },
                "hash": {
                  "type": "string"
                }
              },
              "required": [
                "subject",
                "version",
                "hash"
              ]
            }
          },
          "eventsHead": {
            "type": [
              "string",
              "null"
            ]
          },
          "at": {
            "description": "Present for a passport read at a point in time (`?at=`)",
            "type": "string",
            "format": "date-time",
            "examples": [
              "2026-10-16T08:30:00.000Z"
            ]
          }
        },
        "required": [
          "hash",
          "layers",
          "eventsHead"
        ]
      },
      "PassportComponent": {
        "type": "object",
        "properties": {
          "code": {
            "description": "Itemoo code of the component passport (unit, batch, variant or model — also of another brand)",
            "type": [
              "string",
              "null"
            ]
          },
          "uri": {
            "description": "Address of a component passport outside Itemoo (DPP URL or GS1 Digital Link)",
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": "string",
            "description": "Where to read the component passport"
          },
          "role": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {},
          "quantity": {
            "type": [
              "number",
              "null"
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "level": {
            "type": "string",
            "enum": [
              "model",
              "unit"
            ],
            "description": "model — bill of components of the model; unit — installed in this unit (assembly events)"
          },
          "since": {
            "description": "When the component was installed in this unit",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "code",
          "uri",
          "url",
          "role",
          "name",
          "quantity",
          "unit",
          "level",
          "since"
        ]
      },
      "PartOf": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "partOf": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "role": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "level": {
                  "type": "string",
                  "enum": [
                    "model",
                    "unit"
                  ]
                },
                "since": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "code",
                "url",
                "role",
                "level",
                "since"
              ]
            }
          }
        },
        "required": [
          "code",
          "partOf"
        ]
      },
      "PassportHistory": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "level": {
            "type": "string",
            "enum": [
              "public",
              "legit",
              "authority"
            ]
          },
          "version": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PassportVersion"
              },
              {
                "type": "null"
              }
            ]
          },
          "versions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "subject": {
                  "type": "string",
                  "enum": [
                    "product",
                    "variant",
                    "batch",
                    "unit"
                  ]
                },
                "version": {
                  "type": "integer"
                },
                "hash": {
                  "type": "string"
                },
                "prevHash": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "at": {
                  "type": "string",
                  "format": "date-time",
                  "examples": [
                    "2026-10-16T08:30:00.000Z"
                  ]
                },
                "source": {
                  "type": "string"
                },
                "changes": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "key": {
                        "type": "string"
                      },
                      "op": {
                        "type": "string",
                        "enum": [
                          "add",
                          "change",
                          "remove"
                        ]
                      },
                      "value": {},
                      "redacted": {
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "key",
                      "op"
                    ]
                  }
                },
                "leaves": {
                  "description": "Leaf hashes (authority level only) to recompute the version hash",
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "h": {
                        "type": "string"
                      },
                      "access": {
                        "type": "string",
                        "enum": [
                          "public",
                          "legit",
                          "authority"
                        ]
                      }
                    },
                    "required": [
                      "h",
                      "access"
                    ]
                  }
                }
              },
              "required": [
                "subject",
                "version",
                "hash",
                "prevHash",
                "at",
                "source",
                "changes"
              ]
            }
          }
        },
        "required": [
          "code",
          "level",
          "version",
          "versions"
        ]
      },
      "PassportAnchorProofs": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "algorithm": {
            "type": [
              "string",
              "null"
            ]
          },
          "proofs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "subject": {
                  "type": "string",
                  "enum": [
                    "product",
                    "variant",
                    "batch",
                    "unit",
                    "events"
                  ]
                },
                "version": {
                  "type": "integer"
                },
                "hash": {
                  "type": "string"
                },
                "anchor": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "day": {
                          "type": "string"
                        },
                        "root": {
                          "type": "string"
                        },
                        "algorithm": {
                          "type": "string"
                        },
                        "leaves": {
                          "type": "integer"
                        },
                        "path": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "side": {
                                "type": "string",
                                "enum": [
                                  "left",
                                  "right"
                                ]
                              },
                              "hash": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "side",
                              "hash"
                            ]
                          }
                        },
                        "timestamp": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "provider": {
                                  "type": "string"
                                },
                                "at": {
                                  "type": "string"
                                },
                                "digest": {
                                  "type": "string"
                                },
                                "token": {
                                  "type": "string",
                                  "description": "Base64 RFC 3161 TimeStampResp"
                                }
                              },
                              "required": [
                                "provider",
                                "at",
                                "digest",
                                "token"
                              ]
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "day",
                        "root",
                        "algorithm",
                        "leaves",
                        "path",
                        "timestamp"
                      ]
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "subject",
                "hash",
                "anchor"
              ]
            }
          }
        },
        "required": [
          "code",
          "algorithm",
          "proofs"
        ]
      },
      "PassportAccessRequestCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "new"
          }
        },
        "required": [
          "id",
          "status"
        ]
      },
      "Linkset": {
        "type": "object",
        "properties": {
          "linkset": {
            "type": "array",
            "items": {
              "type": "object",
              "propertyNames": {
                "type": "string"
              },
              "additionalProperties": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "href": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        },
                        "hreflang": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "href"
                      ]
                    }
                  }
                ]
              }
            },
            "description": "One entry: \"anchor\" (the GS1 URI) and one key per link type (https://gs1.org/voc/pip, …/instructions, …/certificationInfo, …/sustainabilityInfo, …/recallStatus)"
          }
        },
        "required": [
          "linkset"
        ]
      }
    }
  }
}