{
  "openapi": "3.1.0",
  "info": {
    "title": "Itemoo API for ERP",
    "version": "1.0.0",
    "description": "SKUs, stock levels, batches, orders and product passports of a brand — for ERP, WMS and MES systems.\n\n**Authentication.** The brand owner creates a key in the panel (Integrations → API keys) and sees it only once. Send it as `Authorization: Bearer itm_…` (or the `X-Api-Key` header). Every key has scopes: items, stock, batches, orders, passport. The API is part of plans with the Integrations module; batches work also for a suspended brand.\n\n**Limits.** 120 calls per minute per IP address; repeated excess blocks the address for 30 minutes (`429`).\n\n**Errors.** `{ statusCode, error, code, params?, message }`. Rely on the stable `code` and `params`; `message` is for people and follows the `Accept-Language` header (without it: English).\n\n**SKUs** are compared case-insensitively, ignoring leading and trailing spaces.\n\n**Compatibility.** Within `/v1` we only add: new endpoints, optional request fields, response fields and enum values. Ignore fields you don’t know. Every response carries `X-Itemoo-Api-Version` — the release you are talking to; endpoints being retired send `Deprecation` and `Sunset` headers.\n\n**Notifications (webhooks).** Itemoo sends a `POST` with JSON `{ id, event, createdAt, data }` for the events below. Header `X-Itemoo-Signature: t=<unix>,v1=<HMAC-SHA256(secret, t + \".\" + body)>` — the secret (`whsec_…`) is in the panel; compare in constant time and reject timestamps older than 5 minutes. Headers `X-Itemoo-Event` and `X-Itemoo-Delivery` repeat the event and the delivery id. Reply with `2xx` within 10 seconds (redirects are not followed); otherwise we retry after 1 min, 5 min, 30 min, 2 h, 6 h and 12 h.",
    "x-major-version": "v1"
  },
  "servers": [
    {
      "url": "https://itemoo.eu/v1"
    }
  ],
  "tags": [
    {
      "name": "Key"
    },
    {
      "name": "Items"
    },
    {
      "name": "Stock"
    },
    {
      "name": "Batches"
    },
    {
      "name": "Orders"
    },
    {
      "name": "Passport"
    },
    {
      "name": "Drafts"
    },
    {
      "name": "Webhooks"
    }
  ],
  "security": [
    {
      "bearer": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "paths": {
    "/ping": {
      "get": {
        "operationId": "ping",
        "tags": [
          "Key"
        ],
        "summary": "Check the key",
        "description": "Returns the brand and the scopes of the key. Use it to test the connection.\n\nKey scope: any.",
        "x-scope": "any",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "brand": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "slug": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "key": {
                      "type": "string",
                      "description": "Name of the API key"
                    },
                    "scopes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "brand",
                    "slug",
                    "key",
                    "scopes"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        }
      }
    },
    "/items": {
      "get": {
        "operationId": "items.list",
        "tags": [
          "Items"
        ],
        "summary": "List of items (SKUs)",
        "description": "Every item for sale: SKU, EAN, catalogue number, name, product, price and stock (`null` = stock not tracked).\n\nKey scope: `items`.",
        "x-scope": "items",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Item"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        }
      },
      "put": {
        "operationId": "items.pair",
        "tags": [
          "Items"
        ],
        "summary": "Pair SKUs with items",
        "description": "Assigns ERP SKUs to items recognised by catalogue number or EAN. Unmatched rows do **not** create new products — they come back in `unmatched` and land on the “To pair” list in the panel. `dryRun: true` = preview without saving.\n\nOptional prices per paired SKU: `priceGross`, `priceNet`, `vatRate` — one amount is enough, the other is computed from the rate; two amounts must match the rate within 0.01 (otherwise the row is listed in `prices.errors`). Prices in the brand additional markets: `prices: [{ currency: \"EUR\", priceGross: 12.5 }]` (gross, market currency).\n\nKey scope: `items`.",
        "x-scope": "items",
        "x-dry-run": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "maxItems": 20000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string",
                          "description": "SKU in your ERP"
                        },
                        "catalogNo": {
                          "description": "Catalogue number used to find the item",
                          "type": "string"
                        },
                        "ean": {
                          "description": "EAN/GTIN used to find the item",
                          "type": "string"
                        },
                        "name": {
                          "description": "Name in the ERP — helps pairing by hand",
                          "type": "string"
                        },
                        "priceGross": {
                          "type": "number"
                        },
                        "priceNet": {
                          "type": "number"
                        },
                        "vatRate": {
                          "description": "23 | 8 | 5 | 0 | exempt (VAT-exempt) | outside_scope (outside the scope of VAT)",
                          "type": "string",
                          "enum": [
                            "0",
                            "5",
                            "8",
                            "23",
                            "exempt",
                            "outside_scope"
                          ]
                        },
                        "prices": {
                          "description": "Prices in the brand additional markets — never overwritten by exchange-rate recalculation",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "currency": {
                                "type": "string",
                                "examples": [
                                  "EUR"
                                ]
                              },
                              "priceGross": {
                                "description": "Gross price in the market currency; null returns the market to the recalculated price",
                                "type": [
                                  "number",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "currency",
                              "priceGross"
                            ]
                          }
                        }
                      },
                      "required": [
                        "sku"
                      ]
                    }
                  },
                  "dryRun": {
                    "description": "true = preview, nothing is saved",
                    "type": "boolean"
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "sku": "KAW-250",
                    "ean": "5901234123457"
                  },
                  {
                    "sku": "KAW-1000",
                    "catalogNo": "K-1000",
                    "priceGross": 89.9,
                    "vatRate": "23"
                  }
                ],
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "received": {
                      "type": "integer"
                    },
                    "alreadyPaired": {
                      "type": "integer"
                    },
                    "paired": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "itemKey": {
                            "type": "string",
                            "description": "Item key in Itemoo"
                          },
                          "by": {
                            "type": "string",
                            "enum": [
                              "ean",
                              "catalogNo"
                            ]
                          }
                        },
                        "required": [
                          "sku",
                          "itemKey",
                          "by"
                        ]
                      }
                    },
                    "unmatched": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "catalogNo": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ean": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "sku",
                          "catalogNo",
                          "ean"
                        ]
                      }
                    },
                    "conflicts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "sku",
                          "reason"
                        ]
                      }
                    },
                    "applied": {
                      "type": "boolean",
                      "description": "false for dryRun"
                    },
                    "prices": {
                      "type": "object",
                      "properties": {
                        "updated": {
                          "type": "integer"
                        },
                        "errors": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "sku": {
                                "type": "string"
                              },
                              "reason": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "sku",
                              "reason"
                            ]
                          }
                        }
                      },
                      "required": [
                        "updated",
                        "errors"
                      ]
                    }
                  },
                  "required": [
                    "received",
                    "alreadyPaired",
                    "paired",
                    "unmatched",
                    "conflicts",
                    "applied",
                    "prices"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_ITEMS_EXPECTED, ERP_MAX_ITEMS, ITEMS_MAX_20000",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_ITEMS_EXPECTED",
              "ERP_MAX_ITEMS",
              "ITEMS_MAX_20000"
            ],
            "x-error-params": {
              "ERP_MAX_ITEMS": [
                "n"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/stock": {
      "put": {
        "operationId": "stock.set",
        "tags": [
          "Stock"
        ],
        "summary": "Stock levels",
        "description": "Overwrites the stock of every SKU (integer ≥ 0), reduced by the units in orders you haven’t acknowledged yet (`POST /orders/ack`). `0` = item unavailable in the shop. The ERP is the source of truth: the stock you send overwrites ours; shop sales between synchronisations reduce it on their own. SKUs without an item are saved — they take effect once the item is paired in the panel (returned in `unknownSku`). A row with an invalid quantity is listed in `errors`; the rest is saved.\n\nKey scope: `stock`.",
        "x-scope": "stock",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "maxItems": 20000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "qty": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "sku",
                        "qty"
                      ]
                    }
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "sku": "KAW-250",
                    "qty": 12
                  },
                  {
                    "sku": "KAW-1000",
                    "qty": 0
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "saved": {
                      "type": "integer"
                    },
                    "soldOut": {
                      "type": "integer",
                      "description": "Items that became unavailable (stock 0)"
                    },
                    "reservedDeducted": {
                      "type": "integer",
                      "description": "Units subtracted for unacknowledged orders"
                    },
                    "unknownSku": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Saved, but no item has this SKU yet — takes effect once paired in the panel"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "sku",
                          "reason"
                        ]
                      }
                    }
                  },
                  "required": [
                    "saved",
                    "soldOut",
                    "reservedDeducted",
                    "unknownSku",
                    "errors"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_ITEMS_EXPECTED, ERP_MAX_ITEMS, ITEMS_MAX_20000",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_ITEMS_EXPECTED",
              "ERP_MAX_ITEMS",
              "ITEMS_MAX_20000"
            ],
            "x-error-params": {
              "ERP_MAX_ITEMS": [
                "n"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/batches": {
      "put": {
        "operationId": "batches.set",
        "tags": [
          "Batches"
        ],
        "summary": "Batches (LOT)",
        "description": "Creates a batch or fills in the dates and quantity of an existing one. The LOT is unique within a product. The batch status (e.g. recall) is changed only by a person in the panel. Works also for a suspended brand (product safety).\n\nKey scope: `batches`.",
        "x-scope": "batches",
        "x-allowed-when-suspended": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "maxItems": 5000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "lot": {
                          "type": "string",
                          "maxLength": 64
                        },
                        "producedAt": {
                          "type": "string",
                          "description": "ISO date (YYYY-MM-DD) or date-time",
                          "examples": [
                            "2026-10-16"
                          ]
                        },
                        "expiresAt": {
                          "type": "string",
                          "description": "ISO date (YYYY-MM-DD) or date-time",
                          "examples": [
                            "2026-10-16"
                          ]
                        },
                        "qty": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "sku",
                        "lot"
                      ]
                    }
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "sku": "KAW-250",
                    "lot": "L2026-10",
                    "producedAt": "2026-10-01",
                    "expiresAt": "2027-10-01",
                    "qty": 500
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "created": {
                      "type": "integer"
                    },
                    "updated": {
                      "type": "integer"
                    },
                    "unknownSku": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "lot": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "sku",
                          "lot",
                          "reason"
                        ]
                      }
                    }
                  },
                  "required": [
                    "created",
                    "updated",
                    "unknownSku",
                    "errors"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_ITEMS_EXPECTED, ERP_MAX_ITEMS",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_ITEMS_EXPECTED",
              "ERP_MAX_ITEMS"
            ],
            "x-error-params": {
              "ERP_MAX_ITEMS": [
                "n"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, INTEGRATIONS_DISABLED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "INTEGRATIONS_DISABLED"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/orders": {
      "get": {
        "operationId": "orders.list",
        "tags": [
          "Orders"
        ],
        "summary": "Orders to fulfil",
        "description": "By default only orders ready to fulfil (paid or cash on delivery). Paging: pass `next` from the previous response as `updatedSince` (≥ condition — the last order may come back; recognise it by `orderNo`). `all=true` = unpaid ones too.\n\nKey scope: `orders`.",
        "x-scope": "orders",
        "parameters": [
          {
            "name": "updatedSince",
            "in": "query",
            "required": false,
            "description": "Only orders changed at or after this moment — pass \"next\" from the previous page",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-16T08:30:00.000Z"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1–200, default 100",
            "schema": {
              "type": "string"
            },
            "example": "100"
          },
          {
            "name": "all",
            "in": "query",
            "required": false,
            "description": "true = also orders that are not ready to fulfil (unpaid)",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "unacknowledged",
            "in": "query",
            "required": false,
            "description": "true = only orders not acknowledged by the ERP yet",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "orders": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Order"
                      }
                    },
                    "next": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "examples": [
                            "2026-10-16T08:30:00.000Z"
                          ]
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Pass as updatedSince to get the next page; null = no more pages"
                    }
                  },
                  "required": [
                    "orders",
                    "next"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_NOT_A_DATE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_NOT_A_DATE"
            ],
            "x-error-params": {
              "ERP_NOT_A_DATE": [
                "field",
                "value"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "query": {
            "unacknowledged": "true",
            "limit": "50"
          }
        }
      }
    },
    "/orders/export": {
      "get": {
        "operationId": "orders.export",
        "tags": [
          "Orders"
        ],
        "summary": "Orders file (CSV or XML)",
        "description": "For ERPs that import files. By default only orders to fulfil that haven’t been acknowledged yet. `ack=true` marks the downloaded orders as handed over (like `POST /orders/ack`).\n\n**CSV** — UTF-8 with BOM, semicolon-separated, CRLF line ends, amounts with a decimal comma (`12,50`). One row per order line; the order columns repeat on every line of the order. New columns are only ever added at the end.\n\n**XML** — UTF-8, one `<order>` per order inside `<orders>`, the lines inside `<items>`; the element tree is listed below. Amounts with a decimal point. Element and attribute names follow the JSON fields of `Order`.\n\nKey scope: `orders`.",
        "x-scope": "orders",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "csv by default",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "xml"
              ]
            }
          },
          {
            "name": "ack",
            "in": "query",
            "required": false,
            "description": "true = mark the downloaded orders as acknowledged",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "unacknowledged",
            "in": "query",
            "required": false,
            "description": "true by default",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-16T08:30:00.000Z"
          },
          {
            "name": "all",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Orders file (attachment).",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_NOT_A_DATE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_NOT_A_DATE"
            ],
            "x-error-params": {
              "ERP_NOT_A_DATE": [
                "field",
                "value"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-file-columns": [
          {
            "name": "order_no",
            "description": "Order number (orderNo)"
          },
          {
            "name": "created_at",
            "description": "Order date and time (ISO 8601)"
          },
          {
            "name": "payment_status",
            "description": "Payment status (payment.status)"
          },
          {
            "name": "payment_method",
            "description": "Payment method (payment.method)"
          },
          {
            "name": "fulfillment",
            "description": "Fulfillment status: new | packing | shipped | delivered | cancelled"
          },
          {
            "name": "buyer_name",
            "description": "Buyer name"
          },
          {
            "name": "buyer_email",
            "description": "Buyer email"
          },
          {
            "name": "buyer_phone",
            "description": "Buyer phone"
          },
          {
            "name": "address_line1",
            "description": "Shipping address, first line"
          },
          {
            "name": "postal_code",
            "description": "Postal code"
          },
          {
            "name": "city",
            "description": "City"
          },
          {
            "name": "country",
            "description": "Country (ISO 3166-1 alpha-2)"
          },
          {
            "name": "pickup_point",
            "description": "Pickup point code or name"
          },
          {
            "name": "shipping_method",
            "description": "Shipping method"
          },
          {
            "name": "shipping_cost",
            "description": "Shipping cost"
          },
          {
            "name": "discount",
            "description": "Order discount total (promotion + code + customer discount)"
          },
          {
            "name": "total",
            "description": "Order total (gross)"
          },
          {
            "name": "invoice_company",
            "description": "Invoice: company name"
          },
          {
            "name": "invoice_tax_id",
            "description": "Invoice: tax id"
          },
          {
            "name": "note",
            "description": "Buyer note"
          },
          {
            "name": "sku",
            "description": "Line: SKU"
          },
          {
            "name": "catalog_no",
            "description": "Line: catalogue number"
          },
          {
            "name": "name",
            "description": "Line: name"
          },
          {
            "name": "qty",
            "description": "Line: quantity"
          },
          {
            "name": "unit_price",
            "description": "Line: unit price (gross)"
          },
          {
            "name": "line_discount",
            "description": "Line: discount on the whole line"
          },
          {
            "name": "gift",
            "description": "Line: true for a free gift, false otherwise"
          },
          {
            "name": "lots",
            "description": "Line: shipped batches as \"LOT:qty LOT:qty\""
          },
          {
            "name": "vat_rate",
            "description": "Line: VAT rate (23 | 8 | 5 | 0 | exempt | outside_scope)"
          },
          {
            "name": "line_net",
            "description": "Line: net value after discounts"
          },
          {
            "name": "total_net",
            "description": "Order total (net)"
          },
          {
            "name": "customer_discount",
            "description": "Order: B2B customer discount"
          },
          {
            "name": "channel",
            "description": "Sales channel (app | site | marketplace:…)"
          },
          {
            "name": "channel_order_no",
            "description": "Order number in the sales channel"
          },
          {
            "name": "fulfilled_by",
            "description": "Who ships: merchant | marketplace"
          }
        ],
        "x-file-xml": {
          "name": "orders",
          "description": "Root element",
          "children": [
            {
              "name": "order",
              "description": "One order",
              "repeated": true,
              "attributes": [
                {
                  "name": "orderNo",
                  "description": "Order number"
                },
                {
                  "name": "createdAt",
                  "description": "Order date and time (ISO 8601)"
                },
                {
                  "name": "channel",
                  "description": "Sales channel (app | site | marketplace:…)"
                },
                {
                  "name": "channelOrderNo",
                  "description": "Order number in the sales channel",
                  "optional": true
                },
                {
                  "name": "fulfilledBy",
                  "description": "\"marketplace\" when the channel warehouse ships; omitted for merchant",
                  "optional": true
                }
              ],
              "children": [
                {
                  "name": "payment",
                  "description": "Payment",
                  "attributes": [
                    {
                      "name": "status",
                      "description": "payment.status"
                    },
                    {
                      "name": "method",
                      "description": "payment.method"
                    }
                  ]
                },
                {
                  "name": "fulfillment",
                  "description": "Fulfillment status"
                },
                {
                  "name": "buyer",
                  "description": "Buyer",
                  "children": [
                    {
                      "name": "name",
                      "description": "Name",
                      "optional": true
                    },
                    {
                      "name": "email",
                      "description": "Email",
                      "optional": true
                    },
                    {
                      "name": "phone",
                      "description": "Phone",
                      "optional": true
                    }
                  ]
                },
                {
                  "name": "shipping",
                  "description": "Delivery",
                  "children": [
                    {
                      "name": "method",
                      "description": "Shipping method",
                      "optional": true
                    },
                    {
                      "name": "address",
                      "description": "Address, first line",
                      "optional": true
                    },
                    {
                      "name": "postalCode",
                      "description": "Postal code",
                      "optional": true
                    },
                    {
                      "name": "city",
                      "description": "City",
                      "optional": true
                    },
                    {
                      "name": "country",
                      "description": "Country (ISO 3166-1 alpha-2)",
                      "optional": true
                    },
                    {
                      "name": "pickupPoint",
                      "description": "Pickup point code or name",
                      "optional": true
                    },
                    {
                      "name": "cost",
                      "description": "Shipping cost (decimal point, two decimals)"
                    }
                  ]
                },
                {
                  "name": "invoice",
                  "description": "Invoice data — only when the buyer gave a tax id",
                  "optional": true,
                  "children": [
                    {
                      "name": "company",
                      "description": "Company name",
                      "optional": true
                    },
                    {
                      "name": "taxId",
                      "description": "Tax id"
                    }
                  ]
                },
                {
                  "name": "note",
                  "description": "Buyer note",
                  "optional": true
                },
                {
                  "name": "discount",
                  "description": "Order discount total (promotion + code + customer discount) (decimal point, two decimals)"
                },
                {
                  "name": "total",
                  "description": "Order total (gross) (decimal point, two decimals)"
                },
                {
                  "name": "totalNet",
                  "description": "Order total (net) (decimal point, two decimals)",
                  "optional": true
                },
                {
                  "name": "customerDiscount",
                  "description": "B2B customer discount (decimal point, two decimals)",
                  "optional": true
                },
                {
                  "name": "items",
                  "description": "Order lines",
                  "children": [
                    {
                      "name": "item",
                      "description": "One order line",
                      "repeated": true,
                      "children": [
                        {
                          "name": "sku",
                          "description": "SKU",
                          "optional": true
                        },
                        {
                          "name": "catalogNo",
                          "description": "Catalogue number",
                          "optional": true
                        },
                        {
                          "name": "name",
                          "description": "Name"
                        },
                        {
                          "name": "qty",
                          "description": "Quantity"
                        },
                        {
                          "name": "unitPrice",
                          "description": "Unit price (gross) (decimal point, two decimals)"
                        },
                        {
                          "name": "discount",
                          "description": "Discount on the whole line (decimal point, two decimals)",
                          "optional": true
                        },
                        {
                          "name": "gift",
                          "description": "\"true\" for a free gift; omitted otherwise",
                          "optional": true
                        },
                        {
                          "name": "vatRate",
                          "description": "VAT rate (23 | 8 | 5 | 0 | exempt | outside_scope)",
                          "optional": true
                        },
                        {
                          "name": "netTotal",
                          "description": "Net value of the line after discounts (decimal point, two decimals)",
                          "optional": true
                        },
                        {
                          "name": "lot",
                          "description": "Batch the line shipped from",
                          "repeated": true,
                          "optional": true,
                          "attributes": [
                            {
                              "name": "number",
                              "description": "Batch number"
                            },
                            {
                              "name": "qty",
                              "description": "Quantity from this batch"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        },
        "x-example": {
          "query": {
            "format": "csv"
          }
        }
      }
    },
    "/orders/ack": {
      "post": {
        "operationId": "orders.ack",
        "tags": [
          "Orders"
        ],
        "summary": "Acknowledge orders received by the ERP",
        "description": "Call it right after importing orders. Until acknowledged, an order **reserves** the goods: we reduce the stock you send by the units in unacknowledged orders, because your stock doesn’t include them yet. After acknowledgement we stop subtracting them. A status change (`PUT /orders/{orderNo}`) also acknowledges. The reservation expires on its own after 72 h. Repeating the call is safe.\n\nKey scope: `orders`.",
        "x-scope": "orders",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "orderNos": {
                    "minItems": 1,
                    "maxItems": 1000,
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "orderNos"
                ]
              },
              "example": {
                "orderNos": [
                  "ITM-2026-000123"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "acknowledged": {
                      "type": "integer"
                    },
                    "unknown": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Order numbers that do not exist in the brand"
                    }
                  },
                  "required": [
                    "acknowledged",
                    "unknown"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_ORDERNOS_EXPECTED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_ORDERNOS_EXPECTED"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/orders/{orderNo}/lots": {
      "put": {
        "operationId": "orders.lots",
        "tags": [
          "Orders"
        ],
        "summary": "Batches (LOT) shipped in an order",
        "description": "Which batches the order lines were shipped from — on a batch recall Itemoo notifies exactly these buyers. A line may ship from several batches: several entries with the same `sku`. A call replaces the batches of the line it concerns. They can also be sent as `lots` with `PUT /orders/{orderNo}`.\n\nKey scope: `orders`.",
        "x-scope": "orders",
        "parameters": [
          {
            "name": "orderNo",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "ITM-2026-000123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "maxItems": 500,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "lot": {
                          "type": "string"
                        },
                        "qty": {
                          "description": "The whole line quantity by default",
                          "type": "integer"
                        }
                      },
                      "required": [
                        "sku",
                        "lot"
                      ]
                    }
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "sku": "KAW-250",
                    "lot": "L2026-10",
                    "qty": 2
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "saved": {
                      "type": "integer"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Rows that were skipped, as human-readable messages"
                    }
                  },
                  "required": [
                    "saved",
                    "errors"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_ITEMS_EXPECTED, ERP_MAX_ITEMS, LOTS_EXPECTED, LOTS_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_ITEMS_EXPECTED",
              "ERP_MAX_ITEMS",
              "LOTS_EXPECTED",
              "LOTS_INVALID"
            ],
            "x-error-params": {
              "ERP_MAX_ITEMS": [
                "n"
              ],
              "LOTS_INVALID": [
                "errors"
              ],
              "LOT_LINE_NOT_FOUND": [
                "item"
              ],
              "LOT_NUMBER_MISSING": [
                "label"
              ],
              "LOT_QTY_MIN": [
                "label"
              ],
              "LOT_QTY_OVER": [
                "label",
                "total",
                "qty"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: ORDER_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ORDER_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "orderNo": "ITM-2026-000123"
          }
        }
      }
    },
    "/orders/{orderNo}/units": {
      "put": {
        "operationId": "orders.units",
        "tags": [
          "Orders"
        ],
        "summary": "Units (Itemoo QR codes) shipped in an order",
        "description": "Which individual units (Itemoo QR codes) were packed on the order lines — a recall then reaches the buyer of that exact unit. A call replaces the units of the line it concerns; an empty list removes them. A code must belong to the product of the line and must not be sold in another order. Lines without batches get them from the units.\n\nKey scope: `orders`.",
        "x-scope": "orders",
        "parameters": [
          {
            "name": "orderNo",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "ITM-2026-000123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "maxItems": 500,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "codes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Itemoo QR codes; an empty list removes the units"
                        }
                      },
                      "required": [
                        "sku",
                        "codes"
                      ]
                    }
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "sku": "KAW-250",
                    "codes": [
                      "U7K2M9QX"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "saved": {
                      "type": "integer"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Rows that were skipped, as human-readable messages"
                    }
                  },
                  "required": [
                    "saved",
                    "errors"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_ITEMS_EXPECTED, ERP_MAX_ITEMS, UNITS_EXPECTED, UNITS_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_ITEMS_EXPECTED",
              "ERP_MAX_ITEMS",
              "UNITS_EXPECTED",
              "UNITS_INVALID"
            ],
            "x-error-params": {
              "ERP_MAX_ITEMS": [
                "n"
              ],
              "UNITS_INVALID": [
                "errors"
              ],
              "UNIT_LINE_NOT_FOUND": [
                "item"
              ],
              "UNIT_QTY_OVER": [
                "label",
                "n",
                "qty"
              ],
              "UNIT_NOT_FOUND": [
                "code"
              ],
              "UNIT_WRONG_PRODUCT": [
                "code",
                "label"
              ],
              "UNIT_TAKEN": [
                "code"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: ORDER_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ORDER_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "orderNo": "ITM-2026-000123"
          }
        }
      }
    },
    "/orders/{orderNo}/invoice": {
      "put": {
        "operationId": "orders.invoice",
        "tags": [
          "Orders"
        ],
        "summary": "Invoice for an order (number, KSeF, PDF)",
        "description": "You issue the invoice in the ERP (and send it to KSeF); here you attach it to the order. The customer gets an email with a link to the PDF, and the invoice is on their order page. Sending again replaces the previous one. `notifyCustomer: false` = no email. Orders from marketplaces get the invoice in the channel instead of an email.\n\nKey scope: `orders`.",
        "x-scope": "orders",
        "parameters": [
          {
            "name": "orderNo",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "ITM-2026-000123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "number": {
                    "type": "string"
                  },
                  "ksefNumber": {
                    "type": "string"
                  },
                  "issuedAt": {
                    "type": "string",
                    "description": "ISO date (YYYY-MM-DD) or date-time",
                    "examples": [
                      "2026-10-16"
                    ]
                  },
                  "pdfBase64": {
                    "description": "PDF file as base64 — the whole request is limited to 2 MB, so about 1.4 MB of PDF",
                    "type": "string"
                  },
                  "notifyCustomer": {
                    "description": "false = no email to the customer",
                    "type": "boolean"
                  }
                },
                "required": [
                  "number"
                ]
              },
              "example": {
                "number": "FV/2026/10/123",
                "issuedAt": "2026-10-16"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "number": {
                      "type": "string"
                    },
                    "ksefNumber": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "issuedAt": {
                      "type": "string",
                      "format": "date-time",
                      "examples": [
                        "2026-10-16T08:30:00.000Z"
                      ]
                    },
                    "hasPdf": {
                      "type": "boolean"
                    },
                    "notified": {
                      "type": "boolean",
                      "description": "The customer got an email with the invoice"
                    }
                  },
                  "required": [
                    "number",
                    "ksefNumber",
                    "issuedAt",
                    "hasPdf",
                    "notified"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: INVOICE_NUMBER_REQUIRED, KSEF_NUMBER_INVALID, INVOICE_DATE_INVALID, INVOICE_PDF_ONLY, INVOICE_PDF_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "INVOICE_NUMBER_REQUIRED",
              "KSEF_NUMBER_INVALID",
              "INVOICE_DATE_INVALID",
              "INVOICE_PDF_ONLY",
              "INVOICE_PDF_TOO_LARGE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: ORDER_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ORDER_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "orderNo": "ITM-2026-000123"
          }
        }
      }
    },
    "/orders/{orderNo}": {
      "put": {
        "operationId": "orders.status",
        "tags": [
          "Orders"
        ],
        "summary": "Fulfilment status from the ERP",
        "description": "`status`: packing | shipped | delivered | cancelled; for shipped also `carrier` and `trackingNo`. The customer gets the same emails as for a change in the panel. Repeating the same status changes nothing (`\"unchanged\": true`). A paid order can’t be cancelled from the ERP — it needs a refund in the panel. The call also acknowledges the order.\n\nKey scope: `orders`.",
        "x-scope": "orders",
        "parameters": [
          {
            "name": "orderNo",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "ITM-2026-000123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "packing",
                      "shipped",
                      "delivered",
                      "cancelled"
                    ]
                  },
                  "carrier": {
                    "type": "string"
                  },
                  "trackingNo": {
                    "type": "string"
                  },
                  "reason": {
                    "description": "Cancellation reason shown to the customer",
                    "type": "string",
                    "maxLength": 300
                  },
                  "lots": {
                    "description": "Batches shipped, like PUT /orders/{orderNo}/lots",
                    "maxItems": 500,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "lot": {
                          "type": "string"
                        },
                        "qty": {
                          "description": "The whole line quantity by default",
                          "type": "integer"
                        }
                      },
                      "required": [
                        "sku",
                        "lot"
                      ]
                    }
                  }
                },
                "required": [
                  "status"
                ]
              },
              "example": {
                "status": "shipped",
                "carrier": "InPost",
                "trackingNo": "6200000000000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderAfterStatusChange"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: ERP_STATUS_INVALID, ORDER_STATUS_TRANSITION, ORDER_NOT_PAID_YET, ORDER_AWAITS_APPROVAL, ORDER_AWAITS_CUSTOMER, ORDER_AWAITS_FOLLOWUP, NOTHING_TO_SHIP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ERP_STATUS_INVALID",
              "ORDER_STATUS_TRANSITION",
              "ORDER_NOT_PAID_YET",
              "ORDER_AWAITS_APPROVAL",
              "ORDER_AWAITS_CUSTOMER",
              "ORDER_AWAITS_FOLLOWUP",
              "NOTHING_TO_SHIP"
            ],
            "x-error-params": {
              "ORDER_STATUS_TRANSITION": [
                "from",
                "to"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: ORDER_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "ORDER_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "orderNo": "ITM-2026-000123"
          }
        }
      }
    },
    "/passport/{code}": {
      "get": {
        "operationId": "passport.get",
        "tags": [
          "Passport"
        ],
        "summary": "Product passport with all access levels",
        "description": "The public data of the published page, model and unit fields with their access level (public | legit | authority), the current unit state (status, SoH, cycles) and the unit history. Recipients outside the brand read `GET /q/{code}/passport` of the public API with a token issued in the panel.\n\nKey scope: `passport`.",
        "x-scope": "passport",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code of a unit, batch, variant or product",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandPassport"
                }
              }
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "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"
          }
        }
      }
    },
    "/passport/{code}/dpp.jsonld": {
      "get": {
        "operationId": "passport.dpp",
        "tags": [
          "Passport"
        ],
        "summary": "Passport in JSON-LD with all access levels",
        "description": "The same document as the public `GET /q/{code}/dpp.jsonld` (Itemoo context `https://itemoo.eu/ns/dpp/1.1/context.jsonld`, fields mapped to the CIRPASS-2 ontology where the meaning matches), at the authority level: all fields of the brand. READ operation of CIRPASS-2 D4.1 recommendation 3. The EN 18222:2026 life cycle API with the EN 18223:2026 payload is `/dpp-api/v1`. Only products with a passport (the “Digital product passport” block or a passport obligation) — otherwise 404 `PASSPORT_NONE`; `GET /passport/{code}` still returns the data.\n\nKey scope: `passport`.",
        "x-scope": "passport",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code of a unit, batch, variant or product",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          }
        ],
        "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: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "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"
          }
        }
      }
    },
    "/passport/{code}/history": {
      "get": {
        "operationId": "passport.history",
        "tags": [
          "Passport"
        ],
        "summary": "Passport version history with hash leaves",
        "description": "All versions of the layers of the code (product, variant, batch, unit) with the changed fields, their values and the leaves of each version, so the brand system can recompute every hash on its own. Values erased under GDPR come as `null` with `redacted`.\n\nKey scope: `passport`.",
        "x-scope": "passport",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code of a unit, batch, variant or product",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassportHistory"
                }
              }
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "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"
          }
        }
      }
    },
    "/passport/export": {
      "get": {
        "operationId": "passport.export",
        "tags": [
          "Passport"
        ],
        "summary": "All brand passports in JSON-LD, page by page",
        "description": "Products, variants with a GTIN and units of the brand as JSON-LD documents (authority level), 100 per page. Pass `cursor` of the response as `cursor` until it is `null`; passports added between pages do not shift the rest. For a backup copy or a move to another DPP service provider (BACKUP / TRANSFER of CIRPASS-2 D4.1 recommendation 3); the same passports in the EN 18223:2026 model and the EN 18222:2026 life cycle API are under `/dpp-api/v1`; the static public package is in the panel (Passport → Export).\n\nKey scope: `passport`.",
        "x-scope": "passport",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `cursor` of the previous page (opaque); without it — the first page",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "@context": {
                            "type": "string"
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "@context",
                          "id"
                        ],
                        "additionalProperties": {}
                      }
                    },
                    "cursor": {
                      "description": "The cursor of the next page, null on the last one",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "items",
                    "cursor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: DPP_CURSOR_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DPP_CURSOR_INVALID"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/passport/products/{sku}": {
      "put": {
        "operationId": "passport.model",
        "tags": [
          "Passport"
        ],
        "summary": "Model passport fields with access levels",
        "description": "Merges fields: `{ fields: { key: value } }` or `{ fields: { key: { value, access } } }`; value `null` removes the field. access: public | legit (persons with a legitimate interest) | authority (default legit). Up to 200 fields, 192 kB. Keys in the passport field dictionary namespaces (`battery.*`, `product.*`, `compliance.*`, `safety.*`, `textile.*`, `medical.*`, `chemical.*`, `transport.*`, `materials.*`, `endOfLife.*`, `repair.*`, `documents.*`) follow the dictionary: known keys only, typed values, the level (model, batch, unit) the field belongs to, and the default access level of the field; battery keys (Regulation (EU) 2023/1542 Annex XIII) have a fixed access level (another level → PASSPORT_ACCESS_FIXED). Other keys are free brand fields.\n\nKey scope: `passport`.",
        "x-scope": "passport",
        "parameters": [
          {
            "name": "sku",
            "in": "path",
            "required": true,
            "description": "Product (model) SKU",
            "schema": {
              "type": "string"
            },
            "example": "AKU-100"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fields": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "anyOf": [
                        {},
                        {
                          "type": "object",
                          "properties": {
                            "value": {},
                            "access": {
                              "type": "string",
                              "enum": [
                                "public",
                                "legit",
                                "authority"
                              ]
                            }
                          },
                          "required": [
                            "value"
                          ]
                        }
                      ]
                    },
                    "description": "{ key: value } or { key: { value, access } }; value null removes the field"
                  }
                },
                "required": [
                  "fields"
                ]
              },
              "example": {
                "fields": {
                  "chemistry": {
                    "value": "LFP",
                    "access": "public"
                  },
                  "cathodeSupplier": "ACME"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "productId": {
                      "type": "string"
                    },
                    "sku": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "fields": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "value": {},
                          "access": {
                            "type": "string",
                            "enum": [
                              "public",
                              "legit",
                              "authority"
                            ]
                          }
                        },
                        "required": [
                          "value",
                          "access"
                        ]
                      }
                    }
                  },
                  "required": [
                    "productId",
                    "sku",
                    "fields"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: PASSPORT_FIELDS_INVALID, PASSPORT_FIELDS_TOO_MANY, PASSPORT_FIELDS_TOO_LARGE, PASSPORT_FIELD_KEY_INVALID, PASSPORT_ACCESS_INVALID, PASSPORT_FIELD_UNKNOWN, PASSPORT_FIELD_NOT_WRITABLE, PASSPORT_FIELD_SCOPE, PASSPORT_ACCESS_FIXED, PASSPORT_VALUE_NUMBER, PASSPORT_VALUE_PERCENT, PASSPORT_VALUE_TEXT, PASSPORT_VALUE_LIST, PASSPORT_VALUE_DATE, PASSPORT_VALUE_CHOICE, PASSPORT_VALUE_DOCUMENT, PASSPORT_VALUE_INVALID, PASSPORT_OPERATOR_NOT_FOUND, PASSPORT_OPERATOR_ROLE, PASSPORT_DECLARATION_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_FIELDS_INVALID",
              "PASSPORT_FIELDS_TOO_MANY",
              "PASSPORT_FIELDS_TOO_LARGE",
              "PASSPORT_FIELD_KEY_INVALID",
              "PASSPORT_ACCESS_INVALID",
              "PASSPORT_FIELD_UNKNOWN",
              "PASSPORT_FIELD_NOT_WRITABLE",
              "PASSPORT_FIELD_SCOPE",
              "PASSPORT_ACCESS_FIXED",
              "PASSPORT_VALUE_NUMBER",
              "PASSPORT_VALUE_PERCENT",
              "PASSPORT_VALUE_TEXT",
              "PASSPORT_VALUE_LIST",
              "PASSPORT_VALUE_DATE",
              "PASSPORT_VALUE_CHOICE",
              "PASSPORT_VALUE_DOCUMENT",
              "PASSPORT_VALUE_INVALID",
              "PASSPORT_OPERATOR_NOT_FOUND",
              "PASSPORT_OPERATOR_ROLE",
              "PASSPORT_DECLARATION_NOT_FOUND"
            ],
            "x-error-params": {
              "PASSPORT_FIELD_UNKNOWN": [
                "key"
              ],
              "PASSPORT_FIELD_NOT_WRITABLE": [
                "key"
              ],
              "PASSPORT_FIELD_SCOPE": [
                "key"
              ],
              "PASSPORT_ACCESS_FIXED": [
                "key",
                "access"
              ],
              "PASSPORT_VALUE_NUMBER": [
                "key"
              ],
              "PASSPORT_VALUE_PERCENT": [
                "key"
              ],
              "PASSPORT_VALUE_TEXT": [
                "key"
              ],
              "PASSPORT_VALUE_LIST": [
                "key"
              ],
              "PASSPORT_VALUE_DATE": [
                "key"
              ],
              "PASSPORT_VALUE_CHOICE": [
                "key"
              ],
              "PASSPORT_VALUE_DOCUMENT": [
                "key"
              ],
              "PASSPORT_VALUE_INVALID": [
                "key"
              ],
              "PASSPORT_OPERATOR_NOT_FOUND": [
                "key"
              ],
              "PASSPORT_OPERATOR_ROLE": [
                "key",
                "role"
              ],
              "PASSPORT_DECLARATION_NOT_FOUND": [
                "key"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: PRODUCT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PRODUCT_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "sku": "AKU-100"
          }
        }
      }
    },
    "/passport/units": {
      "put": {
        "operationId": "passport.units",
        "tags": [
          "Passport"
        ],
        "summary": "Static unit data from production (MES)",
        "description": "Up to 1,000 units per call, each by `code` or by `sku` + `serial`; data merges like model fields. `placedOnMarketAt` declares when the unit was placed on the market; a battery unit placed on the market after the field set takes effect needs a complete passport (row error CODES_PASSPORT_INCOMPLETE). Unknown units are listed in `unknown`, invalid rows in `errors` — the rest is saved.\n\nKey scope: `passport`.",
        "x-scope": "passport",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "maxItems": 1000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "description": "Itemoo code of the unit — or sku + serial",
                          "type": "string"
                        },
                        "sku": {
                          "type": "string"
                        },
                        "serial": {
                          "type": "string"
                        },
                        "data": {
                          "description": "Unit fields; battery passport keys (battery.*) follow the field dictionary and have a fixed access level",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "anyOf": [
                              {},
                              {
                                "type": "object",
                                "properties": {
                                  "value": {},
                                  "access": {
                                    "type": "string",
                                    "enum": [
                                      "public",
                                      "legit",
                                      "authority"
                                    ]
                                  }
                                },
                                "required": [
                                  "value"
                                ]
                              }
                            ]
                          }
                        },
                        "placedOnMarketAt": {
                          "description": "Date the unit was placed on the market (YYYY-MM-DD), null clears it. A unit placed on the market after a field set takes effect must have a complete passport",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "sku": "AKU-100",
                    "serial": "SN-0001",
                    "data": {
                      "cellLot": "C-77"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "received": {
                      "type": "integer"
                    },
                    "saved": {
                      "type": "integer"
                    },
                    "unknown": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "row": {
                            "type": "integer"
                          },
                          "code": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "row",
                          "code"
                        ]
                      }
                    }
                  },
                  "required": [
                    "received",
                    "saved",
                    "unknown",
                    "errors"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: PASSPORT_FIELDS_INVALID, PASSPORT_IMPORT_MAX_1000",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_FIELDS_INVALID",
              "PASSPORT_IMPORT_MAX_1000"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/passport/units/{code}/events": {
      "post": {
        "operationId": "passport.event",
        "tags": [
          "Passport"
        ],
        "summary": "Append a unit event",
        "description": "`kind`: status (`data.status`: original | repurposed | re-used | remanufactured | waste | recycled — recycled ends the passport), soh (`data.soh`, or Annex XIII point 4(b) metrics: soce, remainingCapacityPct, remainingPowerPct, remainingRoundTripEfficiencyPct, selfDischargePct 0–100, ohmicResistanceMOhm), cycles (`data.cycles`), incident (`data.type`: accident | deep_discharge | overheating | overcharge | mechanical_damage | other), temperature (`data.celsius` or `minC` / `maxC`), soc (`data.socPct`) or data (any fields). Optional `occurredAt` (ISO, not in the future) and `access` (battery events have the fixed level legit). Events are append-only and chained by SHA-256 hashes (`hash` in the response).\n\nKey scope: `passport`.",
        "x-scope": "passport",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Itemoo code of a unit, batch, variant or product",
            "schema": {
              "type": "string"
            },
            "example": "A1B2C3D4"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "status",
                      "soh",
                      "cycles",
                      "incident",
                      "temperature",
                      "soc",
                      "data",
                      "assembly"
                    ],
                    "description": "assembly — component with its own passport installed or removed: data { action: install | remove, code (Itemoo code) or uri (https passport address), role? }"
                  },
                  "data": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  },
                  "occurredAt": {
                    "description": "Not in the future; now by default",
                    "type": "string",
                    "format": "date-time",
                    "examples": [
                      "2026-10-16T08:30:00.000Z"
                    ]
                  },
                  "access": {
                    "description": "public for status by default, legit otherwise",
                    "type": "string",
                    "enum": [
                      "public",
                      "legit",
                      "authority"
                    ]
                  }
                },
                "required": [
                  "kind",
                  "data"
                ]
              },
              "example": {
                "kind": "soh",
                "data": {
                  "soh": 96
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string"
                    },
                    "data": {},
                    "access": {
                      "type": "string"
                    },
                    "occurredAt": {
                      "type": "string",
                      "format": "date-time",
                      "examples": [
                        "2026-10-16T08:30:00.000Z"
                      ]
                    },
                    "hash": {
                      "description": "SHA-256 of the event chained with the previous one (RFC 8785)",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "kind",
                    "data",
                    "access",
                    "occurredAt",
                    "hash"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error — code: PASSPORT_EVENT_KIND_INVALID, PASSPORT_STATUS_INVALID, PASSPORT_SOH_INVALID, PASSPORT_CYCLES_INVALID, PASSPORT_INCIDENT_INVALID, PASSPORT_EVENT_DATE_INVALID, PASSPORT_ACCESS_INVALID, PASSPORT_TEMPERATURE_INVALID, PASSPORT_SOC_INVALID, PASSPORT_ACCESS_FIXED, PASSPORT_UNIT_RECYCLED, PASSPORT_PERSONAL_DATA",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_EVENT_KIND_INVALID",
              "PASSPORT_STATUS_INVALID",
              "PASSPORT_SOH_INVALID",
              "PASSPORT_CYCLES_INVALID",
              "PASSPORT_INCIDENT_INVALID",
              "PASSPORT_EVENT_DATE_INVALID",
              "PASSPORT_ACCESS_INVALID",
              "PASSPORT_TEMPERATURE_INVALID",
              "PASSPORT_SOC_INVALID",
              "PASSPORT_ACCESS_FIXED",
              "PASSPORT_UNIT_RECYCLED",
              "PASSPORT_PERSONAL_DATA"
            ],
            "x-error-params": {
              "PASSPORT_ACCESS_FIXED": [
                "key",
                "access"
              ],
              "PASSPORT_PERSONAL_DATA": [
                "key",
                "kind"
              ]
            }
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: PASSPORT_UNIT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "PASSPORT_UNIT_NOT_FOUND"
            ]
          },
          "429": {
            "description": "Error — code: rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "code": "U7K2M9QX"
          }
        }
      }
    },
    "/drafts/products/{product}/page": {
      "get": {
        "operationId": "drafts.productPage.get",
        "tags": [
          "Drafts"
        ],
        "summary": "Product page for editing",
        "description": "The working version of a product page as blocks with the text fields you may change and `draftRevision` (as the MCP tool `product_page_get`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "parameters": [
          {
            "name": "product",
            "in": "path",
            "required": true,
            "description": "Product id, Itemoo code or SKU",
            "schema": {
              "type": "string"
            },
            "example": "KAW-250"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "product": "KAW-250"
          }
        }
      },
      "put": {
        "operationId": "drafts.productPage.patch",
        "tags": [
          "Drafts"
        ],
        "summary": "Edit a product page draft",
        "description": "Text operations on the product page (`set`, `removeItem`, `addBlock`, `removeBlock`); a published page gets a draft, the live page stays (as `product_page_draft_patch`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "x-dry-run": true,
        "parameters": [
          {
            "name": "product",
            "in": "path",
            "required": true,
            "description": "Product id, Itemoo code or SKU",
            "schema": {
              "type": "string"
            },
            "example": "KAW-250"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "draftRevision": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{16}$",
                    "description": "`draftRevision` from the last read; if the draft changed since, the call fails with `draftConflict` — read again"
                  },
                  "operations": {
                    "minItems": 1,
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "set"
                            },
                            "path": {
                              "type": "string",
                              "pattern": "^\\d+(\\.[A-Za-z]+|\\.[A-Za-z]+\\.\\d+\\.[A-Za-z]+)$",
                              "description": "Field path from `product_page_get` (e.g. \"3.lead\", \"5.items.2.a\"); a list index equal to the list length adds an item"
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 10000,
                              "description": "New text of the field"
                            },
                            "lang": {
                              "description": "Language of the texts (two letters); default: the brand default language. Texts in other languages are marked as machine-written for review",
                              "type": "string",
                              "pattern": "^[a-z]{2}$"
                            }
                          },
                          "required": [
                            "op",
                            "path",
                            "value"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "removeItem"
                            },
                            "path": {
                              "type": "string",
                              "pattern": "^\\d+\\.[A-Za-z]+\\.\\d+$",
                              "description": "List item path, e.g. \"5.items.2\""
                            }
                          },
                          "required": [
                            "op",
                            "path"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "addBlock"
                            },
                            "type": {
                              "type": "string",
                              "enum": [
                                "description",
                                "custom",
                                "faq",
                                "specs",
                                "applications"
                              ],
                              "description": "Text block type"
                            },
                            "data": {
                              "type": "object",
                              "propertyNames": {
                                "type": "string"
                              },
                              "additionalProperties": {},
                              "description": "Block fields — only the text fields listed in `product_page_get.editableFields` (text or {lang: text})"
                            },
                            "position": {
                              "description": "Insert before this block index; default: before the navigation tiles at the end",
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 200
                            }
                          },
                          "required": [
                            "op",
                            "type",
                            "data"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "removeBlock"
                            },
                            "block": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 200,
                              "description": "Index of a text block to remove"
                            }
                          },
                          "required": [
                            "op",
                            "block"
                          ]
                        }
                      ]
                    },
                    "description": "Operations applied in order; indexes refer to the page after the previous operations"
                  },
                  "dryRun": {
                    "description": "Default true: nothing is saved — the result shows what would change and a `planToken`. Ask the user, then call again with the SAME arguments, `dryRun: false` and that `planToken`.",
                    "type": "boolean"
                  },
                  "planToken": {
                    "description": "`planToken` from the preview of exactly these arguments (required with `dryRun: false`, valid 10 minutes)",
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 300
                  }
                },
                "required": [
                  "draftRevision",
                  "operations"
                ]
              },
              "example": {
                "draftRevision": "0123456789abcdef",
                "operations": [
                  {
                    "op": "set",
                    "path": "2.lead",
                    "value": "Medium roast, notes of cocoa."
                  }
                ],
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "product": "KAW-250"
          }
        }
      }
    },
    "/drafts/products": {
      "post": {
        "operationId": "drafts.products.create",
        "tags": [
          "Drafts"
        ],
        "summary": "Create product drafts",
        "description": "New products in DRAFT status with the starting page of their category, optionally with text operations; up to 50 per call (as `product_draft_create`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "x-dry-run": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "products": {
                    "minItems": 1,
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200,
                          "description": "Product name"
                        },
                        "sku": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "SKU — unique in the brand"
                        },
                        "category": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64,
                          "description": "Product category key (e.g. \"chemicals\")"
                        },
                        "gtin": {
                          "description": "GTIN / EAN (8–14 digits)",
                          "type": "string",
                          "pattern": "^\\d{8,14}$"
                        },
                        "operations": {
                          "description": "Optional text operations on the starting page (as in `product_page_draft_patch`)",
                          "maxItems": 100,
                          "type": "array",
                          "items": {
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "op": {
                                    "type": "string",
                                    "const": "set"
                                  },
                                  "path": {
                                    "type": "string",
                                    "pattern": "^\\d+(\\.[A-Za-z]+|\\.[A-Za-z]+\\.\\d+\\.[A-Za-z]+)$",
                                    "description": "Field path from `product_page_get` (e.g. \"3.lead\", \"5.items.2.a\"); a list index equal to the list length adds an item"
                                  },
                                  "value": {
                                    "type": "string",
                                    "maxLength": 10000,
                                    "description": "New text of the field"
                                  },
                                  "lang": {
                                    "description": "Language of the texts (two letters); default: the brand default language. Texts in other languages are marked as machine-written for review",
                                    "type": "string",
                                    "pattern": "^[a-z]{2}$"
                                  }
                                },
                                "required": [
                                  "op",
                                  "path",
                                  "value"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "op": {
                                    "type": "string",
                                    "const": "removeItem"
                                  },
                                  "path": {
                                    "type": "string",
                                    "pattern": "^\\d+\\.[A-Za-z]+\\.\\d+$",
                                    "description": "List item path, e.g. \"5.items.2\""
                                  }
                                },
                                "required": [
                                  "op",
                                  "path"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "op": {
                                    "type": "string",
                                    "const": "addBlock"
                                  },
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "description",
                                      "custom",
                                      "faq",
                                      "specs",
                                      "applications"
                                    ],
                                    "description": "Text block type"
                                  },
                                  "data": {
                                    "type": "object",
                                    "propertyNames": {
                                      "type": "string"
                                    },
                                    "additionalProperties": {},
                                    "description": "Block fields — only the text fields listed in `product_page_get.editableFields` (text or {lang: text})"
                                  },
                                  "position": {
                                    "description": "Insert before this block index; default: before the navigation tiles at the end",
                                    "type": "integer",
                                    "minimum": 0,
                                    "maximum": 200
                                  }
                                },
                                "required": [
                                  "op",
                                  "type",
                                  "data"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "op": {
                                    "type": "string",
                                    "const": "removeBlock"
                                  },
                                  "block": {
                                    "type": "integer",
                                    "minimum": 0,
                                    "maximum": 200,
                                    "description": "Index of a text block to remove"
                                  }
                                },
                                "required": [
                                  "op",
                                  "block"
                                ]
                              }
                            ]
                          }
                        }
                      },
                      "required": [
                        "name",
                        "sku",
                        "category"
                      ]
                    }
                  },
                  "lang": {
                    "description": "Language of the texts (two letters); default: the brand default language. Texts in other languages are marked as machine-written for review",
                    "type": "string",
                    "pattern": "^[a-z]{2}$"
                  },
                  "dryRun": {
                    "description": "Default true: nothing is saved — the result shows what would change and a `planToken`. Ask the user, then call again with the SAME arguments, `dryRun: false` and that `planToken`.",
                    "type": "boolean"
                  },
                  "planToken": {
                    "description": "`planToken` from the preview of exactly these arguments (required with `dryRun: false`, valid 10 minutes)",
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 300
                  }
                },
                "required": [
                  "products"
                ]
              },
              "example": {
                "products": [
                  {
                    "name": "Coffee 250 g",
                    "sku": "KAW-250",
                    "category": "food"
                  }
                ],
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/drafts/site": {
      "get": {
        "operationId": "drafts.site.get",
        "tags": [
          "Drafts"
        ],
        "summary": "Brand website draft",
        "description": "The working version of the brand website and `draftRevision` (as `site_draft_get`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        }
      },
      "put": {
        "operationId": "drafts.site.patch",
        "tags": [
          "Drafts"
        ],
        "summary": "Edit the brand website draft",
        "description": "Path operations on theme, pages, navigation and SEO; legal pages and legal links stay as they are (as `site_draft_patch`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "x-dry-run": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "draftRevision": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{16}$",
                    "description": "`draftRevision` from the last read; if the draft changed since, the call fails with `draftConflict` — read again"
                  },
                  "operations": {
                    "minItems": 1,
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "oneOf": [
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "set"
                            },
                            "path": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 300,
                              "description": "Dot path from the draft root, e.g. \"pages.0.sections.2.data.title\" or \"theme.preset\""
                            },
                            "value": {
                              "description": "New value (JSON). With `lang` — the text in that language"
                            },
                            "lang": {
                              "description": "Language of the texts (two letters); default: the brand default language. Texts in other languages are marked as machine-written for review",
                              "type": "string",
                              "pattern": "^[a-z]{2}$"
                            }
                          },
                          "required": [
                            "op",
                            "path",
                            "value"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "insert"
                            },
                            "path": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 300,
                              "description": "List path ending with the index to insert at, e.g. \"pages.0.sections.1\""
                            },
                            "value": {}
                          },
                          "required": [
                            "op",
                            "path",
                            "value"
                          ]
                        },
                        {
                          "type": "object",
                          "properties": {
                            "op": {
                              "type": "string",
                              "const": "remove"
                            },
                            "path": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 300
                            }
                          },
                          "required": [
                            "op",
                            "path"
                          ]
                        }
                      ]
                    },
                    "description": "Operations applied in order; only theme, pages, navigation and seo, never legal pages or legal links"
                  },
                  "dryRun": {
                    "description": "Default true: nothing is saved — the result shows what would change and a `planToken`. Ask the user, then call again with the SAME arguments, `dryRun: false` and that `planToken`.",
                    "type": "boolean"
                  },
                  "planToken": {
                    "description": "`planToken` from the preview of exactly these arguments (required with `dryRun: false`, valid 10 minutes)",
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 300
                  }
                },
                "required": [
                  "draftRevision",
                  "operations"
                ]
              },
              "example": {
                "draftRevision": "0123456789abcdef",
                "operations": [
                  {
                    "op": "set",
                    "path": "seo.description",
                    "value": "Coffee roasted in Krakow."
                  }
                ],
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/drafts/publications/{id}": {
      "get": {
        "operationId": "drafts.publications.get",
        "tags": [
          "Drafts"
        ],
        "summary": "One post",
        "description": "A post with platform texts and `draftRevision` (as `publication_get`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the post, article or campaign",
            "schema": {
              "type": "string"
            },
            "example": "post-ai-x7Kp2"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "id": "post-ai-x7Kp2"
          }
        }
      }
    },
    "/drafts/publications": {
      "post": {
        "operationId": "drafts.publications.upsert",
        "tags": [
          "Drafts"
        ],
        "summary": "Create or edit a post draft",
        "description": "A post always waits for approval by a team member (as `publication_draft_upsert`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "x-dry-run": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Existing post id (edit); omit to create",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "draftRevision": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{16}$",
                    "description": "`draftRevision` from the last read; if the draft changed since, the call fails with `draftConflict` — read again"
                  },
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Working name in the calendar"
                  },
                  "message": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Main message of the post"
                  },
                  "headline": {
                    "type": "string",
                    "maxLength": 80,
                    "description": "Text on the graphic"
                  },
                  "template": {
                    "description": "Graphic template; default: product when products are given, otherwise free",
                    "type": "string",
                    "enum": [
                      "product",
                      "teaser",
                      "free"
                    ]
                  },
                  "productCodes": {
                    "description": "Itemoo codes of the products in the post",
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^[0-9A-Za-z]{4,32}$"
                    }
                  },
                  "scheduledAt": {
                    "description": "Planned publication time (ISO 8601)",
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "variants": {
                    "maxItems": 8,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "platform": {
                          "type": "string",
                          "enum": [
                            "facebook",
                            "instagram",
                            "linkedin",
                            "tiktok"
                          ]
                        },
                        "text": {
                          "type": "string",
                          "maxLength": 4000,
                          "description": "Post text for this platform"
                        },
                        "hashtags": {
                          "maxItems": 30,
                          "type": "array",
                          "items": {
                            "type": "string",
                            "maxLength": 60
                          }
                        },
                        "altText": {
                          "type": "string",
                          "maxLength": 1000,
                          "description": "Alternative text of the graphic"
                        }
                      },
                      "required": [
                        "platform",
                        "text"
                      ]
                    }
                  },
                  "dryRun": {
                    "description": "Default true: nothing is saved — the result shows what would change and a `planToken`. Ask the user, then call again with the SAME arguments, `dryRun: false` and that `planToken`.",
                    "type": "boolean"
                  },
                  "planToken": {
                    "description": "`planToken` from the preview of exactly these arguments (required with `dryRun: false`, valid 10 minutes)",
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 300
                  }
                },
                "required": [
                  "title",
                  "message"
                ]
              },
              "example": {
                "title": "New roast",
                "message": "Our new medium roast is here.",
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/drafts/articles/{id}": {
      "get": {
        "operationId": "drafts.articles.get",
        "tags": [
          "Drafts"
        ],
        "summary": "One article",
        "description": "A knowledge article in all languages and `draftRevision` (as `article_get`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the post, article or campaign",
            "schema": {
              "type": "string"
            },
            "example": "post-ai-x7Kp2"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "id": "clx0article"
          }
        }
      }
    },
    "/drafts/articles": {
      "post": {
        "operationId": "drafts.articles.upsert",
        "tags": [
          "Drafts"
        ],
        "summary": "Create or edit an article draft",
        "description": "A new article or a change of a draft article; a published article is edited in the panel (as `article_draft_upsert`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "x-dry-run": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Existing draft article id; omit to create",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "draftRevision": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{16}$",
                    "description": "`draftRevision` from the last read; if the draft changed since, the call fails with `draftConflict` — read again"
                  },
                  "lang": {
                    "description": "Language of the texts (two letters); default: the brand default language. Texts in other languages are marked as machine-written for review",
                    "type": "string",
                    "pattern": "^[a-z]{2}$"
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Title"
                  },
                  "excerpt": {
                    "type": "string",
                    "maxLength": 400,
                    "description": "Short summary"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Body: paragraphs separated by an empty line, \"## \" for subheadings"
                  },
                  "category": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 40
                  },
                  "slug": {
                    "type": "string",
                    "maxLength": 80,
                    "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                  },
                  "productCodes": {
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^[0-9A-Za-z]{4,32}$"
                    }
                  },
                  "dryRun": {
                    "description": "Default true: nothing is saved — the result shows what would change and a `planToken`. Ask the user, then call again with the SAME arguments, `dryRun: false` and that `planToken`.",
                    "type": "boolean"
                  },
                  "planToken": {
                    "description": "`planToken` from the preview of exactly these arguments (required with `dryRun: false`, valid 10 minutes)",
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 300
                  }
                }
              },
              "example": {
                "title": "How to brew",
                "body": "Use 15 g of coffee per 250 ml of water.",
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/drafts/campaigns/{id}": {
      "get": {
        "operationId": "drafts.campaigns.get",
        "tags": [
          "Drafts"
        ],
        "summary": "One campaign",
        "description": "A push / newsletter campaign and `draftRevision` (as `campaign_get`), without recipient data. Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id of the post, article or campaign",
            "schema": {
              "type": "string"
            },
            "example": "post-ai-x7Kp2"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {
          "params": {
            "id": "clx0campaign"
          }
        }
      }
    },
    "/drafts/campaigns": {
      "post": {
        "operationId": "drafts.campaigns.upsert",
        "tags": [
          "Drafts"
        ],
        "summary": "Create or edit a campaign draft",
        "description": "Nothing is sent or scheduled — a team member sends it from the panel (as `campaign_draft_upsert`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "x-dry-run": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Existing draft campaign id; omit to create",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "draftRevision": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{16}$",
                    "description": "`draftRevision` from the last read; if the draft changed since, the call fails with `draftConflict` — read again"
                  },
                  "lang": {
                    "description": "Language of the texts (two letters); default: the brand default language. Texts in other languages are marked as machine-written for review",
                    "type": "string",
                    "pattern": "^[a-z]{2}$"
                  },
                  "name": {
                    "description": "Internal name",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 60,
                    "description": "Notification title"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 180,
                    "description": "Notification text"
                  },
                  "target": {
                    "description": "Where the button leads; default: the brand app",
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "app",
                          "product",
                          "group"
                        ]
                      },
                      "code": {
                        "description": "Product code for type \"product\"",
                        "type": "string",
                        "pattern": "^[0-9A-Za-z]{4,32}$"
                      },
                      "group": {
                        "description": "Shop category for type \"group\"",
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 120
                      }
                    },
                    "required": [
                      "type"
                    ]
                  },
                  "countries": {
                    "maxItems": 40,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^[A-Z]{2}$"
                    }
                  },
                  "productCodes": {
                    "description": "Only people who scanned these products; empty = everyone with consent",
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^[0-9A-Za-z]{4,32}$"
                    }
                  },
                  "push": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  },
                  "dryRun": {
                    "description": "Default true: nothing is saved — the result shows what would change and a `planToken`. Ask the user, then call again with the SAME arguments, `dryRun: false` and that `planToken`.",
                    "type": "boolean"
                  },
                  "planToken": {
                    "description": "`planToken` from the preview of exactly these arguments (required with `dryRun: false`, valid 10 minutes)",
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 300
                  }
                }
              },
              "example": {
                "title": "New roast",
                "body": "Medium roast with cocoa notes - try it now.",
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    },
    "/drafts/discard": {
      "post": {
        "operationId": "drafts.discard",
        "tags": [
          "Drafts"
        ],
        "summary": "Discard a draft of this key",
        "description": "Removes a draft created with this key and unchanged since (as `draft_discard`). Drafts only: nothing is published, sent or scheduled — a team member reviews and publishes in the Itemoo panel. Every write is a preview by default (`dryRun` omitted or `true`) and returns `planToken`; to save, repeat the SAME body with `dryRun: false` and that `planToken` (valid 10 minutes). The draft is signed with the person who created the key and the key name. Needs the plan feature “drafts from AI assistants”.\n\nKey scope: `drafts`.",
        "x-scope": "drafts",
        "x-dry-run": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "productPage",
                      "publication",
                      "article",
                      "campaign"
                    ]
                  },
                  "id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "Product id/code/SKU for productPage; otherwise the post, article or campaign id"
                  },
                  "dryRun": {
                    "description": "Default true: nothing is saved — the result shows what would change and a `planToken`. Ask the user, then call again with the SAME arguments, `dryRun: false` and that `planToken`.",
                    "type": "boolean"
                  },
                  "planToken": {
                    "description": "`planToken` from the preview of exactly these arguments (required with `dryRun: false`, valid 10 minutes)",
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 300
                  }
                },
                "required": [
                  "kind",
                  "id"
                ]
              },
              "example": {
                "kind": "article",
                "id": "clx0article",
                "dryRun": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {},
                  "description": "Preview (`dryRun: true`, with `planToken`) or the saved draft — the same result as the MCP tool of the same name"
                }
              }
            }
          },
          "400": {
            "description": "Error — code: VAL_INVALID, DRAFT_PATCH_INVALID, DRAFT_PLAN_REQUIRED, DRAFT_PLAN_EXPIRED, DRAFT_NOT_EDITABLE, DRAFT_NOT_DISCARDABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "VAL_INVALID",
              "DRAFT_PATCH_INVALID",
              "DRAFT_PLAN_REQUIRED",
              "DRAFT_PLAN_EXPIRED",
              "DRAFT_NOT_EDITABLE",
              "DRAFT_NOT_DISCARDABLE"
            ]
          },
          "401": {
            "description": "Error — code: API_KEY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "API_KEY_INVALID"
            ]
          },
          "403": {
            "description": "Error — code: DRAFTS_NOT_AVAILABLE, DRAFT_ROLE_NOT_ALLOWED, TENANT_READ_ONLY, API_KEY_SCOPE_MISSING, KEY_READ_ONLY, BRAND_SUSPENDED, INTEGRATIONS_DISABLED, PLAN_MODULE_MISSING",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFTS_NOT_AVAILABLE",
              "DRAFT_ROLE_NOT_ALLOWED",
              "TENANT_READ_ONLY",
              "API_KEY_SCOPE_MISSING",
              "KEY_READ_ONLY",
              "BRAND_SUSPENDED",
              "INTEGRATIONS_DISABLED",
              "PLAN_MODULE_MISSING"
            ],
            "x-error-params": {
              "API_KEY_SCOPE_MISSING": [
                "scope"
              ]
            }
          },
          "404": {
            "description": "Error — code: DRAFT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "Error — code: DRAFT_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_CONFLICT"
            ]
          },
          "429": {
            "description": "Error — code: DRAFT_DAILY_LIMIT, rateLimited, rateBlocked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "DRAFT_DAILY_LIMIT",
              "rateLimited",
              "rateBlocked"
            ]
          }
        },
        "x-example": {}
      }
    }
  },
  "webhooks": {
    "order.ready": {
      "post": {
        "operationId": "webhook.order.ready",
        "tags": [
          "Webhooks"
        ],
        "summary": "Order ready to fulfil",
        "description": "The order was paid, confirmed as cash on delivery or approved (B2B deferred payment) and can be packed.",
        "parameters": [
          {
            "name": "X-Itemoo-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix>,v1=<HMAC-SHA256(secret, t + \".\" + body)>",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Itemoo-Event",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "order.ready"
            }
          },
          {
            "name": "X-Itemoo-Delivery",
            "in": "header",
            "required": true,
            "description": "Delivery id, the same on retries",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer (or no answer within 10 s) is retried."
          }
        }
      }
    },
    "order.cancelled": {
      "post": {
        "operationId": "webhook.order.cancelled",
        "tags": [
          "Webhooks"
        ],
        "summary": "Order cancelled",
        "description": "The order was cancelled outside your ERP (panel, customer or sales channel). Changes you make through this API send no notification.",
        "parameters": [
          {
            "name": "X-Itemoo-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix>,v1=<HMAC-SHA256(secret, t + \".\" + body)>",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Itemoo-Event",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "order.cancelled"
            }
          },
          {
            "name": "X-Itemoo-Delivery",
            "in": "header",
            "required": true,
            "description": "Delivery id, the same on retries",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer (or no answer within 10 s) is retried."
          }
        }
      }
    },
    "order.updated": {
      "post": {
        "operationId": "webhook.order.updated",
        "tags": [
          "Webhooks"
        ],
        "summary": "Fulfilment changed",
        "description": "The fulfilment status or tracking number changed outside your ERP (e.g. in the panel). Changes you make through this API send no notification.",
        "parameters": [
          {
            "name": "X-Itemoo-Signature",
            "in": "header",
            "required": true,
            "description": "t=<unix>,v1=<HMAC-SHA256(secret, t + \".\" + body)>",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Itemoo-Event",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "const": "order.updated"
            }
          },
          {
            "name": "X-Itemoo-Delivery",
            "in": "header",
            "required": true,
            "description": "Delivery id, the same on retries",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received. Any other answer (or no answer within 10 s) is retried."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer itm_…"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "Alternative to the Authorization header"
      }
    },
    "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."
      },
      "Item": {
        "type": "object",
        "properties": {
          "sku": {
            "description": "ERP SKU paired with the item; null = not paired yet",
            "type": [
              "string",
              "null"
            ]
          },
          "ean": {
            "type": [
              "string",
              "null"
            ]
          },
          "catalogNo": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "product": {
            "type": "string",
            "description": "Product (page) name"
          },
          "productSku": {
            "type": "string",
            "description": "SKU of the product model that groups the items on one page"
          },
          "price": {
            "description": "Gross price in the brand currency",
            "type": [
              "number",
              "null"
            ]
          },
          "stock": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "null = stock is not tracked (unlimited sale)"
          },
          "reserved": {
            "type": "integer",
            "description": "Units held by orders not yet acknowledged by the ERP"
          },
          "available": {
            "type": "boolean"
          }
        },
        "required": [
          "sku",
          "ean",
          "catalogNo",
          "name",
          "product",
          "productSku",
          "price",
          "stock",
          "reserved",
          "available"
        ]
      },
      "Order": {
        "type": "object",
        "properties": {
          "orderNo": {
            "type": "string"
          },
          "channel": {
            "type": "string",
            "description": "app | site | marketplace:allegro | marketplace:ebay | marketplace:amazon | erp"
          },
          "external": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "orderId": {
                    "type": "string"
                  },
                  "marketplace": {
                    "type": "string"
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "orderId",
                  "marketplace",
                  "status"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The order in the sales channel; null for brand shop orders"
          },
          "fulfilledBy": {
            "type": "string",
            "enum": [
              "merchant",
              "marketplace"
            ],
            "description": "marketplace = shipped by the channel warehouse (e.g. FBA) — for bookkeeping only"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "examples": [
              "2026-10-16T08:30:00.000Z"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "examples": [
              "2026-10-16T08:30:00.000Z"
            ]
          },
          "payment": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "paid",
                  "failed",
                  "expired",
                  "refunded"
                ]
              },
              "method": {
                "type": "string",
                "enum": [
                  "online",
                  "transfer",
                  "on_delivery",
                  "on_pickup",
                  "deferred",
                  "marketplace"
                ],
                "description": "online = card/BLIK/wallet in the shop; transfer = bank transfer; on_delivery = cash on delivery; on_pickup = paid at pickup; deferred = B2B deferred payment; marketplace = paid in the sales channel"
              },
              "paidAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time",
                    "examples": [
                      "2026-10-16T08:30:00.000Z"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approval": {
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "pending",
                      "approved",
                      "rejected"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "B2B deferred payment over the limit"
              }
            },
            "required": [
              "status",
              "method",
              "paidAt",
              "approval"
            ]
          },
          "fulfillment": {
            "type": "string",
            "enum": [
              "new",
              "packing",
              "shipped",
              "delivered",
              "cancelled"
            ]
          },
          "acknowledgedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "examples": [
                  "2026-10-16T08:30:00.000Z"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "When the ERP acknowledged the order (POST /orders/ack)"
          },
          "readyToShip": {
            "type": "boolean"
          },
          "currency": {
            "type": "string"
          },
          "total": {
            "type": "number"
          },
          "totalNet": {
            "type": [
              "number",
              "null"
            ]
          },
          "customerDiscount": {
            "type": "number"
          },
          "buyerType": {
            "type": "string",
            "description": "consumer | business"
          },
          "vat": {
            "type": "object",
            "properties": {
              "scheme": {
                "type": "string",
                "enum": [
                  "domestic",
                  "eu-domestic",
                  "oss",
                  "intra-eu",
                  "export",
                  "marketplace-collected",
                  "local"
                ],
                "description": "domestic = seller country VAT; eu-domestic = EU consumer below the OSS threshold (seller country rates); oss = EU consumer, buyer country rates; intra-eu = intra-EU supply to a VAT-registered business, 0%; export = outside the EU, 0%; marketplace-collected = the sales channel collected the buyer country tax; local = VAT of the channel warehouse country"
              },
              "collectedByMarketplace": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "country": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "export": {
                "type": "boolean"
              },
              "buyerVatId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "vies": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "status": {
                        "type": "string"
                      },
                      "requestId": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "checkedAt": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date-time",
                            "examples": [
                              "2026-10-16T08:30:00.000Z"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "status",
                      "requestId",
                      "checkedAt"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "scheme",
              "collectedByMarketplace",
              "country",
              "export",
              "buyerVatId",
              "vies"
            ]
          },
          "shippingCost": {
            "type": "number"
          },
          "discount": {
            "type": "number"
          },
          "promoCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "promoDiscount": {
            "type": "number"
          },
          "buyer": {
            "type": "object",
            "properties": {
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "personalDataRemoved": {
                "type": "boolean",
                "description": "true = personal data was erased (GDPR or the sales channel retention); amounts and lines stay"
              }
            },
            "required": [
              "email",
              "name",
              "phone",
              "personalDataRemoved"
            ]
          },
          "shipping": {
            "type": "object",
            "properties": {
              "method": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "address": {
                "type": "object",
                "properties": {
                  "line1": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "line2": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "postal": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "city": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "country": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "line1",
                  "line2",
                  "postal",
                  "city",
                  "country"
                ]
              },
              "point": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": {}
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Pickup point (code, name, address) when chosen"
              }
            },
            "required": [
              "method",
              "address",
              "point"
            ]
          },
          "invoice": {
            "anyOf": [
              {
                "type": "object",
                "properties": {},
                "additionalProperties": {}
              },
              {
                "type": "null"
              }
            ],
            "description": "Invoice data entered by the buyer (company, taxId, address)"
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "carrier": {
            "type": [
              "string",
              "null"
            ]
          },
          "trackingNo": {
            "type": [
              "string",
              "null"
            ]
          },
          "invoiceDocument": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "number": {
                    "type": "string"
                  },
                  "ksefNumber": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "issuedAt": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "hasPdf": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "number",
                  "ksefNumber",
                  "issuedAt",
                  "hasPdf"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Invoice attached with PUT /orders/{orderNo}/invoice"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderLine"
            }
          }
        },
        "required": [
          "orderNo",
          "channel",
          "external",
          "fulfilledBy",
          "createdAt",
          "updatedAt",
          "payment",
          "fulfillment",
          "acknowledgedAt",
          "readyToShip",
          "currency",
          "total",
          "totalNet",
          "customerDiscount",
          "buyerType",
          "vat",
          "shippingCost",
          "discount",
          "promoCode",
          "promoDiscount",
          "buyer",
          "shipping",
          "invoice",
          "note",
          "carrier",
          "trackingNo",
          "invoiceDocument",
          "items"
        ]
      },
      "OrderLine": {
        "type": "object",
        "properties": {
          "sku": {
            "type": [
              "string",
              "null"
            ]
          },
          "catalogNo": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "qty": {
            "type": "number"
          },
          "unitPrice": {
            "type": "number"
          },
          "discount": {
            "type": "number",
            "description": "Promotion and customer discount on the whole line (not per unit)"
          },
          "customerDiscount": {
            "type": "number",
            "description": "Part of the discount coming from the B2B customer discount"
          },
          "vatRate": {
            "type": [
              "string",
              "null"
            ]
          },
          "vatCountry": {
            "description": "Country of the VAT rate (OSS: the buyer country)",
            "type": [
              "string",
              "null"
            ]
          },
          "netTotal": {
            "description": "Net value of the line after discounts",
            "type": [
              "number",
              "null"
            ]
          },
          "gift": {
            "type": "boolean"
          },
          "lots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "lot": {
                  "type": "string"
                },
                "qty": {
                  "type": "number"
                }
              },
              "required": [
                "lot",
                "qty"
              ]
            },
            "description": "Batches the line shipped from"
          },
          "units": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Itemoo QR codes of the shipped units"
          }
        },
        "required": [
          "sku",
          "catalogNo",
          "name",
          "qty",
          "unitPrice",
          "discount",
          "customerDiscount",
          "vatRate",
          "vatCountry",
          "netTotal",
          "gift",
          "lots",
          "units"
        ]
      },
      "OrderAfterStatusChange": {
        "type": "object",
        "properties": {
          "orderNo": {
            "type": "string"
          },
          "channel": {
            "type": "string",
            "description": "app | site | marketplace:allegro | marketplace:ebay | marketplace:amazon | erp"
          },
          "external": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "orderId": {
                    "type": "string"
                  },
                  "marketplace": {
                    "type": "string"
                  },
                  "status": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "orderId",
                  "marketplace",
                  "status"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The order in the sales channel; null for brand shop orders"
          },
          "fulfilledBy": {
            "type": "string",
            "enum": [
              "merchant",
              "marketplace"
            ],
            "description": "marketplace = shipped by the channel warehouse (e.g. FBA) — for bookkeeping only"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "examples": [
              "2026-10-16T08:30:00.000Z"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "examples": [
              "2026-10-16T08:30:00.000Z"
            ]
          },
          "payment": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "paid",
                  "failed",
                  "expired",
                  "refunded"
                ]
              },
              "method": {
                "type": "string",
                "enum": [
                  "online",
                  "transfer",
                  "on_delivery",
                  "on_pickup",
                  "deferred",
                  "marketplace"
                ],
                "description": "online = card/BLIK/wallet in the shop; transfer = bank transfer; on_delivery = cash on delivery; on_pickup = paid at pickup; deferred = B2B deferred payment; marketplace = paid in the sales channel"
              },
              "paidAt": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "date-time",
                    "examples": [
                      "2026-10-16T08:30:00.000Z"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approval": {
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "pending",
                      "approved",
                      "rejected"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "B2B deferred payment over the limit"
              }
            },
            "required": [
              "status",
              "method",
              "paidAt",
              "approval"
            ]
          },
          "fulfillment": {
            "type": "string",
            "enum": [
              "new",
              "packing",
              "shipped",
              "delivered",
              "cancelled"
            ]
          },
          "acknowledgedAt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time",
                "examples": [
                  "2026-10-16T08:30:00.000Z"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "When the ERP acknowledged the order (POST /orders/ack)"
          },
          "readyToShip": {
            "type": "boolean"
          },
          "currency": {
            "type": "string"
          },
          "total": {
            "type": "number"
          },
          "totalNet": {
            "type": [
              "number",
              "null"
            ]
          },
          "customerDiscount": {
            "type": "number"
          },
          "buyerType": {
            "type": "string",
            "description": "consumer | business"
          },
          "vat": {
            "type": "object",
            "properties": {
              "scheme": {
                "type": "string",
                "enum": [
                  "domestic",
                  "eu-domestic",
                  "oss",
                  "intra-eu",
                  "export",
                  "marketplace-collected",
                  "local"
                ],
                "description": "domestic = seller country VAT; eu-domestic = EU consumer below the OSS threshold (seller country rates); oss = EU consumer, buyer country rates; intra-eu = intra-EU supply to a VAT-registered business, 0%; export = outside the EU, 0%; marketplace-collected = the sales channel collected the buyer country tax; local = VAT of the channel warehouse country"
              },
              "collectedByMarketplace": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "country": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "export": {
                "type": "boolean"
              },
              "buyerVatId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "vies": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "status": {
                        "type": "string"
                      },
                      "requestId": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "checkedAt": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date-time",
                            "examples": [
                              "2026-10-16T08:30:00.000Z"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "status",
                      "requestId",
                      "checkedAt"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "scheme",
              "collectedByMarketplace",
              "country",
              "export",
              "buyerVatId",
              "vies"
            ]
          },
          "shippingCost": {
            "type": "number"
          },
          "discount": {
            "type": "number"
          },
          "promoCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "promoDiscount": {
            "type": "number"
          },
          "buyer": {
            "type": "object",
            "properties": {
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "personalDataRemoved": {
                "type": "boolean",
                "description": "true = personal data was erased (GDPR or the sales channel retention); amounts and lines stay"
              }
            },
            "required": [
              "email",
              "name",
              "phone",
              "personalDataRemoved"
            ]
          },
          "shipping": {
            "type": "object",
            "properties": {
              "method": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "address": {
                "type": "object",
                "properties": {
                  "line1": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "line2": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "postal": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "city": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "country": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "line1",
                  "line2",
                  "postal",
                  "city",
                  "country"
                ]
              },
              "point": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {},
                    "additionalProperties": {}
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Pickup point (code, name, address) when chosen"
              }
            },
            "required": [
              "method",
              "address",
              "point"
            ]
          },
          "invoice": {
            "anyOf": [
              {
                "type": "object",
                "properties": {},
                "additionalProperties": {}
              },
              {
                "type": "null"
              }
            ],
            "description": "Invoice data entered by the buyer (company, taxId, address)"
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          },
          "carrier": {
            "type": [
              "string",
              "null"
            ]
          },
          "trackingNo": {
            "type": [
              "string",
              "null"
            ]
          },
          "invoiceDocument": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "number": {
                    "type": "string"
                  },
                  "ksefNumber": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "issuedAt": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "hasPdf": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "number",
                  "ksefNumber",
                  "issuedAt",
                  "hasPdf"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Invoice attached with PUT /orders/{orderNo}/invoice"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderLine"
            }
          },
          "unchanged": {
            "description": "The same status was sent again — nothing changed, no email",
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "orderNo",
          "channel",
          "external",
          "fulfilledBy",
          "createdAt",
          "updatedAt",
          "payment",
          "fulfillment",
          "acknowledgedAt",
          "readyToShip",
          "currency",
          "total",
          "totalNet",
          "customerDiscount",
          "buyerType",
          "vat",
          "shippingCost",
          "discount",
          "promoCode",
          "promoDiscount",
          "buyer",
          "shipping",
          "invoice",
          "note",
          "carrier",
          "trackingNo",
          "invoiceDocument",
          "items"
        ]
      },
      "BrandPassport": {
        "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"
              }
            ]
          },
          "fields": {
            "type": "object",
            "properties": {
              "model": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "value": {},
                    "access": {
                      "type": "string",
                      "enum": [
                        "public",
                        "legit",
                        "authority"
                      ]
                    }
                  },
                  "required": [
                    "value",
                    "access"
                  ]
                }
              },
              "variant": {
                "anyOf": [
                  {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "object",
                      "properties": {
                        "value": {},
                        "access": {
                          "type": "string",
                          "enum": [
                            "public",
                            "legit",
                            "authority"
                          ]
                        }
                      },
                      "required": [
                        "value",
                        "access"
                      ]
                    }
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Variant layer (overrides the model)"
              },
              "batch": {
                "anyOf": [
                  {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "object",
                      "properties": {
                        "value": {},
                        "access": {
                          "type": "string",
                          "enum": [
                            "public",
                            "legit",
                            "authority"
                          ]
                        }
                      },
                      "required": [
                        "value",
                        "access"
                      ]
                    }
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Batch layer (inherited by units)"
              },
              "unit": {
                "anyOf": [
                  {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "object",
                      "properties": {
                        "value": {},
                        "access": {
                          "type": "string",
                          "enum": [
                            "public",
                            "legit",
                            "authority"
                          ]
                        }
                      },
                      "required": [
                        "value",
                        "access"
                      ]
                    }
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "model",
              "variant",
              "batch",
              "unit"
            ],
            "description": "Editable fields with their access levels, per layer"
          },
          "unitMeta": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string"
                  },
                  "activatedAt": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "date-time",
                        "examples": [
                          "2026-10-16T08:30:00.000Z"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "placedOnMarketAt": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "date-time",
                        "examples": [
                          "2026-10-16T08:30:00.000Z"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "predecessorCode": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "status",
                  "activatedAt",
                  "placedOnMarketAt",
                  "predecessorCode"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Unit dates: code activation and placing on the market; predecessor passport code"
          },
          "versions": {
            "type": "array",
            "items": {},
            "description": "Version history of all layers with pseudonymous authors (see the public PassportHistory)"
          },
          "chain": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ]
            },
            "description": "Per layer: number of the first version whose hash does not verify, null = intact"
          }
        },
        "required": [
          "level",
          "version",
          "backup",
          "identity",
          "product",
          "manufacturer",
          "responsiblePerson",
          "importer",
          "authorisedRepresentative",
          "facility",
          "language",
          "published",
          "recall",
          "facts",
          "documents",
          "components",
          "lifecycle",
          "model",
          "unit",
          "fields",
          "unitMeta",
          "versions",
          "chain"
        ]
      },
      "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"
        ]
      },
      "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"
        ]
      },
      "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"
        ]
      },
      "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"
        ]
      },
      "OrderEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Delivery id — the same on retries; use it to ignore duplicates"
          },
          "event": {
            "type": "string",
            "enum": [
              "order.ready",
              "order.cancelled",
              "order.updated"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "examples": [
              "2026-10-16T08:30:00.000Z"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/Order"
          }
        },
        "required": [
          "id",
          "event",
          "createdAt",
          "data"
        ]
      }
    }
  }
}