{
  "openapi": "3.1.0",
  "info": {
    "title": "GoOrder Partner API",
    "version": "1.0.0",
    "summary": "Order food, groceries and pharmacy items from GoOrder stores in your own product.",
    "description": "Stable, versioned REST API for partners. Authenticate with a secret API key, browse live menus, place and track orders, and receive signed webhooks.\n\nStart with the **Quickstart** on the developer portal. Use a `gok_test_…` key to try everything in the sandbox first.",
    "contact": {
      "name": "GoOrder Partner Support",
      "email": "partners@goorder.com"
    }
  },
  "servers": [
    {
      "url": "https://back.goorder.com/api/partner/v1",
      "description": "Production — your key decides live vs sandbox"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "Verify your key."
    },
    {
      "name": "Stores",
      "description": "Stores, menus, search and delivery quotes."
    },
    {
      "name": "Offers",
      "description": "Promotions and promo codes."
    },
    {
      "name": "Orders",
      "description": "Place, track, pay for and cancel orders."
    },
    {
      "name": "Webhooks",
      "description": "Receive order events at your server."
    },
    {
      "name": "Sandbox",
      "description": "Simulate the order lifecycle with a test key."
    }
  ],
  "paths": {
    "/ping": {
      "get": {
        "operationId": "getPing",
        "tags": [
          "Account"
        ],
        "summary": "Check your key",
        "description": "Verifies authentication and returns the partner, environment, scopes and rate limit attached to the API key. Use it as a connectivity check.",
        "responses": {
          "200": {
            "description": "Key is valid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "description": ""
                        },
                        "api_version": {
                          "type": "string",
                          "description": "",
                          "example": "v1"
                        },
                        "environment": {
                          "type": "string",
                          "description": "",
                          "enum": [
                            "live",
                            "sandbox"
                          ]
                        },
                        "partner": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": ""
                            },
                            "name": {
                              "type": "string",
                              "description": ""
                            }
                          }
                        },
                        "scopes": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "description": ""
                          }
                        },
                        "rate_limit_per_min": {
                          "type": "integer",
                          "description": ""
                        },
                        "server_time": {
                          "type": "string",
                          "description": "ISO 8601"
                        }
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/ping' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/ping`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/ping\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/ping');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/stores": {
      "get": {
        "operationId": "listStores",
        "tags": [
          "Stores"
        ],
        "summary": "List stores",
        "description": "Stores you can order from. Pass `lat` and `lng` to get only the stores that deliver to that point, nearest first, each with its distance. `status` reflects opening hours, snoozes and restaurant availability right now.\n\n**Required scope:** `catalog:read`",
        "x-required-scope": "catalog:read",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Customer latitude. Send with `lng` to limit results to stores that deliver there.",
            "schema": {
              "type": "number",
              "description": "Latitude",
              "minimum": -90,
              "maximum": 90,
              "example": 25.2048
            }
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Longitude",
              "minimum": -180,
              "maximum": 180,
              "example": 55.2708
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Match on store name",
              "maxLength": 80
            }
          },
          {
            "name": "vertical",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "",
              "enum": [
                "restaurant",
                "pharmacy",
                "grocery"
              ]
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Only stores with this status",
              "enum": [
                "open",
                "busy",
                "closed"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Page number (1-based)",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Items per page",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of stores",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StoreBrief"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/stores' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/stores`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/stores\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/stores');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/stores/{store_id}": {
      "get": {
        "operationId": "getStore",
        "tags": [
          "Stores"
        ],
        "summary": "Get a store",
        "description": "Full store profile including opening hours.\n\n**Required scope:** `catalog:read`",
        "x-required-scope": "catalog:read",
        "parameters": [
          {
            "name": "store_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Store id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The store",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Store"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown store",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/stores/{store_id}' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/stores/{store_id}`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/stores/{store_id}\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/stores/{store_id}');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/stores/{store_id}/menu": {
      "get": {
        "operationId": "getStoreMenu",
        "tags": [
          "Stores"
        ],
        "summary": "Get a store’s menu",
        "description": "The whole menu grouped by category, with prices, availability and modifier groups. Cache it for a few minutes; use `available` to grey out items.\n\n**Required scope:** `catalog:read`",
        "x-required-scope": "catalog:read",
        "parameters": [
          {
            "name": "store_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Store id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The menu",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Menu"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown store",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/stores/{store_id}/menu' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/stores/{store_id}/menu`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/stores/{store_id}/menu\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/stores/{store_id}/menu');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/stores/{store_id}/items/{item_id}": {
      "get": {
        "operationId": "getStoreItem",
        "tags": [
          "Stores"
        ],
        "summary": "Get one menu item",
        "description": "A single item with its modifier groups.\n\n**Required scope:** `catalog:read`",
        "x-required-scope": "catalog:read",
        "parameters": [
          {
            "name": "store_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Store id"
            }
          },
          {
            "name": "item_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Item id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Item"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown store or item",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/stores/{store_id}/items/{item_id}' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/stores/{store_id}/items/{item_id}`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/stores/{store_id}/items/{item_id}\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/stores/{store_id}/items/{item_id}');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/stores/{store_id}/delivery-quote": {
      "get": {
        "operationId": "getDeliveryQuote",
        "tags": [
          "Stores"
        ],
        "summary": "Quote delivery to an address",
        "description": "Is the address inside the delivery area, how far, and what the delivery fee will be. Call before creating an order.\n\n**Required scope:** `catalog:read`",
        "x-required-scope": "catalog:read",
        "parameters": [
          {
            "name": "store_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Store id"
            }
          },
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "description": "Latitude",
              "minimum": -90,
              "maximum": 90,
              "example": 25.2048
            }
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number",
              "description": "Longitude",
              "minimum": -180,
              "maximum": 180,
              "example": 55.2708
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The quote",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/DeliveryQuote"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown store",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/stores/{store_id}/delivery-quote?lat=25.2048&lng=55.2708' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/stores/{store_id}/delivery-quote?lat=25.2048&lng=55.2708`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/stores/{store_id}/delivery-quote?lat=25.2048&lng=55.2708\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/stores/{store_id}/delivery-quote?lat=25.2048&lng=55.2708');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/search": {
      "get": {
        "operationId": "searchCatalog",
        "tags": [
          "Stores"
        ],
        "summary": "Search stores and dishes",
        "description": "Search by name across stores and menu items.\n\n**Required scope:** `catalog:read`",
        "x-required-scope": "catalog:read",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "At least 2 characters",
              "minLength": 2,
              "maxLength": 80
            }
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Customer latitude. Send with `lng` to limit results to stores that deliver there.",
            "schema": {
              "type": "number",
              "description": "Latitude",
              "minimum": -90,
              "maximum": 90,
              "example": 25.2048
            }
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Longitude",
              "minimum": -180,
              "maximum": 180,
              "example": 55.2708
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Max results per type",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matches",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "stores": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/StoreBrief"
                          }
                        },
                        "items": {
                          "type": "array",
                          "items": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/Item"
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "store": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "description": ""
                                      },
                                      "name": {
                                        "type": "string",
                                        "description": ""
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          }
                        }
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/search?q=string' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/search?q=string`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/search?q=string\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/search?q=string');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/categories": {
      "get": {
        "operationId": "listCategories",
        "tags": [
          "Stores"
        ],
        "summary": "List categories",
        "description": "Top-level food categories (Burgers, Pizza, …).\n\n**Required scope:** `catalog:read`",
        "x-required-scope": "catalog:read",
        "responses": {
          "200": {
            "description": "Categories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Category"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/categories' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/categories`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/categories\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/categories');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/offers": {
      "get": {
        "operationId": "listOffers",
        "tags": [
          "Offers"
        ],
        "summary": "Offers near a location",
        "description": "Active promotions that can be redeemed by a customer at this location.\n\n**Required scope:** `offers:read`",
        "x-required-scope": "offers:read",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Customer latitude. Send with `lng` to limit results to stores that deliver there.",
            "schema": {
              "type": "number",
              "description": "Latitude",
              "minimum": -90,
              "maximum": 90,
              "example": 25.2048
            }
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Longitude",
              "minimum": -180,
              "maximum": 180,
              "example": 55.2708
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Offers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Offer"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/offers' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/offers`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/offers\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/offers');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/stores/{store_id}/offers": {
      "get": {
        "operationId": "listStoreOffers",
        "tags": [
          "Offers"
        ],
        "summary": "Offers for a store",
        "description": "Store-wide offers that will be applied automatically to an order from this store.\n\n**Required scope:** `offers:read`",
        "x-required-scope": "offers:read",
        "parameters": [
          {
            "name": "store_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Store id"
            }
          },
          {
            "name": "fulfilment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "",
              "enum": [
                "delivery",
                "pickup"
              ],
              "default": "delivery"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Offers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Offer"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown store",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/stores/{store_id}/offers' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/stores/{store_id}/offers`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/stores/{store_id}/offers\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/stores/{store_id}/offers');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/promo-codes/validate": {
      "post": {
        "operationId": "validatePromoCode",
        "tags": [
          "Offers"
        ],
        "summary": "Validate a promo code",
        "description": "Checks a code against a store and basket value and returns the discount it would give. Codes are redeemed when you create the order with `promo_code`.\n\n**Required scope:** `offers:read`",
        "x-required-scope": "offers:read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The promo code",
                    "minLength": 2,
                    "maxLength": 40
                  },
                  "store_id": {
                    "type": "string",
                    "description": "Store the order is for"
                  },
                  "subtotal": {
                    "type": "number",
                    "description": "Basket value before delivery",
                    "minimum": 0
                  }
                },
                "required": [
                  "code",
                  "store_id",
                  "subtotal"
                ],
                "additionalProperties": false
              },
              "example": {
                "code": "WELCOME10",
                "store_id": "66f1a2b3c4d5e6f708192a3b",
                "subtotal": 85
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validation result (valid or not)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PromoValidation"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/promo-codes/validate' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"code\": \"WELCOME10\",\n  \"store_id\": \"66f1a2b3c4d5e6f708192a3b\",\n  \"subtotal\": 85\n}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/promo-codes/validate`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    \"code\": \"WELCOME10\",\n    \"store_id\": \"66f1a2b3c4d5e6f708192a3b\",\n    \"subtotal\": 85\n  }),\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/promo-codes/validate\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n    json={\n        \"code\": \"WELCOME10\",\n        \"store_id\": \"66f1a2b3c4d5e6f708192a3b\",\n        \"subtotal\": 85\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/promo-codes/validate');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => json_encode([\n        \"code\" => \"WELCOME10\",\n        \"store_id\" => \"66f1a2b3c4d5e6f708192a3b\",\n        \"subtotal\" => 85\n    ]),\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/orders": {
      "post": {
        "operationId": "createOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Create an order",
        "description": "Places an order with the restaurant. Prices are always calculated by GoOrder — you never send them. **Send an `Idempotency-Key` header** (any unique string, e.g. your order id): retrying with the same key returns the original order instead of creating a duplicate. For `payment_method: \"card\"` the order is held until the customer pays; call *Create a payment link*.\n\n**Required scope:** `orders:write`",
        "x-required-scope": "orders:write",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Unique per order attempt, up to 64 chars",
              "minLength": 8,
              "maxLength": 64
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store_id": {
                    "type": "string",
                    "description": "Store to order from"
                  },
                  "fulfilment": {
                    "type": "string",
                    "description": "`delivery` or `pickup`",
                    "enum": [
                      "delivery",
                      "pickup"
                    ]
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "item_id": {
                          "type": "string",
                          "description": "Item id from the menu"
                        },
                        "quantity": {
                          "type": "integer",
                          "description": "1–99",
                          "minimum": 1,
                          "maximum": 99
                        },
                        "modifier_ids": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "description": "Option id from `modifier_groups`"
                          }
                        },
                        "notes": {
                          "type": "string",
                          "description": "Special instructions",
                          "maxLength": 200
                        }
                      },
                      "required": [
                        "item_id",
                        "quantity"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 60
                  },
                  "customer": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "Full name",
                        "minLength": 2,
                        "maxLength": 80
                      },
                      "phone": {
                        "type": "string",
                        "description": "Mobile number with country code",
                        "example": "+971501234567",
                        "minLength": 7,
                        "maxLength": 20
                      },
                      "email": {
                        "type": "string",
                        "description": "Email (optional)",
                        "maxLength": 120
                      }
                    },
                    "required": [
                      "name",
                      "phone"
                    ],
                    "additionalProperties": false
                  },
                  "delivery_address": {
                    "type": "object",
                    "properties": {
                      "line1": {
                        "type": "string",
                        "description": "Street / building line"
                      },
                      "building": {
                        "type": "string",
                        "description": "Building name"
                      },
                      "floor": {
                        "type": "string",
                        "description": "Floor"
                      },
                      "apartment": {
                        "type": "string",
                        "description": "Apartment / villa"
                      },
                      "area": {
                        "type": "string",
                        "description": "Area / neighbourhood"
                      },
                      "city": {
                        "type": "string",
                        "description": "City"
                      },
                      "instructions": {
                        "type": "string",
                        "description": "Notes for the rider",
                        "maxLength": 200
                      },
                      "location": {
                        "type": "object",
                        "properties": {
                          "lat": {
                            "type": "number",
                            "description": "Latitude",
                            "minimum": -90,
                            "maximum": 90,
                            "example": 25.2048
                          },
                          "lng": {
                            "type": "number",
                            "description": "Longitude",
                            "minimum": -180,
                            "maximum": 180,
                            "example": 55.2708
                          }
                        },
                        "required": [
                          "lat",
                          "lng"
                        ]
                      }
                    },
                    "required": [
                      "line1",
                      "floor",
                      "apartment",
                      "area",
                      "location"
                    ],
                    "additionalProperties": false,
                    "description": "Required for delivery. `floor`, `apartment` and `area` are mandatory so the rider can find the door."
                  },
                  "payment_method": {
                    "type": "string",
                    "description": "`cash` = collected at the door; `card` = customer pays online via the payment link",
                    "enum": [
                      "cash",
                      "card"
                    ]
                  },
                  "promo_code": {
                    "type": "string",
                    "description": "Optional promo code",
                    "maxLength": 40
                  },
                  "tip": {
                    "type": "number",
                    "description": "Optional tip (delivery only)",
                    "minimum": 0,
                    "maximum": 500
                  },
                  "notes": {
                    "type": "string",
                    "description": "Notes for the restaurant",
                    "maxLength": 300
                  },
                  "scheduled_at": {
                    "type": "string",
                    "description": "ISO 8601 time, for scheduled orders"
                  },
                  "reference": {
                    "type": "string",
                    "description": "Your own order reference — stored and searchable",
                    "maxLength": 80
                  }
                },
                "required": [
                  "store_id",
                  "fulfilment",
                  "items",
                  "customer",
                  "payment_method"
                ],
                "additionalProperties": false
              },
              "example": {
                "store_id": "66f1a2b3c4d5e6f708192a3b",
                "fulfilment": "delivery",
                "items": [
                  {
                    "item_id": "66f1a2b3c4d5e6f708192a50",
                    "quantity": 2,
                    "modifier_ids": [],
                    "notes": "No onions"
                  }
                ],
                "customer": {
                  "name": "Sara Ahmed",
                  "phone": "+971501234567"
                },
                "delivery_address": {
                  "line1": "Marina Tower",
                  "building": "Marina Tower",
                  "floor": "12",
                  "apartment": "1204",
                  "area": "Dubai Marina",
                  "city": "Dubai",
                  "location": {
                    "lat": 25.0805,
                    "lng": 55.1403
                  }
                },
                "payment_method": "cash",
                "reference": "PARTNER-100234"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same Idempotency-Key as an earlier request — the original order is returned (`Idempotent-Replayed: true`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Order"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Order created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Order"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_conflict` — the key was used with a different body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Business rule: `store_closed`, `out_of_zone`, `below_minimum_order`, `item_unavailable`, `address_incomplete`, `fulfilment_not_supported`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/orders' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY' \\\n  -H 'Idempotency-Key: order-100234' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"store_id\": \"66f1a2b3c4d5e6f708192a3b\",\n  \"fulfilment\": \"delivery\",\n  \"items\": [\n    {\n      \"item_id\": \"66f1a2b3c4d5e6f708192a50\",\n      \"quantity\": 2,\n      \"modifier_ids\": [],\n      \"notes\": \"No onions\"\n    }\n  ],\n  \"customer\": {\n    \"name\": \"Sara Ahmed\",\n    \"phone\": \"+971501234567\"\n  },\n  \"delivery_address\": {\n    \"line1\": \"Marina Tower\",\n    \"building\": \"Marina Tower\",\n    \"floor\": \"12\",\n    \"apartment\": \"1204\",\n    \"area\": \"Dubai Marina\",\n    \"city\": \"Dubai\",\n    \"location\": {\n      \"lat\": 25.0805,\n      \"lng\": 55.1403\n    }\n  },\n  \"payment_method\": \"cash\",\n  \"reference\": \"PARTNER-100234\"\n}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/orders`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n    'Idempotency-Key': 'order-100234',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    \"store_id\": \"66f1a2b3c4d5e6f708192a3b\",\n    \"fulfilment\": \"delivery\",\n    \"items\": [\n      {\n        \"item_id\": \"66f1a2b3c4d5e6f708192a50\",\n        \"quantity\": 2,\n        \"modifier_ids\": [],\n        \"notes\": \"No onions\"\n      }\n    ],\n    \"customer\": {\n      \"name\": \"Sara Ahmed\",\n      \"phone\": \"+971501234567\"\n    },\n    \"delivery_address\": {\n      \"line1\": \"Marina Tower\",\n      \"building\": \"Marina Tower\",\n      \"floor\": \"12\",\n      \"apartment\": \"1204\",\n      \"area\": \"Dubai Marina\",\n      \"city\": \"Dubai\",\n      \"location\": {\n        \"lat\": 25.0805,\n        \"lng\": 55.1403\n      }\n    },\n    \"payment_method\": \"cash\",\n    \"reference\": \"PARTNER-100234\"\n  }),\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/orders\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n        \"Idempotency-Key\": \"order-100234\",\n    },\n    json={\n        \"store_id\": \"66f1a2b3c4d5e6f708192a3b\",\n        \"fulfilment\": \"delivery\",\n        \"items\": [\n            {\n                \"item_id\": \"66f1a2b3c4d5e6f708192a50\",\n                \"quantity\": 2,\n                \"modifier_ids\": [],\n                \"notes\": \"No onions\"\n            }\n        ],\n        \"customer\": {\n            \"name\": \"Sara Ahmed\",\n            \"phone\": \"+971501234567\"\n        },\n        \"delivery_address\": {\n            \"line1\": \"Marina Tower\",\n            \"building\": \"Marina Tower\",\n            \"floor\": \"12\",\n            \"apartment\": \"1204\",\n            \"area\": \"Dubai Marina\",\n            \"city\": \"Dubai\",\n            \"location\": {\n                \"lat\": 25.0805,\n                \"lng\": 55.1403\n            }\n        },\n        \"payment_method\": \"cash\",\n        \"reference\": \"PARTNER-100234\"\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/orders');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n        'Idempotency-Key: order-100234',\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => json_encode([\n        \"store_id\" => \"66f1a2b3c4d5e6f708192a3b\",\n        \"fulfilment\" => \"delivery\",\n        \"items\" => [\n            [\n                \"item_id\" => \"66f1a2b3c4d5e6f708192a50\",\n                \"quantity\" => 2,\n                \"modifier_ids\" => [],\n                \"notes\" => \"No onions\"\n            ]\n        ],\n        \"customer\" => [\n            \"name\" => \"Sara Ahmed\",\n            \"phone\" => \"+971501234567\"\n        ],\n        \"delivery_address\" => [\n            \"line1\" => \"Marina Tower\",\n            \"building\" => \"Marina Tower\",\n            \"floor\" => \"12\",\n            \"apartment\" => \"1204\",\n            \"area\" => \"Dubai Marina\",\n            \"city\" => \"Dubai\",\n            \"location\" => [\n                \"lat\" => 25.0805,\n                \"lng\" => 55.1403\n            ]\n        ],\n        \"payment_method\" => \"cash\",\n        \"reference\" => \"PARTNER-100234\"\n    ]),\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      },
      "get": {
        "operationId": "listOrders",
        "tags": [
          "Orders"
        ],
        "summary": "List your orders",
        "description": "Orders created with your keys in this environment, newest first.\n\n**Required scope:** `orders:read`",
        "x-required-scope": "orders:read",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "",
              "enum": [
                "placed",
                "confirmed",
                "preparing",
                "ready",
                "out_for_delivery",
                "delivered",
                "completed",
                "cancelled",
                "partially_refunded",
                "refunded"
              ]
            }
          },
          {
            "name": "reference",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Exact match on your reference"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "ISO 8601 — created at or after"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "ISO 8601 — created at or before"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Page number (1-based)",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Items per page",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of orders",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Order"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/orders' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/orders`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/orders\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/orders');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/orders/{order_id}": {
      "get": {
        "operationId": "getOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Get an order",
        "description": "Current state of one order.\n\n**Required scope:** `orders:read`",
        "x-required-scope": "orders:read",
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Order id (`sbx_…` in the sandbox)"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Order"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found (or not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/orders/{order_id}' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/orders/{order_id}`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/orders/{order_id}\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/orders/{order_id}');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/orders/{order_id}/tracking": {
      "get": {
        "operationId": "getOrderTracking",
        "tags": [
          "Orders"
        ],
        "summary": "Track an order",
        "description": "Status timeline and, while a rider is delivering, the rider and their live position. Poll every 10–15 seconds at most — or use webhooks.\n\n**Required scope:** `orders:read`",
        "x-required-scope": "orders:read",
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Order id (`sbx_…` in the sandbox)"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tracking",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Tracking"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/orders/{order_id}/tracking' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/orders/{order_id}/tracking`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/orders/{order_id}/tracking\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/orders/{order_id}/tracking');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/orders/{order_id}/cancel": {
      "post": {
        "operationId": "cancelOrder",
        "tags": [
          "Orders"
        ],
        "summary": "Cancel an order",
        "description": "Cancels an order that the restaurant has not started preparing. Card orders that were already paid are reviewed by GoOrder support for refund.\n\n**Required scope:** `orders:write`",
        "x-required-scope": "orders:write",
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Order id (`sbx_…` in the sandbox)"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Shown to the restaurant",
                    "maxLength": 200
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "reason": "Customer changed their mind"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Order"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`order_not_cancellable`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/orders/{order_id}/cancel' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"reason\": \"Customer changed their mind\"\n}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/orders/{order_id}/cancel`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    \"reason\": \"Customer changed their mind\"\n  }),\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/orders/{order_id}/cancel\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n    json={\n        \"reason\": \"Customer changed their mind\"\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/orders/{order_id}/cancel');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => json_encode([\n        \"reason\" => \"Customer changed their mind\"\n    ]),\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/orders/{order_id}/payment": {
      "post": {
        "operationId": "createOrderPayment",
        "tags": [
          "Orders"
        ],
        "summary": "Create a payment link",
        "description": "For orders created with `payment_method: \"card\"`: returns a hosted payment page URL to send the customer to. The link is single-use: if the customer comes back later, call this endpoint again for a fresh one. When the customer pays, you receive an `order.payment_updated` webhook.\n\n**Required scope:** `orders:write`",
        "x-required-scope": "orders:write",
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Order id (`sbx_…` in the sandbox)"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "return_url": {
                    "type": "string",
                    "description": "Where to send the customer afterwards (must be a GoOrder-approved host)"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment link",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PaymentLink"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`invalid_payment_method` or `already_paid`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/orders/{order_id}/payment' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/orders/{order_id}/payment`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/orders/{order_id}/payment\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/orders/{order_id}/payment');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/webhooks/endpoint": {
      "get": {
        "operationId": "getWebhookEndpoint",
        "tags": [
          "Webhooks"
        ],
        "summary": "Get your webhook endpoint",
        "description": "The URL events are delivered to. The signing secret is never returned here.\n\n**Required scope:** `webhooks:manage`",
        "x-required-scope": "webhooks:manage",
        "responses": {
          "200": {
            "description": "Endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/webhooks/endpoint' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/webhooks/endpoint`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/webhooks/endpoint\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/webhooks/endpoint');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      },
      "put": {
        "operationId": "setWebhookEndpoint",
        "tags": [
          "Webhooks"
        ],
        "summary": "Set your webhook endpoint",
        "description": "Registers or changes the HTTPS URL that receives events. The first time, a signing secret (`whsec_…`) is generated and returned **once** — store it to verify signatures.\n\n**Required scope:** `webhooks:manage`",
        "x-required-scope": "webhooks:manage",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "HTTPS URL",
                    "maxLength": 500
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "",
                      "enum": [
                        "order.created",
                        "order.status_changed",
                        "order.payment_updated",
                        "order.refunded",
                        "webhook.test"
                      ]
                    },
                    "description": "Empty / omitted = all events"
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Pause or resume deliveries"
                  }
                },
                "required": [
                  "url"
                ],
                "additionalProperties": false
              },
              "example": {
                "url": "https://partner.example.com/hooks/goorder",
                "events": [
                  "order.status_changed",
                  "order.payment_updated"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`invalid_url`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X PUT 'https://back.goorder.com/api/partner/v1/webhooks/endpoint' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"url\": \"https://partner.example.com/hooks/goorder\",\n  \"events\": [\n    \"order.status_changed\",\n    \"order.payment_updated\"\n  ]\n}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/webhooks/endpoint`, {\n  method: 'PUT',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    \"url\": \"https://partner.example.com/hooks/goorder\",\n    \"events\": [\n      \"order.status_changed\",\n      \"order.payment_updated\"\n    ]\n  }),\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"PUT\",\n    \"https://back.goorder.com/api/partner/v1/webhooks/endpoint\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n    json={\n        \"url\": \"https://partner.example.com/hooks/goorder\",\n        \"events\": [\n            \"order.status_changed\",\n            \"order.payment_updated\"\n        ]\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/webhooks/endpoint');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'PUT',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => json_encode([\n        \"url\" => \"https://partner.example.com/hooks/goorder\",\n        \"events\" => [\n            \"order.status_changed\",\n            \"order.payment_updated\"\n        ]\n    ]),\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/webhooks/endpoint/rotate-secret": {
      "post": {
        "operationId": "rotateWebhookSecret",
        "tags": [
          "Webhooks"
        ],
        "summary": "Rotate the signing secret",
        "description": "Generates a new secret and returns it once. The old secret stops working immediately.\n\n**Required scope:** `webhooks:manage`",
        "x-required-scope": "webhooks:manage",
        "responses": {
          "200": {
            "description": "New secret",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/webhooks/endpoint/rotate-secret' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/webhooks/endpoint/rotate-secret`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/webhooks/endpoint/rotate-secret\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/webhooks/endpoint/rotate-secret');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/webhooks/test": {
      "post": {
        "operationId": "sendTestWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test event",
        "description": "Queues a `webhook.test` event to your endpoint so you can verify your signature check.\n\n**Required scope:** `webhooks:manage`",
        "x-required-scope": "webhooks:manage",
        "responses": {
          "202": {
            "description": "Queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "delivery_id": {
                          "type": "string",
                          "description": ""
                        },
                        "event_id": {
                          "type": "string",
                          "description": ""
                        }
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`webhook_not_configured`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/webhooks/test' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/webhooks/test`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/webhooks/test\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/webhooks/test');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/webhooks/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook deliveries",
        "description": "Recent deliveries with their status and your server’s last response. Kept for 30 days.\n\n**Required scope:** `webhooks:manage`",
        "x-required-scope": "webhooks:manage",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "",
              "enum": [
                "pending",
                "delivered",
                "failed"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Page number (1-based)",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Items per page",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deliveries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X GET 'https://back.goorder.com/api/partner/v1/webhooks/deliveries' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/webhooks/deliveries`, {\n  method: 'GET',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"GET\",\n    \"https://back.goorder.com/api/partner/v1/webhooks/deliveries\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/webhooks/deliveries');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'GET',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/webhooks/deliveries/{delivery_id}/redeliver": {
      "post": {
        "operationId": "redeliverWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Redeliver an event",
        "description": "Re-sends a delivery (any status) immediately — useful after fixing your endpoint.\n\n**Required scope:** `webhooks:manage`",
        "x-required-scope": "webhooks:manage",
        "parameters": [
          {
            "name": "delivery_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Delivery id"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`insufficient_scope` — the key lacks the required scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/webhooks/deliveries/{delivery_id}/redeliver' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/webhooks/deliveries/{delivery_id}/redeliver`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n  },\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/webhooks/deliveries/{delivery_id}/redeliver\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/webhooks/deliveries/{delivery_id}/redeliver');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n    ],\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    },
    "/sandbox/orders/{order_id}/advance": {
      "post": {
        "operationId": "advanceSandboxOrder",
        "tags": [
          "Sandbox"
        ],
        "summary": "Advance a sandbox order",
        "description": "Sandbox keys only. Moves a sandbox order to the next status (or a specific one) and fires the matching webhook, so you can test your whole integration without a real restaurant. Use `payment` to simulate the customer paying.\n\n**Required scope:** `orders:write`",
        "x-required-scope": "orders:write",
        "x-sandbox-only": true,
        "parameters": [
          {
            "name": "order_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Order id (`sbx_…` in the sandbox)"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "Jump to this status",
                    "enum": [
                      "placed",
                      "confirmed",
                      "preparing",
                      "ready",
                      "out_for_delivery",
                      "delivered",
                      "completed",
                      "cancelled",
                      "partially_refunded",
                      "refunded"
                    ]
                  },
                  "payment": {
                    "type": "string",
                    "description": "Simulate the card result",
                    "enum": [
                      "paid",
                      "failed"
                    ]
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "status": "preparing"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Order"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`validation_error` — a parameter or the body is invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`missing_api_key` or `invalid_api_key`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "`sandbox_only` — called with a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`order_not_advanceable`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` — slow down; see the `Retry-After` header",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error` — retry; quote `request_id` if it persists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "curl -X POST 'https://back.goorder.com/api/partner/v1/sandbox/orders/{order_id}/advance' \\\n  -H 'Authorization: Bearer $GOORDER_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n  \"status\": \"preparing\"\n}'"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js",
            "source": "const res = await fetch(`https://back.goorder.com/api/partner/v1/sandbox/orders/{order_id}/advance`, {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.GOORDER_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    \"status\": \"preparing\"\n  }),\n});\nconst { data, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message} (${error.request_id})`);"
          },
          {
            "lang": "Python",
            "source": "import os, requests\n\nres = requests.request(\n    \"POST\",\n    \"https://back.goorder.com/api/partner/v1/sandbox/orders/{order_id}/advance\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['GOORDER_API_KEY']}\",\n    },\n    json={\n        \"status\": \"preparing\"\n    },\n)\nres.raise_for_status()\nprint(res.json()[\"data\"])"
          },
          {
            "lang": "PHP",
            "source": "<?php\n$ch = curl_init('https://back.goorder.com/api/partner/v1/sandbox/orders/{order_id}/advance');\ncurl_setopt_array($ch, [\n    CURLOPT_CUSTOMREQUEST => 'POST',\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\n        'Authorization: Bearer ' . getenv('GOORDER_API_KEY'),\n        'Content-Type: application/json',\n    ],\n    CURLOPT_POSTFIELDS => json_encode([\n        \"status\" => \"preparing\"\n    ]),\n]);\n$response = json_decode(curl_exec($ch), true);\necho $response['data'] ?? $response['error']['message'];"
          }
        ]
      }
    }
  },
  "webhooks": {
    "order.created": {
      "post": {
        "summary": "order.created",
        "tags": [
          "Webhooks"
        ],
        "description": "Sent to your webhook URL when `order.created` occurs. Verify the `GoOrder-Signature` header before trusting it, and reply with any 2xx within 8 seconds.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              },
              "example": {
                "id": "evt_5b1e0c7d8a9f",
                "object": "event",
                "type": "order.created",
                "created": "2026-10-12T09:30:00.000Z",
                "environment": "live",
                "data": {
                  "order": {
                    "id": "66f1a2b3c4d5e6f708192a3b",
                    "object": "order",
                    "status": "placed",
                    "…": "…"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt (any 2xx)"
          }
        }
      }
    },
    "order.status_changed": {
      "post": {
        "summary": "order.status_changed",
        "tags": [
          "Webhooks"
        ],
        "description": "Sent to your webhook URL when `order.status_changed` occurs. Verify the `GoOrder-Signature` header before trusting it, and reply with any 2xx within 8 seconds.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              },
              "example": {
                "id": "evt_5b1e0c7d8a9f",
                "object": "event",
                "type": "order.status_changed",
                "created": "2026-10-12T09:30:00.000Z",
                "environment": "live",
                "data": {
                  "order": {
                    "id": "66f1a2b3c4d5e6f708192a3b",
                    "object": "order",
                    "status": "preparing",
                    "…": "…"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt (any 2xx)"
          }
        }
      }
    },
    "order.payment_updated": {
      "post": {
        "summary": "order.payment_updated",
        "tags": [
          "Webhooks"
        ],
        "description": "Sent to your webhook URL when `order.payment_updated` occurs. Verify the `GoOrder-Signature` header before trusting it, and reply with any 2xx within 8 seconds.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              },
              "example": {
                "id": "evt_5b1e0c7d8a9f",
                "object": "event",
                "type": "order.payment_updated",
                "created": "2026-10-12T09:30:00.000Z",
                "environment": "live",
                "data": {
                  "order": {
                    "id": "66f1a2b3c4d5e6f708192a3b",
                    "object": "order",
                    "status": "preparing",
                    "…": "…"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt (any 2xx)"
          }
        }
      }
    },
    "order.refunded": {
      "post": {
        "summary": "order.refunded",
        "tags": [
          "Webhooks"
        ],
        "description": "Sent to your webhook URL when `order.refunded` occurs. Verify the `GoOrder-Signature` header before trusting it, and reply with any 2xx within 8 seconds.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              },
              "example": {
                "id": "evt_5b1e0c7d8a9f",
                "object": "event",
                "type": "order.refunded",
                "created": "2026-10-12T09:30:00.000Z",
                "environment": "live",
                "data": {
                  "order": {
                    "id": "66f1a2b3c4d5e6f708192a3b",
                    "object": "order",
                    "status": "preparing",
                    "…": "…"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt (any 2xx)"
          }
        }
      }
    },
    "webhook.test": {
      "post": {
        "summary": "webhook.test",
        "tags": [
          "Webhooks"
        ],
        "description": "Sent to your webhook URL when `webhook.test` occurs. Verify the `GoOrder-Signature` header before trusting it, and reply with any 2xx within 8 seconds.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              },
              "example": {
                "id": "evt_5b1e0c7d8a9f",
                "object": "event",
                "type": "webhook.test",
                "created": "2026-10-12T09:30:00.000Z",
                "environment": "live",
                "data": {
                  "message": "Hello from GoOrder. Your endpoint is reachable."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt (any 2xx)"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "gok_live_… | gok_test_…",
        "description": "Secret API key. Send `Authorization: Bearer gok_live_…`. `X-API-Key` is also accepted. Never expose a key in a browser or mobile app."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable code",
                "example": "store_closed"
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation",
                "example": "This store is currently closed."
              },
              "request_id": {
                "type": "string",
                "description": "Quote this when contacting support",
                "example": "req_9f2c1a7b3d4e"
              },
              "details": {
                "type": "object",
                "additionalProperties": true,
                "description": "Extra context, when available"
              }
            },
            "required": [
              "code",
              "message",
              "request_id"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "description": "Current page",
            "example": 1
          },
          "limit": {
            "type": "integer",
            "description": "Page size",
            "example": 20
          },
          "total": {
            "type": "integer",
            "description": "Total matching records",
            "example": 134
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether another page exists"
          }
        },
        "required": [
          "page",
          "limit",
          "total",
          "has_more"
        ]
      },
      "Money": {
        "type": "number",
        "description": "Amount in AED (two decimals)",
        "example": 42.5
      },
      "StoreBrief": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Store id",
            "example": "66f1a2b3c4d5e6f708192a3b"
          },
          "name": {
            "type": "string",
            "description": "Store name",
            "example": "Burger Lab"
          },
          "name_ar": {
            "type": [
              "string",
              "null"
            ],
            "description": "Arabic name"
          },
          "vertical": {
            "type": "string",
            "description": "Business type",
            "enum": [
              "restaurant",
              "pharmacy",
              "grocery"
            ]
          },
          "image_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Logo / photo URL"
          },
          "rating": {
            "type": [
              "number",
              "null"
            ],
            "description": "Average rating (0–5)"
          },
          "status": {
            "type": "string",
            "description": "Right now: `open`, `busy` (paused by the restaurant) or `closed`",
            "enum": [
              "open",
              "busy",
              "closed"
            ]
          },
          "accepting_orders": {
            "type": "boolean",
            "description": "True only when status is `open`"
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "lat": {
                "type": "number",
                "description": "Latitude",
                "minimum": -90,
                "maximum": 90,
                "example": 25.2048
              },
              "lng": {
                "type": "number",
                "description": "Longitude",
                "minimum": -180,
                "maximum": 180,
                "example": 55.2708
              }
            },
            "required": [
              "lat",
              "lng"
            ]
          },
          "address": {
            "type": "object",
            "properties": {
              "line": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Street address"
              },
              "city": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "City"
              },
              "country": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Country"
              }
            }
          },
          "distance_km": {
            "type": [
              "number",
              "null"
            ],
            "description": "Distance from the supplied lat/lng"
          },
          "delivery": {
            "type": "object",
            "properties": {
              "min_order": {
                "$ref": "#/components/schemas/Money"
              },
              "fee": {
                "$ref": "#/components/schemas/Money"
              },
              "eta_minutes": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Typical preparation + delivery time"
              },
              "radius_km": {
                "type": "number",
                "description": "Delivery radius"
              }
            }
          },
          "fulfilment_types": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "",
              "enum": [
                "delivery",
                "pickup"
              ]
            }
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "accepting_orders"
        ]
      },
      "Store": {
        "allOf": [
          {
            "$ref": "#/components/schemas/StoreBrief"
          },
          {
            "type": "object",
            "properties": {
              "description": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "About the store"
              },
              "description_ar": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Arabic description"
              },
              "cover_url": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Cover image URL"
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Store phone"
              },
              "cuisines": {
                "type": "array",
                "items": {
                  "type": "string",
                  "description": "Cuisine / tag"
                }
              },
              "dietary_tags": {
                "type": "array",
                "items": {
                  "type": "string",
                  "description": "Halal, Vegan, …"
                }
              },
              "hours": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "day": {
                      "type": "string",
                      "description": "Weekday",
                      "example": "Monday"
                    },
                    "open": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "HH:mm",
                      "example": "10:00"
                    },
                    "close": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "HH:mm",
                      "example": "23:00"
                    },
                    "closed": {
                      "type": "boolean",
                      "description": "Closed all day"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "ModifierGroup": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Group id"
          },
          "name": {
            "type": "string",
            "description": "Group name",
            "example": "Choose your size"
          },
          "required": {
            "type": "boolean",
            "description": "Customer must choose"
          },
          "min_select": {
            "type": "integer",
            "description": "Minimum choices"
          },
          "max_select": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Maximum choices (null = unlimited)"
          },
          "options": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Option id (send as modifier_ids when ordering)"
                },
                "name": {
                  "type": "string",
                  "description": "Option name",
                  "example": "Large"
                },
                "price": {
                  "$ref": "#/components/schemas/Money"
                }
              },
              "required": [
                "id",
                "name",
                "price"
              ]
            }
          }
        },
        "required": [
          "name",
          "options"
        ]
      },
      "Item": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Item id (send as item_id when ordering)"
          },
          "name": {
            "type": "string",
            "description": "Item name",
            "example": "Classic Burger"
          },
          "name_ar": {
            "type": [
              "string",
              "null"
            ],
            "description": "Arabic name"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Description"
          },
          "image_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Photo URL"
          },
          "price": {
            "$ref": "#/components/schemas/Money"
          },
          "original_price": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "type": "string",
            "description": "ISO currency",
            "example": "AED"
          },
          "available": {
            "type": "boolean",
            "description": "Orderable right now"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Tag"
            }
          },
          "modifier_groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModifierGroup"
            }
          }
        },
        "required": [
          "id",
          "name",
          "price",
          "available"
        ]
      },
      "Menu": {
        "type": "object",
        "properties": {
          "store": {
            "$ref": "#/components/schemas/Store"
          },
          "currency": {
            "type": "string",
            "description": "",
            "example": "AED"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Category id"
                },
                "name": {
                  "type": "string",
                  "description": "Category name",
                  "example": "Burgers"
                },
                "name_ar": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Arabic name"
                },
                "items": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Item"
                  }
                }
              },
              "required": [
                "name",
                "items"
              ]
            }
          }
        },
        "required": [
          "store",
          "categories"
        ]
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Category id"
          },
          "name": {
            "type": "string",
            "description": "Name",
            "example": "Burgers"
          },
          "name_ar": {
            "type": [
              "string",
              "null"
            ],
            "description": "Arabic name"
          },
          "image_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Image URL"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "DeliveryQuote": {
        "type": "object",
        "properties": {
          "deliverable": {
            "type": "boolean",
            "description": "Whether this address is inside the store’s delivery area"
          },
          "distance_km": {
            "type": [
              "number",
              "null"
            ],
            "description": "Straight-line distance"
          },
          "radius_km": {
            "type": "number",
            "description": "Delivery radius"
          },
          "fee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "type": "string",
            "description": "",
            "example": "AED"
          },
          "min_order": {
            "$ref": "#/components/schemas/Money"
          },
          "status": {
            "type": "string",
            "description": "Store status right now",
            "enum": [
              "open",
              "busy",
              "closed"
            ]
          }
        },
        "required": [
          "deliverable",
          "fee"
        ]
      },
      "Offer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Offer id"
          },
          "title": {
            "type": "string",
            "description": "Title",
            "example": "20% off burgers"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Details"
          },
          "type": {
            "type": "string",
            "description": "Discount type",
            "enum": [
              "percentage",
              "fixed-amount",
              "free-delivery"
            ]
          },
          "value": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent or AED amount"
          },
          "max_discount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ]
          },
          "min_order": {
            "$ref": "#/components/schemas/Money"
          },
          "ends_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "ISO 8601 end time"
          },
          "image_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Banner URL"
          },
          "funded_by": {
            "type": "string",
            "description": "Who pays for it",
            "enum": [
              "platform",
              "merchant"
            ]
          },
          "stores": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Store id"
                },
                "name": {
                  "type": "string",
                  "description": "Store name"
                },
                "distance_km": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "Distance"
                }
              }
            }
          }
        },
        "required": [
          "id",
          "title",
          "type"
        ]
      },
      "PromoValidation": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean",
            "description": "Whether the code can be applied"
          },
          "code": {
            "type": "string",
            "description": "Code, upper-cased"
          },
          "discount_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "percentage or fixed"
          },
          "discount_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Money"
              },
              {
                "type": "null"
              }
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the code was rejected"
          }
        },
        "required": [
          "valid",
          "code"
        ]
      },
      "OrderItem": {
        "type": "object",
        "properties": {
          "item_id": {
            "type": "string",
            "description": "Item id"
          },
          "name": {
            "type": "string",
            "description": "Item name at order time"
          },
          "quantity": {
            "type": "integer",
            "description": "Quantity"
          },
          "unit_price": {
            "$ref": "#/components/schemas/Money"
          },
          "modifiers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": ""
                },
                "name": {
                  "type": "string",
                  "description": ""
                },
                "price": {
                  "$ref": "#/components/schemas/Money"
                }
              }
            }
          },
          "notes": {
            "type": [
              "string",
              "null"
            ],
            "description": "Special instructions"
          },
          "line_total": {
            "$ref": "#/components/schemas/Money"
          }
        },
        "required": [
          "item_id",
          "quantity",
          "unit_price",
          "line_total"
        ]
      },
      "Address": {
        "type": "object",
        "properties": {
          "line1": {
            "type": [
              "string",
              "null"
            ],
            "description": "Street / building line"
          },
          "building": {
            "type": [
              "string",
              "null"
            ],
            "description": "Building"
          },
          "floor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Floor"
          },
          "apartment": {
            "type": [
              "string",
              "null"
            ],
            "description": "Apartment / villa"
          },
          "area": {
            "type": [
              "string",
              "null"
            ],
            "description": "Area / neighbourhood"
          },
          "city": {
            "type": [
              "string",
              "null"
            ],
            "description": "City"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ],
            "description": "Notes for the rider"
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "lat": {
                "type": "number",
                "description": "Latitude",
                "minimum": -90,
                "maximum": 90,
                "example": 25.2048
              },
              "lng": {
                "type": "number",
                "description": "Longitude",
                "minimum": -180,
                "maximum": 180,
                "example": 55.2708
              }
            },
            "required": [
              "lat",
              "lng"
            ]
          }
        }
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Order id",
            "example": "66f1a2b3c4d5e6f708192a3b"
          },
          "object": {
            "type": "string",
            "description": "Always `order`",
            "enum": [
              "order"
            ]
          },
          "environment": {
            "type": "string",
            "description": "`live` or `sandbox`",
            "enum": [
              "live",
              "sandbox"
            ]
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your own order reference"
          },
          "order_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "Customer-facing order number"
          },
          "status": {
            "type": "string",
            "description": "Lifecycle status",
            "enum": [
              "placed",
              "confirmed",
              "preparing",
              "ready",
              "out_for_delivery",
              "delivered",
              "completed",
              "cancelled",
              "partially_refunded",
              "refunded"
            ]
          },
          "fulfilment": {
            "type": "string",
            "description": "",
            "enum": [
              "delivery",
              "pickup",
              "dine_in"
            ]
          },
          "store": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Store id"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Store name"
              }
            }
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderItem"
            }
          },
          "pricing": {
            "type": "object",
            "properties": {
              "subtotal": {
                "$ref": "#/components/schemas/Money"
              },
              "delivery_fee": {
                "$ref": "#/components/schemas/Money"
              },
              "tip": {
                "$ref": "#/components/schemas/Money"
              },
              "discount": {
                "$ref": "#/components/schemas/Money"
              },
              "total": {
                "$ref": "#/components/schemas/Money"
              },
              "currency": {
                "type": "string",
                "description": "",
                "example": "AED"
              }
            }
          },
          "payment": {
            "type": "object",
            "properties": {
              "method": {
                "type": "string",
                "description": "",
                "enum": [
                  "cash",
                  "card"
                ]
              },
              "status": {
                "type": "string",
                "description": "pending, paid, failed, partially_refunded or refunded"
              },
              "amount": {
                "$ref": "#/components/schemas/Money"
              },
              "refunded_amount": {
                "$ref": "#/components/schemas/Money"
              },
              "currency": {
                "type": "string",
                "description": ""
              }
            }
          },
          "customer": {
            "type": "object",
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Customer name"
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Customer phone"
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Customer email"
              }
            }
          },
          "delivery_address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "notes": {
            "type": [
              "string",
              "null"
            ],
            "description": "Order notes"
          },
          "promo_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Applied promo code"
          },
          "scheduled_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "ISO 8601 time for scheduled orders"
          },
          "cancel_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why it was cancelled"
          },
          "created_at": {
            "type": "string",
            "description": "ISO 8601"
          },
          "updated_at": {
            "type": "string",
            "description": "ISO 8601"
          }
        },
        "required": [
          "id",
          "object",
          "status",
          "fulfilment",
          "items",
          "pricing",
          "payment"
        ]
      },
      "Tracking": {
        "type": "object",
        "properties": {
          "order_id": {
            "type": "string",
            "description": "Order id"
          },
          "environment": {
            "type": "string",
            "description": "",
            "enum": [
              "live",
              "sandbox"
            ]
          },
          "status": {
            "type": "string",
            "description": "",
            "enum": [
              "placed",
              "confirmed",
              "preparing",
              "ready",
              "out_for_delivery",
              "delivered",
              "completed",
              "cancelled",
              "partially_refunded",
              "refunded"
            ]
          },
          "fulfilment": {
            "type": "string",
            "description": "",
            "enum": [
              "delivery",
              "pickup",
              "dine_in"
            ]
          },
          "timeline": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string",
                  "description": "",
                  "enum": [
                    "placed",
                    "confirmed",
                    "preparing",
                    "ready",
                    "out_for_delivery",
                    "delivered",
                    "completed",
                    "cancelled",
                    "partially_refunded",
                    "refunded"
                  ]
                },
                "at": {
                  "type": "string",
                  "description": "ISO 8601"
                }
              },
              "required": [
                "status",
                "at"
              ]
            }
          },
          "eta_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Estimated minutes remaining"
          },
          "rider": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "name": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Rider name"
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Rider phone"
              },
              "vehicle": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "bike or car"
              },
              "location": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "lat": {
                    "type": "number",
                    "description": "Latitude",
                    "minimum": -90,
                    "maximum": 90,
                    "example": 25.2048
                  },
                  "lng": {
                    "type": "number",
                    "description": "Longitude",
                    "minimum": -180,
                    "maximum": 180,
                    "example": 55.2708
                  },
                  "updated_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ISO 8601"
                  }
                }
              }
            }
          }
        },
        "required": [
          "order_id",
          "status",
          "timeline"
        ]
      },
      "PaymentLink": {
        "type": "object",
        "properties": {
          "order_id": {
            "type": "string",
            "description": "Order id"
          },
          "payment_url": {
            "type": "string",
            "description": "Send the customer here to pay by card"
          },
          "environment": {
            "type": "string",
            "description": "",
            "enum": [
              "live",
              "sandbox"
            ]
          },
          "note": {
            "type": "string",
            "description": "Sandbox hint"
          }
        },
        "required": [
          "order_id",
          "payment_url"
        ]
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Where events are POSTed"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "",
              "enum": [
                "order.created",
                "order.status_changed",
                "order.payment_updated",
                "order.refunded",
                "webhook.test"
              ]
            }
          },
          "enabled": {
            "type": "boolean",
            "description": "Deliveries on/off"
          },
          "secret": {
            "type": "string",
            "description": "Signing secret — returned only when created or rotated",
            "example": "whsec_…"
          },
          "last_success_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "ISO 8601"
          },
          "last_failure_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "ISO 8601"
          }
        },
        "required": [
          "url",
          "events",
          "enabled"
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Delivery id"
          },
          "event_id": {
            "type": "string",
            "description": "Event id (`evt_…`)"
          },
          "type": {
            "type": "string",
            "description": "",
            "enum": [
              "order.created",
              "order.status_changed",
              "order.payment_updated",
              "order.refunded",
              "webhook.test"
            ]
          },
          "status": {
            "type": "string",
            "description": "",
            "enum": [
              "pending",
              "delivered",
              "failed"
            ]
          },
          "attempts": {
            "type": "integer",
            "description": "Attempts so far"
          },
          "response_code": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Last HTTP status from your server"
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Last failure reason"
          },
          "next_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "ISO 8601"
          },
          "created_at": {
            "type": "string",
            "description": "ISO 8601"
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "ISO 8601"
          }
        },
        "required": [
          "id",
          "event_id",
          "type",
          "status"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Event id",
            "example": "evt_5b1e0c7d8a9f"
          },
          "object": {
            "type": "string",
            "description": "Always `event`",
            "enum": [
              "event"
            ]
          },
          "type": {
            "type": "string",
            "description": "",
            "enum": [
              "order.created",
              "order.status_changed",
              "order.payment_updated",
              "order.refunded",
              "webhook.test"
            ]
          },
          "created": {
            "type": "string",
            "description": "ISO 8601"
          },
          "environment": {
            "type": "string",
            "description": "",
            "enum": [
              "live",
              "sandbox"
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "order": {
                "$ref": "#/components/schemas/Order"
              },
              "previous_status": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Previous order status"
              }
            }
          }
        },
        "required": [
          "id",
          "type",
          "created",
          "data"
        ]
      }
    }
  },
  "x-scopes": {
    "catalog:read": "Read stores, menus, items, search and delivery quotes",
    "offers:read": "Read offers and validate promo codes",
    "orders:read": "Read orders and live tracking",
    "orders:write": "Create, pay for and cancel orders",
    "webhooks:manage": "Configure the webhook endpoint and read deliveries"
  }
}