{
  "openapi": "3.0.0",
  "paths": {
    "/items": {
      "get": {
        "operationId": "listItems",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by item name, barcode or item code",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "groupId",
            "required": false,
            "in": "query",
            "description": "Filter by group/category id(s) — array or CSV",
            "schema": {
              "type": "array",
              "items": {
                "type": "number"
              }
            }
          },
          {
            "name": "brandId",
            "required": false,
            "in": "query",
            "description": "Filter by brand ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "taxId",
            "required": false,
            "in": "query",
            "description": "Filter by tax ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "stockStatus",
            "required": false,
            "in": "query",
            "description": "Filter by stock status: inStock, low, out",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "weighingScale",
            "required": false,
            "in": "query",
            "description": "Filter items flagged for weighing scale (1 = yes, 0 = no)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by item type (0 = standard, 1 = variant, 2 = combo)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List items",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/items/{id}": {
      "get": {
        "operationId": "getItem",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "storeId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get an item",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/categories": {
      "get": {
        "operationId": "listCategories",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by group name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List categories",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/categories/{id}": {
      "get": {
        "operationId": "getCategory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a category",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/menus": {
      "get": {
        "operationId": "listMenus",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by menu name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "delivery",
            "required": false,
            "in": "query",
            "description": "Delivery filter (1 = yes, 0 = no, 2/undefined = any)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "takeaway",
            "required": false,
            "in": "query",
            "description": "Takeaway filter (1 = yes, 0 = no, 2/undefined = any)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "online",
            "required": false,
            "in": "query",
            "description": "Online filter (1 = yes, 0 = no, 2/undefined = any)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List menus",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/menus/{id}/full": {
      "get": {
        "operationId": "getMenuFull",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a menu with its items and store assignments",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/modifiers": {
      "get": {
        "operationId": "listModifiers",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by modifier name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "itemSearch",
            "required": false,
            "in": "query",
            "description": "Filter to modifiers applied to an item whose name matches (searches ItemSelectedModifier, Item.modifierId and the Item.Modifiers JSON column)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List modifier groups",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/modifiers/{id}/full": {
      "get": {
        "operationId": "getModifierFull",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a modifier group with its options",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/customers": {
      "get": {
        "operationId": "listCustomers",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by name, email, mobile, or loyalty number",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "email",
            "required": false,
            "in": "query",
            "description": "Filter by email",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mobile",
            "required": false,
            "in": "query",
            "description": "Filter by mobile",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List customers",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "post": {
        "operationId": "createCustomer",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerCreateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a customer",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/customers/{id}": {
      "get": {
        "operationId": "getCustomer",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a customer",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "patch": {
        "operationId": "updateCustomer",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerUpdateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a customer",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/stores": {
      "get": {
        "operationId": "listStores",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by name, code, or email",
            "schema": {
              "example": "Main Store",
              "type": "string"
            }
          },
          {
            "name": "isActive",
            "required": false,
            "in": "query",
            "description": "Filter by active status",
            "schema": {
              "example": true,
              "type": "boolean"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "1 = active only, 0 = inactive only",
            "schema": {
              "example": 1,
              "type": "number",
              "enum": [
                0,
                1
              ]
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "description": "Restrict to archived (true) or non-archived (false) stores",
            "schema": {
              "example": false,
              "type": "boolean"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "0 = stores only, 1 = warehouses only; omit for both",
            "schema": {
              "example": 0,
              "type": "number",
              "enum": [
                0,
                1
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List stores",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER",
          "Partner:ADSR"
        ]
      }
    },
    "/online-orders": {
      "get": {
        "operationId": "listOrders",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by order number, customer name, mobile, or channel order ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store IDs. Pass 0 (or omit) for all. Supports repeated query keys (`storeId=1&storeId=2`) or a comma-joined string (`storeId=1,2`).",
            "schema": {
              "type": "array",
              "items": {
                "type": "number"
              }
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by order type (0=Standard, 1=DineIn, 2=Delivery, 3=Takeaway, 4=Provider)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (0=Failed, 1=Active, 2=Done, 3=Cancelled)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "description": "Filter by customer ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "From date (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "To date (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List online orders",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "post": {
        "description": "Creates the order and notifies the store in realtime, exactly as the backoffice new-order screen does.",
        "operationId": "createOrder",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOnlineOrderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create an online order",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/online-orders/{id}": {
      "get": {
        "operationId": "getOrder",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get an online order",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/online-orders/{id}/status": {
      "get": {
        "description": "Status values: `new`, `preparing`, `ready`, `completed`, `cancelled` — the same buckets the backoffice order counters use.",
        "operationId": "getOrderStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get the current status of an online order",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    }
  },
  "info": {
    "title": "LithosPOS ONLINE ORDER API",
    "description": "Menu synchronisation and order injection for online ordering platforms: read the catalogue and menus, create customers and orders, and follow order status.\n\nAuthenticate with an app access token from `POST /api/v2/developer/token` (OAuth2 client credentials). Call every path below against `https://api-v2.lithospos.com/v1` — one gateway host for both sandbox and production, with the token itself selecting the environment and the merchant. The `api_base_url` in the token response is authoritative: prefer it over this document if the two differ.",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [
    {
      "url": "https://api-v2.lithospos.com/v1",
      "description": "Global API gateway — same host for sandbox and production; the token response api_base_url is authoritative"
    }
  ],
  "components": {
    "securitySchemes": {
      "appToken": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {
      "PartnerCreateCustomerDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Customer name",
            "maxLength": 150
          },
          "mobile": {
            "type": "string",
            "description": "Mobile number",
            "maxLength": 40
          },
          "email": {
            "type": "string",
            "description": "Email address",
            "maxLength": 65
          },
          "loyaltyNo": {
            "type": "string",
            "description": "Loyalty number",
            "maxLength": 20
          },
          "trn": {
            "type": "string",
            "description": "Tax Registration Number",
            "maxLength": 20
          },
          "countryId": {
            "type": "number",
            "description": "Country ID",
            "default": 0
          },
          "stateId": {
            "type": "number",
            "description": "State ID",
            "default": 0
          },
          "state": {
            "type": "string",
            "description": "State name",
            "maxLength": 45
          },
          "address": {
            "type": "string",
            "description": "Address"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "creditCust": {
            "type": "number",
            "description": "Credit customer flag",
            "default": 0
          },
          "creditLimit": {
            "type": "number",
            "description": "Credit limit"
          },
          "opening": {
            "type": "number",
            "description": "Opening balance"
          },
          "loyaltyPoint": {
            "type": "number",
            "description": "Loyalty points",
            "default": 0
          },
          "birthDate": {
            "type": "string",
            "description": "Birth date (YYYY-MM-DD)"
          },
          "anniversary": {
            "type": "string",
            "description": "Anniversary date (YYYY-MM-DD)"
          },
          "firebaseUserId": {
            "type": "string",
            "description": "Firebase user ID",
            "maxLength": 200
          },
          "latitude": {
            "type": "number",
            "description": "Latitude"
          },
          "longitude": {
            "type": "number",
            "description": "Longitude"
          },
          "landmark": {
            "type": "string",
            "description": "Landmark"
          },
          "ZIP": {
            "type": "string",
            "description": "ZIP code",
            "maxLength": 45
          },
          "StoreId": {
            "type": "number",
            "description": "Store ID",
            "default": 0
          },
          "TaxExempt": {
            "type": "number",
            "description": "Tax exempt flag",
            "default": 0
          }
        },
        "required": [
          "name"
        ]
      },
      "PartnerUpdateCustomerDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Customer name",
            "maxLength": 150
          },
          "mobile": {
            "type": "string",
            "description": "Mobile number",
            "maxLength": 40
          },
          "email": {
            "type": "string",
            "description": "Email address",
            "maxLength": 65
          },
          "loyaltyNo": {
            "type": "string",
            "description": "Loyalty number",
            "maxLength": 20
          },
          "trn": {
            "type": "string",
            "description": "Tax Registration Number",
            "maxLength": 20
          },
          "countryId": {
            "type": "number",
            "description": "Country ID",
            "default": 0
          },
          "stateId": {
            "type": "number",
            "description": "State ID",
            "default": 0
          },
          "state": {
            "type": "string",
            "description": "State name",
            "maxLength": 45
          },
          "address": {
            "type": "string",
            "description": "Address"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "creditCust": {
            "type": "number",
            "description": "Credit customer flag",
            "default": 0
          },
          "creditLimit": {
            "type": "number",
            "description": "Credit limit"
          },
          "opening": {
            "type": "number",
            "description": "Opening balance"
          },
          "loyaltyPoint": {
            "type": "number",
            "description": "Loyalty points",
            "default": 0
          },
          "birthDate": {
            "type": "string",
            "description": "Birth date (YYYY-MM-DD)"
          },
          "anniversary": {
            "type": "string",
            "description": "Anniversary date (YYYY-MM-DD)"
          },
          "firebaseUserId": {
            "type": "string",
            "description": "Firebase user ID",
            "maxLength": 200
          },
          "latitude": {
            "type": "number",
            "description": "Latitude"
          },
          "longitude": {
            "type": "number",
            "description": "Longitude"
          },
          "landmark": {
            "type": "string",
            "description": "Landmark"
          },
          "ZIP": {
            "type": "string",
            "description": "ZIP code",
            "maxLength": 45
          },
          "StoreId": {
            "type": "number",
            "description": "Store ID",
            "default": 0
          },
          "TaxExempt": {
            "type": "number",
            "description": "Tax exempt flag",
            "default": 0
          }
        }
      },
      "CreateOnlineOrderItemDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number"
          },
          "item": {
            "type": "string"
          },
          "qty": {
            "type": "number"
          },
          "rate": {
            "type": "number"
          },
          "note": {
            "type": "string"
          },
          "variantId": {
            "type": "number",
            "description": "Variant master ID (0 for standard items)"
          },
          "itemModifiers": {
            "description": "Modifier group IDs selected on this line",
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "modifiers": {
            "type": "array",
            "description": "Selected modifier items"
          }
        },
        "required": [
          "id",
          "item",
          "qty",
          "rate"
        ]
      },
      "CreateOnlineOrderDto": {
        "type": "object",
        "properties": {
          "storeId": {
            "type": "number",
            "description": "Store the order belongs to"
          },
          "items": {
            "description": "Cart line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateOnlineOrderItemDto"
            }
          },
          "orderType": {
            "type": "number",
            "description": "2 = takeout, 3 = delivery",
            "enum": [
              2,
              3
            ]
          },
          "status": {
            "type": "number",
            "description": "0 = draft, 1 = new/confirmed (default)"
          },
          "customerId": {
            "type": "number"
          },
          "customerName": {
            "type": "string"
          },
          "customerPhone": {
            "type": "string"
          },
          "subtotal": {
            "type": "number"
          },
          "taxAmount": {
            "type": "number"
          },
          "cessAmount": {
            "type": "number",
            "description": "Total cess amount across the cart"
          },
          "tipAmount": {
            "type": "number"
          },
          "tipPercent": {
            "type": "number"
          },
          "totalAmount": {
            "type": "number"
          },
          "note": {
            "type": "string"
          },
          "takenBy": {
            "type": "string",
            "description": "Who took the order (free text)"
          },
          "cartList": {
            "type": "array",
            "description": "Rich v3 POS-style CartList payload. When provided, persisted verbatim into onlineOrders.CartList; the simpler `items` field is ignored."
          }
        },
        "required": [
          "storeId",
          "items"
        ]
      }
    }
  }
}
