{
  "openapi": "3.1.0",
  "info": {
    "title": "Counterpoint Partner API",
    "version": "1.0.0",
    "summary": "Read catalog, stock, customers and sales, and record sales and webhooks.",
    "description": "# Counterpoint Partner API\n\nRead a shop's catalog, stock, customers and sales, and record sales, from your own software. Everything is JSON over HTTPS under `https://counterpoint-api.fly.dev/v1`. The Partner API is part of the **Scale** plan.\n\n## Authentication\n\nCreate a key in the back office under **Setup → Developer** and send it as a bearer token:\n\n```\nAuthorization: Bearer cp_live_<id>_<secret>\n```\n\nThe key is shown once when created; Counterpoint stores only a hash, so a lost key is revoked and replaced. A missing, malformed, unknown or revoked key all answer the same `401`, so the API cannot be used to learn which keys exist.\n\nEach key carries **scopes** and nothing is implied: `catalog:write` does not grant `catalog:read`. A route needs the one scope named on it; a key without it gets `403` naming the missing scope. Scopes: `catalog:read`, `catalog:write`, `inventory:read`, `customers:read`, `customers:write`, `sales:read`, `sales:write`, `reports:read`, `webhooks:manage`.\n\n## Test keys and live keys\n\nA key is either **live** (`cp_live_…`) or **test** (`cp_test_…`), and the environment is part of the credential: a test key does not work as a live one.\n\nA test key reads real shop data, which is what makes it useful while you build. Every write (`POST /products`, `POST /customers`, `POST /sales`, `POST /webhooks`, `DELETE /webhooks/{id}`) is **validated in full and answered with the result it would have produced, but nothing is saved**. The response carries `\"dryRun\": true` and the header `X-Counterpoint-Dry-Run: 1`. No record is created, no stock moves, no receipt number is used up, and no webhook is sent for it. The id and receipt number in a dry-run response are real-looking previews and do not exist afterwards.\n\nBecause a test key never registers an endpoint, test webhook delivery by registering the endpoint with a live key (or from **Setup → Developer**) and acting in a shop you are free to experiment in.\n\n## Rate limits\n\nEach key has a per-minute budget (default 120, up to 6000 on request) in fixed clock-aligned one-minute windows. Every authenticated response carries:\n\n- `X-RateLimit-Limit`: requests allowed per window\n- `X-RateLimit-Remaining`: requests left in this window\n- `X-RateLimit-Reset`: Unix time when the window resets\n\nOver the limit you get `429` with `Retry-After` (seconds). Failed requests (including `403`) count against the limit.\n\n## Errors\n\nErrors are JSON and always carry a `correlationId`. Quote it when you contact support: it finds the request in our logs.\n\n```json\n{ \"statusCode\": 403, \"message\": \"This key is missing the sales:read scope\", \"error\": \"Forbidden\", \"correlationId\": \"7f3a…\" }\n```\n\nA body that fails validation answers `400` with `{ \"formErrors\": [...], \"fieldErrors\": { \"field\": [\"reason\"] }, \"correlationId\": \"…\" }`. A plan that does not include the Partner API (or a suspended account attempting a write) answers `402`.\n\n## Pagination\n\nList endpoints return a plain JSON array by default. For `GET /v1/sales`, set `paginate=true&limit=200` to receive `{sales,nextCursor}`. Pass `nextCursor` as `cursor` until it is null. There is no total history cap. Optional `since` is an inclusive ISO creation timestamp and must stay unchanged across pages. Sales are ordered by creation time and ID, newest first. New arrivals during a walk are picked up on the next sync. Save checkpoints only after the whole walk succeeds, overlap time windows and upsert by sale ID. Webhooks provide prompt events; pagination recovers missed new sales. Refunds or changes to older sales require their corresponding events or reconciliation reads. Legacy calls without pagination parameters still return the latest `limit` sales (default 50, maximum 200).\n\n## Money and times\n\nMoney is a decimal **string** (`\"136.80\"`), never a float. Times are ISO 8601 in UTC.\n\n## Idempotency\n\n`POST /v1/sales` is idempotent: send an `idempotencyKey` and a retry returns the original sale instead of a second one. `POST /v1/products` is protected by the unique SKU, and `POST /v1/webhooks` refuses a URL that is already registered. `POST /v1/customers` is not idempotent: a retry creates another customer, so do not blindly retry it after a timeout.\n\n## Webhooks\n\nRegister an endpoint with `POST /v1/webhooks` (or in **Setup → Developer**) and Counterpoint will POST a JSON envelope to it when an event you subscribed to happens:\n\n```json\n{ \"event\": \"sale.created\", \"createdAt\": \"2026-10-06T09:41:12.000Z\", \"data\": { … } }\n```\n\nEach delivery carries `x-counterpoint-event` (the event name) and `x-counterpoint-delivery` (a unique id, stable across retries: use it to ignore duplicates). Respond with any `2xx` within 5 seconds. Anything else, or a timeout, is retried up to 6 attempts in total with exponential back-off (5s, 15s, 45s, 135s, … capped at 30 minutes). After 10 consecutive failures the endpoint is switched off, not deleted; the merchant sees why in the back office and can switch it back on. Events are queued in the same transaction as the thing they describe, so you are never told about a sale that was rolled back. Events from test keys are never delivered. Delivery order is not guaranteed across retries.\n\n### Verifying a signature\n\nEvery delivery is signed with the endpoint's secret (`whsec_…`, shown once at registration). The header is:\n\n```\nx-counterpoint-signature: t=<unix seconds>,v1=<hex>\n```\n\n`v1` is the lowercase hex HMAC-SHA256, keyed by the secret, of the string `\"<t>.<raw request body>\"`. The timestamp is inside the signed text, so a captured request cannot be replayed with a fresh timestamp. Reject deliveries whose `t` is more than 300 seconds from your clock. Compute over the **raw bytes** you received, before parsing, and compare in constant time.\n\nNode.js:\n\n```js\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\n// `rawBody` must be the exact bytes Counterpoint sent, as a string. Verify BEFORE you\n// JSON.parse, because re-serialising changes the bytes and the signature with them.\nexport function verifyCounterpointWebhook(secret, rawBody, signatureHeader, toleranceSeconds = 300) {\n  const parts = new Map(\n    String(signatureHeader ?? '')\n      .split(',')\n      .map((part) => part.trim().split('='))\n      .filter((pair) => pair.length === 2),\n  );\n  const timestamp = Number(parts.get('t'));\n  const presented = parts.get('v1');\n  if (!Number.isFinite(timestamp) || !presented) return false;\n\n  // Refuse stale signatures so a captured request cannot be replayed later.\n  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;\n\n  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest();\n  const actual = Buffer.from(presented, 'hex');\n  return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n\n// Express:\n//   app.post('/hooks', express.raw({ type: 'application/json' }), (req, res) => {\n//     const body = req.body.toString('utf8');\n//     if (!verifyCounterpointWebhook(process.env.WHSEC, body, req.get('x-counterpoint-signature'))) {\n//       return res.sendStatus(400);\n//     }\n//     const event = JSON.parse(body);\n//     res.sendStatus(200);\n//   });\n```\n\nPython:\n\n```python\nimport hashlib\nimport hmac\nimport time\n\n\ndef verify_counterpoint_webhook(secret: str, raw_body: bytes, signature_header: str,\n                                tolerance_seconds: int = 300) -> bool:\n    \"\"\"raw_body must be the exact bytes Counterpoint sent. Verify before parsing JSON.\"\"\"\n    parts = dict(\n        part.strip().split(\"=\", 1)\n        for part in (signature_header or \"\").split(\",\")\n        if \"=\" in part\n    )\n    try:\n        timestamp = int(parts[\"t\"])\n        presented = parts[\"v1\"]\n    except (KeyError, ValueError):\n        return False\n\n    # Refuse stale signatures so a captured request cannot be replayed later.\n    if abs(time.time() - timestamp) > tolerance_seconds:\n        return False\n\n    signed = str(timestamp).encode() + b\".\" + raw_body\n    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, presented)\n\n\n# Flask:\n#   @app.post(\"/hooks\")\n#   def hook():\n#       sig = request.headers.get(\"x-counterpoint-signature\")\n#       if not verify_counterpoint_webhook(WHSEC, request.get_data(), sig):\n#           return \"\", 400\n#       event = request.get_json()\n#       return \"\", 200\n```\n"
  },
  "servers": [
    {
      "url": "https://counterpoint-api.fly.dev",
      "description": "Counterpoint API"
    }
  ],
  "tags": [
    {
      "name": "Meta",
      "description": "Who you are, and this document."
    },
    {
      "name": "Catalog"
    },
    {
      "name": "Inventory"
    },
    {
      "name": "Customers"
    },
    {
      "name": "Sales"
    },
    {
      "name": "Reports"
    },
    {
      "name": "Webhooks",
      "description": "Manage the endpoints that receive events."
    },
    {
      "name": "Webhook events",
      "description": "What Counterpoint sends to your endpoint."
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/v1/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "tags": [
          "Meta"
        ],
        "summary": "This document",
        "description": "The OpenAPI 3.1 description of this API. Public: no key needed. Cacheable for five minutes and served with an `ETag`.\n\nNo key needed.",
        "security": [],
        "responses": {
          "200": {
            "description": "The OpenAPI document.",
            "headers": {
              "Cache-Control": {
                "description": "public, max-age=300",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenApiDocument"
                },
                "example": {
                  "openapi": "3.1.0",
                  "info": {
                    "title": "Counterpoint Partner API"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/openapi.json"
          }
        ]
      }
    },
    "/v1/whoami": {
      "get": {
        "operationId": "whoami",
        "tags": [
          "Meta"
        ],
        "summary": "What this key is and may do",
        "description": "Call this first. It returns the key's name, whether it is live or test, the scopes it holds and its rate limit, so a missing scope is discovered here rather than by being refused by the endpoint that needed it. Needs `catalog:read`, the narrowest scope a key can usefully hold.\n\nRequires scope `catalog:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "catalog:read",
        "responses": {
          "200": {
            "description": "The key's identity and permissions.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Whoami"
                },
                "example": {
                  "keyName": "Stock feed",
                  "keyId": "a1b2c3d4e5f6",
                  "live": true,
                  "scopes": [
                    "catalog:read",
                    "inventory:read"
                  ],
                  "rateLimitPerMinute": 120,
                  "availableScopes": [
                    {
                      "key": "catalog:read",
                      "description": "Read products, categories, brands and suppliers"
                    },
                    {
                      "key": "catalog:write",
                      "description": "Create and update products"
                    }
                  ],
                  "availableEvents": [
                    {
                      "key": "sale.created",
                      "description": "A sale was recorded"
                    },
                    {
                      "key": "refund.created",
                      "description": "A refund was issued"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/whoami \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      }
    },
    "/v1/products": {
      "get": {
        "operationId": "listProducts",
        "tags": [
          "Catalog"
        ],
        "summary": "List products",
        "description": "Every product, ordered by name. With no `view` you get what can be sold: archived products and variant parents are left out. `view=catalog` returns parent products (variants are counted in `variantCount`, not listed) and adds `cost`, `supplierId`, `brandId` and `archivedAt`.\n\nRequires scope `catalog:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "catalog:read",
        "parameters": [
          {
            "name": "view",
            "in": "query",
            "required": false,
            "description": "`sellable` (default) or `catalog`.",
            "schema": {
              "type": "string",
              "enum": [
                "sellable",
                "catalog"
              ],
              "default": "sellable"
            },
            "example": "catalog"
          }
        ],
        "responses": {
          "200": {
            "description": "The products.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatalogProduct"
                  }
                },
                "example": [
                  {
                    "id": "9c1e5f2a-3b4d-4e6f-8a7b-1c2d3e4f5a6b",
                    "sku": "TSHIRT-BLK-M",
                    "name": "Black tee, medium",
                    "unitPrice": "120.00",
                    "type": "standard",
                    "variantCount": 0,
                    "barcode": "6221234567891"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://counterpoint-api.fly.dev/v1/products?view=catalog\" \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      },
      "post": {
        "operationId": "createProduct",
        "tags": [
          "Catalog"
        ],
        "summary": "Create a product",
        "description": "Adds a standard product. The SKU must be unique in the shop. Queues a `product.created` webhook (not for a test key). Subject to the plan's product limit.\n\nRequires scope `catalog:write`.\n\n**Test keys.** A key created as a test key (`cp_test_…`) can read real data but cannot change any. This call is validated exactly as for a live key and answers with the response it would have produced, plus `\"dryRun\": true` and the header `X-Counterpoint-Dry-Run: 1`. Nothing is saved: no record, no stock movement, no receipt number consumed, and no webhook sent.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "catalog:write",
        "x-dry-run-with-test-key": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProductRequest"
              },
              "example": {
                "sku": "TSHIRT-BLK-M",
                "name": "Black tee, medium",
                "unitPrice": "120.00",
                "barcode": "6221234567891"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new product.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Counterpoint-Dry-Run": {
                "description": "Set to `1` when a test key made this call and nothing was saved.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "1"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/CreatedProduct"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "dryRun": {
                          "type": "boolean",
                          "const": true,
                          "description": "Present and true only when a test key made the call: validated, answered, nothing saved."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "id": "9c1e5f2a-3b4d-4e6f-8a7b-1c2d3e4f5a6b",
                  "sku": "TSHIRT-BLK-M",
                  "name": "Black tee, medium",
                  "unitPrice": "120.00"
                }
              }
            }
          },
          "400": {
            "description": "The body is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ValidationError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "description": "The SKU already exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl -X POST https://counterpoint-api.fly.dev/v1/products \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"sku\":\"TSHIRT-BLK-M\",\"name\":\"Black tee, medium\",\"unitPrice\":\"120.00\"}'"
          }
        ]
      }
    },
    "/v1/categories": {
      "get": {
        "operationId": "listCategories",
        "tags": [
          "Catalog"
        ],
        "summary": "List categories",
        "description": "Product categories, with `parentId` for the tree.\n\nRequires scope `catalog:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "catalog:read",
        "responses": {
          "200": {
            "description": "The categories.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Category"
                  }
                },
                "example": [
                  {
                    "id": "3a5c7e9b-2d4f-4a6c-8e0b-1d3f5a7c9e2b",
                    "name": "Apparel",
                    "parentId": null
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/categories \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      }
    },
    "/v1/locations": {
      "get": {
        "operationId": "listLocations",
        "tags": [
          "Inventory"
        ],
        "summary": "List outlets",
        "description": "Active outlets (stores and warehouses). The `id` is what `locationId` means everywhere else.\n\nRequires scope `inventory:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "inventory:read",
        "responses": {
          "200": {
            "description": "The outlets.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Location"
                  }
                },
                "example": [
                  {
                    "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "name": "Zamalek",
                    "locationType": "store",
                    "numberingPrefix": "R-",
                    "city": "Cairo"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/locations \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      }
    },
    "/v1/inventory": {
      "get": {
        "operationId": "getInventory",
        "tags": [
          "Inventory"
        ],
        "summary": "Stock levels at one outlet",
        "description": "On-hand stock for every product at one outlet. Without `locationId` the first outlet is used, and the response names which one, so the answer is never silently \"one of your outlets\".\n\nRequires scope `inventory:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "inventory:read",
        "parameters": [
          {
            "name": "locationId",
            "in": "query",
            "required": false,
            "description": "An outlet id from `GET /v1/locations`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
          }
        ],
        "responses": {
          "200": {
            "description": "Stock at the chosen outlet.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InventoryResponse"
                },
                "example": {
                  "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "levels": [
                    {
                      "sku": "TSHIRT-BLK-M",
                      "name": "Black tee, medium",
                      "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                      "onHand": 14,
                      "barcode": "6221234567891"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://counterpoint-api.fly.dev/v1/inventory?locationId=0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      }
    },
    "/v1/customers": {
      "get": {
        "operationId": "listCustomers",
        "tags": [
          "Customers"
        ],
        "summary": "List customers",
        "description": "Every customer who is not archived, with balances and marketing consent, ordered by name. Archived customers stay out of this list. Their sales are unchanged.\n\nRequires scope `customers:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "customers:read",
        "responses": {
          "200": {
            "description": "The customers.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Customer"
                  }
                },
                "example": [
                  {
                    "id": "2f4a6c8e-1b3d-4f5a-9c7e-0a2b4c6d8e1f",
                    "code": "Mona-3F2A",
                    "name": "Mona Adel",
                    "phone": "+201001234567",
                    "email": "mona@example.com",
                    "onAccount": "no",
                    "creditLimit": null,
                    "storeCredit": "0.00",
                    "accountBalance": "0.00",
                    "customerGroup": null,
                    "loyaltyPoints": 0,
                    "marketing": {
                      "whatsapp": false,
                      "sms": false,
                      "email": true
                    },
                    "marketingChangedAt": {
                      "whatsapp": null,
                      "sms": null,
                      "email": "2026-10-01T10:00:00.000Z"
                    },
                    "address": null,
                    "notes": null,
                    "birthday": null,
                    "archivedAt": null
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/customers \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      },
      "post": {
        "operationId": "createCustomer",
        "tags": [
          "Customers"
        ],
        "summary": "Create a customer",
        "description": "Adds a customer. The `code` is generated. Marketing consent is opt-in per channel and defaults to off: only set a channel to `true` if the customer actually agreed.\n\nRequires scope `customers:write`.\n\n**Test keys.** A key created as a test key (`cp_test_…`) can read real data but cannot change any. This call is validated exactly as for a live key and answers with the response it would have produced, plus `\"dryRun\": true` and the header `X-Counterpoint-Dry-Run: 1`. Nothing is saved: no record, no stock movement, no receipt number consumed, and no webhook sent.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "customers:write",
        "x-dry-run-with-test-key": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomerRequest"
              },
              "example": {
                "name": "Mona Adel",
                "phone": "+201001234567",
                "email": "mona@example.com",
                "marketingEmail": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new customer.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Counterpoint-Dry-Run": {
                "description": "Set to `1` when a test key made this call and nothing was saved.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "1"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Customer"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "dryRun": {
                          "type": "boolean",
                          "const": true,
                          "description": "Present and true only when a test key made the call: validated, answered, nothing saved."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "id": "2f4a6c8e-1b3d-4f5a-9c7e-0a2b4c6d8e1f",
                  "code": "Mona-3F2A",
                  "name": "Mona Adel",
                  "phone": "+201001234567",
                  "email": "mona@example.com",
                  "onAccount": "no",
                  "creditLimit": null,
                  "storeCredit": "0.00",
                  "accountBalance": "0.00",
                  "customerGroup": null,
                  "loyaltyPoints": 0,
                  "marketing": {
                    "whatsapp": false,
                    "sms": false,
                    "email": true
                  },
                  "marketingChangedAt": {
                    "whatsapp": null,
                    "sms": null,
                    "email": "2026-10-01T10:00:00.000Z"
                  },
                  "address": null,
                  "notes": null,
                  "birthday": null,
                  "archivedAt": null
                }
              }
            }
          },
          "400": {
            "description": "The body is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ValidationError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl -X POST https://counterpoint-api.fly.dev/v1/customers \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Mona Adel\",\"email\":\"mona@example.com\"}'"
          }
        ]
      }
    },
    "/v1/sales": {
      "get": {
        "operationId": "listSales",
        "tags": [
          "Sales"
        ],
        "summary": "List sales, with optional cursor pagination",
        "description": "Sales ordered by creation time and ID, newest first. Set `paginate=true` for `{sales,nextCursor}`; pass `nextCursor` as `cursor` until null to walk all history. `cursor` or `since` also enables pagination. Keep the optional inclusive ISO creation timestamp `since` unchanged across pages. Without pagination parameters the legacy array is returned. Sale lines require `GET /v1/sales/{id}`. Newer arrivals are picked up on the next sync; overlap time windows and upsert by ID. Older-sale refunds require their events or reconciliation reads.\n\nRequires scope `sales:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "sales:read",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1 to 200, default 50. Invalid values are rejected in paginated mode; legacy calls clamp out-of-range values.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "example": 20
          },
          {
            "name": "paginate",
            "in": "query",
            "required": false,
            "description": "Return {sales,nextCursor} instead of the legacy array.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque nextCursor from the previous page. Enables pagination.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Inclusive ISO sale creation timestamp. Enables pagination; keep unchanged across pages.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Legacy array, or {sales,nextCursor} when pagination is enabled. nextCursor is null at the end.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Sale"
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "sales",
                        "nextCursor"
                      ],
                      "properties": {
                        "sales": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Sale"
                          }
                        },
                        "nextCursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Pass as cursor until null."
                        }
                      }
                    }
                  ]
                },
                "example": [
                  {
                    "id": "5b0f6a52-7f3a-4c8e-9a52-6d1f2f0f7e11",
                    "receiptNumber": "R-000412",
                    "currency": "EGP",
                    "subtotal": "120.00",
                    "tax": "16.80",
                    "total": "136.80",
                    "tender": "cash",
                    "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "createdAt": "2026-10-06T09:41:12.000Z",
                    "cashReceived": "150.00",
                    "changeDue": "13.20",
                    "taxDocumentRef": null,
                    "etaUuid": null,
                    "refundedTotal": "0.00",
                    "refunded": false
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Invalid pagination parameters or cursor.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ValidationError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://counterpoint-api.fly.dev/v1/sales?limit=20\" \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      },
      "post": {
        "operationId": "createSale",
        "tags": [
          "Sales"
        ],
        "summary": "Record a sale",
        "description": "Rings up a sale. Totals are computed server-side from the lines (and `discount`), so a client cannot understate them. Stock is decremented at the outlet, a gap-free receipt number is allocated and `sale.created` is queued.\n\n**Idempotent.** `idempotencyKey` (at least 8 characters, yours to generate) makes a retry safe: sending the same key again returns the original sale instead of recording a second one. Always send a stable key per logical sale and reuse it on retries.\n\nWithout `locationId` the shop's first active outlet is used. A cash sale needs an open cash drawer at that outlet.\n\nRequires scope `sales:write`.\n\n**Test keys.** A key created as a test key (`cp_test_…`) can read real data but cannot change any. This call is validated exactly as for a live key and answers with the response it would have produced, plus `\"dryRun\": true` and the header `X-Counterpoint-Dry-Run: 1`. Nothing is saved: no record, no stock movement, no receipt number consumed, and no webhook sent.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "sales:write",
        "x-dry-run-with-test-key": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSaleRequest"
              },
              "example": {
                "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                "currency": "EGP",
                "tender": "cash",
                "cashReceived": "150.00",
                "idempotencyKey": "order-48213-attempt",
                "lines": [
                  {
                    "sku": "TSHIRT-BLK-M",
                    "name": "Black tee, medium",
                    "unitPrice": "120.00",
                    "quantity": 1
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The sale. A replay of the same `idempotencyKey` returns the original.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Counterpoint-Dry-Run": {
                "description": "Set to `1` when a test key made this call and nothing was saved.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "1"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Sale"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "dryRun": {
                          "type": "boolean",
                          "const": true,
                          "description": "Present and true only when a test key made the call: validated, answered, nothing saved."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "id": "5b0f6a52-7f3a-4c8e-9a52-6d1f2f0f7e11",
                  "receiptNumber": "R-000412",
                  "currency": "EGP",
                  "subtotal": "120.00",
                  "tax": "16.80",
                  "total": "136.80",
                  "tender": "cash",
                  "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "createdAt": "2026-10-06T09:41:12.000Z",
                  "cashReceived": "150.00",
                  "changeDue": "13.20",
                  "taxDocumentRef": null,
                  "etaUuid": null,
                  "refundedTotal": "0.00",
                  "refunded": false
                }
              }
            }
          },
          "400": {
            "description": "The body is invalid, or the sale cannot be taken (for example not enough stock where the shop forbids selling below zero).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ValidationError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "description": "Cash sale with no open drawer at that outlet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl -X POST https://counterpoint-api.fly.dev/v1/sales \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"currency\":\"EGP\",\"tender\":\"cash\",\"idempotencyKey\":\"order-48213-attempt\",\"lines\":[{\"sku\":\"TSHIRT-BLK-M\",\"name\":\"Black tee, medium\",\"unitPrice\":\"120.00\",\"quantity\":1}]}'"
          }
        ]
      }
    },
    "/v1/sales/{id}": {
      "get": {
        "operationId": "getSale",
        "tags": [
          "Sales"
        ],
        "summary": "One sale, with its lines",
        "description": "A sale and the lines as they were sold: the unit price is what the customer was charged, not today's catalog price. The optional unitCost and costSource fields require reports:read in addition to sales:read; other keys do not receive them.\n\nRequires scope `sales:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "sales:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The sale id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "5b0f6a52-7f3a-4c8e-9a52-6d1f2f0f7e11"
          }
        ],
        "responses": {
          "200": {
            "description": "The sale.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaleDetail"
                },
                "example": {
                  "id": "5b0f6a52-7f3a-4c8e-9a52-6d1f2f0f7e11",
                  "receiptNumber": "R-000412",
                  "currency": "EGP",
                  "subtotal": "120.00",
                  "tax": "16.80",
                  "total": "136.80",
                  "tender": "cash",
                  "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "createdAt": "2026-10-06T09:41:12.000Z",
                  "cashReceived": "150.00",
                  "changeDue": "13.20",
                  "taxDocumentRef": null,
                  "etaUuid": null,
                  "refundedTotal": "0.00",
                  "refunded": false,
                  "lines": [
                    {
                      "sku": "TSHIRT-BLK-M",
                      "name": "Black tee, medium",
                      "quantity": 1,
                      "unitPrice": "120.00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "No such sale.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/sales/5b0f6a52-7f3a-4c8e-9a52-6d1f2f0f7e11 \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      }
    },
    "/v1/reports/summary": {
      "get": {
        "operationId": "getSalesSummary",
        "tags": [
          "Reports"
        ],
        "summary": "Sales summary",
        "description": "Headline figures across all sales. `netRevenue` is ex-VAT after refunds; `avgBasket` counts only sales that were not fully refunded. All money is a decimal string with two places.\n\nRequires scope `reports:read`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "reports:read",
        "responses": {
          "200": {
            "description": "The summary.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesSummary"
                },
                "example": {
                  "cogs": "30120.00",
                  "estimatedCostLines": 0,
                  "saleCount": 412,
                  "revenue": "58210.40",
                  "taxCollected": "7148.60",
                  "refunds": "640.00",
                  "netRevenue": "50421.80",
                  "grossRevenue": "57570.40",
                  "avgBasket": "122.38",
                  "fullyRefundedCount": 3,
                  "todayNetRevenue": "1830.00",
                  "todaySaleCount": 14,
                  "discounts": "2140.00",
                  "todayDiscounts": "96.50",
                  "todayDiscountedCount": 3
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/reports/summary \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      }
    },
    "/v1/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook endpoints",
        "description": "Registered endpoints and their health. The signing secret is never returned here.\n\nRequires scope `webhooks:manage`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "webhooks:manage",
        "responses": {
          "200": {
            "description": "The endpoints.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEndpoint"
                  }
                },
                "example": [
                  {
                    "id": "7d8e9f0a-1b2c-4d3e-8f4a-5b6c7d8e9f01",
                    "url": "https://partner.example.com/counterpoint",
                    "events": [
                      "sale.created",
                      "refund.created"
                    ],
                    "active": true,
                    "consecutiveFailures": 0,
                    "disabledReason": null,
                    "createdAt": "2026-10-01T10:00:00.000Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl https://counterpoint-api.fly.dev/v1/webhooks \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      },
      "post": {
        "operationId": "registerWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Register a webhook endpoint",
        "description": "Subscribes a URL to one or more events and returns its signing secret, **once**. Store it: it is needed to verify every delivery and cannot be retrieved later. See the Webhooks section for the payloads and how to verify a signature.\n\nRequires scope `webhooks:manage`.\n\n**Test keys.** A key created as a test key (`cp_test_…`) can read real data but cannot change any. This call is validated exactly as for a live key and answers with the response it would have produced, plus `\"dryRun\": true` and the header `X-Counterpoint-Dry-Run: 1`. Nothing is saved: no record, no stock movement, no receipt number consumed, and no webhook sent.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "webhooks:manage",
        "x-dry-run-with-test-key": true,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterWebhookRequest"
              },
              "example": {
                "url": "https://partner.example.com/counterpoint",
                "events": [
                  "sale.created",
                  "refund.created"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The endpoint, with its secret.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Counterpoint-Dry-Run": {
                "description": "Set to `1` when a test key made this call and nothing was saved.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "1"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/RegisteredWebhook"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "dryRun": {
                          "type": "boolean",
                          "const": true,
                          "description": "Present and true only when a test key made the call: validated, answered, nothing saved."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "id": "7d8e9f0a-1b2c-4d3e-8f4a-5b6c7d8e9f01",
                  "url": "https://partner.example.com/counterpoint",
                  "events": [
                    "sale.created",
                    "refund.created"
                  ],
                  "active": true,
                  "secret": "whsec_Zk3q1xV0n8Hc2mT5pYb7LwRd9sJf4GaE",
                  "createdAt": "2026-10-01T10:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "The URL is not https, an event is unknown, or the URL is already registered.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ValidationError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl -X POST https://counterpoint-api.fly.dev/v1/webhooks \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://partner.example.com/counterpoint\",\"events\":[\"sale.created\"]}'"
          }
        ]
      }
    },
    "/v1/webhooks/{id}": {
      "delete": {
        "operationId": "removeWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Remove a webhook endpoint",
        "description": "Stops deliveries to the endpoint.\n\nRequires scope `webhooks:manage`.\n\n**Test keys.** A key created as a test key (`cp_test_…`) can read real data but cannot change any. This call is validated exactly as for a live key and answers with the response it would have produced, plus `\"dryRun\": true` and the header `X-Counterpoint-Dry-Run: 1`. Nothing is saved: no record, no stock movement, no receipt number consumed, and no webhook sent.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "x-required-scope": "webhooks:manage",
        "x-dry-run-with-test-key": true,
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The endpoint id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "7d8e9f0a-1b2c-4d3e-8f4a-5b6c7d8e9f01"
          }
        ],
        "responses": {
          "200": {
            "description": "Removed.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Counterpoint-Dry-Run": {
                "description": "Set to `1` when a test key made this call and nothing was saved.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "1"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Removed"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "dryRun": {
                          "type": "boolean",
                          "const": true,
                          "description": "Present and true only when a test key made the call: validated, answered, nothing saved."
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "removed": true
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "No such endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl -X DELETE https://counterpoint-api.fly.dev/v1/webhooks/7d8e9f0a-1b2c-4d3e-8f4a-5b6c7d8e9f01 \\\n  -H \"Authorization: Bearer $COUNTERPOINT_KEY\""
          }
        ]
      }
    }
  },
  "webhooks": {
    "sale.created": {
      "post": {
        "operationId": "webhook_sale_created",
        "tags": [
          "Webhook events"
        ],
        "summary": "sale.created",
        "description": "A sale was recorded.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "sale.created"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaleCreatedEvent"
              },
              "example": {
                "event": "sale.created",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "id": "5b0f6a52-7f3a-4c8e-9a52-6d1f2f0f7e11",
                  "receiptNumber": "R-000412",
                  "currency": "EGP",
                  "subtotal": "120.00",
                  "tax": "16.80",
                  "total": "136.80",
                  "tender": "cash",
                  "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "lines": [
                    {
                      "sku": "TSHIRT-BLK-M",
                      "name": "Black tee, medium",
                      "quantity": 1,
                      "unitPrice": "120.00"
                    }
                  ],
                  "createdAt": "2026-10-06T09:41:12.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    },
    "refund.created": {
      "post": {
        "operationId": "webhook_refund_created",
        "tags": [
          "Webhook events"
        ],
        "summary": "refund.created",
        "description": "A refund was issued.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "refund.created"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefundCreatedEvent"
              },
              "example": {
                "event": "refund.created",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                  "saleId": "5b0f6a52-7f3a-4c8e-9a52-6d1f2f0f7e11",
                  "currency": "EGP",
                  "subtotal": "120.00",
                  "tax": "16.80",
                  "total": "136.80",
                  "method": "original",
                  "reasonCode": "CHANGED_MIND",
                  "lines": [
                    {
                      "sku": "TSHIRT-BLK-M",
                      "quantity": 1
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    },
    "product.created": {
      "post": {
        "operationId": "webhook_product_created",
        "tags": [
          "Webhook events"
        ],
        "summary": "product.created",
        "description": "A product was added to the catalog.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "product.created"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductCreatedEvent"
              },
              "example": {
                "event": "product.created",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "id": "9c1e5f2a-3b4d-4e6f-8a7b-1c2d3e4f5a6b",
                  "sku": "TSHIRT-BLK-M",
                  "name": "Black tee, medium",
                  "unitPrice": "120.00"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    },
    "product.deleted": {
      "post": {
        "operationId": "webhook_product_deleted",
        "tags": [
          "Webhook events"
        ],
        "summary": "product.deleted",
        "description": "An unused product was deleted.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "product.deleted"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductDeletedEvent"
              },
              "example": {
                "event": "product.deleted",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "id": "9c1e5f2a-3b4d-4e6f-8a7b-1c2d3e4f5a6b",
                  "sku": "TSHIRT-BLK-M",
                  "name": "Black tee, medium",
                  "unitPrice": "120.00"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    },
    "product.updated": {
      "post": {
        "operationId": "webhook_product_updated",
        "tags": [
          "Webhook events"
        ],
        "summary": "product.updated",
        "description": "A product was edited, archived or restored.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "product.updated"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductUpdatedEvent"
              },
              "example": {
                "event": "product.updated",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "id": "9c1e5f2a-3b4d-4e6f-8a7b-1c2d3e4f5a6b",
                  "sku": "TSHIRT-BLK-M",
                  "name": "Black tee, medium",
                  "unitPrice": "135.00",
                  "archived": false
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    },
    "inventory.adjusted": {
      "post": {
        "operationId": "webhook_inventory_adjusted",
        "tags": [
          "Webhook events"
        ],
        "summary": "inventory.adjusted",
        "description": "Stock changed at an outlet.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "inventory.adjusted"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InventoryAdjustedEvent"
              },
              "example": {
                "event": "inventory.adjusted",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "sku": "TSHIRT-BLK-M",
                  "locationId": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                  "onHand": 12,
                  "delta": -2,
                  "reason": "sale"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    },
    "fulfillment.updated": {
      "post": {
        "operationId": "webhook_fulfillment_updated",
        "tags": [
          "Webhook events"
        ],
        "summary": "fulfillment.updated",
        "description": "An order moved through fulfillment.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "fulfillment.updated"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FulfillmentUpdatedEvent"
              },
              "example": {
                "event": "fulfillment.updated",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "id": "8b9c0d1e-2f3a-4b4c-8d5e-6f7a8b9c0d1e",
                  "saleId": null,
                  "status": "shipped",
                  "carrier": "bosta",
                  "trackingNumber": "7234510986"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    },
    "automation.fired": {
      "post": {
        "operationId": "webhook_automation_fired",
        "tags": [
          "Webhook events"
        ],
        "summary": "automation.fired",
        "description": "A rule the merchant built chose to tell you something.\n\nDelivered to your endpoint as a signed POST. See \"Verifying a signature\" above. Respond `2xx` within 5 seconds.",
        "parameters": [
          {
            "name": "x-counterpoint-signature",
            "in": "header",
            "required": true,
            "description": "`t=<unix>,v1=<hex hmac-sha256>`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-counterpoint-event",
            "in": "header",
            "required": true,
            "description": "The event name.",
            "schema": {
              "type": "string",
              "const": "automation.fired"
            }
          },
          {
            "name": "x-counterpoint-delivery",
            "in": "header",
            "required": true,
            "description": "Unique delivery id; stable across retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomationFiredEvent"
              },
              "example": {
                "event": "automation.fired",
                "createdAt": "2026-10-06T09:41:12.000Z",
                "data": {
                  "rule": "Large sale alert",
                  "trigger": "sale.created",
                  "message": "A sale over EGP 5,000 was rung up",
                  "event": {
                    "total": "5400.00",
                    "tender": "card",
                    "receiptNumber": "R-000413"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received. Any 2xx counts as delivered."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "cp_live_<id>_<secret> or cp_test_<id>_<secret>",
        "description": "A key from Setup → Developer. A test key reads real data and dry-runs every write."
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "Requests allowed per one-minute window.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Requests left in this window.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitReset": {
        "description": "Unix time (seconds) when the window resets.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, malformed, unknown or revoked key. One message for all of them.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "statusCode": 401,
              "message": "Invalid API key",
              "error": "Unauthorized",
              "correlationId": "7f3a2c1e9b"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "The shop's plan does not include the Partner API, or the account is suspended and the call writes.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "statusCode": 402,
              "message": "The Partner API is not part of this plan",
              "error": "Payment Required",
              "correlationId": "7f3a2c1e9b"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The key does not hold the scope this route needs.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "statusCode": 403,
              "message": "This key is missing the sales:read scope",
              "error": "Forbidden",
              "correlationId": "7f3a2c1e9b"
            }
          }
        }
      },
      "RateLimited": {
        "description": "The key has used its per-minute budget.",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait.",
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Error"
                },
                {
                  "type": "object",
                  "properties": {
                    "retryAfter": {
                      "type": "integer"
                    }
                  }
                }
              ]
            },
            "example": {
              "statusCode": 429,
              "message": "Rate limit of 120 requests/minute exceeded",
              "retryAfter": 31,
              "correlationId": "7f3a2c1e9b"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer"
          },
          "fieldErrors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "error": {
            "type": "string"
          },
          "correlationId": {
            "type": "string"
          }
        },
        "required": [
          "statusCode",
          "message"
        ],
        "additionalProperties": false
      },
      "ValidationError": {
        "type": "object",
        "properties": {
          "formErrors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fieldErrors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "correlationId": {
            "type": "string"
          }
        },
        "required": [
          "formErrors",
          "fieldErrors"
        ],
        "additionalProperties": false
      },
      "Whoami": {
        "type": "object",
        "properties": {
          "keyName": {
            "type": "string"
          },
          "keyId": {
            "type": "string"
          },
          "live": {
            "type": "boolean"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "rateLimitPerMinute": {
            "type": "integer"
          },
          "availableScopes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                }
              },
              "required": [
                "key",
                "description"
              ],
              "additionalProperties": false
            }
          },
          "availableEvents": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                }
              },
              "required": [
                "key",
                "description"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "keyName",
          "keyId",
          "live",
          "scopes",
          "rateLimitPerMinute",
          "availableScopes",
          "availableEvents"
        ],
        "additionalProperties": false
      },
      "CatalogProduct": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sku": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "unitPrice": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "type": {
            "type": "string",
            "enum": [
              "standard",
              "variant",
              "composite"
            ]
          },
          "costManual": {
            "type": "boolean"
          },
          "costExact": {
            "type": [
              "string",
              "null"
            ]
          },
          "variantCount": {
            "type": "integer",
            "minimum": 0
          },
          "barcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "cost": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              {
                "type": "null"
              }
            ]
          },
          "supplierId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "brandId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "reorderPoint": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "reorderQuantity": {
            "anyOf": [
              {
                "type": "integer",
                "exclusiveMinimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "categoryId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "finalSale": {
            "type": "boolean"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "hiddenOutletIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "hiddenOutletCount": {
            "type": "integer",
            "minimum": 0
          },
          "imageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "unit": {
            "type": "string"
          },
          "purchaseUnit": {
            "type": [
              "string",
              "null"
            ]
          },
          "purchaseFactor": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "soldOnTill": {
            "type": "boolean"
          },
          "parentId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "parentName": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "sku",
          "name",
          "unitPrice",
          "type",
          "variantCount"
        ],
        "additionalProperties": false
      },
      "CreateProductRequest": {
        "type": "object",
        "properties": {
          "soldOnTill": {
            "type": "boolean"
          },
          "sku": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "type": {
            "type": "string",
            "enum": [
              "standard",
              "variant",
              "composite"
            ],
            "default": "standard"
          },
          "unitPrice": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "cost": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d{1,4})?$"
          },
          "categoryId": {
            "type": "string",
            "format": "uuid"
          },
          "supplierId": {
            "type": "string",
            "format": "uuid"
          },
          "brandId": {
            "type": "string",
            "format": "uuid"
          },
          "barcode": {
            "type": "string",
            "minLength": 4,
            "maxLength": 64
          },
          "description": {
            "type": "string",
            "maxLength": 5000
          }
        },
        "required": [
          "sku",
          "name"
        ],
        "additionalProperties": false
      },
      "CreatedProduct": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sku": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "unitPrice": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          }
        },
        "required": [
          "id",
          "sku",
          "name",
          "unitPrice"
        ],
        "additionalProperties": false
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "parentId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "parentId"
        ],
        "additionalProperties": false
      },
      "Location": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "locationType": {
            "type": "string",
            "enum": [
              "store",
              "warehouse"
            ]
          },
          "numberingPrefix": {
            "type": "string"
          },
          "street": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "governate": {
            "type": [
              "string",
              "null"
            ]
          },
          "buildingNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "taxBranchCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "tillMode": {
            "type": "string",
            "enum": [
              "retail",
              "fnb"
            ]
          },
          "openTills": {
            "type": "integer",
            "minimum": 0
          },
          "tillLimit": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "name",
          "locationType",
          "numberingPrefix"
        ],
        "additionalProperties": false
      },
      "StockLevel": {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "locationId": {
            "type": "string",
            "format": "uuid"
          },
          "onHand": {
            "type": "number"
          },
          "barcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "categoryId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "categoryName": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasSupplier": {
            "type": "boolean"
          },
          "reorderQuantity": {
            "type": [
              "number",
              "null"
            ]
          },
          "reorderPoint": {
            "type": [
              "number",
              "null"
            ]
          },
          "outletReorderPoint": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "productReorderPoint": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "soldHere": {
            "type": "boolean"
          },
          "valueAtCost": {
            "type": [
              "string",
              "null"
            ]
          },
          "valueAtRetail": {
            "type": [
              "string",
              "null"
            ]
          },
          "unit": {
            "type": "string"
          },
          "purchaseUnit": {
            "type": [
              "string",
              "null"
            ]
          },
          "purchaseFactor": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0
              },
              {
                "type": "null"
              }
            ]
          },
          "makeable": {
            "type": "integer",
            "minimum": 0
          },
          "recipeNeeds": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "optionId": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uuid"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "effects": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "optionId": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "kind": {
                        "type": "string",
                        "enum": [
                          "replace",
                          "remove"
                        ]
                      },
                      "fromSku": {
                        "type": "string"
                      },
                      "toSku": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "toName": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "toUnit": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "quantityFactor": {
                        "type": "number",
                        "exclusiveMinimum": 0
                      }
                    },
                    "required": [
                      "optionId",
                      "kind",
                      "fromSku",
                      "toSku",
                      "toName",
                      "toUnit",
                      "quantityFactor"
                    ],
                    "additionalProperties": false
                  }
                },
                "sku": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "unit": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                }
              },
              "required": [
                "optionId",
                "sku",
                "name",
                "unit",
                "quantity"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "sku",
          "name",
          "locationId",
          "onHand"
        ],
        "additionalProperties": false
      },
      "InventoryResponse": {
        "type": "object",
        "properties": {
          "locationId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "levels": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sku": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "locationId": {
                  "type": "string",
                  "format": "uuid"
                },
                "onHand": {
                  "type": "number"
                },
                "barcode": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "categoryId": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uuid"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "categoryName": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "hasSupplier": {
                  "type": "boolean"
                },
                "reorderQuantity": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "reorderPoint": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "outletReorderPoint": {
                  "anyOf": [
                    {
                      "type": "integer"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "productReorderPoint": {
                  "anyOf": [
                    {
                      "type": "integer"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "soldHere": {
                  "type": "boolean"
                },
                "valueAtCost": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "valueAtRetail": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "unit": {
                  "type": "string"
                },
                "purchaseUnit": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "purchaseFactor": {
                  "anyOf": [
                    {
                      "type": "number",
                      "exclusiveMinimum": 0
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "makeable": {
                  "type": "integer",
                  "minimum": 0
                },
                "recipeNeeds": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "optionId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "effects": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "optionId": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "kind": {
                              "type": "string",
                              "enum": [
                                "replace",
                                "remove"
                              ]
                            },
                            "fromSku": {
                              "type": "string"
                            },
                            "toSku": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "toName": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "toUnit": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "quantityFactor": {
                              "type": "number",
                              "exclusiveMinimum": 0
                            }
                          },
                          "required": [
                            "optionId",
                            "kind",
                            "fromSku",
                            "toSku",
                            "toName",
                            "toUnit",
                            "quantityFactor"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "sku": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "unit": {
                        "type": "string"
                      },
                      "quantity": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "optionId",
                      "sku",
                      "name",
                      "unit",
                      "quantity"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "sku",
                "name",
                "locationId",
                "onHand"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "locationId",
          "levels"
        ],
        "additionalProperties": false
      },
      "Customer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "onAccount": {
            "type": "string",
            "enum": [
              "no",
              "unlimited",
              "limited"
            ]
          },
          "creditLimit": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              {
                "type": "null"
              }
            ]
          },
          "storeCredit": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "accountBalance": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "customerGroup": {
            "type": [
              "string",
              "null"
            ]
          },
          "loyaltyPoints": {
            "type": "integer"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "marketing": {
            "type": "object",
            "properties": {
              "whatsapp": {
                "type": "boolean"
              },
              "sms": {
                "type": "boolean"
              },
              "email": {
                "type": "boolean"
              }
            },
            "required": [
              "whatsapp",
              "sms",
              "email"
            ],
            "additionalProperties": false
          },
          "marketingChangedAt": {
            "type": "object",
            "properties": {
              "whatsapp": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "sms": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "whatsapp",
              "sms",
              "email"
            ],
            "additionalProperties": false
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ]
          },
          "birthday": {
            "type": [
              "string",
              "null"
            ]
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "code",
          "name",
          "phone",
          "email",
          "onAccount",
          "creditLimit",
          "storeCredit",
          "accountBalance",
          "customerGroup",
          "loyaltyPoints",
          "marketing",
          "marketingChangedAt",
          "address",
          "notes",
          "birthday",
          "archivedAt"
        ],
        "additionalProperties": false
      },
      "CreateCustomerRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "phone": {
            "type": "string",
            "maxLength": 40
          },
          "email": {
            "type": "string",
            "maxLength": 200,
            "format": "email"
          },
          "onAccount": {
            "type": "string",
            "enum": [
              "no",
              "unlimited",
              "limited"
            ],
            "default": "no"
          },
          "creditLimit": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "customerGroup": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60
          },
          "marketingWhatsapp": {
            "type": "boolean",
            "default": false
          },
          "marketingSms": {
            "type": "boolean",
            "default": false
          },
          "marketingEmail": {
            "type": "boolean",
            "default": false
          },
          "address": {
            "type": "string",
            "maxLength": 500
          },
          "notes": {
            "type": "string",
            "maxLength": 2000
          },
          "birthday": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "Sale": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "receiptNumber": {
            "type": "string"
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "subtotal": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "tax": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "total": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "delivery": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "deliveryTax": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "deliveryTaxRatePercent": {
            "type": "string"
          },
          "tender": {
            "type": "string"
          },
          "tenders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "tender": {
                  "type": "string"
                },
                "amount": {
                  "type": "string",
                  "pattern": "^-?\\d+(\\.\\d+)?$"
                },
                "giftCardCode": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "giftCardBalance": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^-?\\d+(\\.\\d+)?$"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "storeCreditBalance": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^-?\\d+(\\.\\d+)?$"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "loyaltyPoints": {
                  "anyOf": [
                    {
                      "type": "integer",
                      "minimum": 0
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "tender",
                "amount",
                "giftCardCode",
                "giftCardBalance",
                "storeCreditBalance"
              ],
              "additionalProperties": false
            }
          },
          "refundedTenders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "tender": {
                  "type": "string"
                },
                "amount": {
                  "type": "string",
                  "pattern": "^-?\\d+(\\.\\d+)?$"
                }
              },
              "required": [
                "tender",
                "amount"
              ],
              "additionalProperties": false
            }
          },
          "locationId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "cashReceived": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              {
                "type": "null"
              }
            ]
          },
          "changeDue": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              {
                "type": "null"
              }
            ]
          },
          "taxDocumentRef": {
            "type": [
              "string",
              "null"
            ]
          },
          "taxQrPayload": {
            "type": [
              "string",
              "null"
            ]
          },
          "returnReceipts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "receiptNumber": {
                  "type": "string"
                },
                "taxQrPayload": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "receiptNumber",
                "taxQrPayload"
              ],
              "additionalProperties": false
            }
          },
          "etaUuid": {
            "type": [
              "string",
              "null"
            ]
          },
          "refundedTotal": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "refunded": {
            "type": "boolean"
          },
          "approvedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "cashierName": {
            "type": [
              "string",
              "null"
            ]
          },
          "customerName": {
            "type": [
              "string",
              "null"
            ]
          },
          "refundApprovedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvalReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "discount": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "discountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "discountNote": {
            "type": [
              "string",
              "null"
            ]
          },
          "exchange": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "originalSaleId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "originalReceiptNumber": {
                    "type": "string"
                  },
                  "refundId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "reasonCode": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "returnedLines": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "nameAr": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "quantity": {
                          "type": "integer"
                        },
                        "unitPrice": {
                          "type": "string",
                          "pattern": "^-?\\d+(\\.\\d+)?$"
                        },
                        "discount": {
                          "type": "string",
                          "pattern": "^-?\\d+(\\.\\d+)?$"
                        },
                        "addons": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "optionId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "group": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "priceDelta": {
                                "type": "string",
                                "pattern": "^-?\\d+(\\.\\d+)?$"
                              }
                            },
                            "required": [
                              "optionId",
                              "group",
                              "name",
                              "priceDelta"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "sku",
                        "name",
                        "quantity",
                        "unitPrice",
                        "discount"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "returnTotal": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "loyaltyRestored": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "credit": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "difference": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "direction": {
                    "type": "string",
                    "enum": [
                      "customer_pays",
                      "shop_pays",
                      "even"
                    ]
                  },
                  "tender": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "cash",
                          "card",
                          "wallet",
                          "instapay",
                          "store_credit"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "originalSaleId",
                  "originalReceiptNumber",
                  "refundId",
                  "reasonCode",
                  "returnedLines",
                  "returnTotal",
                  "credit",
                  "difference",
                  "direction",
                  "tender"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "hasCustomer": {
            "type": "boolean"
          },
          "channelOrder": {
            "type": [
              "string",
              "null"
            ]
          },
          "tenderGateway": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "receiptNumber",
          "currency",
          "subtotal",
          "tax",
          "total",
          "tender",
          "createdAt",
          "taxDocumentRef",
          "etaUuid",
          "refundedTotal",
          "refunded"
        ],
        "additionalProperties": false
      },
      "SaleLine": {
        "type": "object",
        "properties": {
          "unitCost": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d+\\.\\d{6}$"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sale-time unit cost, included only with reports:read in addition to sales:read."
          },
          "costSource": {
            "type": "string",
            "enum": [
              "product",
              "recipe",
              "kit",
              "none",
              "backfill_warehouse",
              "backfill_current"
            ],
            "description": "Cost snapshot source, included only with reports:read in addition to sales:read."
          },
          "sku": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "quantity": {
            "type": "integer"
          },
          "unitPrice": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          }
        },
        "required": [
          "sku",
          "name",
          "quantity",
          "unitPrice"
        ],
        "additionalProperties": false
      },
      "SaleDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "receiptNumber": {
            "type": "string"
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "subtotal": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "tax": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "total": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "delivery": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "deliveryTax": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "deliveryTaxRatePercent": {
            "type": "string"
          },
          "tender": {
            "type": "string"
          },
          "tenders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "tender": {
                  "type": "string"
                },
                "amount": {
                  "type": "string",
                  "pattern": "^-?\\d+(\\.\\d+)?$"
                },
                "giftCardCode": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "giftCardBalance": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^-?\\d+(\\.\\d+)?$"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "storeCreditBalance": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^-?\\d+(\\.\\d+)?$"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "loyaltyPoints": {
                  "anyOf": [
                    {
                      "type": "integer",
                      "minimum": 0
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "tender",
                "amount",
                "giftCardCode",
                "giftCardBalance",
                "storeCreditBalance"
              ],
              "additionalProperties": false
            }
          },
          "refundedTenders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "tender": {
                  "type": "string"
                },
                "amount": {
                  "type": "string",
                  "pattern": "^-?\\d+(\\.\\d+)?$"
                }
              },
              "required": [
                "tender",
                "amount"
              ],
              "additionalProperties": false
            }
          },
          "locationId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "cashReceived": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              {
                "type": "null"
              }
            ]
          },
          "changeDue": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              {
                "type": "null"
              }
            ]
          },
          "taxDocumentRef": {
            "type": [
              "string",
              "null"
            ]
          },
          "taxQrPayload": {
            "type": [
              "string",
              "null"
            ]
          },
          "returnReceipts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "receiptNumber": {
                  "type": "string"
                },
                "taxQrPayload": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "receiptNumber",
                "taxQrPayload"
              ],
              "additionalProperties": false
            }
          },
          "etaUuid": {
            "type": [
              "string",
              "null"
            ]
          },
          "refundedTotal": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "refunded": {
            "type": "boolean"
          },
          "approvedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "cashierName": {
            "type": [
              "string",
              "null"
            ]
          },
          "customerName": {
            "type": [
              "string",
              "null"
            ]
          },
          "refundApprovedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "approvalReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "discount": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "discountName": {
            "type": [
              "string",
              "null"
            ]
          },
          "discountNote": {
            "type": [
              "string",
              "null"
            ]
          },
          "exchange": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "originalSaleId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "originalReceiptNumber": {
                    "type": "string"
                  },
                  "refundId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "reasonCode": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "returnedLines": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "nameAr": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "quantity": {
                          "type": "integer"
                        },
                        "unitPrice": {
                          "type": "string",
                          "pattern": "^-?\\d+(\\.\\d+)?$"
                        },
                        "discount": {
                          "type": "string",
                          "pattern": "^-?\\d+(\\.\\d+)?$"
                        },
                        "addons": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "optionId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "group": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "priceDelta": {
                                "type": "string",
                                "pattern": "^-?\\d+(\\.\\d+)?$"
                              }
                            },
                            "required": [
                              "optionId",
                              "group",
                              "name",
                              "priceDelta"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "sku",
                        "name",
                        "quantity",
                        "unitPrice",
                        "discount"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "returnTotal": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "loyaltyRestored": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "credit": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "difference": {
                    "type": "string",
                    "pattern": "^-?\\d+(\\.\\d+)?$"
                  },
                  "direction": {
                    "type": "string",
                    "enum": [
                      "customer_pays",
                      "shop_pays",
                      "even"
                    ]
                  },
                  "tender": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "cash",
                          "card",
                          "wallet",
                          "instapay",
                          "store_credit"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "originalSaleId",
                  "originalReceiptNumber",
                  "refundId",
                  "reasonCode",
                  "returnedLines",
                  "returnTotal",
                  "credit",
                  "difference",
                  "direction",
                  "tender"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "hasCustomer": {
            "type": "boolean"
          },
          "channelOrder": {
            "type": [
              "string",
              "null"
            ]
          },
          "tenderGateway": {
            "type": [
              "string",
              "null"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "unitCost": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^\\d+\\.\\d{6}$"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Sale-time unit cost, included only with reports:read in addition to sales:read."
                },
                "costSource": {
                  "type": "string",
                  "enum": [
                    "product",
                    "recipe",
                    "kit",
                    "none",
                    "backfill_warehouse",
                    "backfill_current"
                  ],
                  "description": "Cost snapshot source, included only with reports:read in addition to sales:read."
                },
                "sku": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "quantity": {
                  "type": "integer"
                },
                "unitPrice": {
                  "type": "string",
                  "pattern": "^-?\\d+(\\.\\d+)?$"
                }
              },
              "required": [
                "sku",
                "name",
                "quantity",
                "unitPrice"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "id",
          "receiptNumber",
          "currency",
          "subtotal",
          "tax",
          "total",
          "tender",
          "createdAt",
          "taxDocumentRef",
          "etaUuid",
          "refundedTotal",
          "refunded",
          "lines"
        ],
        "additionalProperties": false
      },
      "CreateSaleRequest": {
        "type": "object",
        "properties": {
          "locationId": {
            "type": "string",
            "format": "uuid"
          },
          "currency": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "registerSessionId": {
            "type": "string",
            "format": "uuid"
          },
          "tender": {
            "type": "string",
            "enum": [
              "card",
              "cash",
              "cod",
              "wallet",
              "instapay",
              "on_account",
              "store_credit",
              "talabat",
              "shopify",
              "loyalty",
              "gift_card",
              "layaway"
            ]
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sku": {
                  "type": "string",
                  "minLength": 1
                },
                "name": {
                  "type": "string",
                  "minLength": 1
                },
                "unitPrice": {
                  "type": "string",
                  "pattern": "^\\d+(\\.\\d{1,2})?$"
                },
                "quantity": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 1000000
                },
                "addons": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "optionId": {
                        "type": "string",
                        "format": "uuid"
                      }
                    },
                    "required": [
                      "optionId"
                    ],
                    "additionalProperties": false
                  },
                  "maxItems": 20
                }
              },
              "required": [
                "sku",
                "name",
                "unitPrice",
                "quantity"
              ],
              "additionalProperties": false
            },
            "minItems": 1
          },
          "customerId": {
            "type": "string",
            "format": "uuid"
          },
          "discount": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "percent",
                  "amount"
                ]
              },
              "value": {
                "type": "string",
                "pattern": "^\\d+(\\.\\d+)?$"
              }
            },
            "required": [
              "type",
              "value"
            ],
            "additionalProperties": false
          },
          "discountGroupId": {
            "type": "string",
            "format": "uuid"
          },
          "discountNote": {
            "type": "string",
            "maxLength": 200
          },
          "customerPhone": {
            "type": "string"
          },
          "giftCardCode": {
            "type": "string",
            "minLength": 4,
            "maxLength": 32
          },
          "remainderTender": {
            "type": "string",
            "enum": [
              "card",
              "cash",
              "cod",
              "wallet",
              "instapay",
              "talabat",
              "gift_card"
            ]
          },
          "loyaltyPoints": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "paymentLinkId": {
            "type": "string",
            "format": "uuid"
          },
          "buyerTaxId": {
            "type": "string",
            "minLength": 5,
            "maxLength": 32
          },
          "buyerNationalId": {
            "type": "string",
            "pattern": "^[23]\\d{13}$"
          },
          "buyerName": {
            "type": "string",
            "maxLength": 200
          },
          "cashReceived": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "staffId": {
            "type": "string",
            "format": "uuid"
          },
          "approvalId": {
            "type": "string",
            "format": "uuid"
          },
          "idempotencyKey": {
            "type": "string",
            "minLength": 8
          }
        },
        "required": [
          "currency",
          "tender",
          "lines",
          "idempotencyKey"
        ],
        "additionalProperties": false
      },
      "SalesSummary": {
        "type": "object",
        "properties": {
          "cogs": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$",
            "description": "Net cost of goods from stored sale/refund snapshots, with legacy fallback."
          },
          "estimatedCostLines": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of sale/refund lines whose missing snapshot used today's cost."
          },
          "saleCount": {
            "type": "integer"
          },
          "revenue": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "taxCollected": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "refunds": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "netRevenue": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "grossRevenue": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "avgBasket": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "fullyRefundedCount": {
            "type": "integer"
          },
          "todayNetRevenue": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "todaySaleCount": {
            "type": "integer"
          },
          "discounts": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "todayDiscounts": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d+)?$"
          },
          "todayDiscountedCount": {
            "type": "integer"
          }
        },
        "required": [
          "cogs",
          "saleCount",
          "revenue",
          "taxCollected",
          "refunds",
          "netRevenue",
          "grossRevenue",
          "avgBasket",
          "fullyRefundedCount",
          "todayNetRevenue",
          "todaySaleCount",
          "discounts",
          "todayDiscounts",
          "todayDiscountedCount"
        ],
        "additionalProperties": false
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "active": {
            "type": "boolean"
          },
          "consecutiveFailures": {
            "type": "integer"
          },
          "disabledReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "active",
          "consecutiveFailures",
          "disabledReason",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "RegisterWebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "https only. http://localhost and http://127.0.0.1 are allowed for local development."
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "sale.created",
                "refund.created",
                "product.created",
                "product.deleted",
                "product.updated",
                "inventory.adjusted",
                "fulfillment.updated",
                "automation.fired"
              ]
            },
            "minItems": 1
          }
        },
        "required": [
          "url",
          "events"
        ],
        "additionalProperties": false
      },
      "RegisteredWebhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "active": {
            "type": "boolean"
          },
          "secret": {
            "type": "string",
            "description": "The signing secret. Returned once, here, and never again."
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "active",
          "secret",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "Removed": {
        "type": "object",
        "properties": {
          "removed": {
            "type": "boolean"
          }
        },
        "required": [
          "removed"
        ],
        "additionalProperties": false
      },
      "OpenApiDocument": {
        "type": "object",
        "description": "This OpenAPI 3.1 document.",
        "additionalProperties": true
      },
      "SaleCreatedEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "sale.created"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "receiptNumber": {
                "type": "string"
              },
              "currency": {
                "type": "string"
              },
              "subtotal": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              "tax": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              "total": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              "tender": {
                "type": "string"
              },
              "locationId": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uuid"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "sku": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "quantity": {
                      "type": "integer"
                    },
                    "unitPrice": {
                      "type": "string",
                      "pattern": "^-?\\d+(\\.\\d+)?$"
                    }
                  },
                  "required": [
                    "sku",
                    "name",
                    "quantity",
                    "unitPrice"
                  ],
                  "additionalProperties": false
                }
              },
              "createdAt": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "receiptNumber",
              "currency",
              "subtotal",
              "tax",
              "total",
              "tender",
              "lines",
              "createdAt"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      },
      "RefundCreatedEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "refund.created"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "saleId": {
                "type": "string",
                "format": "uuid"
              },
              "currency": {
                "type": "string"
              },
              "subtotal": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              "tax": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              "total": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              "method": {
                "type": "string",
                "enum": [
                  "original",
                  "store_credit"
                ]
              },
              "reasonCode": {
                "type": "string"
              },
              "lines": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "sku": {
                      "type": "string"
                    },
                    "quantity": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "sku",
                    "quantity"
                  ],
                  "additionalProperties": true
                }
              }
            },
            "required": [
              "id",
              "saleId",
              "currency",
              "subtotal",
              "tax",
              "total",
              "method",
              "reasonCode",
              "lines"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      },
      "ProductCreatedEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "product.created"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "sku": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "unitPrice": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              }
            },
            "required": [
              "id",
              "sku",
              "name",
              "unitPrice"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      },
      "ProductDeletedEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "product.deleted"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "sku": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "unitPrice": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              }
            },
            "required": [
              "id",
              "sku",
              "name",
              "unitPrice"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      },
      "ProductUpdatedEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "product.updated"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "sku": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "unitPrice": {
                "type": "string",
                "pattern": "^-?\\d+(\\.\\d+)?$"
              },
              "archived": {
                "type": "boolean"
              }
            },
            "required": [
              "id",
              "sku",
              "name",
              "unitPrice",
              "archived"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      },
      "InventoryAdjustedEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "inventory.adjusted"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "sku": {
                "type": "string"
              },
              "locationId": {
                "type": "string",
                "format": "uuid"
              },
              "onHand": {
                "type": "number"
              },
              "delta": {
                "type": "number"
              },
              "reason": {
                "type": "string"
              }
            },
            "required": [
              "sku",
              "locationId",
              "onHand",
              "delta",
              "reason"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      },
      "FulfillmentUpdatedEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "fulfillment.updated"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "saleId": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uuid"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "type": "string"
              },
              "carrier": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "trackingNumber": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "saleId",
              "status",
              "carrier",
              "trackingNumber"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      },
      "AutomationFiredEvent": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "const": "automation.fired"
          },
          "createdAt": {
            "type": "string",
            "description": "When the event was queued (ISO 8601)."
          },
          "data": {
            "type": "object",
            "properties": {
              "rule": {
                "type": "string"
              },
              "trigger": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "event": {
                "type": "object",
                "additionalProperties": {}
              }
            },
            "required": [
              "rule",
              "trigger",
              "message",
              "event"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "event",
          "createdAt",
          "data"
        ],
        "additionalProperties": false
      }
    }
  },
  "x-counterpoint": {
    "scopes": [
      {
        "key": "catalog:read",
        "description": "Read products, categories, brands and suppliers"
      },
      {
        "key": "catalog:write",
        "description": "Create and update products"
      },
      {
        "key": "inventory:read",
        "description": "Read stock levels per outlet"
      },
      {
        "key": "customers:read",
        "description": "Read customer profiles and balances"
      },
      {
        "key": "customers:write",
        "description": "Create and update customers"
      },
      {
        "key": "sales:read",
        "description": "Read sales and their lines"
      },
      {
        "key": "sales:write",
        "description": "Record a sale"
      },
      {
        "key": "reports:read",
        "description": "Read aggregate reports"
      },
      {
        "key": "webhooks:manage",
        "description": "Register and remove webhook endpoints"
      }
    ],
    "events": [
      {
        "key": "sale.created",
        "description": "A sale was recorded"
      },
      {
        "key": "refund.created",
        "description": "A refund was issued"
      },
      {
        "key": "product.created",
        "description": "A product was added to the catalog"
      },
      {
        "key": "product.deleted",
        "description": "An unused product was deleted"
      },
      {
        "key": "product.updated",
        "description": "A product was edited, archived or restored"
      },
      {
        "key": "inventory.adjusted",
        "description": "Stock changed at an outlet"
      },
      {
        "key": "fulfillment.updated",
        "description": "An order moved through fulfillment"
      },
      {
        "key": "automation.fired",
        "description": "A rule the merchant built chose to tell you something"
      }
    ],
    "webhookVerification": {
      "node": "import { createHmac, timingSafeEqual } from 'node:crypto';\n\n// `rawBody` must be the exact bytes Counterpoint sent, as a string. Verify BEFORE you\n// JSON.parse, because re-serialising changes the bytes and the signature with them.\nexport function verifyCounterpointWebhook(secret, rawBody, signatureHeader, toleranceSeconds = 300) {\n  const parts = new Map(\n    String(signatureHeader ?? '')\n      .split(',')\n      .map((part) => part.trim().split('='))\n      .filter((pair) => pair.length === 2),\n  );\n  const timestamp = Number(parts.get('t'));\n  const presented = parts.get('v1');\n  if (!Number.isFinite(timestamp) || !presented) return false;\n\n  // Refuse stale signatures so a captured request cannot be replayed later.\n  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;\n\n  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest();\n  const actual = Buffer.from(presented, 'hex');\n  return actual.length === expected.length && timingSafeEqual(actual, expected);\n}\n\n// Express:\n//   app.post('/hooks', express.raw({ type: 'application/json' }), (req, res) => {\n//     const body = req.body.toString('utf8');\n//     if (!verifyCounterpointWebhook(process.env.WHSEC, body, req.get('x-counterpoint-signature'))) {\n//       return res.sendStatus(400);\n//     }\n//     const event = JSON.parse(body);\n//     res.sendStatus(200);\n//   });",
      "python": "import hashlib\nimport hmac\nimport time\n\n\ndef verify_counterpoint_webhook(secret: str, raw_body: bytes, signature_header: str,\n                                tolerance_seconds: int = 300) -> bool:\n    \"\"\"raw_body must be the exact bytes Counterpoint sent. Verify before parsing JSON.\"\"\"\n    parts = dict(\n        part.strip().split(\"=\", 1)\n        for part in (signature_header or \"\").split(\",\")\n        if \"=\" in part\n    )\n    try:\n        timestamp = int(parts[\"t\"])\n        presented = parts[\"v1\"]\n    except (KeyError, ValueError):\n        return False\n\n    # Refuse stale signatures so a captured request cannot be replayed later.\n    if abs(time.time() - timestamp) > tolerance_seconds:\n        return False\n\n    signed = str(timestamp).encode() + b\".\" + raw_body\n    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, presented)\n\n\n# Flask:\n#   @app.post(\"/hooks\")\n#   def hook():\n#       sig = request.headers.get(\"x-counterpoint-signature\")\n#       if not verify_counterpoint_webhook(WHSEC, request.get_data(), sig):\n#           return \"\", 400\n#       event = request.get_json()\n#       return \"\", 200"
    }
  }
}