{
  "openapi": "3.0.0",
  "paths": {
    "/stores": {
      "get": {
        "operationId": "listStores",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by name, code, or email",
            "schema": {
              "example": "Main Store",
              "type": "string"
            }
          },
          {
            "name": "isActive",
            "required": false,
            "in": "query",
            "description": "Filter by active status",
            "schema": {
              "example": true,
              "type": "boolean"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "1 = active only, 0 = inactive only",
            "schema": {
              "example": 1,
              "type": "number",
              "enum": [
                0,
                1
              ]
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "description": "Restrict to archived (true) or non-archived (false) stores",
            "schema": {
              "example": false,
              "type": "boolean"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "0 = stores only, 1 = warehouses only; omit for both",
            "schema": {
              "example": 0,
              "type": "number",
              "enum": [
                0,
                1
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List stores",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/business-summary": {
      "get": {
        "operationId": "businessSummaryReport",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Business summary report",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/items": {
      "get": {
        "operationId": "itemsReport",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sales by item report",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/pay-types": {
      "get": {
        "operationId": "payTypesReport",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sales by payment type report",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/sales": {
      "get": {
        "operationId": "salesList",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sales list",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/daily-sales": {
      "get": {
        "description": "One canonical row per calendar day. Field semantics (ported from the V1 ADSR summary):\n- `grossSales` — taxable + voucher + taxes + cess + rounding + KFC + charges + tips + item charges + all discounts (the pre-discount bill value).\n- `discountAmount` — the gross-to-net delta: bill and item discounts plus the rounding adjustment.\n- `refundAmount` — value refunded through sales returns, on the same net basis.\n- `taxAmount` — sale tax (tax1 + tax2 + cess + KFC + item-charge tax) net of tax refunded on returns.\n- `netSales` — `grossSales - discountAmount - refundAmount`, exactly.\n- `transactionCount` — sale invoices for the day; returns are counted in `refundAmount`, not here.\nVoided sales (`Avoid = 1`) are excluded. Maximum window: 31 days.",
        "operationId": "dailySales",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "description": "First day of the feed window (YYYY-MM-DD)",
            "schema": {
              "example": "2026-07-01",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "description": "Last day of the feed window (YYYY-MM-DD), inclusive. Maximum span: 31 days.",
            "schema": {
              "example": "2026-07-31",
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "hourly",
            "required": false,
            "in": "query",
            "description": "Include 24 hourly buckets per day.",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "ADSR daily sales feed",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    }
  },
  "info": {
    "title": "LithosPOS ADSR API",
    "description": "Automated daily sales reporting for malls and landlords: the canonical daily-sales feed plus the reports and store directory it is reconciled against.\n\nAuthenticate with an app access token from `POST /api/v2/developer/token` (OAuth2 client credentials). Call every path below against `https://api-v2.lithospos.com/v1` — one gateway host for both sandbox and production, with the token itself selecting the environment and the merchant. The `api_base_url` in the token response is authoritative: prefer it over this document if the two differ.",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [
    {
      "url": "https://api-v2.lithospos.com/v1",
      "description": "Global API gateway — same host for sandbox and production; the token response api_base_url is authoritative"
    }
  ],
  "components": {
    "securitySchemes": {
      "appToken": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {}
  }
}
