{
  "openapi": "3.1.0",
  "info": {
    "title": "Clopos Open API v2",
    "description": "The **Clopos Open API v2** provides secure and unified access to the Clopos ecosystem, enabling seamless integration of POS, ordering, payments, and restaurant management services.",
    "contact": {
      "email": "dev@clopos.com"
    },
    "version": "2.0.0",
    "license": {
      "name": ""
    }
  },
  "servers": [
    {
      "url": "https://integrations.clopos.com/open-api/v2",
      "description": "**Base Url**"
    }
  ],
  "security": [
    {
      "xToken": []
    }
  ],
  "paths": {
    "/auth": {
      "post": {
        "summary": "Generate access token",
        "description": "Exchange client credentials for a short-lived JWT token used in the `x-token` header.",
        "tags": ["Authentication"],
        "operationId": "authV2",
        "security": [],
        "requestBody": {
          "description": "API credentials",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token generated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/venues": {
      "get": {
        "summary": "List Venues",
        "description": "Retrieve a list of all venues (locations).",
        "tags": ["Venues"],
        "responses": {
          "200": {
            "description": "Venues retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VenuesResponse"
                }
              }
            }
          }
        }
      }
    },
    "/users": {
      "get": {
        "summary": "List Users",
        "description": "Retrieve a list of all users.",
        "tags": ["Users"],
        "responses": {
          "200": {
            "description": "Users retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsersResponse"
                }
              }
            }
          }
        }
      }
    },
    "/users/{id}": {
      "get": {
        "summary": "Get User by ID",
        "description": "Retrieve a specific user by their unique identifier.",
        "tags": ["Users"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "User not found."
          }
        }
      }
    },
    "/customers": {
      "get": {
        "summary": "List customers",
        "description": "Retrieve all customers with pagination, filtering, and relationship inclusion",
        "tags": ["Customers"],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination (1-based)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of customers to return per page (1-999)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 999,
              "default": 50
            }
          },
          {
            "name": "with[]",
            "in": "query",
            "description": "Include related data in the response. Supported values: group",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["group"]
              }
            },
            "style": "form",
            "explode": true
          },
          {
            "name": "filters",
            "in": "query",
            "description": "Filter customers by specific fields. Use array notation: filters[0][0]=field_name&filters[0][1]=value. Supported fields: name, phones, group_id",
            "schema": {
              "type": "array",
              "items": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "style": "form",
            "explode": false
          }
        ],
        "responses": {
          "200": {
            "description": "Customers retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomersResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create customer",
        "description": "Create a new customer with contact information and group assignment",
        "tags": ["Customers"],
        "requestBody": {
          "description": "Customer details",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomerRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Customer created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateCustomerResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error - missing required fields or invalid data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict - duplicate unique field (code, phone, or cid)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/customers/{id}": {
      "get": {
        "summary": "Get Customer by ID",
        "description": "Retrieve a specific customer by their unique identifier.",
        "tags": ["Customers"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Customer ID",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Customer retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Customer"
                }
              }
            }
          },
          "404": {
            "description": "Customer not found."
          }
        }
      }
    },
    "/customer-groups": {
      "get": {
        "summary": "List Customer Groups",
        "description": "Retrieve a list of all customer groups with pagination support.",
        "tags": ["Customers"],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination (starts at 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of customer groups to return per page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Customer groups retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerGroupsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/categories": {
      "get": {
        "summary": "List categories",
        "description": "Retrieve menu categories with optional hierarchy, type and status filters",
        "tags": ["Menu"],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination (starts at 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of categories to return per page (1-999)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 999,
              "default": 50
            }
          },
          {
            "name": "parent_id",
            "in": "query",
            "description": "Filter to categories under a specific parent ID",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by category type",
            "schema": {
              "type": "string",
              "enum": ["PRODUCT", "INGREDIENT", "ACCOUNTING"]
            }
          },
          {
            "name": "include_children",
            "in": "query",
            "description": "Include nested child categories in the response",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "include_inactive",
            "in": "query",
            "description": "Whether to include inactive categories",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Categories retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoriesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/categories/{id}": {
      "get": {
        "summary": "Get category by ID",
        "description": "Retrieve a single menu category with optional hierarchy metadata",
        "tags": ["Menu"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Category ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_children",
            "in": "query",
            "description": "Include nested child categories in the response",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Category retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryResponse"
                }
              }
            }
          },
          "404": {
            "description": "Category not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/stations": {
      "get": {
        "summary": "List stations",
        "description": "Retrieve all preparation and service stations for the venue",
        "tags": ["Stations"],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filter by station status",
            "schema": {
              "type": "integer",
              "enum": [0, 1]
            }
          },
          {
            "name": "can_print",
            "in": "query",
            "description": "Filter stations that can print order tickets",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination (starts at 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of stations to return per page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stations retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StationsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/stations/{id}": {
      "get": {
        "summary": "Get station by ID",
        "description": "Retrieve a single preparation or service station",
        "tags": ["Stations"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Station ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Station retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StationResponse"
                }
              }
            }
          },
          "404": {
            "description": "Station not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/products": {
      "get": {
        "summary": "List products",
        "description": "Retrieve all products with optional filtering and pagination",
        "tags": ["Products"],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination (starts at 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of products to return (1-100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "filters",
            "in": "query",
            "description": "JSON-stringified filter array. Each filter is an array of [field, value] or [field, operator, value]. Example: [[\"type\", \"PRODUCT\"]]",
            "schema": {
              "type": "string",
              "example": "[[\"type\",\"PRODUCT\"]]"
            }
          },
          {
            "name": "selects",
            "in": "query",
            "description": "Comma-separated list of fields to include in the response. The fields id, name, and type are always included.",
            "schema": {
              "type": "string",
              "example": "id,name,type,price,image"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Products retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/products/{id}": {
      "get": {
        "summary": "Get product by ID",
        "description": "Retrieve a single product by ID",
        "tags": ["Products"],
        "operationId": "getProductV2",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Product ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/products/stop-list": {
      "get": {
        "summary": "Get stop list",
        "description": "Retrieve stop list data for specific products. The stop list indicates product limitations such as stock limits.",
        "tags": ["Products"],
        "parameters": [
          {
            "name": "filters[0][0]",
            "in": "query",
            "description": "Filter field name. Use 'id' to filter by product ID.",
            "schema": {
              "type": "string",
              "example": "id"
            }
          },
          {
            "name": "filters[0][1]",
            "in": "query",
            "description": "Array of product IDs to filter",
            "schema": {
              "type": "array",
              "items": {
                "type": "integer"
              }
            },
            "style": "form",
            "explode": true
          }
        ],
        "responses": {
          "200": {
            "description": "Stop list retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StopListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid filter parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sale-types": {
      "get": {
        "summary": "List Sale Types",
        "description": "Retrieve a list of all available sale types.",
        "tags": ["Sales"],
        "responses": {
          "200": {
            "description": "Sale types retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SaleType"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/payment-methods": {
      "get": {
        "summary": "List Payment Methods",
        "description": "Retrieve a list of all configured payment methods.",
        "tags": ["Sales"],
        "responses": {
          "200": {
            "description": "Payment methods retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PaymentMethod"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/price-lists": {
      "get": {
        "summary": "List Price Lists",
        "description": "Retrieve all price lists. A price list is a named set of product prices that can be applied to specific venues or sales channels (for example, a separate menu price list for delivery).",
        "tags": ["Price Lists"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of price lists to return per page (1-999).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 999,
              "default": 50
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sort the results. Supported fields: id, name, created_at. Use array notation, e.g. sort[0][0]=name&sort[0][1]=asc.",
            "schema": {
              "type": "array",
              "items": {
                "type": "array",
                "items": { "type": "string" }
              }
            },
            "style": "form",
            "explode": false
          },
          {
            "name": "with[]",
            "in": "query",
            "description": "Include related data in the response. Supported values: prices.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["prices"]
              }
            },
            "style": "form",
            "explode": true
          },
          {
            "name": "selects",
            "in": "query",
            "description": "Comma-separated list of fields to include in the response.",
            "schema": {
              "type": "string",
              "example": "id,name,status"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Price lists retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceListsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/price-lists/prices": {
      "get": {
        "summary": "List Prices",
        "description": "Retrieve the individual product prices that belong to price lists. Each entry maps a product to its price within a given price list.",
        "tags": ["Price Lists"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of prices to return per page (1-999).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 999,
              "default": 50
            }
          },
          {
            "name": "filters",
            "in": "query",
            "description": "Filter prices by specific fields. Use array notation: filters[0][0]=field_name&filters[0][1]=value. Supported fields: id, product_id, list_id.",
            "schema": {
              "type": "array",
              "items": {
                "type": "array",
                "items": { "type": "string" }
              }
            },
            "style": "form",
            "explode": false
          },
          {
            "name": "with[]",
            "in": "query",
            "description": "Include related data in the response. Supported values: product, list.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["product", "list"]
              }
            },
            "style": "form",
            "explode": true
          }
        ],
        "responses": {
          "200": {
            "description": "Prices retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceListPricesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders": {
      "get": {
        "summary": "List orders",
        "description": "Retrieve orders with optional filtering and pagination",
        "tags": ["Orders"],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of orders to return (1-100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by order status",
            "schema": {
              "type": "string",
              "enum": ["PENDING", "RECEIVED", "IGNORE", "DELIVERED"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Orders retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrdersResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create order",
        "description": "Create a new order using the streamlined v2 payload with flat schema, customer object, and products array.",
        "tags": ["Orders"],
        "requestBody": {
          "description": "Order details",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateOrderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid order data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/orders/{id}": {
      "get": {
        "summary": "Get order by ID",
        "description": "Retrieve a specific order by its unique identifier",
        "tags": ["Orders"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Order ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "with[0]",
            "in": "query",
            "description": "Include related resources. Supported: receipt:id,service_notification_id,status",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Order retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateOrderResponse"
                }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Update order",
        "description": "Update the status of an existing order (e.g. set to IGNORE to cancel)",
        "tags": ["Orders"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Order ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOrderStatus"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderStatusResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/receipts": {
      "get": {
        "summary": "List receipts",
        "description": "Retrieve receipts with filtering, sorting, and pagination options.",
        "tags": ["Receipts"],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number for pagination (starts at 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of receipts to return per page (1-200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "sort[0]",
            "in": "query",
            "description": "Primary sort field",
            "schema": {
              "type": "string",
              "default": "created_at"
            }
          },
          {
            "name": "sort[1]",
            "in": "query",
            "description": "Primary sort direction (1 = ascending, -1 = descending)",
            "schema": {
              "type": "integer",
              "enum": [1, -1],
              "default": -1
            }
          },
          {
            "name": "date[0]",
            "in": "query",
            "description": "Start date (inclusive) in YYYY-MM-DD format",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date[1]",
            "in": "query",
            "description": "End date (inclusive) in YYYY-MM-DD format",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Receipts retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/receipts/{id}": {
      "get": {
        "summary": "Get receipt by ID",
        "description": "Retrieve a single receipt by its identifier.",
        "tags": ["Receipts"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Receipt ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Receipt retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptResponse"
                }
              }
            }
          },
          "404": {
            "description": "Receipt not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update receipt",
        "description": "Update specific fields of an existing receipt. Only provided fields will be updated. Can update receipts even after they are closed.",
        "tags": ["Receipts"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Receipt ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReceiptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Receipt updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid field values",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Receipt not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/receipts/{id}/close": {
      "post": {
        "summary": "Close receipt",
        "description": "Close an existing receipt by updating its payment methods and setting the closing timestamp.",
        "tags": ["Receipts"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Receipt ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloseReceiptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Receipt closed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CloseReceiptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error - closed_at must be greater than created_at",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Receipt not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/receipts/{id}/stock-operations": {
      "get": {
        "summary": "Get receipt stock operations",
        "description": "Retrieve the stock deduction operations generated by a receipt (\"Çıxarılan ehtiyat\"). Returns only the stock write-offs caused by the receipt itself, where `operation_id` is `null` and `receipt_product_id` is set. Each item reports the quantity and cost movement per stock and storage, together with the related product and storage details. Requires the `receipts:read` scope.",
        "tags": ["Receipts"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Receipt ID",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stock operations retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptStockOperationsResponse"
                }
              }
            }
          },
          "404": {
            "description": "Receipt not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/stock": {
      "get": {
        "summary": "List Stock",
        "description": "Current stock levels, grouped by product.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Stock" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/stock/total": {
      "get": {
        "summary": "Stock Totals",
        "description": "Aggregate stock value and quantity for the current filters.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/StockTotalResponse" }
              }
            }
          }
        }
      }
    },
    "/stock/info": {
      "get": {
        "summary": "Stock Info",
        "description": "Summary information about stock across storages.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": { "type": "object" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/stock/product": {
      "get": {
        "summary": "Stock by Product",
        "description": "Stock rows resolved per product rather than per storage row.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Stock" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/stock/product-group": {
      "get": {
        "summary": "Stock by Product Group",
        "description": "Stock aggregated by product group. Proxies to client-api `stock/productGroup`.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Stock" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/stock/{id}": {
      "get": {
        "summary": "Get Stock by ID",
        "description": "Retrieve a single stock row.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/Stock" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Stock row ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/stock-operations": {
      "get": {
        "summary": "List Stock Operations",
        "description": "Every stock movement: supplies, waste, transfers and the deductions receipts cause.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/StockOperation" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/stock-operations/total": {
      "get": {
        "summary": "Stock Operation Totals",
        "description": "Aggregate quantity and cost for the current filters.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/StockOperationTotalResponse" }
              }
            }
          }
        }
      }
    },
    "/stock-operations/products": {
      "get": {
        "summary": "Stock Operations by Product",
        "description": "Per-product view of stock movement. Proxies to client-api `stock-operations/follow/products`.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/StockOperation" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/stock-operations/{id}": {
      "get": {
        "summary": "Get Stock Operation by ID",
        "description": "Retrieve a single stock movement.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/StockOperation" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Stock operation ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/storages": {
      "get": {
        "summary": "List Storages",
        "description": "Storage locations stock is tracked against.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Storage" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/storages/{id}": {
      "get": {
        "summary": "Get Storage by ID",
        "description": "Retrieve a single storage.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/Storage" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Storage ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/suppliers": {
      "get": {
        "summary": "List Suppliers",
        "description": "Suppliers goods are purchased from.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Supplier" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/suppliers/total": {
      "get": {
        "summary": "Supplier Totals",
        "description": "Aggregate spend and balance across suppliers.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SupplierTotalResponse" }
              }
            }
          }
        }
      }
    },
    "/suppliers/{id}": {
      "get": {
        "summary": "Get Supplier by ID",
        "description": "Retrieve a single supplier.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/Supplier" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Supplier ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/operations": {
      "get": {
        "summary": "List Operations",
        "description": "Inventory documents: supply, waste, transfer, produce and inventory checks.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Operation" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/operations/total": {
      "get": {
        "summary": "Operation Totals",
        "description": "Aggregate subtotal for the current filters.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OperationTotalResponse" }
              }
            }
          }
        }
      }
    },
    "/operations/statuses": {
      "get": {
        "summary": "Operation Statuses",
        "description": "The status vocabulary, with localised display names.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "integer" },
                          "name": { "type": "string" },
                          "display_name": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/operations/{id}": {
      "get": {
        "summary": "Get Operation by ID",
        "description": "Retrieve a single inventory document.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/Operation" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Operation ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/operations/{id}/items": {
      "get": {
        "summary": "Get Operation Items",
        "description": "Line items belonging to one operation.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/OperationItem" }
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Operation ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/operation-items": {
      "get": {
        "summary": "List Operation Items",
        "description": "Operation line items across all documents.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/OperationItem" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/operation-items/total": {
      "get": {
        "summary": "Operation Item Totals",
        "description": "Aggregate quantity and cost for the current filters. Sending with[]=group_by_storage_id returns one row per storage instead.",
        "tags": ["Inventory"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    { "$ref": "#/components/schemas/OperationItemTotalResponse" },
                    { "$ref": "#/components/schemas/OperationItemTotalByStorageResponse" }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/finance/categories": {
      "get": {
        "summary": "List Finance Categories",
        "description": "Categories money movements are classified under.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/FinanceCategory" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/categories/{id}": {
      "get": {
        "summary": "Get Finance Category by ID",
        "description": "Retrieve a single finance category.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/FinanceCategory" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Finance category ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/finance/balances": {
      "get": {
        "summary": "List Balances",
        "description": "Cash and bank accounts with their current balance.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/FinanceBalance" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/balances/list": {
      "get": {
        "summary": "Balance List",
        "description": "Condensed account list for selectors.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/FinanceBalance" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/balances/date-states": {
      "get": {
        "summary": "Balance Date States",
        "description": "Per-date balance states across the requested range.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "array",
                      "items": { "type": "object" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/balances/customer": {
      "get": {
        "summary": "Customer Balances",
        "description": "Balances held against customers.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "array",
                      "items": { "type": "object" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/balances/transactions": {
      "get": {
        "summary": "Balance Transactions",
        "description": "Transactions grouped by account. Proxies to client-api `finance/balance/transaction`.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/FinanceTransaction" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/balances/{id}": {
      "get": {
        "summary": "Get Balance by ID",
        "description": "Retrieve a single account.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/FinanceBalance" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Balance ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/finance/transactions": {
      "get": {
        "summary": "List Transactions",
        "description": "Money movements in and out of accounts.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/FinanceTransaction" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/transactions/{id}": {
      "get": {
        "summary": "Get Transaction by ID",
        "description": "Retrieve a single transaction.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/FinanceTransaction" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Transaction ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/finance/taxes": {
      "get": {
        "summary": "List Taxes",
        "description": "Tax rates configured for the brand.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/FinanceTax" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/taxes/types": {
      "get": {
        "summary": "Tax Types",
        "description": "The tax type vocabulary. Proxies to client-api `finance/tax/types`.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "integer" },
                          "name": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/taxes/report": {
      "get": {
        "summary": "Tax Report",
        "description": "Tax report over the requested period. Proxies to client-api `finance/tax/report`.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": {
                      "type": "array",
                      "items": { "type": "object" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/taxes/total": {
      "get": {
        "summary": "Tax Totals",
        "description": "Aggregate tax amounts. Proxies to client-api `finance/tax/total`.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TaxTotalResponse" }
              }
            }
          }
        }
      }
    },
    "/finance/taxes/{id}": {
      "get": {
        "summary": "Get Tax by ID",
        "description": "Retrieve a single tax rate.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/FinanceTax" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Tax ID",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    },
    "/finance/cash-shifts": {
      "get": {
        "summary": "List Cash Shifts",
        "description": "Till sessions opened and closed on terminals.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/CashShift" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/finance/cash-shifts/{id}": {
      "get": {
        "summary": "Get Cash Shift by ID",
        "description": "Retrieve a single cash shift. The identifier is a UUID.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/CashShift" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Cash shift UUID",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ]
      }
    },
    "/finance/cash-shifts/{id}/report": {
      "get": {
        "summary": "Cash Shift Report",
        "description": "Sales, refunds and cash in/out totals for one shift.",
        "tags": ["Finance"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data": { "type": "object" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Cash shift UUID",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ]
      }
    },
    "/receipts/cid/{cid}": {
      "get": {
        "summary": "Get Receipt by CID",
        "description": "Retrieve a receipt by the `cid` UUID terminals key it by. Returns the same payload as retrieving it by numeric id.",
        "tags": ["Receipts"],
        "responses": {
          "200": {
            "description": "Request completed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "example": true },
                    "data": { "$ref": "#/components/schemas/Receipt" }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "cid",
            "in": "path",
            "description": "Receipt CID (UUID)",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ReceiptStockStorage": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "description": "Storage identifier." },
          "name": { "type": "string", "description": "Storage name." }
        }
      },
      "ReceiptStockOperationStock": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "description": "Stock identifier." },
          "storage": { "$ref": "#/components/schemas/ReceiptStockStorage" }
        }
      },
      "ReceiptStockOperationProduct": {
        "type": "object",
        "description": "Related product. Present even if the product was soft-deleted.",
        "properties": {
          "id": { "type": "integer", "description": "Product identifier." },
          "name": { "type": "string", "description": "Product name." }
        },
        "additionalProperties": true
      },
      "ReceiptStockOperation": {
        "type": "object",
        "description": "A single stock write-off generated by the receipt.",
        "properties": {
          "id": { "type": "integer", "description": "Stock operation identifier." },
          "receipt_id": { "type": "integer", "description": "Receipt identifier the operation belongs to." },
          "receipt_product_id": { "type": ["integer", "null"], "description": "Receipt product line that produced the write-off." },
          "product_id": { "type": "integer", "description": "Product identifier." },
          "stock_id": { "type": "integer", "description": "Stock identifier affected by the operation." },
          "storage_id": { "type": "integer", "description": "Storage identifier the stock belongs to." },
          "quantity": { "type": "number", "description": "Quantity deducted from stock." },
          "before_quantity": { "type": "number", "description": "Stock quantity before the operation." },
          "after_quantity": { "type": "number", "description": "Stock quantity after the operation." },
          "cost": { "type": "number", "description": "Unit cost applied to the deduction." },
          "before_cost": { "type": "number", "description": "Stock cost before the operation." },
          "total_cost": { "type": "number", "description": "Total cost of the deducted quantity." },
          "operated_at": { "type": "string", "description": "Timestamp when the operation was applied (YYYY-MM-DD HH:mm:ss)." },
          "product": { "$ref": "#/components/schemas/ReceiptStockOperationProduct" },
          "stock": { "$ref": "#/components/schemas/ReceiptStockOperationStock" }
        }
      },
      "ReceiptStockOperationsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "description": "Stock deduction operations caused by the receipt itself (operation_id is null and receipt_product_id is set).",
            "items": { "$ref": "#/components/schemas/ReceiptStockOperation" }
          }
        }
      },
      "AuthRequest": {
        "type": "object",
        "required": ["client_id", "client_secret", "brand", "integrator_id"],
        "properties": {
          "client_id": {
            "type": "string",
            "description": "Your client ID issued by Clopos",
            "example": "your_client_id_here"
          },
          "client_secret": {
            "type": "string",
            "description": "Secret paired with the client",
            "example": "your_client_secret_here"
          },
          "brand": {
            "type": "string",
            "description": "Brand identifier",
            "example": "your_brand"
          },
          "integrator_id": {
            "type": "string",
            "description": "Integrator ID. New in v2 — identifies the integrator making the request. Request one via https://forms.gle/Y9P1Wnv4QFAruxny8",
            "example": "your_integrator_id_here"
          }
        },
        "example": {
          "client_id": "your_client_id_here",
          "client_secret": "your_client_secret_here",
          "brand": "your_brand",
          "integrator_id": "your_integrator_id_here"
        }
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "token": {
            "type": "string",
            "description": "JWT access token for API requests",
            "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
          },
          "token_type": {
            "type": "string",
            "description": "Token type",
            "example": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "description": "Token expiration time in seconds",
            "example": 3600
          },
          "expires_at": {
            "type": "integer",
            "description": "Unix timestamp when the token becomes invalid",
            "example": 1767852332
          },
          "message": {
            "type": "string",
            "example": "Authentication successful"
          }
        },
        "example": {
          "success": true,
          "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
          "token_type": "Bearer",
          "expires_in": 3600,
          "expires_at": 1767852332,
          "message": "Authentication successful"
        }
      },
      "CreateOrderRequest": {
        "type": "object",
        "required": ["sale_type_id", "venue_id", "customer", "products"],
        "properties": {
          "auto_accept_terminal": {
            "type": "integer",
            "description": "Terminal ID that auto-accepts the order",
            "example": 1
          },
          "auto_order_accept": {
            "type": "boolean",
            "description": "Auto-accept the order",
            "default": false
          },
          "auto_order_sent_to_station": {
            "type": "boolean",
            "description": "Auto-send to stations after acceptance",
            "default": false
          },
          "sale_type_id": {
            "type": "integer",
            "description": "Sale type to use",
            "example": 2
          },
          "venue_id": {
            "type": "integer",
            "description": "Venue where the order belongs",
            "example": 1
          },
          "delivery_fee": {
            "type": "number",
            "description": "Delivery charge to apply",
            "example": 2.5
          },
          "comment": {
            "type": "string",
            "description": "Free text note for the order",
            "example": "Leave at the door"
          },
          "customer": {
            "$ref": "#/components/schemas/OrderCustomer"
          },
          "discount": {
            "type": "object",
            "description": "Order-level discount",
            "properties": {
              "discount_type": {
                "type": "integer",
                "description": "Discount type",
                "default": 0
              },
              "discount_value": {
                "type": "number",
                "description": "Discount value",
                "default": 0
              }
            }
          },
          "service_charge": {
            "type": "object",
            "description": "Service charge settings",
            "properties": {
              "enabled": {
                "type": "boolean",
                "default": false
              },
              "value": {
                "type": "number",
                "default": 0
              }
            }
          },
          "products": {
            "type": "array",
            "description": "List of products in the order",
            "items": {
              "$ref": "#/components/schemas/OrderProduct"
            },
            "minItems": 1
          }
        },
        "example": {
          "auto_accept_terminal": 1,
          "auto_order_accept": true,
          "auto_order_sent_to_station": true,
          "sale_type_id": 2,
          "venue_id": 1,
          "delivery_fee": 2.5,
          "customer": {
            "id": 9,
            "phone": "+994705401040",
            "address": "123 Main St",
            "customer_discount_type": 1,
            "name": "Rahid Akhundzada"
          },
          "comment": "Leave at the door",
          "discount": {
            "discount_type": 1,
            "discount_value": 10
          },
          "service_charge": {
            "enabled": true,
            "value": 5
          },
          "products": [
            {
              "product_id": 101,
              "product_name": "Pizza",
              "count": 2,
              "price": 8.5,
              "status": "new",
              "product_hash": "abc123",
              "portion_size": 1,
              "modifiers": [
                {
                  "modifier_id": 501,
                  "modifier_name": "Extra Cheese",
                  "count": 1,
                  "price": 0.5,
                  "portion_size": 1
                }
              ]
            }
          ]
        }
      },
      "OrderCustomer": {
        "type": "object",
        "description": "Customer information for the order",
        "required": ["id", "phone", "address", "name"],
        "properties": {
          "id": {
            "type": "integer",
            "description": "Customer ID",
            "example": 9
          },
          "phone": {
            "type": "string",
            "description": "Customer phone number",
            "example": "+994705401040"
          },
          "address": {
            "type": "string",
            "description": "Delivery address",
            "example": "123 Main St"
          },
          "customer_discount_type": {
            "type": "integer",
            "description": "Customer discount type"
          },
          "name": {
            "type": "string",
            "description": "Customer name",
            "example": "Rahid Akhundzada"
          }
        }
      },
      "OrderProduct": {
        "type": "object",
        "required": ["product_id", "product_name", "count", "price", "status", "product_hash"],
        "properties": {
          "product_id": {
            "type": "integer",
            "description": "Product identifier",
            "example": 101
          },
          "product_name": {
            "type": "string",
            "description": "Display name of the product",
            "example": "Pizza"
          },
          "count": {
            "type": "integer",
            "description": "Quantity",
            "example": 2
          },
          "price": {
            "type": "number",
            "description": "Unit price",
            "example": 8.5
          },
          "status": {
            "type": "string",
            "description": "Product status",
            "example": "new"
          },
          "product_hash": {
            "type": "string",
            "description": "Product hash identifier",
            "example": "abc123"
          },
          "portion_size": {
            "type": "number",
            "description": "Portion size",
            "default": 1
          },
          "modifiers": {
            "type": "array",
            "description": "List of modifiers for the product",
            "default": [],
            "items": {
              "$ref": "#/components/schemas/OrderModifier"
            }
          }
        }
      },
      "OrderModifier": {
        "type": "object",
        "required": ["modifier_id", "modifier_name", "count"],
        "properties": {
          "modifier_id": {
            "type": "integer",
            "description": "Modifier identifier",
            "example": 501
          },
          "modifier_name": {
            "type": "string",
            "description": "Display name of the modifier",
            "example": "Extra Cheese"
          },
          "count": {
            "type": "integer",
            "description": "Quantity",
            "example": 1
          },
          "price": {
            "type": "number",
            "description": "Modifier price",
            "default": 0,
            "example": 0.5
          },
          "portion_size": {
            "type": "number",
            "description": "Portion size",
            "default": 1
          }
        }
      },
      "CreateOrderResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "message": { "type": "string" },
          "data": {
            "type": "object",
            "properties": {
              "status": { "type": "string", "example": "PENDING" },
              "payload": {
                "type": "object",
                "properties": {
                  "updated_at": { "type": "string", "format": "date-time" },
                  "created_at": { "type": "string", "format": "date-time" },
                  "id": { "type": "integer" },
                  "venue_id": { "type": "integer" }
                }
              }
            }
          }
        },
        "example": {
          "success": true,
          "message": "Order created",
          "data": {
            "status": "PENDING",
            "payload": {
              "updated_at": "2026-01-08T06:28:23.000000Z",
              "created_at": "2026-01-08T06:28:23.000000Z",
              "id": 295,
              "venue_id": 1
            }
          }
        }
      },
      "UpdateOrderStatus": {
        "type": "object",
        "required": ["status"],
        "properties": {
          "status": {
            "type": "string",
            "description": "Set to IGNORE to cancel the order",
            "enum": ["IGNORE"],
            "example": "IGNORE"
          }
        }
      },
      "OrderStatusResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "object",
            "properties": {
              "id": { "type": "integer" },
              "status": { "type": "string" }
            }
          },
          "timestamp": { "type": "string" },
          "unix": { "type": "integer" }
        },
        "example": {
          "success": true,
          "data": { "id": 108, "status": "IGNORE" },
          "timestamp": "2025-10-23 14:13:09",
          "unix": 1761211989
        }
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "customer_id": { "type": "string" },
          "status": {
            "type": "string",
            "enum": ["PENDING", "RECEIVED", "IGNORE", "DELIVERED"]
          },
          "total_amount": { "type": "number", "format": "decimal" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "OrdersResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Order" }
          },
          "pagination": { "$ref": "#/components/schemas/Pagination" }
        }
      },
      "CloseReceiptRequest": {
        "type": "object",
        "required": ["payment_methods"],
        "properties": {
          "payment_methods": {
            "type": "array",
            "description": "List of payment methods with amounts",
            "items": {
              "$ref": "#/components/schemas/PaymentMethodEntry"
            },
            "minItems": 1
          },
          "closed_at": {
            "type": "string",
            "description": "Closing timestamp. Defaults to current time if omitted. Format: YYYY-MM-DD HH:mm:ss",
            "example": "2025-11-07 09:59:54"
          }
        },
        "example": {
          "payment_methods": [
            { "id": 2, "name": "Cash", "amount": 8.14 }
          ],
          "closed_at": "2025-11-07 09:59:54"
        }
      },
      "CloseReceiptResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "message": { "type": "string" },
          "data": {
            "type": "object",
            "properties": {
              "id": { "type": "integer" },
              "closed_at": { "type": "string" },
              "payment_methods": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/PaymentMethodEntry" }
              }
            }
          }
        },
        "example": {
          "success": true,
          "message": "Receipt closed",
          "data": {
            "id": 10950,
            "closed_at": "2025-11-07 09:59:54",
            "payment_methods": [
              { "id": 2, "name": "Cash", "amount": 8.14 }
            ]
          }
        }
      },
      "UpdateReceiptRequest": {
        "type": "object",
        "properties": {
          "order_status": {
            "type": "string",
            "enum": ["NEW", "SCHEDULED", "IN_PROGRESS", "READY", "PICKED_UP", "COMPLETED", "CANCELLED"],
            "description": "Order status"
          },
          "order_number": {
            "type": "string",
            "description": "Order number identifier"
          },
          "fiscal_id": {
            "type": "string",
            "description": "Fiscal receipt identifier"
          },
          "lock": {
            "type": "boolean",
            "description": "Lock status of the receipt"
          }
        },
        "example": {
          "order_status": "NEW",
          "order_number": "RPO-00001",
          "fiscal_id": "Twrewr89fnscvj22",
          "lock": false
        }
      },
      "Product": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "type": {
            "type": "string",
            "enum": ["GOODS", "DISH", "TIMER", "PREPARATION", "INGREDIENT", "MODIFICATION"]
          },
          "name": { "type": "string" },
          "full_name": { "type": "string" },
          "status": { "type": "integer" },
          "price": { "type": "number" },
          "cost_price": { "type": "number" },
          "has_modifications": { "type": "boolean" },
          "modifications": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Modification" }
          },
          "modificator_groups": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ModificatorGroup" }
          },
          "recipe": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/RecipeItem" }
          },
          "packages": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Package" }
          },
          "setting": { "$ref": "#/components/schemas/TimerSetting", "nullable": true },
          "taxes": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Tax" }
          },
          "tags": {
            "type": "array",
            "items": { "type": "object" }
          },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "ProductsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Product" }
          },
          "pagination": { "$ref": "#/components/schemas/Pagination" }
        }
      },
      "StopListResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/StopListEntry" }
          }
        },
        "required": ["success", "data"]
      },
      "StopListEntry": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "limit": { "type": "integer" },
          "timestamp": { "type": "integer" }
        },
        "required": ["id", "limit", "timestamp"]
      },
      "Modification": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "parent_id": { "type": "integer" },
          "type": { "type": "string", "enum": ["MODIFICATION"] },
          "name": { "type": "string" },
          "price": { "type": "number" },
          "cost_price": { "type": "number" },
          "barcode": { "type": "string", "nullable": true },
          "full_name": { "type": "string" },
          "status": { "type": "integer" }
        }
      },
      "Modificator": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "price": { "type": "number" },
          "cost_price": { "type": "number" },
          "max_count": { "type": "integer" },
          "status": { "type": "boolean" },
          "ingredient": { "$ref": "#/components/schemas/Product", "nullable": true }
        }
      },
      "ModificatorGroup": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "type": { "type": "integer" },
          "min_select": { "type": "integer" },
          "max_select": { "type": "integer" },
          "modificators": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Modificator" }
          }
        }
      },
      "RecipeItem": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "type": { "type": "string", "enum": ["PREPARATION", "INGREDIENT", "DISH"] },
          "name": { "type": "string" },
          "cost_price": { "type": "number" },
          "pivot": {
            "type": "object",
            "properties": {
              "gross": { "type": "string" }
            }
          }
        }
      },
      "TimerSetting": {
        "type": "object",
        "properties": {
          "interval": { "type": "integer" },
          "prices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "price": { "type": "number" },
                "from": { "type": "integer" }
              }
            }
          }
        }
      },
      "Package": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "equal": { "type": "integer" }
        }
      },
      "Tax": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "rate": { "type": "number" }
        }
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "parent_id": { "type": "integer", "nullable": true },
          "name": { "type": "string" },
          "slug": { "type": "string", "nullable": true },
          "type": { "type": "string", "enum": ["PRODUCT", "INGREDIENT", "ACCOUNTING"] },
          "color": { "type": "string" },
          "status": { "type": "integer" },
          "depth": { "type": "integer" },
          "_lft": { "type": "integer" },
          "_rgt": { "type": "integer" },
          "properties": { "type": "object" },
          "children": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Category" }
          },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "CategoriesResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Category" }
          },
          "total": { "type": "integer" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string", "format": "date-time" },
          "unix": { "type": "integer" }
        }
      },
      "CategoryResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": { "$ref": "#/components/schemas/Category" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string", "format": "date-time" },
          "unix": { "type": "integer" }
        }
      },
      "Station": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "status": { "type": "integer" },
          "can_print": { "type": "boolean" },
          "reminder_enabled": { "type": "boolean" },
          "description": { "type": "string" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "StationsResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Station" }
          },
          "total": { "type": "integer" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string", "format": "date-time" }
        }
      },
      "StationResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": { "$ref": "#/components/schemas/Station" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string", "format": "date-time" }
        }
      },
      "Customer": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string" },
          "group_id": { "type": "integer" },
          "balance": { "$ref": "#/components/schemas/Balance" },
          "cashback_balance": { "$ref": "#/components/schemas/CashbackBalance" },
          "group": { "$ref": "#/components/schemas/CustomerGroup" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "CreateCustomerRequest": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string", "example": "John Doe" },
          "email": { "type": "string", "format": "email", "example": "john.doe@example.com" },
          "phone": { "type": "string", "example": "+15551234567" },
          "code": { "type": "string", "example": "CUST001" },
          "cid": { "type": "string", "format": "uuid", "example": "0f9654bc-9520-43d7-8109-317d9820f54c" },
          "description": { "type": "string", "example": "Test Customer" },
          "group_id": { "type": "integer", "example": 1 },
          "gender": { "type": "integer", "nullable": true, "example": 1 },
          "date_of_birth": { "type": "string", "format": "date", "example": "1990-05-15" }
        }
      },
      "CreateCustomerResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": { "$ref": "#/components/schemas/Customer" },
          "message": { "type": "string" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string", "format": "date-time" },
          "unix": { "type": "integer" }
        }
      },
      "CustomerGroup": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "discount_type": { "type": "string", "nullable": true },
          "discount_value": { "type": "number" },
          "system_type": { "type": "string" },
          "total_amount": { "type": "number", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" },
          "deleted_at": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "CustomerGroupsResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CustomerGroup" }
          },
          "total": { "type": "integer" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string" },
          "sorts": {
            "type": "array",
            "items": { "type": "string" }
          },
          "unix": { "type": "integer" }
        }
      },
      "CustomersResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Customer" }
          },
          "pagination": { "$ref": "#/components/schemas/Pagination" }
        }
      },
      "Balance": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "amount": { "type": "number" },
          "type": { "type": "string" }
        }
      },
      "CashbackBalance": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "nullable": true },
          "amount": { "type": "number" },
          "type": { "type": "string" }
        }
      },
      "SaleType": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "system_type": { "type": "string", "nullable": true },
          "channel": { "type": "string" },
          "service_charge_rate": { "type": "number", "nullable": true },
          "payment_method": { "$ref": "#/components/schemas/PaymentMethod", "nullable": true }
        }
      },
      "PaymentMethod": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "customer_required": { "type": "integer" },
          "is_system": { "type": "integer" },
          "balance": { "$ref": "#/components/schemas/Balance", "nullable": true }
        }
      },
      "PaymentMethodEntry": {
        "type": "object",
        "required": ["id", "name", "amount"],
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "amount": { "type": "number" }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "email": { "type": "string", "format": "email", "nullable": true },
          "username": { "type": "string" },
          "first_name": { "type": "string", "nullable": true },
          "last_name": { "type": "string", "nullable": true },
          "status": { "type": "boolean" },
          "owner": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "UsersResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/User" }
          },
          "total": { "type": "integer" }
        }
      },
      "Venue": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "is_main": { "type": "integer" }
        }
      },
      "VenuesResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Venue" }
          }
        }
      },
      "Receipt": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "venue_id": { "type": "integer" },
          "cid": { "type": "string" },
          "user_id": { "type": "integer" },
          "terminal_id": { "type": "integer" },
          "source": { "type": "string" },
          "customer_id": { "type": ["integer", "null"] },
          "sale_type_id": { "type": "integer" },
          "guests": { "type": "integer" },
          "status": { "type": "integer" },
          "lock": { "type": "boolean" },
          "total": { "type": "number" },
          "subtotal": { "type": "number" },
          "payment_methods": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PaymentMethodEntry" }
          },
          "fiscal_id": { "type": ["string", "null"] },
          "discount_type": { "type": "integer" },
          "discount_value": { "type": "number" },
          "service_charge": { "type": "number" },
          "delivery_fee": { "type": "number" },
          "order_status": { "type": ["string", "null"] },
          "order_number": { "type": ["string", "null"] },
          "created_at": { "type": "string" },
          "updated_at": { "type": "string" },
          "closed_at": { "type": ["string", "null"] },
          "deleted_at": { "type": ["string", "null"] }
        }
      },
      "ReceiptsResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Receipt" }
          },
          "total": { "type": "integer" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string" },
          "unix": { "type": "integer" }
        }
      },
      "ReceiptResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "data": { "$ref": "#/components/schemas/Receipt" },
          "message": { "type": "string" },
          "time": { "type": "integer" },
          "timestamp": { "type": "string" },
          "unix": { "type": "integer" }
        }
      },
      "PriceList": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "status": { "type": "boolean" },
          "prices": {
            "type": "array",
            "description": "Included only when requested via with[]=prices.",
            "items": { "$ref": "#/components/schemas/PriceListPrice" }
          },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "PriceListsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PriceList" }
          },
          "pagination": { "$ref": "#/components/schemas/Pagination" }
        }
      },
      "PriceListPrice": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "list_id": { "type": "integer" },
          "product_id": { "type": "integer" },
          "price": { "type": "number" },
          "product": {
            "description": "Included only when requested via with[]=product.",
            "allOf": [{ "$ref": "#/components/schemas/Product" }],
            "nullable": true
          },
          "list": {
            "description": "Included only when requested via with[]=list.",
            "allOf": [{ "$ref": "#/components/schemas/PriceList" }],
            "nullable": true
          }
        }
      },
      "PriceListPricesResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PriceListPrice" }
          },
          "pagination": { "$ref": "#/components/schemas/Pagination" }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": { "type": "integer" },
          "per_page": { "type": "integer" },
          "total": { "type": "integer" },
          "total_pages": { "type": "integer" }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error", "message"],
        "properties": {
          "error": { "type": "string" },
          "message": { "type": "string" },
          "details": { "type": "object" }
        }
      },
      "Stock": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "venue_id": { "type": "integer" },
          "product_id": { "type": "integer" },
          "storage_id": { "type": "integer" },
          "reserved": { "type": "number", "description": "Quantity reserved by open receipts." },
          "origin": { "type": "string", "nullable": true, "description": "What created the stock row." },
          "origin_id": { "type": "integer", "nullable": true },
          "cost": { "type": "number", "description": "Unit cost." },
          "quantity": { "type": "number", "description": "Quantity currently on hand." }
        }
      },
      "StockOperation": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "venue_id": { "type": "integer" },
          "stock_id": { "type": "integer" },
          "reserved": { "type": "number" },
          "receipt_id": { "type": "integer", "nullable": true },
          "receipt_product_id": { "type": "integer", "nullable": true },
          "product_id": { "type": "integer" },
          "modificator_id": { "type": "integer", "nullable": true },
          "operation_id": { "type": "integer", "nullable": true },
          "operation_item_id": { "type": "integer", "nullable": true },
          "parent_id": { "type": "integer", "nullable": true },
          "unit_id": { "type": "integer", "nullable": true },
          "quantity": { "type": "number" },
          "before_quantity": { "type": "number" },
          "after_quantity": { "type": "number" },
          "before": { "type": "number" },
          "after": { "type": "number" },
          "cost": { "type": "number" },
          "before_cost": { "type": "number" },
          "total_cost": { "type": "number" },
          "operated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Storage": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "venue_id": { "type": "integer" },
          "status": { "type": "boolean" },
          "name": { "type": "string" }
        }
      },
      "Supplier": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "balance_id": { "type": "integer", "nullable": true },
          "name": { "type": "string" },
          "phone": { "type": "string", "nullable": true },
          "description": { "type": "string", "nullable": true },
          "tin": { "type": "string", "nullable": true, "description": "Taxpayer identification number." },
          "spent": { "type": "number", "description": "Total spent with this supplier." }
        }
      },
      "Operation": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "user_id": { "type": "integer", "nullable": true },
          "venue_id": { "type": "integer" },
          "to_venue_id": { "type": "integer", "nullable": true },
          "supplier_id": { "type": "integer", "nullable": true },
          "supplier_remain": { "type": "number", "nullable": true },
          "storage_id": { "type": "integer", "nullable": true },
          "from_storage_id": { "type": "integer", "nullable": true },
          "type": {
            "type": "integer",
            "enum": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
            "description": "1 IN, 2 OUT (deprecated), 3 TRANSFER, 4 WASTE, 5 RETURN, 6 FIXATION (deprecated), 7 MAKE, 8 MERGE (deprecated), 9 INVENTORY_CHECK, 10 SUPPLY_RETURN, 11 INITIAL_STOCK."
          },
          "status": {
            "type": "integer",
            "enum": [1, 2],
            "description": "1 Published, 2 Draft."
          },
          "inventory_status": {
            "type": "integer",
            "enum": [0, 1, 2, 3, 4, 5, 6],
            "description": "0 NoAction, 1 Processed, 2 InProcess, 3 Restored, 4 Failed, 5 Deleting, 6 Canceling."
          },
          "force_apply": { "type": "boolean" },
          "parent_id": { "type": "integer", "nullable": true },
          "is_system": { "type": "boolean" },
          "returns_id": { "type": "integer", "nullable": true },
          "reason": { "type": "string", "nullable": true },
          "description": { "type": "string", "nullable": true },
          "invoice_number": { "type": "string", "nullable": true },
          "tax_rate": { "type": "number" },
          "discount_rate": { "type": "number" },
          "tax_value": { "type": "number" },
          "discount_value": { "type": "number" },
          "subtotal": { "type": "number" },
          "operated_at": { "type": "string", "format": "date-time" },
          "published_at": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "OperationItem": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "operation_id": { "type": "integer" },
          "product_id": { "type": "integer" },
          "stock_id": { "type": "integer", "nullable": true },
          "storage_id": { "type": "integer", "nullable": true },
          "unit_id": { "type": "integer", "nullable": true },
          "quantity": { "type": "number" },
          "unit_quantity": { "type": "number" },
          "before_quantity": { "type": "number" },
          "after_quantity": { "type": "number" },
          "expected_quantity": { "type": "number", "nullable": true },
          "total_quantity": { "type": "number" },
          "difference_quantity": { "type": "number", "nullable": true },
          "difference_cost": { "type": "number", "nullable": true },
          "waste_cost": { "type": "number", "nullable": true },
          "total_cost": { "type": "number" },
          "cost": { "type": "number" },
          "unit_cost": { "type": "number" },
          "tax_rate": { "type": "number" },
          "discount_rate": { "type": "number" },
          "tax_value": { "type": "number" },
          "discount_value": { "type": "number" },
          "subtotal": { "type": "number" },
          "comment": { "type": "string", "nullable": true },
          "operated_at": { "type": "string", "format": "date-time" }
        }
      },
      "FinanceCategory": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "type": { "type": "string", "description": "Category direction, e.g. IN or OUT." },
          "hide": { "type": "boolean" },
          "position": { "type": "integer" }
        }
      },
      "FinanceBalance": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "venue_id": { "type": "integer" },
          "system_type": { "type": "string", "nullable": true },
          "name": { "type": "string" },
          "type": { "type": "string", "description": "Account type, e.g. CASH or BANK." },
          "amount": { "type": "number", "description": "Current balance." },
          "position": { "type": "integer" }
        }
      },
      "FinanceTransaction": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "venue_id": { "type": "integer" },
          "cid": { "type": "string", "nullable": true },
          "group": { "type": "string", "nullable": true },
          "type": { "type": "string", "description": "IN or OUT." },
          "account_type": { "type": "string", "nullable": true },
          "indicator": { "type": "boolean" },
          "category_id": { "type": "integer", "nullable": true },
          "user_id": { "type": "integer", "nullable": true },
          "operation_id": { "type": "integer", "nullable": true },
          "receipt_id": { "type": "integer", "nullable": true },
          "sale_type_id": { "type": "integer", "nullable": true },
          "customer_id": { "type": "integer", "nullable": true },
          "supplier_id": { "type": "integer", "nullable": true },
          "payment_method_id": { "type": "integer", "nullable": true },
          "terminal_id": { "type": "integer", "nullable": true },
          "returns_id": { "type": "integer", "nullable": true },
          "staff_id": { "type": "integer", "nullable": true },
          "balance_id": { "type": "integer", "nullable": true },
          "from_balance_id": { "type": "integer", "nullable": true },
          "amount": { "type": "number" },
          "before_amount": { "type": "number" },
          "after_amount": { "type": "number" },
          "description": { "type": "string", "nullable": true },
          "service_name": { "type": "string", "nullable": true },
          "service_ref_id": { "type": "string", "nullable": true },
          "operated_at": { "type": "string", "format": "date-time" },
          "shift_date": { "type": "string", "format": "date", "nullable": true },
          "accounting_period": { "type": "string", "format": "date", "nullable": true }
        }
      },
      "CashShift": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid", "description": "Cash shifts key on a UUID, not an integer." },
          "venue_id": { "type": "integer" },
          "cid": { "type": "string", "nullable": true },
          "shift_no": { "type": "integer" },
          "terminal_id": { "type": "integer", "nullable": true },
          "opened_by_user_id": { "type": "integer", "nullable": true },
          "closed_by_user_id": { "type": "integer", "nullable": true },
          "initial_amount": { "type": "number" },
          "closed_amount": { "type": "number", "nullable": true },
          "opening_diff": { "type": "number", "nullable": true },
          "diff": { "type": "number", "nullable": true },
          "status": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "accounting_day_opened_at": { "type": "string", "format": "date", "nullable": true },
          "accounting_day_closed_at": { "type": "string", "format": "date", "nullable": true },
          "opened_at": { "type": "string", "format": "date-time" },
          "closed_at": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "FinanceTax": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "name": { "type": "string" },
          "rate": { "type": "number" },
          "priority": { "type": "integer", "nullable": true },
          "type": { "type": "integer", "description": "1 excl_tax (added to price), 2 incl_tax (included in price)." }
        }
      },
      "StockTotalResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "total_cost": { "type": "number", "description": "Summed stock value." },
                "storage_id": { "type": "integer", "description": "Present only with group_by=storage_id." }
              }
            },
            "description": "A single row, or one row per storage when group_by=storage_id is sent."
          }
        }
      },
      "StockOperationTotalResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "total_quantity": { "type": "number", "description": "SUM(after_quantity) - SUM(before_quantity)." }
              }
            }
          }
        }
      },
      "SupplierTotalResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": {
            "type": "object",
            "properties": {
              "debt": { "type": "number", "description": "Sum of negative supplier balances." },
              "balance": { "type": "number", "description": "Sum of positive supplier balances." },
              "total": { "type": "number", "description": "debt + balance." }
            }
          }
        }
      },
      "OperationTotalResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "total_cost": { "type": "number" },
                "total_count": { "type": "integer" }
              }
            }
          }
        }
      },
      "OperationItemTotalResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": {
            "type": "object",
            "properties": {
              "total_cost": { "type": "number" }
            }
          }
        }
      },
      "OperationItemTotalByStorageResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "storage_id": { "type": "integer" },
                "storage_name": { "type": "string", "nullable": true },
                "total_cost": { "type": "number" }
              }
            },
            "description": "Returned when with[]=group_by_storage_id is sent."
          }
        }
      },
      "TaxTotalResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": {
            "type": "object",
            "properties": {
              "used_amount": { "type": "number" },
              "return_tax_amount": { "type": "number" },
              "used_count": { "type": "integer" }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "xToken": {
        "type": "apiKey",
        "in": "header",
        "name": "x-token",
        "description": "JWT access token obtained from /v2/auth endpoint"
      }
    }
  },
  "tags": [
    { "name": "Authentication" },
    { "name": "Venues" },
    { "name": "Users" },
    { "name": "Customers" },
    { "name": "Menu" },
    { "name": "Stations" },
    { "name": "Products" },
    { "name": "Price Lists" },
    { "name": "Sales" },
    { "name": "Orders" },
    { "name": "Receipts" },
    { "name": "Inventory" },
    { "name": "Finance" }
  ]
}