{
  "openapi": "3.0.3",
  "info": {
    "title": "Bookings API",
    "version": "7.6.0",
    "contact": {
      "name": "Bookable",
      "url": "https://www.bookabletech.com",
      "email": "hello@bookabletech.com"
    },
    "description": "Bookings VenueAPI is a RESTful, OpenAPI-based interface that enables seamless, standardized booking operations across diverse table management systems (TMS). \n\nDesigned for maximum interoperability, the API allows platforms to search, discover, and book venues regardless of the underlying technology stack. \n\nKey capabilities include:\n- Retrieving venue data and availability in real-time\n- Creating bookings through a unified interface\n- Supporting both direct bookings and inquiry-based workflows\n- Enabling venues and distributors to discover each other via a dynamic, service-driven marketplace\n\nThe API supports RBAC-secured OAuth2 to ensure role-based access control and secure data transactions. Built for SaaS environments, this service offers scalable, multi-tenant integrations for distribution platforms, booking engines, and TMS providers.\n"
  },
  "servers": [
    {
      "url": "https://api.bookabletech.com",
      "description": "Live"
    },
    {
      "url": "https://api-sandbox.bookabletech.com",
      "description": "Sandbox"
    }
  ],
  "tags": [
    {
      "name": "Venue",
      "description": "Information about venue"
    },
    {
      "name": "Booking",
      "description": "Information about the booking"
    }
  ],
  "paths": {
    "/venues": {
      "get": {
        "operationId": "getVenues",
        "summary": "Retrieve a list of venues",
        "description": "Returns a paginated list of venues available to the authenticated user or system.  This endpoint supports page-based pagination to efficiently retrieve large sets of results.\n",
        "tags": [
          "Venue"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          },
          {
            "name": "venueName",
            "in": "query",
            "required": false,
            "description": "Filter venues by name. Supports partial matching (case-insensitive). Example: \"dishoom\" will match \"Dishoom Covent Garden\".\n",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "dishoom"
          },
          {
            "name": "venueGroupName",
            "in": "query",
            "required": false,
            "description": "Filter venues by group or chain name. Supports partial matching (case-insensitive). Example: \"gordon ramsay\" will match all Gordon Ramsay restaurants.\n",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "gordon ramsay"
          },
          {
            "name": "features",
            "in": "query",
            "required": false,
            "description": "Filter venues by features. Supports multiple values separated by commas. Available features include: dog_friendly, wifi, parking, wheelchair_accessible,  tv_sports, live_music, karaoke, pool_table, romantic, casual, family_friendly,  quiet, lively, italian, asian, vegetarian, seafood, etc.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "maxItems": 10
            },
            "style": "form",
            "explode": false,
            "example": [
              "dog_friendly",
              "wifi",
              "romantic"
            ]
          },
          {
            "name": "content",
            "in": "query",
            "required": false,
            "description": "Filter venues by description content. Supports partial matching (case-insensitive). Searches within the venue's content/description field.\n",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 200
            },
            "example": "bombay cuisine"
          },
          {
            "name": "productName",
            "in": "query",
            "required": false,
            "description": "Filter venues by product/experience name. Supports partial matching (case-insensitive). Searches within product names and experience names.\n",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "dining room"
          },
          {
            "name": "productCategory",
            "in": "query",
            "required": false,
            "description": "Filter venues by product categories. Supports multiple values separated by commas. Only returns venues that have active products in the specified categories. Supports partial matching (case-insensitive).\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "maxItems": 10
            },
            "style": "form",
            "explode": false,
            "example": [
              "lunch",
              "dinner",
              "brunch"
            ]
          },
          {
            "name": "bookingDays",
            "in": "query",
            "required": false,
            "description": "Filter venues by available booking days. Supports multiple values separated by commas. Use day names (monday, tuesday, wednesday, thursday, friday, saturday, sunday).\n",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/DayOfWeek"
              },
              "minItems": 1,
              "maxItems": 7
            },
            "style": "form",
            "explode": false,
            "example": [
              "monday",
              "tuesday",
              "friday"
            ]
          },
          {
            "name": "area",
            "in": "query",
            "required": false,
            "description": "Filter venues by area/location. Supports partial matching (case-insensitive). Searches within the venue's area field.\n",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "covent garden"
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "description": "Filter venues by city. Supports partial matching (case-insensitive).\n",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "london"
          },
          {
            "name": "street",
            "in": "query",
            "required": false,
            "description": "Filter venues by street address. Supports partial matching (case-insensitive). Searches within the venue's street address field.\n",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 200
            },
            "example": "upper st martin"
          },
          {
            "name": "venueTypes",
            "in": "query",
            "required": false,
            "description": "Filter venues by type. Supports multiple values separated by commas. Available types include: restaurant, bar, cafe, hotel, pub, club, etc.\n",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "maxItems": 10
            },
            "style": "form",
            "explode": false,
            "example": [
              "restaurant",
              "bar"
            ]
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "description": "Filter venues by booking rules for a specific date. Format: ISO 8601 (YYYY-MM-DD). Returns venues that accept bookings on the specified date according to their booking rules. When both 'date' and 'bookingDays' filters are provided,  the 'date' filter takes precedence and overrides the 'bookingDays' filter.\n",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2025-10-15"
          },
          {
            "name": "time",
            "in": "query",
            "required": false,
            "description": "Filter venues by booking rules at a specific time. Format: 24-hour (HH:MM). Returns venues that accept bookings at the specified time according to their booking rules.  Must be used in conjunction with the date parameter.\n",
            "schema": {
              "type": "string",
              "format": "time",
              "nullable": true
            },
            "example": "19:30"
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Field selection using Google Fields syntax. Comma-separated list of top-level\nVenue fields to include. Use parentheses to select sub-fields of complex objects.\nWhen omitted, all fields are returned (backwards compatible).\n\nExamples:\n  - fields=id,name,location,products\n  - fields=id,name,location(lat,lng,city),products(compositeId,productName,category)\n  - fields=id,name,products(compositeId,productName,availabilityRules(from,to))\n\nValid top-level fields: id, name, venueGroupName, content, phone_number, website,\nreservable, location, types, photos, is_active, created_at, updated_at,\nproducts, preorders, opening_times\n",
            "schema": {
              "type": "string"
            },
            "example": "id,name,location(lat,lng,city),products(compositeId,productName,category)"
          },
          {
            "name": "pageNumber",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "nullable": false
            },
            "description": "The index of the page to return (default is 1)."
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "nullable": false
            },
            "description": "The number of items to return per page (default is 20, max is 100)."
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "The field to sort results by. Defaults to 'Default' (composite ID ordering).\n- **default**: Sort by composite ID (venue_group_id, rms_id, venue_id)\n- **name**: Sort venues alphabetically by name\n- **city**: Sort venues by city name, then by venue name\n- **area**: Sort venues by area, then by venue name\n- **venueGroup**: Sort venues by venue group name (requires venueGroupName filter)\n- **relevance**: Sort by semantic similarity using vector embeddings (requires at least one embedding filter: venueName, content, or features with semantic search enabled)\n",
            "schema": {
              "type": "string",
              "enum": [
                "default",
                "name",
                "city",
                "area",
                "venueGroup",
                "relevance"
              ],
              "default": "default"
            },
            "example": "name"
          },
          {
            "$ref": "#/components/parameters/SortDirection"
          }
        ],
        "responses": {
          "200": {
            "description": "A list of venues was successfully retrieved.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "$ref": "#/components/schemas/VenueResponse"
                    }
                  ]
                },
                "example": {
                  "meta": {
                    "currentPage": 1,
                    "pageSize": 20,
                    "totalItems": 2,
                    "totalPages": 1
                  },
                  "data": [
                    {
                      "id": "29|X9|275cc44dd2e2496fba44857c9257443a",
                      "name": "Dishoom",
                      "venueGroupName": "Dishoom Group",
                      "reservable": true,
                      "location": {
                        "city": "London",
                        "area": "Covent Garden",
                        "lat": 51.5118,
                        "lng": -0.1236
                      },
                      "types": [
                        "restaurant"
                      ],
                      "products": [
                        {
                          "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a",
                          "productName": "Dinner",
                          "timeInterval": 30,
                          "preOrderRequired": false,
                          "category": "dinner",
                          "feedUrl": "https://feeds.bookabletech.com/29/275cc44dd2e2496fba44857c9257443a/5c4af02d6354a83e3a0ea3b4/index.json",
                          "spaces": [
                            {
                              "id": 1,
                              "spaceName": "Main Dining Room",
                              "capacitySeated": {
                                "min": 10,
                                "max": 50
                              },
                              "policies": {
                                "minimumSpend": {
                                  "enabled": true,
                                  "rules": [
                                    {
                                      "label": "Weekend Evening",
                                      "conditions": {
                                        "daysOfWeek": [
                                          5,
                                          6,
                                          7
                                        ]
                                      },
                                      "spendValue": 5000,
                                      "notes": null
                                    }
                                  ],
                                  "overrides": []
                                },
                                "under18s": {
                                  "enabled": true,
                                  "allowed": true,
                                  "until": "21:00"
                                },
                                "occasionTypes": {
                                  "enabled": true,
                                  "values": [
                                    "Corporate Event",
                                    "Work Get Together"
                                  ]
                                }
                              }
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              },
              "text/toon": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "$ref": "#/components/schemas/VenueResponse"
                    }
                  ]
                },
                "example": "meta:\n  currentPage: 1\n  pageSize: 20\n  totalItems: 2\n  totalPages: 1\ndata[2]:\n  - id: \"29|X9|275cc44dd2e2496fba44857c9257443a\"\n    name: Dishoom\n    venueGroupName: Dishoom Group\n    reservable: true\n    location:\n      city: London\n      area: Covent Garden\n      lat: 51.5118\n      lng: -0.1236\n    types[1]: restaurant\n  - id: \"29|X9|a87ff679a2f3e71d9181a67b7542122c\"\n    name: The Ivy\n    venueGroupName: Ivy Collection\n    reservable: true\n    location:\n      city: London\n      area: West End\n      lat: 51.513\n      lng: -0.127\n    types[2]: restaurant,bar\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue:read"
            ]
          },
          {
            "Sandbox": [
              "venue:read"
            ]
          }
        ]
      }
    },
    "/venues/{venueId}": {
      "get": {
        "operationId": "getVenue",
        "summary": "Get the venue",
        "description": "Retrieve a list of venues.",
        "tags": [
          "Venue"
        ],
        "parameters": [
          {
            "name": "venueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of venue\n",
            "example": "29|X9|275cc44dd2e2496fba44857c9257443a"
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Field selection using Google Fields syntax. Comma-separated list of top-level\nVenue fields to include. Use parentheses to select sub-fields of complex objects.\nWhen omitted, all fields are returned (backwards compatible).\n\nExamples:\n  - fields=id,name,location,products\n  - fields=id,name,location(lat,lng,city),products(compositeId,productName,category)\n  - fields=id,name,products(compositeId,productName,availabilityRules(from,to))\n\nValid top-level fields: id, name, venueGroupName, content, phone_number, website,\nreservable, location, types, photos, is_active, created_at, updated_at,\nproducts, preorders, opening_times\n",
            "schema": {
              "type": "string"
            },
            "example": "id,name,location(lat,lng,city),products(compositeId,productName,category)"
          }
        ],
        "responses": {
          "200": {
            "description": "Schema for the response returned when retrieving a list of venues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Venue"
                },
                "example": {
                  "id": "29|X9|275cc44dd2e2496fba44857c9257443a",
                  "name": "Dishoom",
                  "venueGroupName": "Dishoom Group",
                  "content": "An Indian restaurant.",
                  "phone_number": "+441234567890",
                  "website": "https://dishoom.com",
                  "reservable": true,
                  "location": {
                    "area": "Covent Garden",
                    "city": "London",
                    "lat": 51.5118,
                    "lng": -0.1236,
                    "street": "12 Upper St Martin's Lane",
                    "postCode": "WC2H 9FB"
                  },
                  "types": [
                    "restaurant",
                    "bar"
                  ],
                  "products": [
                    {
                      "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a",
                      "productName": "Dinner",
                      "timeInterval": 30,
                      "preOrderRequired": false,
                      "category": "dinner",
                      "feedUrl": "https://feeds.bookabletech.com/29/275cc44dd2e2496fba44857c9257443a/5c4af02d6354a83e3a0ea3b4/index.json",
                      "spaces": [
                        {
                          "id": 1,
                          "spaceName": "Main Dining Room",
                          "capacitySeated": {
                            "min": 10,
                            "max": 50
                          },
                          "policies": {
                            "minimumSpend": {
                              "enabled": true,
                              "rules": [
                                {
                                  "label": "Weekend Evening",
                                  "conditions": {
                                    "daysOfWeek": [
                                      5,
                                      6,
                                      7
                                    ]
                                  },
                                  "spendValue": 5000,
                                  "notes": null
                                }
                              ],
                              "overrides": []
                            },
                            "under18s": {
                              "enabled": true,
                              "allowed": true,
                              "until": "21:00"
                            },
                            "occasionTypes": {
                              "enabled": true,
                              "values": [
                                "Corporate Event",
                                "Work Get Together"
                              ]
                            }
                          }
                        }
                      ]
                    }
                  ]
                }
              },
              "text/toon": {
                "schema": {
                  "$ref": "#/components/schemas/Venue"
                },
                "example": "id: \"29|X9|275cc44dd2e2496fba44857c9257443a\"\nname: Dishoom\nvenueGroupName: Dishoom Group\ncontent: An Indian restaurant.\nphone_number: \"+441234567890\"\nwebsite: \"https://dishoom.com\"\nreservable: true\nlocation:\n  area: Covent Garden\n  city: London\n  lat: 51.5118\n  lng: -0.1236\n  street: 12 Upper St Martin's Lane\n  postCode: WC2H 9FB\ntypes[2]: restaurant,bar\nproducts[1]:\n  - compositeId: \"29|X9|275cc44dd2e2496fba44857c9257443a\"\n    productName: Dinner\n    timeInterval: 30\n    preOrderRequired: false\n    category: dinner\n    feedUrl: \"https://feeds.bookabletech.com/29/275cc44dd2e2496fba44857c9257443a/5c4af02d6354a83e3a0ea3b4/index.json\"\n    spaces[1]:\n      - id: 1\n        spaceName: \"Main Dining Room\"\n        capacitySeated: {min: 10, max: 50}\n        policies:\n          minimumSpend:\n            enabled: true\n            rules[1]:\n              - label: \"Weekend Evening\"\n                conditions.daysOfWeek[3]: 5,6,7\n                spendValue: 5000\n            overrides[0]:\n          under18s: {enabled: true, allowed: true, until: \"21:00\"}\n          occasionTypes:\n            enabled: true\n            values[2]: Corporate Event,Work Get Together\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue:read"
            ]
          },
          {
            "Sandbox": [
              "venue:read"
            ]
          }
        ]
      }
    },
    "/venues/{compositeId}/availability": {
      "get": {
        "operationId": "checkVenueAvailability",
        "summary": "Check venue availability",
        "tags": [
          "Venue"
        ],
        "parameters": [
          {
            "name": "compositeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The unique identifier of the venue or product."
          },
          {
            "name": "AvailabilityRequest",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/AvailabilityRequest"
            }
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Field selection using Google Fields syntax. Comma-separated list of top-level\nAvailabilityResponse fields to include. Use parentheses to select sub-fields of\ncomplex objects. When omitted, all fields are returned (backwards compatible).\n\nExamples:\n  - fields=name,times\n  - fields=times(time,duration,type)\n  - fields=name,deposit,policy,times(time,duration,preOrderItems)\n\nValid top-level fields: name, deposit, policy, cancellationPolicy, times\n",
            "schema": {
              "type": "string"
            },
            "example": "name,times(time,duration,type)"
          }
        ],
        "responses": {
          "200": {
            "description": "Success response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityResponse"
                },
                "example": {
                  "name": "Dinner",
                  "deposit": 10,
                  "policy": "Please arrive on time.",
                  "cancellationPolicy": "Cancel 48h before or a fee applies.",
                  "times": [
                    {
                      "time": "18:00",
                      "duration": 90,
                      "type": "book",
                      "productId": "29|X9|275cc44dd2e2496fba44857c9257443a"
                    },
                    {
                      "time": "18:30",
                      "duration": 90,
                      "type": "book",
                      "productId": "29|X9|275cc44dd2e2496fba44857c9257443a"
                    },
                    {
                      "time": "19:00",
                      "duration": 90,
                      "type": "request",
                      "productId": "29|X9|275cc44dd2e2496fba44857c9257443a"
                    }
                  ]
                }
              },
              "text/toon": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityResponse"
                },
                "example": "name: Dinner\ndeposit: 10\npolicy: Please arrive on time.\ncancellationPolicy: Cancel 48h before or a fee applies.\ntimes[3]{time,duration,type,productId}:\n  \"18:00\",90,book,\"29|X9|275cc44dd2e2496fba44857c9257443a\"\n  \"18:30\",90,book,\"29|X9|275cc44dd2e2496fba44857c9257443a\"\n  \"19:00\",90,request,\"29|X9|275cc44dd2e2496fba44857c9257443a\"\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue:read"
            ]
          },
          {
            "Sandbox": [
              "venue:read"
            ]
          }
        ]
      }
    },
    "/venues/{compositeId}/booking": {
      "post": {
        "operationId": "createBooking",
        "summary": "Create a new booking",
        "tags": [
          "Venue",
          "Booking"
        ],
        "parameters": [
          {
            "name": "compositeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The unique identifier of the venue/product."
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          },
          {
            "$ref": "#/components/parameters/IntegrationSlug"
          },
          {
            "in": "header",
            "name": "X-Is-Cross-Sale",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Indicates whether this booking is a cross-sale (i.e. the booking was initiated\nthrough another venue's channel). When true, any cross-sale booking label rules\nconfigured for this operator will be applied automatically.\n"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingRequest"
              },
              "example": {
                "firstName": "John",
                "lastName": "Doe",
                "partySize": 4,
                "date": "2025-06-15",
                "time": "19:00",
                "type": "book",
                "duration": 90,
                "email": "john.doe@example.com",
                "phone": "+441234567890",
                "notes": "Birthday celebration",
                "partnerBookingId": "ext-ref-123"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": {
                  "id": "29|X9|69b3e37eb35cb412b60f3737",
                  "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738",
                  "date": "2025-06-15",
                  "time": "19:00",
                  "partySize": 4,
                  "status": "Confirmed",
                  "firstName": "John",
                  "lastName": "Doe",
                  "email": "john.doe@example.com",
                  "phone": "+441234567890",
                  "venueGroupName": "Dishoom Group",
                  "location": {
                    "city": "London",
                    "area": "Covent Garden",
                    "street": "12 Upper St Martin's Lane",
                    "postCode": "WC2H 9FB"
                  },
                  "duration": 90,
                  "productName": "Dinner",
                  "notes": "Birthday celebration",
                  "createdDate": "2025-05-01T10:00:00Z",
                  "lastUpdate": "2025-05-01T10:00:00Z",
                  "partnerBookingId": "ext-ref-123",
                  "operatorBookingId": "op-ref-456"
                }
              },
              "text/toon": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": "id: \"29|X9|69b3e37eb35cb412b60f3737\"\ncompositeId: \"29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738\"\ndate: 2025-06-15\ntime: \"19:00\"\npartySize: 4\nstatus: Confirmed\nfirstName: John\nlastName: Doe\nemail: john.doe@example.com\nphone: \"+441234567890\"\nvenueGroupName: Dishoom Group\nlocation:\n  city: London\n  area: Covent Garden\n  street: 12 Upper St Martin's Lane\n  postCode: WC2H 9FB\nduration: 90\nproductName: Dinner\nnotes: Birthday celebration\ncreatedDate: \"2025-05-01T10:00:00Z\"\nlastUpdate: \"2025-05-01T10:00:00Z\"\npartnerBookingId: ext-ref-123\noperatorBookingId: op-ref-456\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue-booking:create"
            ]
          },
          {
            "Sandbox": [
              "venue-booking:create"
            ]
          }
        ]
      }
    },
    "/venues/bookings": {
      "get": {
        "summary": "Retrieve a list of bookings",
        "description": "Returns a paginated list of all bookings.",
        "operationId": "getBookings",
        "parameters": [
          {
            "name": "compositeId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "nullable": true
            },
            "description": "Filter bookings by the unique composite identifier. This parameter supports two filtering modes:\n- **Filter by venue**: Provide a 3-part composite ID (venueGroupId|rmsId|venueId) to retrieve all bookings for a specific venue, regardless of product.\n- **Filter by product**: Provide a complete 4-part composite ID (venueGroupId|rmsId|venueId|productId) to retrieve bookings for a specific product within a venue.\n",
            "example": "29|X9|275cc44dd2e2496fba44857c9257443a"
          },
          {
            "name": "firstName",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "nullable": true
            },
            "description": "Filter bookings by customer first name (partial match)."
          },
          {
            "name": "lastName",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "nullable": true
            },
            "description": "Filter bookings by customer last name (partial match)."
          },
          {
            "name": "email",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "nullable": true
            },
            "description": "Filter bookings by customer email (partial match)."
          },
          {
            "name": "partnerId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "minimum": 1,
              "nullable": true
            },
            "description": "Filter bookings by the exact internal partner ID. Only applied for venue-group callers; ignored for partner-scoped callers, whose results are always limited to their own bookings."
          },
          {
            "name": "partnerBookingId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "nullable": true
            },
            "description": "Filter bookings by partner booking reference ID."
          },
          {
            "name": "operatorBookingId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "nullable": true
            },
            "description": "Filter bookings by operator booking reference ID."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "nullable": true
            },
            "description": "Filter bookings by exact booking date (YYYY-MM-DD)."
          },
          {
            "name": "dateFrom",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "nullable": true
            },
            "description": "Filter bookings from this date onwards (inclusive, YYYY-MM-DD)."
          },
          {
            "name": "dateTo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "nullable": true
            },
            "description": "Filter bookings up to this date (inclusive, YYYY-MM-DD)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/BookingStatus"
            },
            "description": "Filter bookings by status."
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Field selection using Google Fields syntax. Comma-separated list of top-level\nBooking fields to include. Use parentheses to select sub-fields of complex objects.\nWhen omitted, all fields are returned (backwards compatible).\n\nExamples:\n  - fields=id,compositeId,date,time,status\n  - fields=id,date,partySize,firstName,lastName,email\n  - fields=id,compositeId,date,preorders(packages,menus)\n\nValid top-level fields: id, compositeId, date, time, partySize, status,\nfirstName, lastName, email, phone, venueGroupName, location, duration,\nproductName, notes, createdDate, tmsCreatedDate, lastUpdate, preorders, partnerBookingId,\noperatorBookingId\n",
            "schema": {
              "type": "string"
            },
            "example": "id,compositeId,date,time,partySize,status,firstName,lastName,email"
          },
          {
            "name": "pageNumber",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "nullable": true
            },
            "description": "The index of the page to return (default is 1)."
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "nullable": true
            },
            "description": "The number of items to return per page (default is 20, max is 100)."
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          }
        ],
        "tags": [
          "Venue",
          "Booking"
        ],
        "responses": {
          "200": {
            "description": "A list of bookings",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "$ref": "#/components/schemas/ReservationResponse"
                    }
                  ]
                },
                "example": {
                  "meta": {
                    "currentPage": 1,
                    "pageSize": 20,
                    "totalItems": 2,
                    "totalPages": 1
                  },
                  "data": [
                    {
                      "id": "29|X9|69b3e37eb35cb412b60f3737",
                      "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738",
                      "date": "2025-06-15",
                      "time": "19:00",
                      "partySize": 4,
                      "status": "Confirmed",
                      "firstName": "John",
                      "lastName": "Doe",
                      "email": "john.doe@example.com",
                      "phone": "+441234567890"
                    },
                    {
                      "id": "29|X9|69b3e37eb35cb412b60f3739",
                      "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3740",
                      "date": "2025-06-16",
                      "time": "20:00",
                      "partySize": 2,
                      "status": "Pending",
                      "firstName": "Jane",
                      "lastName": "Smith",
                      "email": "jane.smith@example.com",
                      "phone": "+441234567891"
                    }
                  ]
                }
              },
              "text/toon": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Page"
                    },
                    {
                      "$ref": "#/components/schemas/ReservationResponse"
                    }
                  ]
                },
                "example": "meta:\n  currentPage: 1\n  pageSize: 20\n  totalItems: 2\n  totalPages: 1\ndata[2]{id,compositeId,date,time,partySize,status,firstName,lastName,email,phone}:\n  \"29|X9|69b3e37eb35cb412b60f3737\",\"29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738\",2025-06-15,\"19:00\",4,Confirmed,John,Doe,john.doe@example.com,\"+441234567890\"\n  \"29|X9|69b3e37eb35cb412b60f3739\",\"29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3740\",2025-06-16,\"20:00\",2,Pending,Jane,Smith,jane.smith@example.com,\"+441234567891\"\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue-booking:read"
            ]
          },
          {
            "Sandbox": [
              "venue-booking:read"
            ]
          }
        ]
      }
    },
    "/venues/bookings/{bookingId}": {
      "get": {
        "summary": "Retrieve a booking by ID",
        "description": "Returns a specific booking by its unique ID.",
        "operationId": "getBookingById",
        "tags": [
          "Venue",
          "Booking"
        ],
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Unique identifier of the booking"
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Field selection using Google Fields syntax. Comma-separated list of top-level\nBooking fields to include. Use parentheses to select sub-fields of complex objects.\nWhen omitted, all fields are returned (backwards compatible).\n\nExamples:\n  - fields=id,compositeId,date,time,status\n  - fields=id,date,partySize,firstName,lastName,email\n  - fields=id,compositeId,date,preorders(packages,menus)\n\nValid top-level fields: id, compositeId, date, time, partySize, status,\nfirstName, lastName, email, phone, venueGroupName, location, duration,\nproductName, notes, createdDate, tmsCreatedDate, lastUpdate, preorders, partnerBookingId,\noperatorBookingId\n",
            "schema": {
              "type": "string"
            },
            "example": "id,compositeId,date,time,partySize,status,firstName,lastName,email"
          }
        ],
        "responses": {
          "200": {
            "description": "Reservation details",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": {
                  "id": "29|X9|69b3e37eb35cb412b60f3737",
                  "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738",
                  "date": "2025-06-15",
                  "time": "19:00",
                  "partySize": 4,
                  "status": "Confirmed",
                  "firstName": "John",
                  "lastName": "Doe",
                  "email": "john.doe@example.com",
                  "phone": "+441234567890",
                  "venueGroupName": "Dishoom Group",
                  "location": {
                    "city": "London",
                    "area": "Covent Garden",
                    "street": "12 Upper St Martin's Lane",
                    "postCode": "WC2H 9FB"
                  },
                  "duration": 90,
                  "productName": "Dinner",
                  "notes": "Birthday celebration",
                  "createdDate": "2025-05-01T10:00:00Z",
                  "lastUpdate": "2025-05-01T10:00:00Z",
                  "partnerBookingId": "ext-ref-123",
                  "operatorBookingId": "op-ref-456"
                }
              },
              "text/toon": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": "id: \"29|X9|69b3e37eb35cb412b60f3737\"\ncompositeId: \"29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738\"\ndate: 2025-06-15\ntime: \"19:00\"\npartySize: 4\nstatus: Confirmed\nfirstName: John\nlastName: Doe\nemail: john.doe@example.com\nphone: \"+441234567890\"\nvenueGroupName: Dishoom Group\nlocation:\n  city: London\n  area: Covent Garden\n  street: 12 Upper St Martin's Lane\n  postCode: WC2H 9FB\nduration: 90\nproductName: Dinner\nnotes: Birthday celebration\ncreatedDate: \"2025-05-01T10:00:00Z\"\nlastUpdate: \"2025-05-01T10:00:00Z\"\npartnerBookingId: ext-ref-123\noperatorBookingId: op-ref-456\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue-booking:read"
            ]
          },
          {
            "Sandbox": [
              "venue-booking:read"
            ]
          }
        ]
      },
      "put": {
        "operationId": "updateBookingById",
        "summary": "Update an existing booking by ID",
        "tags": [
          "Venue",
          "Booking"
        ],
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The unique identifier of the booking."
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBookingRequest"
              },
              "example": {
                "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738",
                "firstName": "John",
                "lastName": "Doe",
                "partySize": 4,
                "date": "2025-06-15",
                "time": "19:00",
                "duration": 90,
                "email": "john.doe@example.com",
                "phone": "+441234567890",
                "notes": "Birthday celebration"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reservation details",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": {
                  "id": "29|X9|69b3e37eb35cb412b60f3737",
                  "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738",
                  "date": "2025-06-15",
                  "time": "19:00",
                  "partySize": 4,
                  "status": "Confirmed",
                  "firstName": "John",
                  "lastName": "Doe",
                  "email": "john.doe@example.com",
                  "phone": "+441234567890",
                  "venueGroupName": "Dishoom Group",
                  "location": {
                    "city": "London",
                    "area": "Covent Garden",
                    "street": "12 Upper St Martin's Lane",
                    "postCode": "WC2H 9FB"
                  },
                  "duration": 90,
                  "productName": "Dinner",
                  "notes": "Birthday celebration",
                  "createdDate": "2025-05-01T10:00:00Z",
                  "lastUpdate": "2025-05-01T10:00:00Z",
                  "partnerBookingId": "ext-ref-123",
                  "operatorBookingId": "op-ref-456"
                }
              },
              "text/toon": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": "id: \"29|X9|69b3e37eb35cb412b60f3737\"\ncompositeId: \"29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738\"\ndate: 2025-06-15\ntime: \"19:00\"\npartySize: 4\nstatus: Confirmed\nfirstName: John\nlastName: Doe\nemail: john.doe@example.com\nphone: \"+441234567890\"\nvenueGroupName: Dishoom Group\nlocation:\n  city: London\n  area: Covent Garden\n  street: 12 Upper St Martin's Lane\n  postCode: WC2H 9FB\nduration: 90\nproductName: Dinner\nnotes: Birthday celebration\ncreatedDate: \"2025-05-01T10:00:00Z\"\nlastUpdate: \"2025-05-01T10:00:00Z\"\npartnerBookingId: ext-ref-123\noperatorBookingId: op-ref-456\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue-booking:update"
            ]
          },
          {
            "Sandbox": [
              "venue-booking:update"
            ]
          }
        ]
      },
      "patch": {
        "operationId": "patchBookingById",
        "summary": "Update a booking",
        "description": "Partially updates a booking using JSON Patch operations as defined in RFC 6902.\nThis endpoint allows you to perform granular updates on a booking without  sending the entire resource. Supported operations include:\n- **add**: Add a new field or append to an array\n- **remove**: Remove a field or array element\n- **replace**: Update an existing field value\n**Read-only Fields (cannot be patched):**\n- `/id`, `/compositeId`, `/status`, `/reference`, `/venueGroupName`, `/location/*`,\n  `/productName`, `/createdDate`, `/tmsCreatedDate`, `/lastUpdate`\n\n**Patchable Fields:**\n- `/date` - Change booking date (format: YYYY-MM-DD)\n- `/time` - Change booking time (format: HH:MM)\n- `/duration` - Update duration in minutes\n- `/partySize` - Change number of guests\n- `/firstName` - Update guest first name\n- `/lastName` - Update guest last name\n- `/email` - Update guest email\n- `/phone` - Update guest phone number\n- `/notes` - Update booking notes\n- `/partnerBookingId` - Update partner booking reference\n- `/operatorBookingId` - Update operator booking ID\n**Preorders - Packages:**\n- `/preorders/packages` - Add/remove entire packages array\n- `/preorders/packages/-` - Add a package to the end of the array\n- `/preorders/packages/{packageId}` - Replace/remove a specific package by ID\n- `/preorders/packages/{packageId}/quantity` - Update quantity by package ID\nNote: For packages, only `id` and `quantity` can be modified. Other fields (name, description, type, price) are read-only.\n**Package IDs** are alphanumeric strings (e.g., \"5de64c68ce9583458c447544\"). Index-based paths are NOT supported.\n**Preorders - Menus:**\n- `/preorders/menus` - Add/remove entire menus array\n- `/preorders/menus/-` - Add a menu to the end of the array\n- `/preorders/menus/{menuId}` - Replace/remove a specific menu by ID\n- `/preorders/menus/{menuId}/quantity` - Update menu quantity by ID\n- `/preorders/menus/{menuId}/items` - Replace entire items array for a menu\n- `/preorders/menus/{menuId}/items/-` - Add an item to a menu\n- `/preorders/menus/{menuId}/items/{itemId}` - Replace/remove a menu item by ID\n- `/preorders/menus/{menuId}/items/{itemId}/quantity` - Update item quantity by ID\nNote: For menu items, only `id` and `quantity` can be modified. The `name` field is read-only.\n**Menu and Item IDs** are alphanumeric strings (e.g., \"5de64c68ce9583458c447544\"). Index-based paths are NOT supported.\n**Examples:**\nUpdate guest information:\n```json [\n  { \"op\": \"replace\", \"path\": \"/email\", \"value\": \"newemail@example.com\" },\n  { \"op\": \"replace\", \"path\": \"/phone\", \"value\": \"+44 20 7946 0958\" }\n] ```\nUpdate booking date and time: ```json [\n  { \"op\": \"replace\", \"path\": \"/date\", \"value\": \"2025-12-25\" },\n  { \"op\": \"replace\", \"path\": \"/time\", \"value\": \"19:30\" }\n] ```\nAdd a package to preorders: ```json [\n  { \"op\": \"add\", \"path\": \"/preorders/packages/-\", \"value\": { \"id\": \"5de64c68ce9583458c447544\", \"quantity\": 2 } }\n] ```\nUpdate package quantity: ```json [\n  { \"op\": \"replace\", \"path\": \"/preorders/packages/5de64c68ce9583458c447544/quantity\", \"value\": 5 }\n] ```\nRemove a package: ```json [\n  { \"op\": \"remove\", \"path\": \"/preorders/packages/5de64c68ce9583458c447544\" }\n] ```\nAdd a menu with items: ```json [\n  {\n    \"op\": \"add\",\n    \"path\": \"/preorders/menus/-\",\n    \"value\": {\n      \"id\": \"5de64c68ce9583458c447abc\",\n      \"quantity\": 3,\n      \"items\": [\n        { \"id\": \"5de64c68ce9583458c447001\", \"quantity\": 1 },\n        { \"id\": \"5de64c68ce9583458c447002\", \"quantity\": 2 }\n      ]\n    }\n  }\n] ```\nAdd item to existing menu: ```json [\n  { \"op\": \"add\", \"path\": \"/preorders/menus/5de64c68ce9583458c447abc/items/-\", \"value\": { \"id\": \"5de64c68ce9583458c447003\", \"quantity\": 1 } }\n] ```\nUpdate menu item quantity: ```json [\n  { \"op\": \"replace\", \"path\": \"/preorders/menus/5de64c68ce9583458c447abc/items/5de64c68ce9583458c447001/quantity\", \"value\": 2 }\n] ```\n",
        "tags": [
          "Venue",
          "Booking"
        ],
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The unique identifier of the booking."
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of JSON Patch operations to apply to the booking",
          "content": {
            "application/json-patch+json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/JsonPatchOperation"
                },
                "minItems": 1
              },
              "examples": {
                "updateGuestInfo": {
                  "summary": "Update guest information",
                  "value": [
                    {
                      "op": "replace",
                      "path": "/email",
                      "value": "newemail@example.com"
                    },
                    {
                      "op": "replace",
                      "path": "/firstName",
                      "value": "John"
                    }
                  ]
                },
                "updateDateTime": {
                  "summary": "Update booking date and time",
                  "value": [
                    {
                      "op": "replace",
                      "path": "/date",
                      "value": "2025-12-25"
                    },
                    {
                      "op": "replace",
                      "path": "/time",
                      "value": "19:30"
                    }
                  ]
                },
                "updatePartySize": {
                  "summary": "Update party size and duration",
                  "value": [
                    {
                      "op": "replace",
                      "path": "/partySize",
                      "value": 8
                    },
                    {
                      "op": "replace",
                      "path": "/duration",
                      "value": 150
                    }
                  ]
                },
                "addPackage": {
                  "summary": "Add a preorder package",
                  "value": [
                    {
                      "op": "add",
                      "path": "/preorders/packages/-",
                      "value": {
                        "id": "5de64c68ce9583458c447544",
                        "quantity": 2
                      }
                    }
                  ]
                },
                "updatePackageQuantity": {
                  "summary": "Update package quantity",
                  "value": [
                    {
                      "op": "replace",
                      "path": "/preorders/packages/5de64c68ce9583458c447544/quantity",
                      "value": 5
                    }
                  ]
                },
                "removePackage": {
                  "summary": "Remove a package",
                  "value": [
                    {
                      "op": "remove",
                      "path": "/preorders/packages/5de64c68ce9583458c447544"
                    }
                  ]
                },
                "addMenu": {
                  "summary": "Add a menu with items",
                  "value": [
                    {
                      "op": "add",
                      "path": "/preorders/menus/-",
                      "value": {
                        "id": "5de64c68ce9583458c447abc",
                        "quantity": 3,
                        "items": [
                          {
                            "id": "5de64c68ce9583458c447001",
                            "quantity": 1
                          },
                          {
                            "id": "5de64c68ce9583458c447002",
                            "quantity": 2
                          }
                        ]
                      }
                    }
                  ]
                },
                "addMenuItems": {
                  "summary": "Add item to existing menu",
                  "value": [
                    {
                      "op": "add",
                      "path": "/preorders/menus/5de64c68ce9583458c447abc/items/-",
                      "value": {
                        "id": "5de64c68ce9583458c447003",
                        "quantity": 1
                      }
                    }
                  ]
                },
                "updateMenuItemQuantity": {
                  "summary": "Update menu item quantity",
                  "value": [
                    {
                      "op": "replace",
                      "path": "/preorders/menus/5de64c68ce9583458c447abc/items/5de64c68ce9583458c447001/quantity",
                      "value": 3
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking successfully updated",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": {
                  "id": "29|X9|69b3e37eb35cb412b60f3737",
                  "compositeId": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738",
                  "date": "2025-06-15",
                  "time": "19:00",
                  "partySize": 4,
                  "status": "Confirmed",
                  "firstName": "John",
                  "lastName": "Doe",
                  "email": "john.doe@example.com",
                  "phone": "+441234567890",
                  "venueGroupName": "Dishoom Group",
                  "location": {
                    "city": "London",
                    "area": "Covent Garden",
                    "street": "12 Upper St Martin's Lane",
                    "postCode": "WC2H 9FB"
                  },
                  "duration": 90,
                  "productName": "Dinner",
                  "notes": "Birthday celebration",
                  "createdDate": "2025-05-01T10:00:00Z",
                  "lastUpdate": "2025-05-01T10:00:00Z",
                  "partnerBookingId": "ext-ref-123",
                  "operatorBookingId": "op-ref-456"
                }
              },
              "text/toon": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                },
                "example": "id: \"29|X9|69b3e37eb35cb412b60f3737\"\ncompositeId: \"29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738\"\ndate: 2025-06-15\ntime: \"19:00\"\npartySize: 4\nstatus: Confirmed\nfirstName: John\nlastName: Doe\nemail: john.doe@example.com\nphone: \"+441234567890\"\nvenueGroupName: Dishoom Group\nlocation:\n  city: London\n  area: Covent Garden\n  street: 12 Upper St Martin's Lane\n  postCode: WC2H 9FB\nduration: 90\nproductName: Dinner\nnotes: Birthday celebration\ncreatedDate: \"2025-05-01T10:00:00Z\"\nlastUpdate: \"2025-05-01T10:00:00Z\"\npartnerBookingId: ext-ref-123\noperatorBookingId: op-ref-456\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue-booking:update"
            ]
          },
          {
            "Sandbox": [
              "venue-booking:update"
            ]
          }
        ]
      },
      "delete": {
        "operationId": "deleteBookingById",
        "summary": "Cancel a booking by ID",
        "tags": [
          "Venue",
          "Booking"
        ],
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Unique identifier of the booking"
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          }
        ],
        "responses": {
          "204": {
            "description": "Booking cancelled successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue-booking:delete"
            ]
          },
          {
            "Sandbox": [
              "venue-booking:delete"
            ]
          }
        ]
      }
    },
    "/venues/bookings/{bookingId}/status": {
      "put": {
        "operationId": "updateBookingStatus",
        "summary": "Change the status of an in-progress booking",
        "description": "Confirms or rejects an unconfirmed booking request, allowing an operator to accept or decline it. Set `status` to `Confirmed` to accept the booking, or `Rejected` to decline it. Only a booking that is still awaiting a decision (`Pending` or `InProgress`) can be actioned; attempting to change the status of a booking in any other state returns `422`. When rejecting, you may include an optional free-text `reason` explaining the decision, which is recorded against the booking.\n\nThis endpoint requires the `venue-booking:update:status` permission, which is granted separately and is not available to all integration partners by default. If your client is not authorised for it, the request returns `403`. Contact Bookable to request access.\n",
        "tags": [
          "Venue",
          "Booking"
        ],
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The unique identifier of the booking."
          },
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBookingStatusRequest"
              },
              "example": {
                "status": "Confirmed"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking status successfully updated",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Booking"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue-booking:update:status"
            ]
          },
          {
            "Sandbox": [
              "venue-booking:update:status"
            ]
          }
        ]
      }
    },
    "/venues/category": {
      "get": {
        "operationId": "getProductCategories",
        "summary": "Retrieve all product categories",
        "description": "Returns a list of all available product categories used to classify venue products (e.g., Breakfast, Lunch, Dinner, Afternoon Tea).",
        "tags": [
          "Venue"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/PartnerReference"
          },
          {
            "$ref": "#/components/parameters/CorrelationID"
          }
        ],
        "responses": {
          "200": {
            "description": "A list of product categories",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductCategoryResponse"
                },
                "example": {
                  "data": [
                    {
                      "slug": "lunch",
                      "name": "Lunch"
                    },
                    {
                      "slug": "dinner",
                      "name": "Dinner"
                    },
                    {
                      "slug": "breakfast",
                      "name": "Breakfast"
                    }
                  ]
                }
              },
              "text/toon": {
                "schema": {
                  "$ref": "#/components/schemas/ProductCategoryResponse"
                },
                "example": "data[3]{slug,name}:\n  lunch,Lunch\n  dinner,Dinner\n  breakfast,Breakfast\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          },
          "default": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "security": [
          {
            "Live": [
              "venue:read"
            ]
          },
          {
            "Sandbox": [
              "venue:read"
            ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "SpaceCapacityRange": {
        "type": "object",
        "description": "Min/max capacity range for a space layout type.",
        "properties": {
          "min": {
            "type": "integer",
            "nullable": true
          },
          "max": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "BookingStatus": {
        "nullable": true,
        "type": "string",
        "title": "Booking Status",
        "description": "Indicates the current status of the booking:\n- `Pending`: The booking request has been received but not yet processed.\n- `InProgress`: The enquiry has been received and assigned but is not yet confirmed.\n- `Confirmed`: The booking has been confirmed.\n- `Cancelled`: The booking was cancelled or rejected.\n- `Deleted`: The booking has been deleted from the system.\n- `Lost`: The booking was not completed before its scheduled date.\n",
        "enum": [
          "Pending",
          "InProgress",
          "Confirmed",
          "Cancelled",
          "Deleted",
          "Lost"
        ],
        "example": "Confirmed"
      },
      "DayOfWeek": {
        "type": "string",
        "enum": [
          "sunday",
          "monday",
          "tuesday",
          "wednesday",
          "thursday",
          "friday",
          "saturday"
        ],
        "description": "Day of the week for booking availability"
      },
      "ProductCategoryResponse": {
        "type": "object",
        "description": "Response containing a list of product categories",
        "properties": {
          "data": {
            "type": "array",
            "description": "List of available product categories",
            "items": {
              "$ref": "#/components/schemas/ProductCategory"
            }
          }
        },
        "required": [
          "data"
        ]
      },
      "ProductCategory": {
        "type": "object",
        "description": "Represents a product category used to classify venue products",
        "properties": {
          "slug": {
            "type": "string",
            "description": "URL-friendly identifier for the category, typically lowercase with underscores or hyphens",
            "example": "lunch"
          },
          "name": {
            "type": "string",
            "description": "Display name of the product category",
            "example": "Lunch"
          }
        },
        "required": [
          "slug",
          "name"
        ]
      },
      "VenueResponse": {
        "type": "object",
        "description": "A paginated list of venues with a cursor for retrieving the next page of results.",
        "properties": {
          "data": {
            "type": "array",
            "description": "A list of venue records for the current page.",
            "items": {
              "$ref": "#/components/schemas/Venue"
            }
          }
        },
        "required": [
          "data"
        ]
      },
      "Venue": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Unique identifier for the venue."
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "The name of the venue."
          },
          "venueGroupName": {
            "type": "string",
            "nullable": true,
            "description": "The name of the venue group or chain that this venue belongs to."
          },
          "content": {
            "type": "string",
            "nullable": true,
            "description": "Description or additional content about the venue."
          },
          "faqs": {
            "type": "array",
            "nullable": true,
            "description": "Operator-managed public-facing FAQ list for the venue. Omitted/null when no FAQs are configured.\n",
            "items": {
              "$ref": "#/components/schemas/FaqItem"
            },
            "example": [
              {
                "question": "What is your cancellation policy?",
                "answer": "See our **cancellation policy** [here](https://example.com/policy)."
              }
            ]
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "The contact phone number of the venue."
          },
          "website": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "The official website of the venue."
          },
          "reservable": {
            "type": "boolean",
            "nullable": true,
            "description": "Indicates if the venue can be reserved."
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "types": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "A list of types that categorize the venue."
          },
          "photos": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "A collection of photo URLs representing the venue."
          },
          "is_active": {
            "type": "boolean",
            "nullable": true,
            "description": "Indicates if the venue is currently active.",
            "deprecated": true,
            "default": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the venue was created.",
            "deprecated": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the venue was last updated."
          },
          "products": {
            "type": "array",
            "nullable": true,
            "description": "List of products available at the venue.",
            "items": {
              "$ref": "#/components/schemas/Product"
            }
          },
          "preorders": {
            "nullable": true,
            "description": "Pre-order options available at the venue, including packages and menus.",
            "$ref": "#/components/schemas/VenuePreorders"
          },
          "opening_times": {
            "type": "object",
            "nullable": true,
            "description": "Opening times for the venue, including weekly schedule and specific date overrides.",
            "additionalProperties": {
              "$ref": "#/components/schemas/OpeningTime"
            },
            "example": {
              "monday": {
                "status": true,
                "open": "10:00",
                "close": "23:00",
                "notes": "",
                "private_hire": false
              },
              "tuesday": {
                "status": true,
                "open": "10:00",
                "close": "23:00",
                "notes": "",
                "private_hire": false
              },
              "2025-12-25": {
                "status": false,
                "open": "",
                "close": "",
                "notes": "Closed for Christmas"
              }
            }
          }
        }
      },
      "VenuePreorders": {
        "type": "object",
        "description": "Pre-order options available at the venue, including packages and menus.",
        "properties": {
          "packages": {
            "type": "array",
            "nullable": true,
            "description": "List of packages available for pre-ordering.",
            "items": {
              "$ref": "#/components/schemas/Package"
            }
          },
          "menus": {
            "type": "array",
            "nullable": true,
            "description": "List of menus available for pre-ordering.",
            "items": {
              "$ref": "#/components/schemas/Menu"
            }
          }
        }
      },
      "Product": {
        "type": "object",
        "description": "A product available at a venue.",
        "properties": {
          "compositeId": {
            "type": "string",
            "nullable": true,
            "description": "Unique identifier of the venue/product, used by other services (availability, booking, amendment).."
          },
          "productName": {
            "type": "string",
            "nullable": true,
            "description": "Name of the booking product."
          },
          "timeInterval": {
            "type": "integer",
            "nullable": true,
            "description": "The valid time options per booking for this product."
          },
          "preOrderRequired": {
            "type": "boolean",
            "nullable": true,
            "description": "If true it means a menu, or package, (if present) must be added to the booking to submit it."
          },
          "preOrderRequiredType": {
            "type": "string",
            "nullable": true,
            "enum": [
              "none",
              "package",
              "menu",
              "packageAndMenu"
            ],
            "description": "Specifies which type of preorder is required by the RMS. - none: no preorder needed - package: an upsell/package must be added - menu: a menu must be selected - packageAndMenu: both package and menu required\n"
          },
          "depositRequired": {
            "type": "boolean",
            "nullable": true,
            "description": "Indicates whether a deposit is required when booking this product."
          },
          "depositRule": {
            "$ref": "#/components/schemas/ProductDepositRule"
          },
          "availabilityRules": {
            "$ref": "#/components/schemas/ProductAvailabilityRules"
          },
          "category": {
            "type": "string",
            "nullable": true,
            "description": "Primary main category slug (first of `categories`). Kept for backwards compatibility."
          },
          "categories": {
            "type": "array",
            "nullable": true,
            "description": "All main category slugs assigned to this product. A product may have more than one (e.g. a \"Food Table\" that is both lunch and dinner).",
            "items": {
              "type": "string"
            }
          },
          "sub_category": {
            "type": "string",
            "nullable": true,
            "description": "Optional admin-defined sub-category slug (e.g. \"outdoor\", \"easter\", \"christmas\"). Null when no sub-category applies."
          },
          "preorders": {
            "$ref": "#/components/schemas/ProductPreorders"
          },
          "spaces": {
            "type": "array",
            "nullable": true,
            "description": "Spaces available within this product.",
            "items": {
              "$ref": "#/components/schemas/VenueSpaceResponse"
            }
          },
          "slug": {
            "type": "string",
            "nullable": true,
            "description": "Aggregation slug identifier for the product."
          },
          "feedUrl": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Direct URL to the pre-generated availability feed index for this product. Null if the product is not currently reachable by any partner, or if no feed has been generated for it yet. The index is a plain JSON document listing each day in the 90-day rolling window that has availability, with a download URL for that day's gzip-compressed daily shard file. Regenerated once daily. Download directly from this URL — no additional authentication required.\n",
            "example": "https://feeds.bookabletech.com/1/5ece848cd4ea51354476a79d/5c4af02d6354a83e3a0ea3b4/index.json"
          }
        }
      },
      "ProductDepositRule": {
        "nullable": true,
        "type": "object",
        "description": "Deposit amounts for a product. Either perAdult/perChild are populated (per-cover deposit) or perBooking (flat deposit), never both at the same time.\n",
        "properties": {
          "perAdult": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Deposit amount per adult cover."
          },
          "perChild": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Deposit amount per child cover."
          },
          "perBooking": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Flat deposit amount per booking."
          }
        }
      },
      "ProductPreorders": {
        "nullable": true,
        "type": "object",
        "description": "Package and menu IDs available for a specific product, filtered by partner mapping rules.\n",
        "properties": {
          "packageIds": {
            "type": "array",
            "nullable": true,
            "description": "IDs of packages linked to this product for the requesting partner.",
            "items": {
              "type": "string"
            }
          },
          "menuIds": {
            "type": "array",
            "nullable": true,
            "description": "IDs of menus linked to this product for the requesting partner.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ProductAvailabilityRules": {
        "nullable": true,
        "type": "object",
        "description": "Availability rules for a product, grouped by source.\n`weekly` and `exceptions` are constraints imposed by the TMS (read-only).\n`rules` are operator-defined rules configurable per partner.\n",
        "properties": {
          "weekly": {
            "$ref": "#/components/schemas/WeeklyRule"
          },
          "exceptions": {
            "type": "array",
            "nullable": true,
            "description": "Date-specific availability exceptions defined by the TMS.",
            "items": {
              "$ref": "#/components/schemas/RuleException"
            }
          },
          "rules": {
            "type": "array",
            "nullable": true,
            "description": "Operator-defined availability rules for specific partners.",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRule"
            }
          }
        }
      },
      "WeeklyRule": {
        "nullable": true,
        "type": "object",
        "description": "Weekly booking availability schedule, one entry per day of the week.",
        "properties": {
          "monday": {
            "$ref": "#/components/schemas/BookingRule"
          },
          "tuesday": {
            "$ref": "#/components/schemas/BookingRule"
          },
          "wednesday": {
            "$ref": "#/components/schemas/BookingRule"
          },
          "thursday": {
            "$ref": "#/components/schemas/BookingRule"
          },
          "friday": {
            "$ref": "#/components/schemas/BookingRule"
          },
          "saturday": {
            "$ref": "#/components/schemas/BookingRule"
          },
          "sunday": {
            "$ref": "#/components/schemas/BookingRule"
          }
        }
      },
      "RuleException": {
        "type": "object",
        "description": "A date-specific availability exception imposed by the TMS.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Unique identifier for the booking override",
            "example": "5e33079d6e4fb3019d08d127"
          },
          "date_from": {
            "type": "string",
            "format": "date",
            "description": "Start date for the override rule (inclusive)",
            "example": "2020-04-10",
            "nullable": true
          },
          "date_to": {
            "type": "string",
            "format": "date",
            "description": "End date for the override rule (inclusive)",
            "example": "2020-04-10",
            "nullable": true
          },
          "booking_available": {
            "type": "boolean",
            "description": "Whether bookings are available during this period",
            "example": true,
            "nullable": true
          },
          "bookings_from": {
            "type": "string",
            "format": "time",
            "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
            "description": "Start time for accepting bookings (HH:mm format)",
            "example": "11:00",
            "nullable": true
          },
          "bookings_to": {
            "type": "string",
            "format": "time",
            "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
            "description": "End time for accepting bookings (HH:mm format)",
            "example": "15:00",
            "nullable": true
          },
          "min_duration": {
            "type": "integer",
            "format": "int32",
            "description": "Minimum booking duration in minutes",
            "example": 120,
            "nullable": true,
            "minimum": 0
          },
          "max_duration": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum booking duration in minutes",
            "example": 120,
            "nullable": true,
            "minimum": 0
          },
          "min_people": {
            "type": "integer",
            "format": "int32",
            "description": "Minimum number of people allowed per booking",
            "example": 1,
            "nullable": true
          },
          "max_people": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of people allowed per booking",
            "example": 24,
            "nullable": true
          },
          "auto_confirm_max": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of people for automatic booking confirmation",
            "example": 14,
            "nullable": true
          },
          "booking_notes": {
            "type": "string",
            "description": "Special notes or conditions for bookings during this period",
            "example": "£10 per person card authentication required to confirm your booking. Should you wish to cancel the booking, please let us know within 48 hours of your reservation otherwise your card will be charged at £10 per person.",
            "nullable": true
          }
        }
      },
      "RuleDataBase": {
        "nullable": true,
        "type": "object",
        "required": [
          "ruleType"
        ],
        "properties": {
          "ruleType": {
            "$ref": "#/components/schemas/AvailabilityRuleType"
          }
        },
        "discriminator": {
          "propertyName": "ruleType",
          "mapping": {
            "date_range": "#/components/schemas/DateRangeRuleData",
            "recurring": "#/components/schemas/RecurringRuleData",
            "time_based": "#/components/schemas/TimeBasedRuleData",
            "specific_dates": "#/components/schemas/SpecificDatesRuleData",
            "specific_dates_with_time": "#/components/schemas/SpecificDatesWithTimeRuleData",
            "date_range_with_time": "#/components/schemas/DateRangeWithTimeRuleData",
            "recurring_with_time": "#/components/schemas/RecurringWithTimeRuleData"
          }
        }
      },
      "AvailabilityRule": {
        "type": "object",
        "description": "An operator-defined availability rule that controls booking availability per partner.",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Name of the availability rule.",
            "example": "Weekend Availability Rule"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Detailed description of the availability rule.",
            "example": "Rule that manages availability during weekends."
          },
          "ruleType": {
            "$ref": "#/components/schemas/AvailabilityRuleType"
          },
          "ruleData": {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          "ruleMode": {
            "type": "string",
            "nullable": true,
            "enum": [
              "allow",
              "block"
            ],
            "description": "Defines how this rule should be applied.\n- **allow**: the rule explicitly permits the associated items within the specified conditions.\n- **block**: the rule explicitly restricts or disables the associated items within the specified conditions.\n"
          },
          "packageIds": {
            "type": "array",
            "nullable": true,
            "description": "List of package IDs included in the rule.\n",
            "items": {
              "type": "string"
            }
          },
          "menuIds": {
            "type": "array",
            "nullable": true,
            "description": "List of menu IDs included in the rule.\n",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "AvailabilityRuleType": {
        "nullable": true,
        "type": "string",
        "enum": [
          "date_range",
          "recurring",
          "time_based",
          "specific_dates",
          "specific_dates_with_time",
          "date_range_with_time",
          "recurring_with_time"
        ],
        "description": "Type of availability rule:\n- `date_range`: Rules that apply to a continuous date range\n- `recurring`: Rules that repeat based on patterns (days of week, months)\n- `time_based`: Rules that apply to specific time periods within a day\n- `specific_dates`: Rules that apply to explicitly listed dates\n- `specific_dates_with_time`: Rules that apply to specific dates with time constraints\n- `date_range_with_time`: Rules that apply to a date range with time constraints\n- `recurring_with_time`: Rules that repeat based on patterns with time constraints\n",
        "example": "date_range"
      },
      "DateRangeRuleData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          {
            "type": "object",
            "description": "Rule data for date range based availability rules",
            "required": [
              "startDate",
              "endDate"
            ],
            "properties": {
              "startDate": {
                "type": "string",
                "format": "date",
                "description": "Start date of the date range (inclusive)",
                "example": "2025-11-01"
              },
              "endDate": {
                "type": "string",
                "format": "date",
                "description": "End date of the date range (inclusive)",
                "example": "2025-11-04"
              }
            }
          }
        ]
      },
      "RecurringRuleData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          {
            "type": "object",
            "description": "Rule data for recurring availability rules based on patterns.\nAt least one of `daysOfWeek` or `months` is expected; either may be provided alone\n(when both are present the match is AND). Neither field is individually required.\n",
            "properties": {
              "daysOfWeek": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 6
                },
                "description": "Days of the week when the rule applies (0=Sunday, 1=Monday, ..., 6=Saturday).\nOptional - if not provided, rule applies to all days.\n",
                "example": [
                  0,
                  5
                ],
                "maxItems": 7
              },
              "months": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 12
                },
                "description": "Months when the rule applies (1=January, 2=February, ..., 12=December).\nOptional - if not provided, rule applies to all months.\n",
                "example": [
                  1,
                  2
                ],
                "maxItems": 12
              }
            }
          }
        ]
      },
      "TimeBasedRuleData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          {
            "type": "object",
            "description": "Rule data for time-based availability rules within a day",
            "required": [
              "startTime",
              "endTime"
            ],
            "properties": {
              "startTime": {
                "type": "string",
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Start time when the rule applies (HH:mm format, 24-hour)",
                "example": "20:51"
              },
              "endTime": {
                "type": "string",
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "End time when the rule applies (HH:mm format, 24-hour)",
                "example": "03:51"
              }
            }
          }
        ]
      },
      "SpecificDatesRuleData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          {
            "type": "object",
            "description": "Rule data for availability rules that apply to specific dates",
            "required": [
              "dates"
            ],
            "properties": {
              "dates": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "date"
                },
                "description": "List of specific dates when the rule applies (YYYY-MM-DD format).\nEach date in the array represents a day when this availability rule is active.\n",
                "example": [
                  "2025-11-03",
                  "2025-11-05",
                  "2025-11-06"
                ],
                "minItems": 1
              }
            }
          }
        ]
      },
      "SpecificDatesWithTimeRuleData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          {
            "type": "object",
            "description": "Rule data for availability rules that apply to specific dates with time constraints",
            "required": [
              "dates",
              "startTime",
              "endTime"
            ],
            "properties": {
              "dates": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "date"
                },
                "description": "List of specific dates when the rule applies (YYYY-MM-DD format).\n",
                "example": [
                  "2026-01-15"
                ],
                "minItems": 1
              },
              "startTime": {
                "type": "string",
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Start time when the rule applies (HH:mm format, 24-hour)",
                "example": "10:00"
              },
              "endTime": {
                "type": "string",
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "End time when the rule applies (HH:mm format, 24-hour)",
                "example": "11:00"
              }
            }
          }
        ]
      },
      "DateRangeWithTimeRuleData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          {
            "type": "object",
            "description": "Rule data for date range with time constraints",
            "required": [
              "startDate",
              "endDate",
              "startTime",
              "endTime"
            ],
            "properties": {
              "startDate": {
                "type": "string",
                "format": "date",
                "description": "Start date of the date range (inclusive)",
                "example": "2026-01-31"
              },
              "endDate": {
                "type": "string",
                "format": "date",
                "description": "End date of the date range (inclusive)",
                "example": "2026-02-27"
              },
              "startTime": {
                "type": "string",
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Start time when the rule applies (HH:mm format, 24-hour)",
                "example": "13:23"
              },
              "endTime": {
                "type": "string",
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "End time when the rule applies (HH:mm format, 24-hour)",
                "example": "18:23"
              }
            }
          }
        ]
      },
      "RecurringWithTimeRuleData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/RuleDataBase"
          },
          {
            "type": "object",
            "description": "Rule data for recurring availability rules with time constraints",
            "properties": {
              "daysOfWeek": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 6
                },
                "description": "Days of the week when the rule applies (0=Sunday, 1=Monday, ..., 6=Saturday).\nOptional - if not provided, rule applies to all days.\n",
                "example": [
                  0,
                  5
                ],
                "maxItems": 7
              },
              "months": {
                "type": "array",
                "nullable": true,
                "items": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 12
                },
                "description": "Months when the rule applies (1=January, 2=February, ..., 12=December).\nOptional - if not provided, rule applies to all months.\n",
                "example": [
                  2,
                  4
                ],
                "maxItems": 12
              },
              "startTime": {
                "type": "string",
                "nullable": true,
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Start time when the rule applies (HH:mm format, 24-hour)",
                "example": "13:23"
              },
              "endTime": {
                "type": "string",
                "nullable": true,
                "format": "time",
                "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
                "description": "End time when the rule applies (HH:mm format, 24-hour)",
                "example": "18:23"
              }
            }
          }
        ]
      },
      "Location": {
        "nullable": true,
        "type": "object",
        "properties": {
          "area": {
            "type": "string",
            "nullable": true,
            "description": "The general area where the venue is located Can be more than one separated by |."
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "The city where the venue is located."
          },
          "lat": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "The latitude coordinate of the venue."
          },
          "lng": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "The longitude coordinate of the venue."
          },
          "street": {
            "type": "string",
            "nullable": true,
            "description": "The street address of the venue."
          },
          "postCode": {
            "type": "string",
            "nullable": true,
            "description": "The postal code of the venue."
          },
          "gPlace": {
            "type": "string",
            "nullable": true,
            "description": "The Google Place ID associated with the venue."
          }
        }
      },
      "BookingRule": {
        "type": "object",
        "nullable": true,
        "description": "Booking rule information.",
        "properties": {
          "from": {
            "type": "string",
            "format": "time",
            "nullable": true,
            "description": "Starting time for which bookings are allowed (ISO8601 hh:mm format)."
          },
          "to": {
            "type": "string",
            "format": "time",
            "nullable": true,
            "description": "Ending time for which bookings are allowed (ISO8601 hh:mm format)."
          },
          "bookingCutoff": {
            "type": "string",
            "nullable": true,
            "description": "The cutoff time after which bookings are no longer accepted. Accepts time in ISO 8601 `hh:mm` format or as a duration (e.g., `-60` for 2 hours)."
          },
          "minDuration": {
            "type": "integer",
            "nullable": true,
            "description": "The minimum duration in minutes allowed for the booking"
          },
          "maxDuration": {
            "type": "integer",
            "nullable": true,
            "description": "The maximum duration in minutes allowed for the booking"
          },
          "minPartySize": {
            "type": "integer",
            "nullable": true,
            "description": "The minimum partySize allowed for the booking"
          },
          "maxPartySize": {
            "type": "integer",
            "nullable": true,
            "description": "The maximum partySize allowed for the booking"
          },
          "notes": {
            "type": "string",
            "nullable": true,
            "description": "Optional notes or remarks for the booking."
          }
        }
      },
      "Package": {
        "type": "object",
        "description": "Represents a venue package/product",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Unique identifier for the package",
            "example": "5888a5afc71620e04002d5bb"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Package name",
            "example": "*Pan roasted Padron peppers (V)"
          },
          "price": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Package price",
            "example": 5.57
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Detailed package description",
            "example": "5 items per guest: Salmon & celeriac on rye, Buttermilk fries chicken..."
          },
          "type": {
            "type": "string",
            "nullable": true,
            "description": "Main package type",
            "example": "food"
          },
          "sub_type": {
            "type": "string",
            "nullable": true,
            "description": "Package subtype (mainly for type=food)",
            "example": "starter"
          },
          "diet_types": {
            "type": "array",
            "nullable": true,
            "description": "Supported diet types",
            "items": {
              "type": "string"
            },
            "example": [
              "Vegetarian",
              "Vegan"
            ]
          },
          "allergens": {
            "type": "array",
            "nullable": true,
            "description": "List of allergens present",
            "items": {
              "type": "string"
            },
            "example": [
              "Gluten",
              "Milk"
            ]
          },
          "configurable_options": {
            "type": "array",
            "nullable": true,
            "description": "Configurable options for the package",
            "items": {
              "$ref": "#/components/schemas/ConfigurableOption"
            }
          },
          "slug": {
            "type": "string",
            "nullable": true,
            "description": "Aggregation slug identifier for the package."
          }
        }
      },
      "ConfigurableOption": {
        "type": "object",
        "description": "Configurable option for a package",
        "properties": {
          "label": {
            "type": "string",
            "nullable": true,
            "description": "Option label",
            "example": "How Would You Like It Cooked ?"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Option description",
            "example": "Let us know how you like your steak cooked?"
          },
          "min": {
            "type": "integer",
            "nullable": true,
            "description": "Minimum number of selections required",
            "example": 1
          },
          "max": {
            "type": "integer",
            "nullable": true,
            "description": "Maximum number of selections allowed",
            "example": 1
          },
          "values": {
            "type": "array",
            "nullable": true,
            "description": "Available values for the option",
            "items": {
              "$ref": "#/components/schemas/ConfigurableValue"
            }
          }
        }
      },
      "ConfigurableValue": {
        "type": "object",
        "description": "Configurable value of an option",
        "properties": {
          "label": {
            "type": "string",
            "nullable": true,
            "description": "Value label",
            "example": "Rare"
          },
          "price_change": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Price change for this value",
            "example": 2.5
          },
          "diet_types": {
            "type": "array",
            "nullable": true,
            "description": "Diet types supported by this value",
            "items": {
              "type": "string"
            },
            "example": [
              "Vegetarian",
              "Vegan"
            ]
          },
          "allergens": {
            "type": "array",
            "nullable": true,
            "description": "Allergens added by this value",
            "items": {
              "type": "string"
            },
            "example": [
              "Milk"
            ]
          },
          "removes_allergens": {
            "type": "array",
            "nullable": true,
            "description": "Allergens removed by this value",
            "items": {
              "type": "string"
            },
            "example": [
              "Gluten"
            ]
          }
        }
      },
      "Menu": {
        "type": "object",
        "description": "Represents a venue menu",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Unique identifier for the menu",
            "example": "68a5f2eee07ae30fcd653b03"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Menu name",
            "example": "Set Menu"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Detailed menu description",
            "example": "A choice of 2 or 3 courses from our set menu. Disclaimer:..."
          },
          "items": {
            "type": "array",
            "nullable": true,
            "description": "The available options for the menu",
            "items": {
              "$ref": "#/components/schemas/MenuItem"
            }
          },
          "slug": {
            "type": "string",
            "nullable": true,
            "description": "Aggregation slug identifier for the menu."
          }
        }
      },
      "MenuItem": {
        "type": "object",
        "description": "Represents an option available for the menu",
        "properties": {
          "packageId": {
            "type": "string",
            "nullable": true,
            "description": "The ID of the package that composes the menu item",
            "example": "62c6c9f532c7cc7e4265dfdc"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Menu item name",
            "example": "*Pan roasted Padron peppers (V)"
          },
          "price": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Menu item price",
            "example": 5.57
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Detailed menu item description",
            "example": "5 items per guest: Salmon & celeriac on rye, Buttermilk fries chicken..."
          },
          "diet_types": {
            "type": "array",
            "nullable": true,
            "description": "Supported diet types for the menu item",
            "items": {
              "type": "string"
            },
            "example": [
              "Vegetarian",
              "Vegan"
            ]
          },
          "allergens": {
            "type": "array",
            "nullable": true,
            "description": "List of allergens present in the menu item",
            "items": {
              "type": "string"
            },
            "example": [
              "Gluten",
              "Milk"
            ]
          },
          "configurable_options": {
            "type": "array",
            "nullable": true,
            "description": "Configurable options for the menu item",
            "items": {
              "$ref": "#/components/schemas/ConfigurableOption"
            }
          },
          "type": {
            "type": "string",
            "nullable": true,
            "description": "The menu item type (e.g. food, drink, etc.)",
            "example": "food"
          },
          "subType": {
            "type": "string",
            "nullable": true,
            "description": "The group this item belongs to (e.g. Main Dish, Desserts, Starter)",
            "example": "Desserts"
          },
          "displayOrder": {
            "type": "integer",
            "nullable": true,
            "description": "The display order of this item within its subGroup",
            "example": 1
          }
        }
      },
      "OpeningTime": {
        "type": "object",
        "description": "Opening time information for a specific day or date.",
        "properties": {
          "status": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the venue is open on this day/date.",
            "example": true
          },
          "open": {
            "type": "string",
            "format": "time",
            "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
            "description": "Opening time in HH:mm format (e.g., \"10:00\").",
            "example": "10:00",
            "nullable": true
          },
          "close": {
            "type": "string",
            "format": "time",
            "pattern": "^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$",
            "description": "Closing time in HH:mm format (e.g., \"23:00\"). Can be \"00:00\" for midnight.",
            "example": "23:00",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "description": "Optional notes about the opening times.",
            "example": "Happy hour until 19:00",
            "nullable": true
          },
          "private_hire": {
            "type": "boolean",
            "description": "Whether this is available for private hire only.",
            "example": false,
            "nullable": true
          }
        }
      },
      "AvailabilityRequest": {
        "type": "object",
        "properties": {
          "partySize": {
            "type": "integer",
            "description": "The number of adults in the booking.",
            "minimum": 1
          },
          "children": {
            "type": "integer",
            "nullable": true,
            "description": "The number of children in the booking. Note: not all TMS providers support a distinction between adults and children. When unsupported, children may be added to the total party size or ignored entirely.\n",
            "example": 2
          },
          "date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "The date for which availability is being checked (YYYY-MM-DD)."
          },
          "startTime": {
            "type": "string",
            "format": "time",
            "nullable": true,
            "description": "Preferred start time for the booking (HH:MM format)"
          },
          "endTime": {
            "type": "string",
            "format": "time",
            "nullable": true,
            "description": "Desired end time of the booking (HH:MM format)."
          },
          "duration": {
            "type": "integer",
            "description": "The duration of the booking in minutes",
            "nullable": true
          },
          "minimumSpend": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Filter results by maximum minimum spend (in pence). Only returns time slots where the space's minimum spend is at or below this value.\n"
          },
          "under18s": {
            "type": "boolean",
            "nullable": true,
            "description": "Soft filter on the under-18s policy `allowed` field. Pass `true` to exclude only spaces where under-18s are explicitly prohibited (`allowed=false`); pass `false` to exclude only spaces where under-18s are explicitly permitted (`allowed=true`). Spaces with no under-18s policy set are always included regardless of this filter.\n"
          },
          "occasionTypes": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OccasionType"
              }
            ],
            "nullable": true,
            "description": "Filter by occasion type. Only returns time slots where the space supports the specified occasion type.\n"
          },
          "promotedEvents": {
            "type": "boolean",
            "nullable": true,
            "description": "Soft filter on the promoted-events policy `allowed` field. Pass `true` to exclude only spaces where promoted events are explicitly prohibited (`allowed=false`); pass `false` to exclude only spaces where promoted events are explicitly permitted (`allowed=true`). Spaces with no promoted-events policy set are always included regardless of this filter.\n"
          },
          "accessibility": {
            "type": "boolean",
            "nullable": true,
            "description": "Filter by whether the space is wheelchair accessible.\n"
          },
          "servesFood": {
            "type": "boolean",
            "nullable": true,
            "description": "Soft filter on the serves-food policy `allowed` field. Pass `true` to exclude only spaces where food service is explicitly prohibited (`allowed=false`); pass `false` to exclude only spaces where food service is explicitly permitted (`allowed=true`). Spaces with no serves-food policy set are always included regardless of this filter.\n"
          },
          "includeUnavailable": {
            "type": "boolean",
            "nullable": true,
            "description": "When `true`, time slots that do not match the active space policy filters are included in the response instead of being excluded. Each such slot will have `unavailableReasons` populated with a human-readable explanation of why it was filtered out. Defaults to `false` (standard filtering behaviour).\n"
          }
        },
        "required": [
          "partySize",
          "date"
        ]
      },
      "AvailabilityResponse": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "The name of the available booking option.",
            "nullable": true
          },
          "deposit": {
            "type": "number",
            "format": "float",
            "description": "The deposit amount required for the booking.",
            "nullable": true
          },
          "policy": {
            "type": "string",
            "description": "General policy details regarding the booking.",
            "nullable": true
          },
          "autoConfirmRule": {
            "$ref": "#/components/schemas/AutoConfirmRule"
          },
          "cancellationPolicy": {
            "type": "string",
            "description": "Terms and conditions for canceling the booking.",
            "nullable": true
          },
          "times": {
            "nullable": true,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "time": {
                  "type": "string",
                  "nullable": true,
                  "description": "Available time slot for the booking (HH:MM format)."
                },
                "duration": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Duration of the booking in minutes."
                },
                "type": {
                  "$ref": "#/components/schemas/AvailabilityType"
                },
                "requestReason": {
                  "type": "string",
                  "nullable": true,
                  "description": "Present only when `type` is `request`. Indicates why this time slot requires manual operator approval rather than instant confirmation, allowing integration partners to communicate the appropriate message to their end users.\n\nPossible values:\n\n- `fully_booked` — the venue has no real-time availability for this slot, but the operator\n  is still open to receiving enquiries. Submitting an enquiry allows the operator to manually\n  assess whether they can accommodate the request (e.g. by rearranging covers or accepting\n  a waitlist entry).\n\n\n- `exceeds_auto_confirm` — availability exists for this slot, but the requested party size\n  is above the venue's auto-confirm threshold and therefore requires explicit operator\n  approval before the booking is confirmed.\n\n\n- `request_only` — the venue is configured to accept only enquiries for this product and\n  does not support instant bookings. All submissions for this slot will be treated as\n  requests regardless of availability or party size.\n\n\nNew values may be introduced in future API versions; clients should handle unknown values gracefully.\n"
                },
                "productId": {
                  "type": "string",
                  "description": "Unique identifier of the product (compositeId) that this time slot refers to.",
                  "nullable": true,
                  "deprecated": true
                },
                "product": {
                  "nullable": true,
                  "type": "object",
                  "description": "Product information and applicable space policies for this time slot. minSpend entries are pre-filtered to match both the requested date and this specific time slot, so the client can display the applicable spend rule directly.\n",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Unique identifier of the product (compositeId)."
                    },
                    "name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Display name of the product."
                    },
                    "spaces": {
                      "nullable": true,
                      "type": "array",
                      "description": "Spaces associated with this product. Each element contains physical data and applicable policies for one space.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer",
                            "description": "Unique identifier of the space."
                          },
                          "spaceName": {
                            "type": "string",
                            "nullable": true,
                            "description": "Name of the space."
                          },
                          "description": {
                            "type": "string",
                            "nullable": true,
                            "description": "Description of the space."
                          },
                          "floorLocation": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Floor number (0 = ground floor)."
                          },
                          "facilities": {
                            "nullable": true,
                            "type": "array",
                            "description": "Facilities available in this space.",
                            "items": {
                              "$ref": "#/components/schemas/SpaceFacility"
                            }
                          },
                          "capacityStanding": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacitySeated": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacityCabaret": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacityTheatre": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacityBoardroom": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacityClassroom": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacityUShape": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacityBanquet": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "capacityReception": {
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/SpaceCapacityRange"
                              }
                            ],
                            "nullable": true
                          },
                          "policies": {
                            "type": "object",
                            "description": "Policy information for this space.",
                            "properties": {
                              "minimumSpend": {
                                "nullable": true,
                                "type": "array",
                                "description": "Minimum spend entries applicable to this time slot. Filtered by date (override wins) and time range. Each entry is a matching rule or the date-specific override.\n",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "spendValue": {
                                      "type": "integer",
                                      "nullable": true,
                                      "description": "Minimum spend in pence (GBP)."
                                    }
                                  }
                                }
                              },
                              "under18s": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "until": {
                                    "type": "string",
                                    "nullable": true
                                  }
                                }
                              },
                              "occasionTypes": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "values": {
                                    "nullable": true,
                                    "type": "array",
                                    "items": {
                                      "$ref": "#/components/schemas/OccasionType"
                                    }
                                  }
                                }
                              },
                              "promotedEvents": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "notes": {
                                    "type": "string",
                                    "nullable": true
                                  }
                                }
                              },
                              "accessibility": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "accessible": {
                                    "type": "boolean",
                                    "nullable": true
                                  },
                                  "notes": {
                                    "type": "string",
                                    "nullable": true
                                  }
                                }
                              },
                              "servesFood": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "preOrderItems": {
                  "type": "object",
                  "nullable": true,
                  "description": "Provides information about which packages and menus are available for this availability result.\n",
                  "properties": {
                    "packageIds": {
                      "nullable": true,
                      "type": "array",
                      "description": "List of package IDs available **when `allowedPackages` is set to `set`**.\n",
                      "items": {
                        "type": "string"
                      }
                    },
                    "allowedPackages": {
                      "nullable": true,
                      "type": "string",
                      "enum": [
                        "none",
                        "all",
                        "set"
                      ],
                      "description": "Defines how package availability should be interpreted:\n- **none**: no packages are available.\n- **all**: all packages are available.\n- **set**: only the packages listed in `packageIds` are available.\n"
                    },
                    "menuIds": {
                      "nullable": true,
                      "type": "array",
                      "description": "List of menu IDs available **when `allowedMenu` is set to `set`**.\n",
                      "items": {
                        "type": "string"
                      }
                    },
                    "allowedMenus": {
                      "nullable": true,
                      "type": "string",
                      "enum": [
                        "none",
                        "all",
                        "set"
                      ],
                      "description": "Defines how menu availability should be interpreted:\n- **none**: no menus are available.\n- **all**: all menus are available.\n- **set**: only the menus listed in `menuIds` are available.\n"
                    }
                  }
                },
                "unavailableReasons": {
                  "nullable": true,
                  "type": "array",
                  "description": "Present only when `includeUnavailable=true` is set on the request. If this slot was excluded by one or more space policy filters, this array contains a human-readable explanation for each failing filter. `null` (or absent) means the slot is fully available given the active filters.\n",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "noAvailabilityReason": {
            "nullable": true,
            "type": "string",
            "description": "Populated only when `times` is empty. Human-readable message explaining why no availability was found for the requested parameters.\n"
          },
          "noAvailabilityCode": {
            "nullable": true,
            "type": "string",
            "description": "Populated only when `times` is empty. Machine-readable code indicating why no availability was found. Known values:\n- `NO_AVAILABILITY` — the RMS found no availability for the requested parameters. - `NO_AVAILABLE_TIMES` — the RMS confirmed the request was valid but returned no bookable time slots. - `NO_ELIGIBLE_PRODUCTS` — no booking products are available for the selected criteria. - `FILTERED_BY_OPERATOR_RULES` — operator availability rules block this partner/date combination. - `FILTERED_BY_CAPACITY` — the requested party size does not fit within the venue's configured space capacity (no space filters were active). - `FILTERED_BY_CAPACITY_MIN` — party size is below the minimum capacity of every available space. - `FILTERED_BY_CAPACITY_MAX` — party size exceeds the maximum capacity of every available space. - `FILTERED_BY_SPACE_FILTERS` — no spaces match the requested space filter combination (under-18s, accessibility, occasion type, etc.). - `FILTERED_BY_SPACE_FILTERS_CAPACITY_MIN` — party size is below the minimum capacity of every available space (space filters were also active). - `FILTERED_BY_SPACE_FILTERS_CAPACITY_MAX` — party size exceeds the maximum capacity of every available space (space filters were also active). - `NUM_PEOPLE_INVALID` — the RMS rejected the party size (see `noAvailabilityReason` for the exact message). - `NUM_PEOPLE_EXCEEDS_MAX` — party size exceeds the maximum allowed for this booking type. - `NUM_PEOPLE_BELOW_MIN` — party size is below the minimum required for this booking type. - `BOOKING_TYPE_UNAVAILABLE` — the requested booking type is not available at this venue. - `DATE_UNAVAILABLE` — the requested date is not available for this booking type.\nNew values may be added in future without prior notice — treat unknown values as a generic no-availability condition.\n"
          }
        }
      },
      "AutoConfirmRule": {
        "nullable": true,
        "type": "object",
        "description": "Defines the criteria for automatically confirming bookings without manual intervention.",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Specific date when this rule applies (YYYY-MM-DD format). If null, rule applies based on other criteria."
          },
          "dateType": {
            "type": "string",
            "nullable": true,
            "description": "Type of date restriction (e.g., \"date\", \"weekend\", \"special_event\"). Allows for categorized date-based rules."
          },
          "minPeople": {
            "type": "integer",
            "nullable": true,
            "description": "Minimum number of people required for auto-confirmation. If null, no minimum limit applies."
          },
          "maxPeople": {
            "type": "integer",
            "nullable": true,
            "description": "Maximum number of people allowed for auto-confirmation. If null, no maximum limit applies."
          },
          "timeFrom": {
            "type": "string",
            "nullable": true,
            "format": "time",
            "description": "Start time for the auto-confirm window (HH:MM format). Bookings before this time won't be auto-confirmed."
          },
          "timeTo": {
            "type": "string",
            "nullable": true,
            "format": "time",
            "description": "End time for the auto-confirm window (HH:MM format). Bookings after this time won't be auto-confirmed."
          },
          "weekdays": {
            "$ref": "#/components/schemas/VenueSearchWeekdays"
          }
        }
      },
      "VenueSearchWeekdays": {
        "nullable": true,
        "type": "object",
        "description": "Configuration object defining which weekdays a rule applies to.",
        "properties": {
          "monday": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the rule applies on Mondays."
          },
          "tuesday": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the rule applies on Tuesdays."
          },
          "wednesday": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the rule applies on Wednesdays."
          },
          "thursday": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the rule applies on Thursdays."
          },
          "friday": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the rule applies on Fridays."
          },
          "saturday": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the rule applies on Saturdays."
          },
          "sunday": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the rule applies on Sundays."
          }
        }
      },
      "Area": {
        "type": "object",
        "description": "Represents an area/zone within a venue available for booking.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the area (as provided by the RMS)."
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Display name of the area. May be null if no name is configured."
          }
        },
        "required": [
          "id"
        ]
      },
      "AvailabilityType": {
        "nullable": true,
        "description": "Specifies how an operators time slot can be handled. A value of book indicates the slot is available for instant confirmation, while request means the slot requires manual approval through an enquiry-based process.",
        "type": "string",
        "enum": [
          "book",
          "request"
        ],
        "example": "request"
      },
      "BookingRequest": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "description": "The first name for the booking.",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "description": "The last name for the booking.",
            "example": "Doe"
          },
          "partySize": {
            "type": "integer",
            "description": "The number of adults the booking is for.",
            "minimum": 1,
            "example": 4
          },
          "children": {
            "type": "integer",
            "nullable": true,
            "description": "The number of children included in the booking. Note: not all TMS providers support a distinction between adults and children. When unsupported, children may be added to the total party size or ignored entirely.\n",
            "example": 2
          },
          "date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "The date of the booking, in the format YYYY-MM-DD.",
            "example": "2025-06-15"
          },
          "time": {
            "type": "string",
            "format": "time",
            "nullable": true,
            "description": "The time of the booking, in the format HH:mm.",
            "example": "19:00"
          },
          "type": {
            "$ref": "#/components/schemas/AvailabilityType"
          },
          "duration": {
            "type": "integer",
            "nullable": true,
            "description": "The duration of the booking in minutes.",
            "example": 90
          },
          "email": {
            "type": "string",
            "format": "email",
            "pattern": "^\\S+@\\S+\\.\\S+$",
            "description": "The guest's email address.",
            "example": "john.doe@example.com"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "The guest's phone number.",
            "example": "+441234567890"
          },
          "notes": {
            "type": "string",
            "nullable": true,
            "description": "Any additional booking notes or special requests.",
            "example": "Birthday celebration"
          },
          "adminNotes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true,
            "description": "Internal notes or comments specific to the distributor."
          },
          "comments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true,
            "description": "Additional comments or notes provided by the distributor."
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true,
            "description": "A list of labels or tags associated with the booking."
          },
          "preorders": {
            "$ref": "#/components/schemas/PreorderContainer"
          },
          "partnerBookingId": {
            "type": "string",
            "nullable": true,
            "description": "Optional field that stores a reference code or unique identifier provided by an external system, used to link or synchronize records across platforms.",
            "example": "ext-ref-123"
          },
          "spaceId": {
            "type": "integer",
            "nullable": true,
            "description": "Optional space ID to book. When provided, overrides automatic area selection by the TMS. Obtain valid space IDs from the `spaces` array returned in the availability response time slots.\n"
          },
          "depositAmount": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Optional deposit amount to charge for this booking. When provided, the payment call is made to the RMS for this exact amount. When absent, no payment is processed.\n"
          }
        },
        "required": [
          "firstName",
          "lastName",
          "partySize",
          "date",
          "time",
          "type",
          "email"
        ]
      },
      "PreorderContainer": {
        "nullable": true,
        "type": "object",
        "description": "Container for all preorder items (packages and menus)",
        "properties": {
          "packages": {
            "type": "array",
            "description": "List of package preorders",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/PreorderPackageRequest"
            }
          },
          "menus": {
            "type": "array",
            "description": "List of menu preorders with optional item selection",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/PreorderMenuRequestV2"
            }
          }
        }
      },
      "PreorderPackageRequest": {
        "type": "object",
        "description": "A single package preorder item",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the package to be pre-ordered",
            "example": "62692e90d2cf1f163744efc4"
          },
          "quantity": {
            "type": "integer",
            "description": "The quantity of the package to be pre-ordered",
            "default": 1,
            "example": 2,
            "minimum": 1
          }
        },
        "required": [
          "id",
          "quantity"
        ]
      },
      "PreorderMenuRequestV2": {
        "type": "object",
        "description": "A menu preorder with optional item selection",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the menu to be added to the booking",
            "example": "61a4af3137b80d0bae3a7e19"
          },
          "quantity": {
            "type": "integer",
            "description": "The quantity of menus",
            "default": 1,
            "example": 4,
            "minimum": 1
          },
          "items": {
            "type": "array",
            "description": "Optional list of specific menu items to select",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/MenuItemSelection"
            }
          }
        },
        "required": [
          "id",
          "quantity"
        ]
      },
      "MenuItemSelection": {
        "type": "object",
        "description": "A specific menu item selection",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the menu item (package) to select",
            "example": "619d19eb40e1512ebb03b378"
          },
          "quantity": {
            "type": "integer",
            "description": "The quantity of this item",
            "default": 1,
            "example": 3,
            "minimum": 1
          },
          "options": {
            "type": "array",
            "nullable": true,
            "description": "Optional configurable options for this menu item",
            "items": {
              "$ref": "#/components/schemas/MenuItemOption"
            }
          }
        },
        "required": [
          "id",
          "quantity"
        ]
      },
      "MenuItemOption": {
        "type": "object",
        "description": "A configurable option for a menu item (e.g., side choice)",
        "properties": {
          "value": {
            "type": "string",
            "description": "The option value (e.g., \"Garden Peas\")",
            "example": "Garden Peas"
          }
        },
        "required": [
          "value"
        ]
      },
      "UpdateBookingStatusRequest": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "Confirmed",
              "Rejected"
            ],
            "description": "The target status transition for the in-progress booking. `Confirmed` completes the booking; `Rejected` declines it (reflected locally as `Cancelled`).\n",
            "example": "Confirmed"
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "Optional free-text reason for rejecting the booking (e.g. why the request was declined). Recorded against the booking. Ignored when `status` is `Confirmed`.",
            "example": "Requested slot no longer available"
          }
        }
      },
      "UpdateBookingRequest": {
        "type": "object",
        "properties": {
          "compositeId": {
            "type": "string",
            "description": "The unique identifier of the venue/product.",
            "example": "29|X9|275cc44dd2e2496fba44857c9257443a|69b3e389b35cb412b60f3738"
          },
          "firstName": {
            "type": "string",
            "description": "The first name for the booking.",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "description": "The last name for the booking.",
            "example": "Doe"
          },
          "partySize": {
            "type": "integer",
            "description": "The number of people the booking is for.",
            "minimum": 1,
            "example": 4
          },
          "date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "The date of the booking, in the format YYYY-MM-DD.",
            "example": "2025-06-15"
          },
          "time": {
            "type": "string",
            "format": "time",
            "nullable": true,
            "description": "The time of the booking, in the format HH:mm.",
            "example": "19:00"
          },
          "duration": {
            "type": "integer",
            "description": "The duration of the booking in minutes.",
            "nullable": true,
            "example": 90
          },
          "email": {
            "type": "string",
            "format": "email",
            "pattern": "^\\S+@\\S+\\.\\S+$",
            "description": "The guest's email address.",
            "example": "john.doe@example.com"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "The guest's phone number.",
            "example": "+441234567890"
          },
          "notes": {
            "type": "string",
            "nullable": true,
            "description": "Any additional booking notes or special requests.",
            "example": "Birthday celebration"
          }
        },
        "required": [
          "compositeId",
          "firstName",
          "lastName",
          "partySize",
          "date",
          "time",
          "email"
        ]
      },
      "ReservationResponse": {
        "type": "object",
        "title": "Bookings",
        "description": "A paginated list of bookings",
        "properties": {
          "data": {
            "title": "Bookings",
            "description": "The list of bookings",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Booking"
            }
          }
        },
        "required": [
          "data"
        ]
      },
      "Booking": {
        "type": "object",
        "title": "Booking",
        "description": "A detailed booking record.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "title": "The Booking ID",
            "description": "A globally unique identifier for the booking."
          },
          "compositeId": {
            "type": "string",
            "nullable": true,
            "title": "The Composite ID",
            "description": "A globally unique identifier for the venue/product."
          },
          "date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "title": "Reservation Date",
            "description": "The date of the booking."
          },
          "time": {
            "type": "string",
            "format": "time",
            "nullable": true,
            "title": "Reservation Time",
            "description": "The time of the booking."
          },
          "partySize": {
            "type": "integer",
            "format": "int32",
            "nullable": true,
            "title": "Party Size",
            "description": "Number of guests for the booking."
          },
          "status": {
            "$ref": "#/components/schemas/BookingStatus"
          },
          "reference": {
            "type": "string",
            "nullable": true,
            "title": "Reference (deprecated)",
            "description": "Legacy reference code for the booking. This field is deprecated and will be removed in future versions. Please use `operatorBookingId` instead.\n",
            "deprecated": true
          },
          "firstName": {
            "type": "string",
            "nullable": true,
            "title": "First Name",
            "description": "Guest's first name."
          },
          "lastName": {
            "type": "string",
            "nullable": true,
            "title": "Last Name",
            "description": "Guest's last name."
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "title": "Email",
            "description": "Email address of the guest."
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "title": "Phone",
            "description": "Phone number of the guest."
          },
          "venueGroupName": {
            "type": "string",
            "nullable": true,
            "title": "Venue Group Name",
            "description": "The name of the venue group that the booked venue belongs to."
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "duration": {
            "type": "integer",
            "format": "int32",
            "nullable": true,
            "title": "Duration",
            "description": "Duration of the booking in minutes."
          },
          "productName": {
            "type": "string",
            "nullable": true,
            "title": "Product Type",
            "description": "Name of the product or service reserved."
          },
          "notes": {
            "type": "string",
            "nullable": true,
            "title": "Notes",
            "description": "Additional notes for the booking."
          },
          "rejectionReason": {
            "type": "string",
            "nullable": true,
            "title": "Rejection Reason",
            "description": "The reason the booking was rejected, if a reason was provided when it was declined. Null otherwise."
          },
          "createdDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "title": "Created Date",
            "description": "Timestamp when the booking record was created in Bookable."
          },
          "tmsCreatedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "title": "TMS Created Date",
            "description": "Timestamp reported by the originating TMS for when the booking was created. Null when unavailable."
          },
          "lastUpdate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "title": "Last Updated",
            "description": "Timestamp of the last booking update."
          },
          "preorders": {
            "type": "object",
            "description": "Preordered items for the booking",
            "nullable": true,
            "properties": {
              "packages": {
                "type": "array",
                "description": "List of preordered packages",
                "nullable": true,
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "nullable": true,
                      "description": "Package identifier"
                    },
                    "name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Package name",
                      "example": "*Pan roasted Padron peppers (V)"
                    },
                    "description": {
                      "type": "string",
                      "nullable": true,
                      "description": "Package description",
                      "example": "5 items per guest: Salmon & celeriac on rye, Buttermilk fries chicken..."
                    },
                    "type": {
                      "type": "string",
                      "nullable": true,
                      "description": "Package type",
                      "example": "food"
                    },
                    "quantity": {
                      "type": "integer",
                      "nullable": true,
                      "description": "Quantity ordered"
                    },
                    "price": {
                      "type": "number",
                      "format": "float",
                      "nullable": true,
                      "description": "Package price",
                      "example": 5.57
                    }
                  }
                }
              },
              "menus": {
                "type": "array",
                "description": "List of preordered menus with items",
                "nullable": true,
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menu identifier"
                    },
                    "name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menu name"
                    },
                    "quantity": {
                      "type": "integer",
                      "nullable": true,
                      "description": "Number of menus ordered"
                    },
                    "submitted": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "post",
                        "pre"
                      ],
                      "description": "Describes the timing of menu item selection relative to the booking workflow. `pre` indicates items supplied during the booking and therefore included in this menu object. `post` indicates that no items were provided at booking time, and a link was generated to allow item selection after submission.\n"
                    },
                    "link": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL generated to allow menu item selection for this booking menu.",
                      "example": "set-menu"
                    },
                    "price": {
                      "type": "number",
                      "format": "float",
                      "nullable": true,
                      "description": "Price per person / fixed price for this menu.",
                      "example": 35
                    },
                    "items": {
                      "type": "array",
                      "description": "Menu items selected",
                      "nullable": true,
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "nullable": true,
                            "description": "Menu item (package) identifier"
                          },
                          "name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Item name"
                          },
                          "quantity": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Item quantity"
                          },
                          "price": {
                            "type": "number",
                            "format": "float",
                            "nullable": true,
                            "description": "Price of this menu item.",
                            "example": 12.5
                          },
                          "options": {
                            "type": "array",
                            "nullable": true,
                            "description": "Selected configurable option values for this menu item.",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "partnerBookingId": {
            "type": "string",
            "nullable": true,
            "title": "Partner Booking Reference",
            "description": "A custom booking identifier provided by the distributor (partner). This ID is submitted when creating a booking via API or Portal and serves as the partner's own reference code for cross-system tracking.\n"
          },
          "operatorBookingId": {
            "type": "string",
            "nullable": true,
            "title": "Operator Booking ID",
            "description": "The booking identifier generated by the operator's TMS platform (e.g., SevenRooms, Collins, Zonal). This ID uniquely identifies the reservation within the operator's system and is displayed in the portal instead of the composite ID.\n"
          },
          "depositAmount": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "title": "Deposit Amount",
            "description": "The deposit amount already collected for this booking at the time of reservation. This value is captured from the operator's TMS (e.g., Zonal) and reflects any per-person or per-booking deposit charged to the guest.\n"
          },
          "area": {
            "nullable": true,
            "title": "Booking Area",
            "description": "The area or zone assigned to this booking within the venue. Contains both the internal area identifier used by the TMS and a human-readable name for display purposes.\n",
            "$ref": "#/components/schemas/BookingArea"
          }
        }
      },
      "BookingArea": {
        "type": "object",
        "nullable": true,
        "title": "Booking Area",
        "description": "Represents the area or zone assigned to a booking within a venue, as reported by the operator's TMS.\n",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "The internal area identifier used by the TMS.",
            "example": "42"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Human-readable name of the area or zone.",
            "example": "Main Dining Room"
          }
        }
      },
      "JsonPatchOperation": {
        "type": "object",
        "title": "JSON Patch Operation (RFC 6902)",
        "description": "A single JSON Patch operation following RFC 6902 standard. Each operation modifies the target document at a specific path.\n",
        "required": [
          "op",
          "path"
        ],
        "properties": {
          "op": {
            "type": "string",
            "description": "The operation to perform",
            "enum": [
              "add",
              "remove",
              "replace"
            ],
            "example": "replace"
          },
          "path": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) to the target location in the document. Must start with `/` and use `/` as path separator.\n",
            "example": "/status",
            "pattern": "^\\/.*"
          },
          "value": {
            "description": "The value to use for the operation. Required for `add`, `replace`, and `test` operations. Can be any valid JSON value (string, number, boolean, object, array, null).\n",
            "example": "Confirmed"
          }
        },
        "example": {
          "op": "replace",
          "path": "/status",
          "value": "Confirmed"
        }
      },
      "ServerError": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "A URI reference [rfc9457] that identifies the problem type. This specification encourages that, when dereferenced, it provides human-readable documentation for the problem type (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be \"about:blank\"."
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization."
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "description": "The HTTP status code [rfc9457, Section 3.1.12] generated by the origin server for this occurrence of the problem."
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem."
          },
          "code": {
            "type": "string",
            "description": "Error code in the format RESOURCE-X-NNN where X is R (retryable) or N (non-retryable). See ErrorCatalog.md for all error codes.",
            "example": "BOOK-N-001"
          },
          "isRetryable": {
            "type": "boolean",
            "description": "Indicates whether the error is retryable. If true, the request may succeed if retried. If false, the request will fail again with the same input."
          },
          "traceId": {
            "type": "string",
            "description": "Request trace identifier for debugging and correlation purposes.",
            "example": "0HNJ2BG2TU3BU:00000001"
          }
        },
        "required": [
          "title",
          "status",
          "code",
          "isRetryable"
        ]
      },
      "Page": {
        "type": "object",
        "properties": {
          "meta": {
            "type": "object",
            "properties": {
              "currentPage": {
                "type": "integer",
                "description": "The current page number based on `limit` and `offset`."
              },
              "pageSize": {
                "type": "integer",
                "description": "The number of items returned per page."
              },
              "totalItems": {
                "type": "integer",
                "description": "The total number of items available."
              },
              "totalPages": {
                "type": "integer",
                "description": "The total number of pages."
              }
            }
          }
        }
      },
      "FaqItem": {
        "type": "object",
        "description": "Single FAQ entry. `question`/`answer` are plain strings and may contain markdown syntax; the server does not parse or sanitize it — rendering happens client-side.\n",
        "properties": {
          "question": {
            "type": "string",
            "nullable": true,
            "example": "What is your cancellation policy?"
          },
          "answer": {
            "type": "string",
            "nullable": true,
            "example": "See our **cancellation policy** [here](https://example.com/policy)."
          }
        }
      },
      "SpaceFacility": {
        "type": "string",
        "description": "Facilities available in a space.",
        "enum": [
          "Stage",
          "Private Bar",
          "Private Toilets",
          "Soundproof",
          "Own Street Entrance",
          "Fixed Seating",
          "Outside Space",
          "Can Be Decorated",
          "DJ Stand",
          "Suitable for Meetings",
          "Wheelchair Accessible",
          "Accessible Toilets",
          "Projector",
          "Screen / TV",
          "Microphone / PA",
          "Laptop Connection",
          "Own Sound System",
          "HDMI / AV",
          "In-House Lighting",
          "Sports TV",
          "Bring Own DJ",
          "Serves Food",
          "External Catering Permitted",
          "Draft Beer",
          "Cash Bar",
          "Can Bring Own Cake",
          "Tea/Coffee Facilities",
          "Cloakroom",
          "Smoking Area",
          "Wifi Available",
          "Pet Friendly",
          "Parking",
          "Air Conditioning"
        ]
      },
      "CapacityRange": {
        "type": "object",
        "description": "Min/max capacity range; both bounds are optional.",
        "properties": {
          "min": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "max": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        }
      },
      "MinimumSpendDateRange": {
        "type": "object",
        "description": "Explicit date interval (inclusive, ISO 8601). Does not recur.",
        "properties": {
          "from": {
            "type": "string",
            "format": "date"
          },
          "to": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "MinimumSpendTimeRange": {
        "type": "object",
        "description": "Time window of the booking start time (HH:MM, inclusive, Europe/London).",
        "properties": {
          "from": {
            "type": "string",
            "example": "18:00"
          },
          "to": {
            "type": "string",
            "example": "23:59"
          }
        }
      },
      "MinimumSpendConditions": {
        "type": "object",
        "description": "Conditions that must all be satisfied for the rule to apply (AND logic).\nAn empty object means the rule applies without restriction.\n",
        "properties": {
          "daysOfWeek": {
            "type": "array",
            "nullable": true,
            "description": "Days of the week (1=Monday, 7=Sunday). Absent means all days.",
            "items": {
              "type": "integer",
              "format": "int32"
            }
          },
          "months": {
            "type": "array",
            "nullable": true,
            "description": "Calendar months (1=January, 12=December). Absent means all months.",
            "items": {
              "type": "integer",
              "format": "int32"
            }
          },
          "dateRange": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MinimumSpendDateRange"
              }
            ],
            "nullable": true
          },
          "timeRange": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MinimumSpendTimeRange"
              }
            ],
            "nullable": true
          }
        }
      },
      "MinimumSpendRuleBase": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "nullable": true
          },
          "conditions": {
            "$ref": "#/components/schemas/MinimumSpendConditions"
          },
          "spendValue": {
            "type": "integer",
            "format": "int32",
            "nullable": true,
            "description": "Minimum spend amount in pence (GBP)."
          },
          "notes": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "MinimumSpendOverrideBase": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "description": "The specific calendar date. Also serves as the URL key."
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "spendValue": {
            "type": "integer",
            "format": "int32",
            "nullable": true,
            "description": "Minimum spend amount in pence (GBP)."
          },
          "timeRange": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MinimumSpendTimeRange"
              }
            ],
            "nullable": true,
            "description": "Optional time window (Europe/London) the override applies to. Absent means the override covers the whole date. Outside the window, normal rules apply."
          }
        }
      },
      "MinimumSpendPolicyResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "rules": {
            "type": "array",
            "description": "Weekly recurring minimum spend rules. Empty array means none configured.",
            "items": {
              "$ref": "#/components/schemas/MinimumSpendRuleBase"
            }
          },
          "overrides": {
            "type": "array",
            "description": "Date-specific minimum spend overrides. Empty array means none configured.",
            "items": {
              "$ref": "#/components/schemas/MinimumSpendOverrideBase"
            }
          }
        }
      },
      "OccasionType": {
        "type": "string",
        "description": "Allowed occasion types for a space.",
        "enum": [
          "Christmas Party",
          "Corporate Event",
          "Engagement Party",
          "Funeral/Wake",
          "Summer Party",
          "Wedding Party",
          "Winter Party",
          "Work Get Together",
          "Working Breakfast",
          "Working Lunch",
          "Working Dinner",
          "Promoted Event"
        ]
      },
      "OccasionTypesPolicyResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "values": {
            "type": "array",
            "nullable": true,
            "description": "Allowed occasion types.",
            "items": {
              "$ref": "#/components/schemas/OccasionType"
            }
          }
        }
      },
      "Under18sPolicyResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "allowed": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether under-18s are permitted (`true`) or prohibited (`false`) in this space.\n`null` means the policy has not been explicitly set.\n`allowed` must not be `true` when `enabled` is `false`.\n"
          },
          "until": {
            "type": "string",
            "nullable": true,
            "description": "Cutoff time for under-18s, e.g. \"21:00\"."
          }
        }
      },
      "PromotedEventsPolicyResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "allowed": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether promoted events are permitted (`true`) or prohibited (`false`) in this space.\n`null` means the policy has not been explicitly set.\n`allowed` must not be `true` when `enabled` is `false`.\n"
          },
          "notes": {
            "type": "string",
            "nullable": true,
            "description": "Optional notes about promoted events at this space."
          }
        }
      },
      "AccessibilityPolicyResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "accessible": {
            "type": "boolean",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ServesFoodPolicyResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "allowed": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the space serves food (`true`) or does not (`false`).\n`null` means the policy has not been explicitly set.\n`allowed` must not be `true` when `enabled` is `false`.\n"
          }
        }
      },
      "SpacePoliciesMap": {
        "type": "object",
        "description": "All policies for a space, keyed by policy type. An empty/default object means\nthat policy has not been configured for this space yet.\n",
        "properties": {
          "minimumSpend": {
            "$ref": "#/components/schemas/MinimumSpendPolicyResponse"
          },
          "occasionTypes": {
            "$ref": "#/components/schemas/OccasionTypesPolicyResponse"
          },
          "under18s": {
            "$ref": "#/components/schemas/Under18sPolicyResponse"
          },
          "promotedEvents": {
            "$ref": "#/components/schemas/PromotedEventsPolicyResponse"
          },
          "accessibility": {
            "$ref": "#/components/schemas/AccessibilityPolicyResponse"
          },
          "servesFood": {
            "$ref": "#/components/schemas/ServesFoodPolicyResponse"
          }
        }
      },
      "VenueSpaceResponse": {
        "type": "object",
        "description": "A space or area available within a product/venue (read-only).",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "spaceName": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "floorLocation": {
            "type": "integer",
            "format": "int32",
            "nullable": true,
            "description": "Floor number (-10 to +10; 0 = ground floor)."
          },
          "facilities": {
            "type": "array",
            "nullable": true,
            "description": "Facilities available in the space.",
            "items": {
              "$ref": "#/components/schemas/SpaceFacility"
            }
          },
          "capacityStanding": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacitySeated": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacityCabaret": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacityTheatre": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacityBoardroom": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacityClassroom": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacityUShape": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacityBanquet": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "capacityReception": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CapacityRange"
              }
            ],
            "nullable": true
          },
          "policies": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SpacePoliciesMap"
              }
            ],
            "nullable": true
          }
        }
      },
      "ClientError": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "A URI reference [rfc9457] that identifies the problem type. This specification encourages that, when dereferenced, it provides human-readable documentation for the problem type (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be \"about:blank\"."
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization."
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "description": "The HTTP status code [rfc9457, Section 3.1.12] generated by the origin server for this occurrence of the problem."
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem."
          },
          "code": {
            "type": "string",
            "description": "Error code in the format RESOURCE-X-NNN where X is R (retryable) or N (non-retryable). See ErrorCatalog.md for all error codes.",
            "example": "VALID-N-001"
          },
          "isRetryable": {
            "type": "boolean",
            "description": "Indicates whether the error is retryable. If true, the request may succeed if retried. If false, the request will fail again with the same input."
          },
          "traceId": {
            "type": "string",
            "description": "Request trace identifier for debugging and correlation purposes.",
            "example": "0HNJ2BG2TU3BU:00000001"
          },
          "errors": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Validation errors dictionary mapping field names to arrays of error messages. Only present for validation errors (VALID-N-001).",
            "example": {
              "Date": [
                "Availability date cannot be in the past."
              ],
              "EndTime": [
                "EndTime must be after StartTime."
              ]
            }
          }
        },
        "required": [
          "title",
          "status",
          "code",
          "isRetryable"
        ]
      }
    },
    "securitySchemes": {
      "Live": {
        "type": "oauth2",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://auth.bookabletech.com/oauth/token",
            "scopes": {
              "venue:read": "Grants read access to venue details",
              "venue-booking:read": "Grants read access to venue bookings",
              "venue-booking:create": "Grants permission to create venue bookings",
              "venue-booking:update": "Grants permission to update venue bookings",
              "venue-booking:update:status": "Grants permission to change the status of an in-progress booking (confirm/reject)",
              "venue-booking:delete": "Grants permission to delete venue bookings",
              "agent:write": "Grants write access to bookable agents"
            }
          }
        },
        "description": "This API uses OAuth2 client credentials flow via Auth0.\n**Important:** Include the `audience` parameter in your token request.\nExample token request:\n```\nPOST https://auth.bookabletech.com/oauth/token\n{\n  \"grant_type\": \"client_credentials\",\n  \"client_id\": \"YOUR_CLIENT_ID\",\n  \"client_secret\": \"YOUR_CLIENT_SECRET\",\n  \"audience\": \"api.bookabletech.com\"\n}\n```\n"
      },
      "Sandbox": {
        "type": "oauth2",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://auth-sandbox.bookabletech.com/oauth/token",
            "scopes": {
              "venue:read": "Grants read access to venue details",
              "venue-booking:read": "Grants read access to venue bookings",
              "venue-booking:create": "Grants permission to create venue bookings",
              "venue-booking:update": "Grants permission to update venue bookings",
              "venue-booking:update:status": "Grants permission to change the status of an in-progress booking (confirm/reject)",
              "venue-booking:delete": "Grants permission to delete venue bookings",
              "agent:write": "Grants write access to bookable agents"
            }
          }
        },
        "description": "This API uses OAuth2 client credentials flow via Auth0 for the Sandbox environment.\nThis environment is used for partner testing with production-like data and WireMock integrations.\n**Important:** Include the `audience` parameter in your token request.\nExample token request:\n```\nPOST https://auth-sandbox.bookabletech.com/oauth/token\n{\n  \"grant_type\": \"client_credentials\",\n  \"client_id\": \"YOUR_CLIENT_ID\",\n  \"client_secret\": \"YOUR_CLIENT_SECRET\",\n  \"audience\": \"api.bookabletech.com\"\n}\n```\n"
      }
    },
    "parameters": {
      "CorrelationID": {
        "in": "header",
        "name": "X-Correlation-ID",
        "required": false,
        "description": "An optional ID which you can use to track transactions across multiple systems. It can have any value, but we recommend avoiding `.` characters.\nMirrored back in a response header.\n",
        "schema": {
          "type": "string",
          "example": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA"
        }
      },
      "PartnerReference": {
        "in": "header",
        "name": "X-Partner-Reference",
        "required": false,
        "description": "Required for Bookable Agents. Specifies the partner reference for whom the booking is being made.\nThis header must contain a valid partner reference when making requests with the `agent:write` scope.\n",
        "schema": {
          "type": "string"
        }
      },
      "IntegrationSlug": {
        "in": "header",
        "name": "X-Booking-Source",
        "required": false,
        "description": "Identifies the source or channel through which the booking was created. Valid values include:\n- \"email\" - Booking created via email integration\n- \"phone\" - Booking created via phone integration\n- \"api\" - Booking created via API (default if not provided)\n- \"webhook\" - Booking created via webhook integration\n- \"js-tag\" - Booking created via JavaScript tag integration\n- \"chatbot\" - Booking created via chatbot integration\n- \"puller\" - Booking created via puller synchronization\n- \"portal\" - Booking created via portal integration\n\nIf not provided, defaults to \"api\" in the application logic.\n",
        "schema": {
          "type": "string",
          "enum": [
            "email",
            "phone",
            "api",
            "webhook",
            "js-tag",
            "chatbot",
            "puller",
            "portal"
          ],
          "example": "api"
        }
      },
      "SortDirection": {
        "in": "query",
        "name": "sortDirection",
        "required": false,
        "description": "The direction to sort results. Defaults to 'ASC'.\n- **ASC**: Ascending order (A-Z, 0-9, most similar to least similar for relevance)\n- **DESC**: Descending order (Z-A, 9-0, least similar to most similar for relevance)\n",
        "schema": {
          "type": "string",
          "enum": [
            "ASC",
            "DESC"
          ],
          "default": "ASC"
        },
        "example": "ASC"
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "Maximum number of requests allowed per window.",
        "schema": {
          "type": "integer"
        },
        "example": 200
      },
      "RateLimitRemaining": {
        "description": "Number of requests remaining in the current window.",
        "schema": {
          "type": "integer"
        },
        "example": 150
      },
      "RateLimitReset": {
        "description": "Unix timestamp (seconds since epoch) when the current rate-limit window resets.",
        "schema": {
          "type": "integer",
          "format": "int64"
        },
        "example": 1741651200
      }
    },
    "responses": {
      "ServerError": {
        "description": "Server error",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ServerError"
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ServerError"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Bad Request - The request was invalid or cannot be served",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": {
              "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
              "title": "Validation Failed",
              "status": 400,
              "detail": "One or more validation errors occurred.",
              "code": "VALID-N-001",
              "isRetryable": false,
              "traceId": "0HNJ2BG2TU3BU:00000001",
              "errors": {
                "Date": [
                  "Availability date cannot be in the past."
                ]
              }
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": "type: \"https://tools.ietf.org/html/rfc9110#section-15.5.1\"\ntitle: Validation Failed\nstatus: 400\ndetail: One or more validation errors occurred.\ncode: VALID-N-001\nisRetryable: false\ntraceId: \"0HNJ2BG2TU3BU:00000001\"\nerrors.Date[1]: \"Availability date cannot be in the past.\"\n"
          }
        }
      },
      "Unauthorized": {
        "description": "Unauthorized - Authentication is required",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": {
              "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
              "title": "Invalid User Credentials",
              "status": 401,
              "detail": "The provided credentials are invalid",
              "code": "USER-N-003",
              "isRetryable": false,
              "traceId": "0HNJ2BG2TU3BU:00000002"
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": "type: \"https://tools.ietf.org/html/rfc9110#section-15.5.5\"\ntitle: Invalid User Credentials\nstatus: 401\ndetail: The provided credentials are invalid\ncode: USER-N-003\nisRetryable: false\ntraceId: \"0HNJ2BG2TU3BU:00000002\"\n"
          }
        }
      },
      "Forbidden": {
        "description": "Forbidden - The request is understood but access is denied",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": {
              "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
              "title": "Venue Not Mapped to Partner",
              "status": 403,
              "detail": "The requested venue is not mapped to the current partner",
              "code": "PMAP-N-001",
              "isRetryable": false,
              "traceId": "0HNJ2BG2TU3BU:00000003"
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": "type: \"https://tools.ietf.org/html/rfc9110#section-15.5.4\"\ntitle: Venue Not Mapped to Partner\nstatus: 403\ndetail: The requested venue is not mapped to the current partner\ncode: PMAP-N-001\nisRetryable: false\ntraceId: \"0HNJ2BG2TU3BU:00000003\"\n"
          }
        }
      },
      "NotFound": {
        "description": "Not Found - The requested resource was not found",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": {
              "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
              "title": "Venue Not Found",
              "status": 404,
              "detail": "The requested venue could not be found",
              "code": "VENUE-N-001",
              "isRetryable": false,
              "traceId": "0HNJ2BG2TU3BU:00000004"
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": "type: \"https://tools.ietf.org/html/rfc9110#section-15.5.5\"\ntitle: Venue Not Found\nstatus: 404\ndetail: The requested venue could not be found\ncode: VENUE-N-001\nisRetryable: false\ntraceId: \"0HNJ2BG2TU3BU:00000004\"\n"
          }
        }
      },
      "TooManyRequests": {
        "description": "Too Many Requests - Rate limit exceeded. Retry after the window specified in the Retry-After header.",
        "headers": {
          "Retry-After": {
            "description": "Number of seconds to wait before retrying the request.",
            "schema": {
              "type": "integer"
            },
            "example": 60
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": {
              "type": "https://tools.ietf.org/html/rfc6585#section-4",
              "title": "Rate Limit Exceeded",
              "status": 429,
              "detail": "Too many requests have been made in a short period. Please wait and retry.",
              "code": "RATE-R-001",
              "isRetryable": true,
              "traceId": "0HNJ2BG2TU3BU:00000006"
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": "type: \"https://tools.ietf.org/html/rfc6585#section-4\"\ntitle: Rate Limit Exceeded\nstatus: 429\ndetail: Too many requests have been made in a short period. Please wait and retry.\ncode: RATE-R-001\nisRetryable: true\ntraceId: \"0HNJ2BG2TU3BU:00000006\"\n"
          }
        }
      },
      "InternalServerError": {
        "description": "Internal Server Error - An unexpected error occurred",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ServerError"
            },
            "example": {
              "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
              "title": "Internal Server Error",
              "status": 500,
              "detail": "An unexpected error occurred while processing the request",
              "code": "SYS-N-001",
              "isRetryable": false,
              "traceId": "0HNJ2BG2TU3BU:00000007"
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ServerError"
            },
            "example": "type: \"https://tools.ietf.org/html/rfc9110#section-15.6.1\"\ntitle: Internal Server Error\nstatus: 500\ndetail: An unexpected error occurred while processing the request\ncode: SYS-N-001\nisRetryable: false\ntraceId: \"0HNJ2BG2TU3BU:00000007\"\n"
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Service Unavailable - The server is temporarily unavailable",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ServerError"
            },
            "example": {
              "type": "https://api.bookabletech.com/problems/service-unavailable",
              "title": "Service Unavailable",
              "status": 503,
              "detail": "The server is temporarily unavailable. Please try again later",
              "code": "SYS-R-503",
              "isRetryable": true
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ServerError"
            },
            "example": "type: \"https://api.bookabletech.com/problems/service-unavailable\"\ntitle: Service Unavailable\nstatus: 503\ndetail: The server is temporarily unavailable. Please try again later\ncode: SYS-R-503\nisRetryable: true\n"
          }
        }
      },
      "Conflict": {
        "description": "Conflict - The request conflicts with the current state of the resource",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": {
              "type": "https://tools.ietf.org/html/rfc9110#section-15.5.10",
              "title": "Email Already In Use",
              "status": 409,
              "detail": "A user with this email address already exists",
              "code": "USER-N-001",
              "isRetryable": false,
              "traceId": "0HNJ2BG2TU3BU:00000005"
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": "type: \"https://tools.ietf.org/html/rfc9110#section-15.5.10\"\ntitle: Email Already In Use\nstatus: 409\ndetail: A user with this email address already exists\ncode: USER-N-001\nisRetryable: false\ntraceId: \"0HNJ2BG2TU3BU:00000005\"\n"
          }
        }
      },
      "UnprocessableEntity": {
        "description": "Unprocessable Entity - The request is well-formed but contains semantic errors",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": {
              "type": "https://api.bookabletech.com/problems/unprocessable-entity",
              "title": "Unprocessable Entity",
              "status": 422,
              "detail": "The request is well-formed but contains semantic errors",
              "code": "VALID-N-001",
              "isRetryable": false
            }
          },
          "text/toon": {
            "schema": {
              "$ref": "#/components/schemas/ClientError"
            },
            "example": "type: \"https://api.bookabletech.com/problems/unprocessable-entity\"\ntitle: Unprocessable Entity\nstatus: 422\ndetail: The request is well-formed but contains semantic errors\ncode: VALID-N-001\nisRetryable: false\n"
          }
        }
      }
    }
  }
}