{
    "openapi": "3.0.3",
    "info": {
        "title": "ServedHQ API",
        "version": "1.1.0",
        "description": "Integration API for ServedHQ businesses: catalogue and record reads,\nbooking availability, and reservation creation.\n\nThis contract documents the currently implemented read and booking API\nsurface. POS writes, customer mutations, loyalty, and webhook management\nare not API operations in this version. Booking prices and availability\nare always calculated and checked by ServedHQ.\n\nCredentials are issued by a business owner in the ServedHQ admin area.\nTokens are scoped, expire optionally, and are revoked by deleting them.\nExisting legacy credentials with a null scope value retain the three\ndocumented read capabilities only.\n",
        "contact": {
            "name": "ServedHQ support"
        },
        "license": {
            "name": "ServedHQ terms of service"
        }
    },
    "servers": [
        {
            "url": "https://{host}/api",
            "description": "ServedHQ API host",
            "variables": {
                "host": {
                    "default": "servedhq.com",
                    "description": "The ServedHQ application host"
                }
            }
        }
    ],
    "tags": [
        {
            "name": "Menu",
            "description": "Default menu catalogue"
        },
        {
            "name": "Orders",
            "description": "Read-only online order records"
        },
        {
            "name": "Reservations",
            "description": "Booking services, availability, creation and reservation records"
        }
    ],
    "paths": {
        "/v1/menu": {
            "get": {
                "tags": [
                    "Menu"
                ],
                "summary": "Get the business menu",
                "description": "Returns the authenticated business's default menu grouped by category.\nAn empty `data` array is returned when no default menu exists.\nOnly available fields are returned; this is not a complete catalogue\nor public discovery contract.\n",
                "operationId": "getMenu",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "catalog:read",
                "responses": {
                    "200": {
                        "description": "Menu returned successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/MenuResponse"
                                },
                                "examples": {
                                    "populated": {
                                        "value": {
                                            "data": [
                                                {
                                                    "category": "Mains",
                                                    "items": [
                                                        {
                                                            "id": 42,
                                                            "name": "Chickpea curry",
                                                            "description": "Tomato, ginger and toasted cumin",
                                                            "price_pence": 1250,
                                                            "is_available": true
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    },
                                    "empty": {
                                        "value": {
                                            "data": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/v1/orders": {
            "get": {
                "tags": [
                    "Orders"
                ],
                "summary": "List orders",
                "description": "Returns orders belonging to the authenticated business. Results are\nordered newest first and paginated. `since` accepts a date or timestamp\nunderstood by the application.\n",
                "operationId": "listOrders",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "orders:read",
                "x-required-addon": "online_ordering",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Filter by order status.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 40
                        }
                    },
                    {
                        "name": "since",
                        "in": "query",
                        "description": "Return orders created at or after this date or timestamp.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        },
                        "example": "2026-09-22T00:00:00Z"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated orders",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/OrderListResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/v1/orders/{order}": {
            "get": {
                "tags": [
                    "Orders"
                ],
                "summary": "Get an order",
                "description": "Returns one order belonging to the authenticated business.",
                "operationId": "getOrder",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "orders:read",
                "x-required-addon": "online_ordering",
                "parameters": [
                    {
                        "name": "order",
                        "in": "path",
                        "description": "Numeric order identifier.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Order returned successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/OrderResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/v1/services": {
            "get": {
                "tags": [
                    "Reservations"
                ],
                "summary": "List bookable services",
                "description": "Returns the public, available services and their option groups for booking.",
                "operationId": "listBookableServices",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "reservations:create",
                "x-required-addon": "reservations",
                "responses": {
                    "200": {
                        "description": "Bookable services",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ServiceListResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/v1/availability": {
            "get": {
                "tags": [
                    "Reservations"
                ],
                "summary": "List available booking slots",
                "description": "Returns slots calculated for the selected services on a business-local date.\nWhen the business sets a number of people per time slot, a group larger\nthan that capacity needs one run of the services per wave of people,\nback to back within one shift (for example 3 people at 2 per slot need\ntwo consecutive runs). Only start times where every run fits are returned.\nOmitting party_size checks availability for one person, which matches the\nbehaviour before contract 1.1.0.\n",
                "operationId": "listAvailability",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "reservations:create",
                "x-required-addon": "reservations",
                "parameters": [
                    {
                        "name": "date",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "menu_item_ids",
                        "in": "query",
                        "required": false,
                        "description": "Menu item IDs whose combined duration should be checked.",
                        "style": "form",
                        "explode": true,
                        "schema": {
                            "type": "array",
                            "maxItems": 20,
                            "items": {
                                "type": "integer"
                            }
                        }
                    },
                    {
                        "name": "party_size",
                        "in": "query",
                        "required": false,
                        "description": "Number of people to fit (added in 1.1.0). Defaults to 1.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 50,
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Available slots",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AvailabilityResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/v1/reservations": {
            "get": {
                "tags": [
                    "Reservations"
                ],
                "summary": "List reservations",
                "description": "Returns reservations belonging to the authenticated business. Results\nare ordered by reserved date and time. Enquiry-only records may have a\nnull reserved date and are identified by `is_enquiry_only`.\n",
                "operationId": "listReservations",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "reservations:read",
                "x-required-addon": "reservations",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Filter by reservation status.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 40
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "description": "Return reservations on or after this business date.",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-09-22"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated reservations",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ReservationListResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Reservations"
                ],
                "summary": "Create a reservation",
                "description": "Creates a pending reservation after validating the selected public\nservices, option selections, booking window, business ownership of a\nstaff member, and slot availability. The client must send a unique\nIdempotency-Key. Repeating the same request with the same key replays\nthe original response; reusing a key with a different body is a 409.\nPrices and duration supplied by a client are ignored.\n\nFrom contract 1.1.0, services are priced per person: each item's\nprice_pence is the unit price (service plus selected options) times\nparty_size, reported as quantity and unit_price_pence. Restaurant\ntable bookings are not priced per person. When the business sets a\nnumber of people per time slot, total_duration_minutes covers every\nback-to-back run the group needs and the whole run must be free;\notherwise the request fails with slot_unavailable. Deposits that a\nbusiness sets per service are taken per person.\n",
                "operationId": "createReservation",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "reservations:create",
                "x-required-addon": "reservations",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/IdempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateReservationRequest"
                            },
                            "example": {
                                "customer_name": "Alex Morgan",
                                "customer_email": "alex@example.com",
                                "customer_phone": "+447700900123",
                                "party_size": 2,
                                "reserved_date": "2026-10-01",
                                "reserved_time": "18:30",
                                "service_items": [
                                    {
                                        "menu_item_id": 42,
                                        "selected_options": [
                                            {
                                                "group_id": 7,
                                                "option_ids": [
                                                    12
                                                ]
                                            }
                                        ]
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Reservation created in pending state",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ReservationResponse"
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "Deposit payment is required before the reservation is created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/PaymentRequiredResponse"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/IdempotencyRequired"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/BookingConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/v1/reservations/{reservation}": {
            "get": {
                "tags": [
                    "Reservations"
                ],
                "summary": "Get a reservation",
                "description": "Returns one reservation belonging to the authenticated business.",
                "operationId": "getReservation",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "x-required-scope": "reservations:read",
                "x-required-addon": "reservations",
                "parameters": [
                    {
                        "name": "reservation",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "format": "int64",
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reservation returned successfully",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ReservationResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "ServedHQ API token",
                "description": "Send the token in `Authorization: Bearer <token>`. Tokens are shown\nonly once when created. Never put a merchant token in browser code or\na distributed client.\n"
            }
        },
        "parameters": {
            "IdempotencyKey": {
                "name": "Idempotency-Key",
                "in": "header",
                "required": true,
                "description": "A client-generated key reused for safe retries of the same request.",
                "schema": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                }
            },
            "PerPage": {
                "name": "per_page",
                "in": "query",
                "description": "Number of records per page.",
                "required": false,
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 25
                }
            },
            "Page": {
                "name": "page",
                "in": "query",
                "description": "One-based page number.",
                "required": false,
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 1
                }
            }
        },
        "responses": {
            "Unauthorized": {
                "description": "Missing, invalid, revoked, or expired token",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "error": "Invalid or expired API token."
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "Business, entitlement, or scope access denied",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "insufficientScope": {
                                "value": {
                                    "error": "Token does not permit this action.",
                                    "code": "insufficient_scope"
                                }
                            },
                            "capabilityDisabled": {
                                "value": {
                                    "error": "Required API capability is not enabled.",
                                    "code": "capability_disabled"
                                }
                            },
                            "businessDisabled": {
                                "value": {
                                    "error": "Business access is disabled.",
                                    "code": "business_disabled"
                                }
                            }
                        }
                    }
                }
            },
            "NotFound": {
                "description": "Resource does not exist for this business",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "No query results for model [App\\\\Models\\\\Order]."
                        }
                    }
                }
            },
            "ValidationFailed": {
                "description": "Invalid query parameter or request body",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ValidationError"
                        },
                        "example": {
                            "message": "The given data was invalid.",
                            "errors": {
                                "per_page": [
                                    "The per page field must be at least 1."
                                ]
                            }
                        }
                    }
                }
            },
            "RateLimited": {
                "description": "More than 60 requests in one minute",
                "headers": {
                    "Retry-After": {
                        "schema": {
                            "type": "integer"
                        },
                        "description": "Number of seconds to wait before retrying."
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "IdempotencyRequired": {
                "description": "Missing or invalid Idempotency-Key header",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "error": "The Idempotency-Key header is required and must be 255 characters or fewer.",
                            "code": "idempotency_key_required"
                        }
                    }
                }
            },
            "BookingConflict": {
                "description": "Slot, idempotency, or booking state conflict",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "error": "The requested booking slot is no longer available.",
                            "code": "slot_unavailable"
                        }
                    }
                }
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "required": [
                    "error"
                ],
                "properties": {
                    "error": {
                        "type": "string"
                    },
                    "code": {
                        "type": "string",
                        "description": "Stable machine-readable error code when supplied."
                    }
                },
                "additionalProperties": true
            },
            "ValidationError": {
                "type": "object",
                "required": [
                    "message",
                    "errors"
                ],
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "errors": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "PaginationMeta": {
                "type": "object",
                "required": [
                    "current_page",
                    "last_page",
                    "total"
                ],
                "properties": {
                    "current_page": {
                        "type": "integer",
                        "minimum": 1
                    },
                    "last_page": {
                        "type": "integer",
                        "minimum": 1
                    },
                    "total": {
                        "type": "integer",
                        "minimum": 0
                    }
                }
            },
            "MenuResponse": {
                "type": "object",
                "required": [
                    "data"
                ],
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/MenuCategory"
                        }
                    }
                }
            },
            "MenuCategory": {
                "type": "object",
                "required": [
                    "category",
                    "items"
                ],
                "properties": {
                    "category": {
                        "type": "string"
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/MenuItem"
                        }
                    }
                }
            },
            "MenuItem": {
                "type": "object",
                "required": [
                    "id",
                    "name",
                    "description",
                    "price_pence",
                    "is_available"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "price_pence": {
                        "type": "integer",
                        "minimum": 0
                    },
                    "is_available": {
                        "type": "boolean"
                    }
                }
            },
            "ServiceListResponse": {
                "type": "object",
                "required": [
                    "data"
                ],
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/BookableService"
                        }
                    }
                }
            },
            "BookableService": {
                "type": "object",
                "required": [
                    "id",
                    "name",
                    "duration",
                    "price_pence",
                    "option_groups"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "menu": {
                        "type": "string"
                    },
                    "category": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "is_bookable": {
                        "type": "boolean"
                    },
                    "duration": {
                        "type": "integer"
                    },
                    "requires_address": {
                        "type": "boolean"
                    },
                    "is_enquiry_only": {
                        "type": "boolean"
                    },
                    "price_pence": {
                        "type": "integer"
                    },
                    "option_groups": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OptionGroup"
                        }
                    }
                }
            },
            "OptionGroup": {
                "type": "object",
                "required": [
                    "id",
                    "name",
                    "selection_type",
                    "min_selections",
                    "max_selections",
                    "is_required",
                    "options"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "selection_type": {
                        "type": "string"
                    },
                    "min_selections": {
                        "type": "integer"
                    },
                    "max_selections": {
                        "type": "integer"
                    },
                    "is_required": {
                        "type": "boolean"
                    },
                    "options": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ServiceOption"
                        }
                    }
                }
            },
            "ServiceOption": {
                "type": "object",
                "required": [
                    "id",
                    "name",
                    "price_pence"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "price_pence": {
                        "type": "integer"
                    }
                }
            },
            "AvailabilityResponse": {
                "type": "object",
                "required": [
                    "date",
                    "duration_minutes",
                    "slots"
                ],
                "properties": {
                    "date": {
                        "type": "string",
                        "format": "date"
                    },
                    "duration_minutes": {
                        "type": "integer",
                        "description": "Total booking time for the requested party, including back-to-back runs for groups larger than the slot capacity."
                    },
                    "slots": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "pattern": "^\\\\d{2}:\\\\d{2}$"
                        }
                    }
                }
            },
            "CreateReservationRequest": {
                "type": "object",
                "required": [
                    "customer_name",
                    "customer_email",
                    "party_size"
                ],
                "properties": {
                    "customer_name": {
                        "type": "string",
                        "maxLength": 150
                    },
                    "customer_email": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 255
                    },
                    "customer_phone": {
                        "type": "string",
                        "maxLength": 30
                    },
                    "attendee_name": {
                        "type": "string",
                        "maxLength": 150
                    },
                    "attendee_phone": {
                        "type": "string",
                        "maxLength": 30
                    },
                    "service_name": {
                        "type": "string",
                        "maxLength": 150
                    },
                    "service_address": {
                        "type": "string",
                        "maxLength": 500
                    },
                    "party_size": {
                        "type": "integer",
                        "minimum": 1
                    },
                    "reserved_date": {
                        "type": "string",
                        "format": "date"
                    },
                    "reserved_time": {
                        "type": "string",
                        "pattern": "^\\\\d{2}:\\\\d{2}$"
                    },
                    "staff_member_id": {
                        "type": "integer"
                    },
                    "notes": {
                        "type": "string",
                        "maxLength": 500
                    },
                    "custom_field_values": {
                        "type": "object",
                        "additionalProperties": true
                    },
                    "marketing_consent": {
                        "type": "boolean"
                    },
                    "service_items": {
                        "type": "array",
                        "maxItems": 20,
                        "items": {
                            "$ref": "#/components/schemas/ReservationServiceSelection"
                        }
                    }
                }
            },
            "ReservationServiceSelection": {
                "type": "object",
                "required": [
                    "menu_item_id"
                ],
                "properties": {
                    "menu_item_id": {
                        "type": "integer"
                    },
                    "selected_options": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "group_id",
                                "option_ids"
                            ],
                            "properties": {
                                "group_id": {
                                    "type": "integer"
                                },
                                "option_ids": {
                                    "type": "array",
                                    "items": {
                                        "type": "integer"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "ReservationResponse": {
                "type": "object",
                "required": [
                    "data"
                ],
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/CreatedReservation"
                    }
                }
            },
            "CreatedReservation": {
                "type": "object",
                "required": [
                    "id",
                    "status",
                    "customer_name",
                    "customer_email",
                    "party_size",
                    "items",
                    "created_at"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "status": {
                        "type": "string",
                        "example": "pending"
                    },
                    "customer_name": {
                        "type": "string"
                    },
                    "customer_email": {
                        "type": "string",
                        "format": "email"
                    },
                    "customer_phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "service_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "party_size": {
                        "type": "integer"
                    },
                    "reserved_date": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "reserved_time": {
                        "type": "string",
                        "nullable": true
                    },
                    "total_duration_minutes": {
                        "type": "integer",
                        "nullable": true
                    },
                    "staff_member": {
                        "type": "string",
                        "nullable": true
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/CreatedReservationItem"
                        }
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "CreatedReservationItem": {
                "type": "object",
                "required": [
                    "menu_item_id",
                    "service_name",
                    "duration_minutes",
                    "price_pence",
                    "quantity",
                    "unit_price_pence"
                ],
                "properties": {
                    "menu_item_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "service_name": {
                        "type": "string"
                    },
                    "duration_minutes": {
                        "type": "integer",
                        "description": "Length of one run of this service."
                    },
                    "price_pence": {
                        "type": "integer",
                        "description": "Line total (unit_price_pence x quantity)."
                    },
                    "quantity": {
                        "type": "integer",
                        "description": "People charged for this line (added in 1.1.0). Always 1 for restaurant bookings."
                    },
                    "unit_price_pence": {
                        "type": "integer",
                        "description": "Price for one person including selected options (added in 1.1.0)."
                    },
                    "selected_options": {
                        "type": "array",
                        "nullable": true,
                        "items": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            },
            "PaymentRequiredResponse": {
                "type": "object",
                "required": [
                    "status",
                    "deposit_pence",
                    "checkout_url"
                ],
                "properties": {
                    "status": {
                        "type": "string",
                        "enum": [
                            "payment_required"
                        ]
                    },
                    "deposit_pence": {
                        "type": "integer"
                    },
                    "checkout_url": {
                        "type": "string",
                        "format": "uri"
                    }
                }
            },
            "OrderResponse": {
                "type": "object",
                "required": [
                    "data"
                ],
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/Order"
                    }
                }
            },
            "OrderListResponse": {
                "type": "object",
                "required": [
                    "data",
                    "meta"
                ],
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Order"
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/PaginationMeta"
                    }
                }
            },
            "Order": {
                "type": "object",
                "required": [
                    "id",
                    "status",
                    "order_type",
                    "payment_method",
                    "customer_name",
                    "customer_email",
                    "customer_phone",
                    "customer_address",
                    "special_requests",
                    "subtotal_pence",
                    "delivery_fee_pence",
                    "discount_pence",
                    "total_pence",
                    "refunded_pence",
                    "items",
                    "created_at"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "status": {
                        "type": "string"
                    },
                    "order_type": {
                        "type": "string"
                    },
                    "payment_method": {
                        "type": "string"
                    },
                    "customer_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "customer_email": {
                        "type": "string",
                        "format": "email",
                        "nullable": true
                    },
                    "customer_phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "customer_address": {
                        "type": "object",
                        "nullable": true,
                        "additionalProperties": true
                    },
                    "special_requests": {
                        "type": "string",
                        "nullable": true
                    },
                    "subtotal_pence": {
                        "type": "integer"
                    },
                    "delivery_fee_pence": {
                        "type": "integer"
                    },
                    "discount_pence": {
                        "type": "integer"
                    },
                    "total_pence": {
                        "type": "integer"
                    },
                    "refunded_pence": {
                        "type": "integer"
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderItem"
                        }
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "OrderItem": {
                "type": "object",
                "required": [
                    "name",
                    "quantity",
                    "price_pence",
                    "total_pence"
                ],
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "quantity": {
                        "type": "number"
                    },
                    "price_pence": {
                        "type": "integer"
                    },
                    "total_pence": {
                        "type": "integer"
                    }
                }
            },
            "ReservationListResponse": {
                "type": "object",
                "required": [
                    "data",
                    "meta"
                ],
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Reservation"
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/PaginationMeta"
                    }
                }
            },
            "Reservation": {
                "type": "object",
                "required": [
                    "id",
                    "status",
                    "customer_name",
                    "customer_email",
                    "customer_phone",
                    "service_name",
                    "party_size",
                    "total_duration_minutes",
                    "reserved_date",
                    "reserved_time",
                    "is_enquiry_only",
                    "attendee_name",
                    "attendee_phone",
                    "staff_member",
                    "notes",
                    "created_at"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "format": "int64"
                    },
                    "status": {
                        "type": "string"
                    },
                    "customer_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "customer_email": {
                        "type": "string",
                        "format": "email",
                        "nullable": true
                    },
                    "customer_phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "service_name": {
                        "type": "string"
                    },
                    "party_size": {
                        "type": "integer"
                    },
                    "total_duration_minutes": {
                        "type": "integer"
                    },
                    "reserved_date": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "reserved_time": {
                        "type": "string",
                        "nullable": true
                    },
                    "is_enquiry_only": {
                        "type": "boolean"
                    },
                    "attendee_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "attendee_phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "staff_member": {
                        "type": "string",
                        "nullable": true
                    },
                    "notes": {
                        "type": "string",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            }
        }
    }
}
