Skip to content
innovorder
⌘K

Product graph

Products & Steps

Products

Products represent purchasable items or options within a step.

Key Concept: Signatures & Versioning

Products and steps are versioned. Every update creates a new version: the numeric productId / stepId changes, while the signature remains stable across versions. Always use the signature to reference a product or step in read/write operations, and re-read the entity after an update to get the new ID.

GET/menus/{menuId}/productsGet All Products

Retrieve a list of all products associated with a specific menu. Supports name search and pagination.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
searchstringNoFilter products by name (query parameter).
step_exclusionintegerNoExclude products already attached to the given step ID (query parameter).
limitintegerNoPagination limit (query parameter).
offsetintegerNoPagination offset (query parameter).
orderstringNoSort order (query parameter).

Response

json
{
  "status": 200,
  "code": "products_succeed",
  "message": "Products succeed.",
  "data": [
    {
      "productId": 464462,
      "menuId": 106477,
      "signature": "d41d8cd98f00b204",
      "name": "Cheeseburger",
      "price": 1200,
      "vat": 1000,
      "webAvailability": true,
      "kioskAvailability": true
    }
  ]
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"products_succeed"Machine-readable application code for the result.
messagestring"Products succeed."Human-readable result message. Do not use this value for program logic.
dataarray[…]Endpoint-specific response payload.
data[]object{…}Endpoint-specific response payload.
data[].productIdinteger464462Identifier of the product.
data[].menuIdinteger106477Identifier of the menu.
data[].signaturestring"d41d8cd98f00b204"The signature value.
data[].namestring"Cheeseburger"The name value.
data[].priceinteger1200The price value.
data[].vatinteger1000The vat value.
data[].webAvailabilitybooleantrueThe web availability value.
data[].kioskAvailabilitybooleantrueThe kiosk availability value.

GET/menus/{menuId}/products/{signature}Get Product Details

Retrieve full details for a single product identified by its signature, including image, tags, categories, steps and external references.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the product.

Response

json
{
  "status": 200,
  "data": {
    "productId": 464462,
    "menuId": 106477,
    "signature": "d41d8cd98f00b204",
    "name": "Cheeseburger",
    "price": 1200,
    "vat": 1000,
    "tags": [],
    "productStep": []
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
dataobject{…}Endpoint-specific response payload.
data.productIdinteger464462Identifier of the product.
data.menuIdinteger106477Identifier of the menu.
data.signaturestring"d41d8cd98f00b204"The signature value.
data.namestring"Cheeseburger"The name value.
data.priceinteger1200The price value.
data.vatinteger1000The vat value.
data.tagsarray[]List of tags entries.
data.productSteparray[]List of product step entries.

Create, Update & Delete Products

Prices are expressed in cents (1200 = 12.00) and VAT rates in basis points (1000 = 10%). If the restaurant is attached to an operation zone, vatGroupId (the VAT family) is mandatory when creating or updating a product. Valid VAT family IDs can be retrieved with GET /api/v1/restaurants/{id}/vat-rates (see Restaurant Ops → Zones): each entry of its vatGroups array carries the vatGroupId to send here, along with the family code, name and its per-consumption-mode rates (eatIn, takeAway, delivery) in basis points.

POST/menus/{menuId}/productsCreate Product

Create a new product in a menu. Providing a "sku" object creates (or reuses) the brand-level SKU and links it to the product. "tags" and "categories" reference existing tag/category IDs of the menu, and "productStep" lists the steps attached to the product.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.

Request Body

json
{
  "name": "Cheeseburger",
  "price": 1200,
  "description": "Beef patty, cheddar, pickles",
  "vat": 1000,
  "vatSitIn": 1000,
  "vatTakeAway": 550,
  "vatDelivery": 1000,
  "vatGroupId": 12,
  "consumptionFlags": 7,
  "webAvailability": true,
  "kioskAvailability": true,
  "isSitInEnabled": true,
  "isTakeAwayEnabled": true,
  "isDeliveryEnabled": true,
  "measurementUnit": "unit",
  "imageId": 1001,
  "tags": [
    101,
    102
  ],
  "categories": [
    30085
  ],
  "sku": {
    "value": "BURGER-001"
  },
  "productStep": []
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
namestring"Cheeseburger"The name value.
priceinteger1200The price value.
descriptionstring"Beef patty, cheddar, pickles"The description value.
vatinteger1000The vat value.
vatSitIninteger1000The vat sit in value.
vatTakeAwayinteger550The vat take away value.
vatDeliveryinteger1000The vat delivery value.
vatGroupIdinteger12Identifier of the associated vat group.
consumptionFlagsinteger7The consumption flags value.
webAvailabilitybooleantrueThe web availability value.
kioskAvailabilitybooleantrueThe kiosk availability value.
isSitInEnabledbooleantrueWhether sit in enabled is enabled or applies.
isTakeAwayEnabledbooleantrueWhether take away enabled is enabled or applies.
isDeliveryEnabledbooleantrueWhether delivery enabled is enabled or applies.
measurementUnitstring"unit"The measurement unit value.
imageIdinteger1001Identifier of the associated image.
tagsarray[…]List of tags entries.
tags[]integer101The tags value.
categoriesarray[…]List of categories entries.
categories[]integer30085The categories value.
skuobject{…}Object containing sku fields.
sku.valuestring"BURGER-001"The value value.
productSteparray[]List of product step entries.

Response

json
{
  "status": 200,
  "code": "product_create_succeed",
  "data": {
    "productId": 464470,
    "menuId": 106477,
    "signature": "9b2f4c1a7e3d",
    "name": "Cheeseburger",
    "price": 1200
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"product_create_succeed"Machine-readable application code for the result.
dataobject{…}Endpoint-specific response payload.
data.productIdinteger464470Identifier of the product.
data.menuIdinteger106477Identifier of the menu.
data.signaturestring"9b2f4c1a7e3d"The signature value.
data.namestring"Cheeseburger"The name value.
data.priceinteger1200The price value.

Tags Reset

When updating a product, always resend the full tags array: if tags is omitted, the new product version is created with no tags at all.

PUT/menus/{menuId}/products/{signature}Update Product

Update a product. This creates a new version: the productId changes while the signature remains stable. Most omitted fields keep their current value, but "tags" is an exception: if omitted, the new version is created with no tags - always resend the full tags array. When "productStep" is provided, the full list of steps attached to the product is replaced (recursion between products and steps is validated server-side).

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the product.

Request Body

json
{
  "name": "Cheeseburger XL",
  "price": 1350,
  "vat": 1000,
  "vatGroupId": 12,
  "webAvailability": true,
  "kioskAvailability": true,
  "tags": [
    101
  ],
  "claimOrder": 10,
  "productStep": [
    {
      "stepId": 560,
      "menuId": 106477,
      "product_step": {
        "position": 1
      }
    },
    {
      "stepId": 561,
      "menuId": 106477,
      "product_step": {
        "position": 2
      }
    }
  ],
  "pos": {
    "ticketLabel": "CHZBRG XL",
    "discountable": true
  }
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
namestring"Cheeseburger XL"The name value.
priceinteger1350The price value.
vatinteger1000The vat value.
vatGroupIdinteger12Identifier of the associated vat group.
webAvailabilitybooleantrueThe web availability value.
kioskAvailabilitybooleantrueThe kiosk availability value.
tagsarray[…]List of tags entries.
tags[]integer101The tags value.
claimOrderinteger10The claim order value.
productSteparray[…]List of product step entries.
productStep[]object{…}Object containing product step fields.
productStep[].stepIdinteger560Identifier of the associated step.
productStep[].menuIdinteger106477Identifier of the menu.
productStep[].product_stepobject{…}Object containing product step fields.
productStep[].product_step.positioninteger1The position value.
posobject{…}Object containing pos fields.
pos.ticketLabelstring"CHZBRG XL"The ticket label value.
pos.discountablebooleantrueThe discountable value.

Response

json
{
  "status": 200,
  "code": "product_update_succeed",
  "message": "Product updated.",
  "data": {
    "productId": 464471,
    "menuId": 106477,
    "signature": "9b2f4c1a7e3d",
    "name": "Cheeseburger XL",
    "price": 1350
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"product_update_succeed"Machine-readable application code for the result.
messagestring"Product updated."Human-readable result message. Do not use this value for program logic.
dataobject{…}Endpoint-specific response payload.
data.productIdinteger464471Identifier of the product.
data.menuIdinteger106477Identifier of the menu.
data.signaturestring"9b2f4c1a7e3d"The signature value.
data.namestring"Cheeseburger XL"The name value.
data.priceinteger1350The price value.

Workflow: Product with Steps

To build a composite product (e.g. a burger with a "Cooking Level" choice):

  1. Create the option products (e.g. "Rare", "Medium") with POST /menus/{menuId}/products.
  2. Create the step listing them with POST /menus/{menuId}/steps and its stepProduct array.
  3. Attach the step to the parent product via productStep on create or update. Each entry references an existing step of the menu by its current numeric stepId (not its signature), with an optional product_step.position (defaults to the array order): { "stepId": 560, "menuId": 106477, "product_step": { "position": 1 } }.

Remember that productStep replaces the full list of attached steps, and that updating a step changes its stepId - re-read the step to get the new ID before re-attaching it.

PATCH/menus/{menuId}/productsMass Update Products

Update several products of a menu at once, targeted by their signatures. The "data" object contains the fields to apply to all targeted products. The "overwrite" object controls whether categories, steps, tags and consumption modes are replaced or merged.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.

Request Body

json
{
  "signatures": [
    "d41d8cd98f00b204",
    "9b2f4c1a7e3d"
  ],
  "data": {
    "price": 1300,
    "vat": 1000,
    "kioskAvailability": true,
    "tags": [
      101
    ],
    "categories": [
      30085
    ]
  },
  "overwrite": {
    "categories": false,
    "steps": false,
    "tags": false,
    "consumptionMode": {
      "MODE_SIT_IN": false,
      "MODE_TAKE_AWAY": false,
      "MODE_DELIVERY": false,
      "MODE_DRIVE": false
    }
  }
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
signaturesarray[…]List of signatures entries.
signatures[]string"d41d8cd98f00b204"The signatures value.
dataobject{…}Endpoint-specific response payload.
data.priceinteger1300The price value.
data.vatinteger1000The vat value.
data.kioskAvailabilitybooleantrueThe kiosk availability value.
data.tagsarray[…]List of tags entries.
data.tags[]integer101The tags value.
data.categoriesarray[…]List of categories entries.
data.categories[]integer30085The categories value.
overwriteobject{…}Object containing overwrite fields.
overwrite.categoriesbooleanfalseThe categories value.
overwrite.stepsbooleanfalseThe steps value.
overwrite.tagsbooleanfalseThe tags value.
overwrite.consumptionModeobject{…}Object containing consumption mode fields.
overwrite.consumptionMode.MODE_SIT_INbooleanfalseThe mode sit in value.
overwrite.consumptionMode.MODE_TAKE_AWAYbooleanfalseThe mode take away value.
overwrite.consumptionMode.MODE_DELIVERYbooleanfalseThe mode delivery value.
overwrite.consumptionMode.MODE_DRIVEbooleanfalseThe mode drive value.

Response

json
{
  "status": 200,
  "code": "menu_update_succeed",
  "message": "Menu has been successfully updated.",
  "data": {
    "menuId": 106477,
    "name": "Main Menu",
    "channels": []
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"menu_update_succeed"Machine-readable application code for the result.
messagestring"Menu has been successfully updated."Human-readable result message. Do not use this value for program logic.
dataobject{…}Endpoint-specific response payload.
data.menuIdinteger106477Identifier of the menu.
data.namestring"Main Menu"The name value.
data.channelsarray[]List of channels entries.

PUT/menus/{menuId}/products/{signature}/quantityUpdate Product Stock

Update only the stock quantity (currentQuantity) of a product. When stock management is enabled, the stock movement is audited and the product can be automatically disabled when reaching zero. The product is also removed from in-progress carts.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the product.

Request Body

json
{
  "quantity": 25
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
quantityinteger25The quantity value.

Response

json
{
  "status": 200,
  "code": "product_quantity_succeed",
  "message": "Products quantity was update successfully.",
  "data": {
    "productId": 464471,
    "signature": "9b2f4c1a7e3d",
    "currentQuantity": 25
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"product_quantity_succeed"Machine-readable application code for the result.
messagestring"Products quantity was update successfully."Human-readable result message. Do not use this value for program logic.
dataobject{…}Endpoint-specific response payload.
data.productIdinteger464471Identifier of the product.
data.signaturestring"9b2f4c1a7e3d"The signature value.
data.currentQuantityinteger25The current quantity value.

POST/menus/{menuId}/products/{signature}/duplicateDuplicate Product

Duplicate a product within the same menu. The copy gets a new signature. No request body is needed.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the product to duplicate.

Response

json
{
  "status": 200,
  "code": "product_duplicate_succeed",
  "data": {
    "productId": 464480,
    "signature": "3c7e9a1b5d2f",
    "name": "Cheeseburger XL"
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"product_duplicate_succeed"Machine-readable application code for the result.
dataobject{…}Endpoint-specific response payload.
data.productIdinteger464480Identifier of the product.
data.signaturestring"3c7e9a1b5d2f"The signature value.
data.namestring"Cheeseburger XL"The name value.

DELETE/menus/{menuId}/products/{signature}Delete Product

Delete a product from the menu. Associated external ID mappings and external references are cleaned up.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the product to delete.

Response

json
{
  "status": 200,
  "code": "product_delete_succeed"
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"product_delete_succeed"Machine-readable application code for the result.

Product Attributes

ProductAttributes Model
export interface ProductAttributes {
  productId: number;         // Changes on every update (versioning)
  signature: string;         // Stable identifier across versions
  menuId: number;
  name: string;
  description: string | null;
  additionalInformation: string | null;
  price: number;             // in cents (e.g. 1200 = 12.00)
  purchasePrice: number | null;
  vat: number;               // basis points (e.g. 1000 = 10%)
  vatSitIn: number;
  vatTakeAway: number;
  vatDelivery: number;
  vatGroupId: number | null; // VAT family (required with operation zones)
  consumptionFlags: number;  // Bitmask for consumption modes
  webAvailability: boolean;
  kioskAvailability: boolean;
  isSitInEnabled: boolean;
  isTakeAwayEnabled: boolean;
  isDeliveryEnabled: boolean;
  isFinalProduct: boolean;
  isUpselling: boolean;
  isProducible: boolean;
  isEligibleLuncheon: boolean;
  measurementUnit: 'unit' | 'kg';
  servingCount: number;
  currentQuantity: number | null; // Stock level
  defaultQuantity: number | null;
  claimOrder: number | null;      // 0-99
  billingCode: string | null;
  machineCode: string | null;
  imageId: number | null;
  skuId: number | null;
  tags: TagAttributes[];
  productStep: StepAttributes[];  // Steps attached to the product
  pos: object;                    // POS-specific settings
}

Steps

Steps (or Option Groups) define modifiers for products, such as "Cooking Level" or "Sauces". A step has a type: 1 (CUSTOMIZATION) or 2 (CROSS_SELLING). Like products, steps are versioned: updates create a new stepId while the signature remains stable.

GET/menus/{menuId}/stepsGet Steps

Retrieve all steps for a specific menu, with their step products. Supports name search and pagination.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
searchstringNoFilter steps by name (query parameter).
limitintegerNoPagination limit (query parameter).
offsetintegerNoPagination offset (query parameter).
orderstringNoSort order (query parameter).

Response

json
{
  "status": 200,
  "code": "steps_succeed",
  "data": [
    {
      "stepId": 554,
      "signature": "7f3a9c1e5b2d",
      "name": "Cooking Level",
      "type": 1,
      "minChoice": 1,
      "maxChoice": 1,
      "stepProduct": [
        {
          "name": "Rare",
          "productId": 991
        },
        {
          "name": "Medium",
          "productId": 992
        }
      ]
    }
  ]
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"steps_succeed"Machine-readable application code for the result.
dataarray[…]Endpoint-specific response payload.
data[]object{…}Endpoint-specific response payload.
data[].stepIdinteger554Identifier of the associated step.
data[].signaturestring"7f3a9c1e5b2d"The signature value.
data[].namestring"Cooking Level"The name value.
data[].typeinteger1The type value.
data[].minChoiceinteger1The min choice value.
data[].maxChoiceinteger1The max choice value.
data[].stepProductarray[…]List of step product entries.
data[].stepProduct[]object{…}Object containing step product fields.
data[].stepProduct[].namestring"Rare"The name value.
data[].stepProduct[].productIdinteger991Identifier of the product.

GET/menus/{menuId}/steps/{signature}Get Step Details

Retrieve a single step by its signature, including its step products.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the step.

Response

json
{
  "status": 200,
  "data": {
    "stepId": 554,
    "signature": "7f3a9c1e5b2d",
    "name": "Cooking Level",
    "type": 1,
    "minChoice": 1,
    "maxChoice": 1,
    "stepProduct": [
      {
        "name": "Rare",
        "productId": 991
      },
      {
        "name": "Medium",
        "productId": 992
      }
    ]
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
dataobject{…}Endpoint-specific response payload.
data.stepIdinteger554Identifier of the associated step.
data.signaturestring"7f3a9c1e5b2d"The signature value.
data.namestring"Cooking Level"The name value.
data.typeinteger1The type value.
data.minChoiceinteger1The min choice value.
data.maxChoiceinteger1The max choice value.
data.stepProductarray[…]List of step product entries.
data.stepProduct[]object{…}Object containing step product fields.
data.stepProduct[].namestring"Rare"The name value.
data.stepProduct[].productIdinteger991Identifier of the product.

Create, Update & Delete Steps

POST/menus/{menuId}/stepsCreate Step

Create a step in a menu with its step products. The "stepProduct" array is required and lists existing products of the menu with their per-step settings. Products tagged with a customizable price/label, or sold by weight, cannot be added to a step. If provided, "stepRef" must be unique within the menu.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.

Request Body

json
{
  "name": "Cooking Level",
  "type": 1,
  "minChoice": 1,
  "maxChoice": 1,
  "ticketLabel": "COOK",
  "webAvailability": true,
  "kioskAvailability": true,
  "stepProduct": [
    {
      "productId": 991,
      "step_product": {
        "price": 0,
        "position": 1
      }
    },
    {
      "productId": 992,
      "step_product": {
        "price": 0,
        "position": 2
      }
    }
  ]
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
namestring"Cooking Level"The name value.
typeinteger1The type value.
minChoiceinteger1The min choice value.
maxChoiceinteger1The max choice value.
ticketLabelstring"COOK"The ticket label value.
webAvailabilitybooleantrueThe web availability value.
kioskAvailabilitybooleantrueThe kiosk availability value.
stepProductarray[…]List of step product entries.
stepProduct[]object{…}Object containing step product fields.
stepProduct[].productIdinteger991Identifier of the product.
stepProduct[].step_productobject{…}Object containing step product fields.
stepProduct[].step_product.priceinteger0The price value.
stepProduct[].step_product.positioninteger1The position value.

Response

json
{
  "status": 200,
  "code": "step_create_succeed",
  "data": {
    "stepId": 560,
    "signature": "1e8b4d7a2c9f",
    "name": "Cooking Level",
    "type": 1
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"step_create_succeed"Machine-readable application code for the result.
dataobject{…}Endpoint-specific response payload.
data.stepIdinteger560Identifier of the associated step.
data.signaturestring"1e8b4d7a2c9f"The signature value.
data.namestring"Cooking Level"The name value.
data.typeinteger1The type value.

PUT/menus/{menuId}/steps/{signature}Update Step

Update a step. This creates a new version: the stepId changes while the signature remains stable. The "stepProduct" array is required and replaces the full list of step products. For CROSS_SELLING steps, step product prices are forced to null (the price comes from the product itself). Recursion between products and steps is validated server-side.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the step.

Request Body

json
{
  "name": "Cooking Level",
  "type": 1,
  "minChoice": 1,
  "maxChoice": 1,
  "webAvailability": true,
  "kioskAvailability": true,
  "stepProduct": [
    {
      "productId": 991,
      "step_product": {
        "price": 0,
        "position": 1
      }
    },
    {
      "productId": 992,
      "step_product": {
        "price": 0,
        "position": 2
      }
    },
    {
      "productId": 993,
      "step_product": {
        "price": 100,
        "position": 3
      }
    }
  ]
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
namestring"Cooking Level"The name value.
typeinteger1The type value.
minChoiceinteger1The min choice value.
maxChoiceinteger1The max choice value.
webAvailabilitybooleantrueThe web availability value.
kioskAvailabilitybooleantrueThe kiosk availability value.
stepProductarray[…]List of step product entries.
stepProduct[]object{…}Object containing step product fields.
stepProduct[].productIdinteger991Identifier of the product.
stepProduct[].step_productobject{…}Object containing step product fields.
stepProduct[].step_product.priceinteger0The price value.
stepProduct[].step_product.positioninteger1The position value.

Response

json
{
  "status": 200,
  "code": "step_update_succeed",
  "data": {
    "stepId": 561,
    "signature": "7f3a9c1e5b2d",
    "name": "Cooking Level",
    "type": 1
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"step_update_succeed"Machine-readable application code for the result.
dataobject{…}Endpoint-specific response payload.
data.stepIdinteger561Identifier of the associated step.
data.signaturestring"7f3a9c1e5b2d"The signature value.
data.namestring"Cooking Level"The name value.
data.typeinteger1The type value.

POST/menus/{menuId}/steps/convertConvert Steps

Convert steps in bulk between the CUSTOMIZATION and CROSS_SELLING types. All targeted steps must currently be of the same type, otherwise the request is rejected.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.

Request Body

json
{
  "signatures": [
    "7f3a9c1e5b2d",
    "1e8b4d7a2c9f"
  ]
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
signaturesarray[…]List of signatures entries.
signatures[]string"7f3a9c1e5b2d"The signatures value.

Response

json
{
  "status": 200,
  "data": [
    {
      "stepId": 562,
      "signature": "7f3a9c1e5b2d",
      "type": 2
    },
    {
      "stepId": 563,
      "signature": "1e8b4d7a2c9f",
      "type": 2
    }
  ]
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
dataarray[…]Endpoint-specific response payload.
data[]object{…}Endpoint-specific response payload.
data[].stepIdinteger562Identifier of the associated step.
data[].signaturestring"7f3a9c1e5b2d"The signature value.
data[].typeinteger2The type value.

POST/menus/{menuId}/steps/{signature}/duplicateDuplicate Step

Duplicate a step within the same menu, including its step products. No request body is needed.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the step to duplicate.

Response

json
{
  "status": 200,
  "code": "step_duplicate_succeed",
  "data": {
    "stepId": 570,
    "signature": "5a2d8f1c4e7b",
    "name": "Cooking Level"
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"step_duplicate_succeed"Machine-readable application code for the result.
dataobject{…}Endpoint-specific response payload.
data.stepIdinteger570Identifier of the associated step.
data.signaturestring"5a2d8f1c4e7b"The signature value.
data.namestring"Cooking Level"The name value.

DELETE/menus/{menuId}/steps/{signature}Delete Step

Delete a step from the menu.

Parameters

NameTypeRequiredDescription
menuIdintegerYesThe unique identifier of the menu.
signaturestringYesThe stable signature of the step to delete.

Response

json
{
  "status": 200,
  "code": "step_delete_succeed"
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"step_delete_succeed"Machine-readable application code for the result.

Data Models

StepAttributes
typescript
interface StepAttributes {
  stepId: number;          // Changes on every update (versioning)
  signature: string;       // Stable identifier across versions
  menuId: number;
  name: string;
  type: number;            // 1 = CUSTOMIZATION, 2 = CROSS_SELLING
  minChoice: number;
  maxChoice: number;
  stepRef: string | null;  // Optional stable reference, unique per menu
  ticketLabel: string | null;
  webAvailability: boolean;
  kioskAvailability: boolean;
  isExcessAllowed: boolean;
  isGroupEnabled: boolean;
  isDescriptionDisplayEnabled: boolean;
  isImageDisplayEnabled: boolean;
  isQuantitySelectionEnabled: boolean;
  isWeightStrategyEnabled: boolean;
  posType: 'SINGLE' | 'MULTIPLE' | null;
  posName: string | null;
  stepProduct: StepProductAttributes[];
}
StepProductAttributes
typescript
interface StepProductAttributes {
  productId: number;
  step_product: {
    price: number | null;       // in cents; overrides the product price
                                // (forced to null for CROSS_SELLING steps)
    position: number;
    exceedPrice: number | null; // price applied beyond the free quota
    maxProductQuantity: number | null;
    groupName: string | null;
    weight: number | null;
    posDefaultProductQuantity: number | null;
    posMinProductQuantity: number | null;
    posIsSelectedByDefault: boolean;
    posIsPriceModificationEnabled: boolean;
    posIsQuantityModificationEnabled: boolean;
  };
}

SKU Management

SKUs (Stock Keeping Units) are brand-level identifiers used to map internal product IDs to external references. Each SKU can carry per-consumption-mode VAT rates (sit-in, take-away, delivery, drive).

GET/brands/{brandId}/skuList SKUs

Retrieve all SKUs for a given brand.

Parameters

NameTypeRequiredDescription
brandIdintegerYesThe ID of the brand.

Response

json
{
  "status": 200,
  "code": "sku_list_success",
  "message": "Sku list linked to this brand has been found",
  "data": [
    {
      "skuId": 101,
      "brandId": 3325,
      "value": "BURGER-001",
      "deliveryVat": 1000,
      "driveVat": 1000,
      "takeAwayVat": 550,
      "sitInVat": 1000
    }
  ]
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"sku_list_success"Machine-readable application code for the result.
messagestring"Sku list linked to this brand has been found"Human-readable result message. Do not use this value for program logic.
dataarray[…]Endpoint-specific response payload.
data[]object{…}Endpoint-specific response payload.
data[].skuIdinteger101Identifier of the associated sku.
data[].brandIdinteger3325Identifier of the brand.
data[].valuestring"BURGER-001"The value value.
data[].deliveryVatinteger1000The delivery vat value.
data[].driveVatinteger1000The drive vat value.
data[].takeAwayVatinteger550The take away vat value.
data[].sitInVatinteger1000The sit in vat value.

POST/brands/{brandId}/skuCreate SKU

Create a new SKU for a brand. VAT rates default to 1000 (10%) if not specified.

Parameters

NameTypeRequiredDescription
brandIdintegerYesThe ID of the brand.

Request Body

json
{
  "value": "DRINK-042",
  "deliveryVat": 550,
  "driveVat": 550,
  "takeAwayVat": 550,
  "sitInVat": 1000
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
valuestring"DRINK-042"The value value.
deliveryVatinteger550The delivery vat value.
driveVatinteger550The drive vat value.
takeAwayVatinteger550The take away vat value.
sitInVatinteger1000The sit in vat value.

Response

json
{
  "status": 200,
  "code": "sku_created",
  "message": "The SKU has been created",
  "data": {
    "skuId": 102,
    "brandId": 3325,
    "value": "DRINK-042",
    "deliveryVat": 550,
    "sitInVat": 1000
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"sku_created"Machine-readable application code for the result.
messagestring"The SKU has been created"Human-readable result message. Do not use this value for program logic.
dataobject{…}Endpoint-specific response payload.
data.skuIdinteger102Identifier of the associated sku.
data.brandIdinteger3325Identifier of the brand.
data.valuestring"DRINK-042"The value value.
data.deliveryVatinteger550The delivery vat value.
data.sitInVatinteger1000The sit in vat value.

PATCH/brands/{brandId}/skus/{skuId}Update SKU

Update the value of an existing SKU.

Parameters

NameTypeRequiredDescription
brandIdintegerYesThe ID of the brand.
skuIdintegerYesThe ID of the SKU to update.

Request Body

json
{
  "value": "DRINK-042-V2"
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
valuestring"DRINK-042-V2"The value value.

Response

json
{
  "status": 200,
  "code": "sku_updated",
  "message": "The SKU has been updated",
  "data": {
    "skuId": 102,
    "value": "DRINK-042-V2"
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"sku_updated"Machine-readable application code for the result.
messagestring"The SKU has been updated"Human-readable result message. Do not use this value for program logic.
dataobject{…}Endpoint-specific response payload.
data.skuIdinteger102Identifier of the associated sku.
data.valuestring"DRINK-042-V2"The value value.

POST/brands/{brandId}/skus/bulk_deleteBulk Delete Unused SKUs

Hard-deletes SKU rows only when no live product of the brand still references them. Use either an explicit list of up to 200 IDs or orphansOnly=true, never both. Referenced rows are preserved and reported in skippedInUse; IDs outside the brand are indistinguishable from missing IDs and are reported in notFoundSkuIds. Requires the CAN_CREATE_SKU access flag.

Parameters

NameTypeRequiredDescription
brandIdintegerYesBrand that owns every SKU to inspect and delete.

Request Body

json
{
  "skuIds": [
    101,
    102
  ]
}
Request Body Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeRequiredExampleDescription
skuIdsarrayNot specified[…]List of sku ids entries.
skuIds[]integerNo101Explicit SKU IDs to inspect. Supply between 1 and 200 IDs; mutually exclusive with orphansOnly.
orphansOnlybooleanNoNot providedMust be true when supplied. Deletes every unreferenced SKU in the brand; mutually exclusive with skuIds.

Response

json
{
  "status": 200,
  "code": "skus_deleted",
  "message": "The SKUs have been deleted",
  "data": {
    "brandId": 3325,
    "deleted": [
      {
        "skuId": 101,
        "value": "BURGER-001",
        "deliveryVat": 1000,
        "driveVat": 1000,
        "takeAwayVat": 1000,
        "sitInVat": 1000
      }
    ],
    "skippedInUse": [
      {
        "skuId": 102,
        "value": "DRINK-042",
        "productCount": 3
      }
    ],
    "notFoundSkuIds": [
      999
    ]
  }
}
Response Properties

Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.

PropertyTypeExampleDescription
statusinteger200HTTP status code returned by the API.
codestring"skus_deleted"Machine-readable application code for the result.
messagestring"The SKUs have been deleted"Human-readable result message. Do not use this value for program logic.
dataobject{…}Endpoint-specific response payload.
data.brandIdinteger3325Identifier of the brand.
data.deletedarray[…]List of deleted entries.
data.deleted[]object{…}Object containing deleted fields.
data.deleted[].skuIdinteger101Identifier of the associated sku.
data.deleted[].valuestring"BURGER-001"The value value.
data.deleted[].deliveryVatinteger1000The delivery vat value.
data.deleted[].driveVatinteger1000The drive vat value.
data.deleted[].takeAwayVatinteger1000The take away vat value.
data.deleted[].sitInVatinteger1000The sit in vat value.
data.skippedInUsearray[…]List of skipped in use entries.
data.skippedInUse[]object{…}Object containing skipped in use fields.
data.skippedInUse[].skuIdinteger102Identifier of the associated sku.
data.skippedInUse[].valuestring"DRINK-042"The value value.
data.skippedInUse[].productCountinteger3The product count value.
data.notFoundSkuIdsarray[…]List of not found sku ids entries.
data.notFoundSkuIds[]integer999The not found sku ids value.

Data Models

SkuAttributes
typescript
interface SkuAttributes {
  skuId: number;
  brandId: number;
  value: string;        // The SKU identifier string
  deliveryVat: number;  // VAT rate for delivery (e.g. 1000 = 10%)
  driveVat: number;     // VAT rate for drive-through
  takeAwayVat: number;  // VAT rate for take-away
  sitInVat: number;     // VAT rate for sit-in
}