{
  "openapi": "3.1.0",
  "info": {
    "title": "VacoTours Distribution API v2",
    "version": "2.2.0",
    "summary": "Every tour and activity we sell, on the v2 contract you may already speak.",
    "description": "A field for field compatible implementation of the v2 distribution contract many travel agencies and OTAs already integrate against. Change your base URL and your existing client keeps working: paths, payloads, the pagination envelope and the error format all match.\n\nIt sells everything we sell, our own operators' products and the channel inventory we resell, through the same endpoints. Starting from scratch? The [OCTO API](/developers/octo) is the same inventory with a two step booking and webhooks.\n\n## Authentication\n\n```http\nX-Authorization: vt_live_xxxxx.sk_xxxxx\n```\n\nA `vt_test_` key is a sandbox key on the same host: bookings made with it are real in every step here, including the wallet hold, except that they never reach the operator. This API is for trade buyers; an operator's key is refused, since it imports products through the [Supplier API](/developers/supplier-api) and exports none.\n\n## Languages\n\nThe catalogue is served in six languages: English (`en`), Persian (`fa`), Russian (`ru`), Arabic (`ar`), Hindi (`hi`) and Simplified Chinese (`zh-Hans`). Ask for one with the `Accept-Language` header or `?language=` (or `?locale=`); the response says which it used in `Content-Language`.\n\n```http\nAccept-Language: fa\n```\n\nOperators write in English and the other five are translated from it as a product is published or reworded, so a product's words can lag its English by a little while. A field not yet translated comes back in English rather than empty, and `translationLanguages` lists the languages a product has. Anything you are not sent a language for (a region tag such as `ru-RU` is fine) is answered in English.\n\n## Which products\n\nEvery product is `direct` (run by one of our own operators) or `channel` (resold from a partner platform), and says which in `source`. Each key is set in your panel to export all of them, only `channel` ones, or only `direct` ones, and a `direct` key can be narrowed further to one operator or several. A key never sees anything else: not in the catalogue, not by id, not to book. `GET /config` says what the key is set to in `user.productSource`, and the operators it is narrowed to in `user.suppliers` (null is every operator). `?source=direct` or `?source=channel` on the catalogue narrows it further.\n\n## Vocabulary\n\n| This API | Means |\n| --- | --- |\n| Product | What a traveller searches for |\n| Product type | A separately bookable variant with its own price, times and capacity |\n| Ticket type | A priced ticket: adult, child, senior, and on some products youth, infant, family, vehicle and others |\n| Price list | Availability, prices, times, terms and questions for one travel date |\n\n## Rates\n\nEach price list gives, per ticket type:\n\n| Price type | Meaning |\n| --- | --- |\n| `nettPrice` | What you pay. What your wallet is charged. |\n| `retailPrice` | What a traveller pays on our own site |\n| `recommendedPrice` | What we suggest you sell at (the same figure) |\n| `minimumSellingPrice` | The operator's parity floor, when they set one |\n\nA product type with `isFlatPaxPrice: true` is one price for the whole party: its rates carry `meta.perBooking: true` and the same figure on every ticket type. Charge it once, never per traveller.\n\n## Booking\n\n1. Read the product type for its `ticketTypes` (each with a `uuid`) and its `options`.\n2. Read the price list for the date. On a product sold by the hour, `timeslots` lists the times: send one as `timeSlotUuid`.\n3. `POST /bookings` reserves: seats and funds are held and the booking is `reserved` until `expiresAt`.\n4. `PUT /bookings/{uuid}/confirm` sells it and issues vouchers. `GET /bookings/{uuid}/vouchers` has a signed PDF link per voucher that your traveller can open without a login.\n5. `PUT /bookings/{uuid}/cancel` releases a reservation, or cancels a sale and refunds your wallet on the operator's terms.\n\nCount travellers with `adults`, `children` and `seniors`, as the contract does. A product type that sells other tickets takes `ticketTypes: [{ uuid, quantity }]` instead. `travellers` gives each traveller's own name, in ticket order.\n\n## Rentals and stays\n\nA product type with `rental` is booked from one date to another: a car or a scooter by the day, a villa by the night, a jet ski by the hour, travel cover by the day. `rental.basis` says how the length is counted and `minLength` and `maxLength` bound it. Price lists are per day, night or hour.\n\n`POST /product-types/{uuid}/rental-quote` prices and checks a whole period: every date in it has to be open and have room, the car or boat has to be free for all of it, and longer bookings get their cheaper rate. Send the same `rental` with `POST /bookings`:\n\n```json\n{ \"productTypeUuid\": \"...\", \"arrivalDate\": \"2026-10-03\",\n  \"ticketTypes\": [{ \"uuid\": \"...\", \"quantity\": 1 }],\n  \"rental\": { \"returnDate\": \"2026-10-07\", \"pickupTime\": \"10:00\", \"returnTime\": \"10:00\" } }\n```\n\nWithout `rental`, a booking is for the shortest length allowed. `returnLocation` is accepted only where `rental.oneWay` is true.\n\n## Priced on request\n\nA product with `quoteOnly: true` (a tailor-made itinerary, an incentive) has no price list: `POST /quote-requests` asks the operator for a price for your group, `GET /quote-requests/{uuid}` has the answer (`status: quoted`, `price.total`, `validUntil`), and `POST /quote-requests/{uuid}/accept` books it as an ordinary reservation, confirmed with `PUT /bookings/{uuid}/confirm`. These return the request itself, not wrapped in `data`.\n\n## Booking options\n\nThe operator's questions, as `options.perBooking` and `options.perPax`. Answer in the same shape:\n\n```json\n{ \"perBooking\": [{ \"uuid\": \"...\", \"value\": \"Vegetarian\" }],\n  \"perPax\": [[{ \"uuid\": \"...\", \"value\": \"X1234567\" }], [{ \"uuid\": \"...\", \"value\": \"Y7654321\" }]] }\n```\n\none `perPax` array per traveller. Required answers are checked for every traveller, choices must be one of the `items`, and `formatRegex` must match; a booking that breaks one is refused with a message you can show. `inputType` follows the contract: 1 select, 2 multiple select, 3 number, 4 text, 5 checkbox, 6 date (YYYY-MM-DD), 7 file, 9 textarea, 10 time, 11 date and time, 12 country, 13 phone.\n\n## Currency and limits\n\nSend `X-Currency` for every amount in that currency. A booking read back in its own currency shows the rate it was made at. Each key is limited to 120 requests a minute by default; a 429 says how long to wait in `Retry-After`.",
    "contact": {
      "name": "VacoTours partner support",
      "email": "hello@vacotours.com",
      "url": "https://vacotours.com/for-partners"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.vacotours.com/v2",
      "description": "Production and sandbox (use a vt_test_ key for sandbox)"
    }
  ],
  "security": [
    {
      "apiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Configuration",
      "description": "Reference data for building filters."
    },
    {
      "name": "Products",
      "description": "Catalogue search and detail."
    },
    {
      "name": "Product types",
      "description": "Bookable variants, prices, times and availability."
    },
    {
      "name": "Bookings",
      "description": "Create, confirm, cancel, retrieve, vouchers."
    },
    {
      "name": "Quotes",
      "description": "Products priced on request: ask, read the answer, book it."
    }
  ],
  "paths": {
    "/config": {
      "get": {
        "tags": [
          "Configuration"
        ],
        "summary": "Reference data",
        "description": "Currencies, languages, activity types, our product types, categories, countries and cities, and the booking option input types. `user` describes your key, including which products it exports (`productSource`) and the operators a direct key is narrowed to (`suppliers`).",
        "operationId": "config",
        "responses": {
          "200": {
            "description": "Configuration.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object"
                    }
                  }
                },
                "example": {
                  "data": {
                    "now": "2026-09-28T20:29:05+00:00",
                    "version": 2,
                    "serverUrl": "https://api.vacotours.com/v2",
                    "photosUrl": "http://localhost:3000",
                    "activitiesSorting": [
                      "popularity",
                      "price",
                      "date",
                      "title",
                      "rating"
                    ],
                    "user": {
                      "uuid": "ec3cfb7b-1bbc-4bfb-b91c-cced32426bcb",
                      "name": "Northbound Travel",
                      "type": "reseller",
                      "environment": "sandbox",
                      "currency": "USD",
                      "language": "en",
                      "productSource": "all",
                      "suppliers": null
                    },
                    "languages": [
                      {
                        "uuid": "4201fb76-e581-469c-80da-9e49325259d8",
                        "code": "ar",
                        "name": "Arabic"
                      },
                      {
                        "uuid": "12af17f5-20f9-4f16-bf84-602a808165d9",
                        "code": "zh",
                        "name": "Chinese"
                      },
                      {
                        "uuid": "09bfe258-ca0d-4e71-9da4-480fe3aff784",
                        "code": "en",
                        "name": "English"
                      }
                    ],
                    "currencies": [
                      {
                        "uuid": "AED",
                        "code": "AED",
                        "name": "UAE Dirham",
                        "symbol": "AED ",
                        "precision": 2
                      },
                      {
                        "uuid": "AUD",
                        "code": "AUD",
                        "name": "Australian Dollar",
                        "symbol": "A$",
                        "precision": 2
                      },
                      {
                        "uuid": "BRL",
                        "code": "BRL",
                        "name": "Brazilian Real",
                        "symbol": "R$",
                        "precision": 2
                      }
                    ],
                    "types": [
                      {
                        "uuid": "122f0220-760e-41a8-9504-4d6898e12ceb",
                        "name": "Activity"
                      },
                      {
                        "uuid": "987b668d-9211-4d09-82cb-3866e9eb8a72",
                        "name": "Attraction"
                      },
                      {
                        "uuid": "c22ef5bb-329a-4a73-bce9-bdfa1abff23a",
                        "name": "Tour"
                      }
                    ],
                    "productTypes": [
                      {
                        "uuid": "e3b0a58c-b7cb-4c96-a63f-6502d5df78a9",
                        "code": "activity",
                        "name": "Activity",
                        "family": "activity"
                      },
                      {
                        "uuid": "ed32217c-f1ec-4613-8c21-98967dcde0fe",
                        "code": "attraction",
                        "name": "Attraction",
                        "family": "attraction"
                      },
                      {
                        "uuid": "b12e9e0d-2abb-4ae9-8da8-9e41c224b550",
                        "code": "attraction_ticket",
                        "name": "Attraction ticket",
                        "family": "ticket"
                      }
                    ],
                    "categories": [
                      {
                        "uuid": "13658693-27a9-4637-bf8d-5900d7672cec",
                        "Name": "Tours & Sightseeing",
                        "children": [
                          {
                            "uuid": "e1930346-6ce3-4f18-be6d-edd3c9526432",
                            "Name": "Walking Tours"
                          },
                          {
                            "uuid": "799f9d25-d6d0-40e5-9c11-b27db42ad411",
                            "Name": "Day Trips"
                          },
                          {
                            "uuid": "c56750c7-aa62-4585-b929-bf2f45ec8582",
                            "Name": "Private Tours"
                          },
                          {
                            "uuid": "bf981196-9579-43db-810a-45c7a6290c76",
                            "Name": "City Sightseeing"
                          },
                          {
                            "uuid": "1e74a8c5-f006-4788-9306-673e5d5d7412",
                            "Name": "Hop-on Hop-off"
                          }
                        ]
                      },
                      {
                        "uuid": "05d4ce28-e2e3-42e1-a3ab-c42eead7c3ca",
                        "Name": "Shopping",
                        "children": []
                      },
                      {
                        "uuid": "0b2ccd39-0500-4a1f-878f-db2567900a53",
                        "Name": "Transport",
                        "children": [
                          {
                            "uuid": "0c8681cd-2b76-4b75-a433-1e32593d6a61",
                            "Name": "Water"
                          },
                          {
                            "uuid": "1de71461-9bb7-477a-aa76-c9d54592d235",
                            "Name": "Bus"
                          },
                          {
                            "uuid": "1d7fcc25-ea5c-46a4-aa0b-05c376dedd6b",
                            "Name": "Train"
                          },
                          {
                            "uuid": "8bfa3138-01c4-4e9a-860a-31bd29838a79",
                            "Name": "Airport Transfers"
                          },
                          {
                            "uuid": "65233dc7-f073-4fa0-a099-ffffa36a8a11",
                            "Name": "Hotel Transfers"
                          },
                          {
                            "uuid": "5e9b0377-6e64-4f45-957b-17bdb20b37af",
                            "Name": "Car"
                          },
                          {
                            "uuid": "ad93bb41-a9da-4d10-8155-22c5655c8e7c",
                            "Name": "Transfers"
                          },
                          {
                            "uuid": "42185cb8-a4fe-4fea-8959-9b4c50c093cd",
                            "Name": "Public Transport"
                          }
                        ]
                      }
                    ],
                    "locations": [
                      {
                        "uuid": "e2c07941-ffe4-4a59-b0e2-d13e748a23e8",
                        "name": "Armenia",
                        "iso2": "AM",
                        "cities": [
                          {
                            "uuid": "038dccdd-6ffe-406c-b025-3b1fae5a3cb2",
                            "name": "Abovyan",
                            "slug": "abovyan",
                            "latitude": "40.2740000",
                            "longitude": "44.6330000"
                          },
                          {
                            "uuid": "9d6a2752-23ce-49df-9120-2ee54adafec7",
                            "name": "Alaverdi",
                            "slug": "alaverdi",
                            "latitude": "41.0970000",
                            "longitude": "44.6720000"
                          }
                        ]
                      },
                      {
                        "uuid": "7b0ece24-42af-4fb9-b408-c092facd0186",
                        "name": "Australia",
                        "iso2": "AU",
                        "cities": [
                          {
                            "uuid": "5d674cbf-7b04-47c8-9231-5694a24ee793",
                            "name": "Adelaide",
                            "slug": "adelaide"
                          },
                          {
                            "uuid": "999a4b1b-966a-4e5e-9fe3-fc4bfcbd7a2f",
                            "name": "Airlie Beach",
                            "slug": "airlie-beach"
                          }
                        ]
                      }
                    ],
                    "optionInputTypes": [
                      {
                        "rel": "select",
                        "uri": "1"
                      },
                      {
                        "rel": "multiple select",
                        "uri": "2"
                      },
                      {
                        "rel": "number",
                        "uri": "3"
                      },
                      {
                        "rel": "text",
                        "uri": "4"
                      },
                      {
                        "rel": "checkbox",
                        "uri": "5"
                      },
                      {
                        "rel": "date",
                        "uri": "6"
                      },
                      {
                        "rel": "file",
                        "uri": "7"
                      },
                      {
                        "rel": "image",
                        "uri": "8"
                      },
                      {
                        "rel": "textarea",
                        "uri": "9"
                      },
                      {
                        "rel": "time",
                        "uri": "10"
                      },
                      {
                        "rel": "date and time",
                        "uri": "11"
                      },
                      {
                        "rel": "string: country",
                        "uri": "12"
                      },
                      {
                        "rel": "phone number",
                        "uri": "13"
                      },
                      {
                        "rel": "flight number",
                        "uri": "14"
                      }
                    ],
                    "links": [
                      {
                        "rel": "products",
                        "uri": "https://api.vacotours.com/v2/products"
                      },
                      {
                        "rel": "bookings",
                        "uri": "https://api.vacotours.com/v2/bookings"
                      }
                    ],
                    "productSources": [
                      "all",
                      "direct",
                      "channel"
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/products": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "List products",
        "description": "The catalogue, paginated as the contract paginates it.",
        "operationId": "listProducts",
        "responses": {
          "200": {
            "description": "Products.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProductSummary"
                      }
                    },
                    "meta": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "An activity type uuid, or one of our product types by uuid or code."
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category uuid, including its children."
          },
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "City uuid."
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Country uuid."
          },
          {
            "name": "query",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Words in the title."
          },
          {
            "name": "updated_since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO date: only products changed since."
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "all, direct (our own operators' products) or channel (resold). Narrows what the key is set to."
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma separated: popularity, price, date, title, rating, updated; prefix with - to reverse."
          },
          {
            "name": "fields",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Sparse fieldset, comma separated."
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": ""
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Up to 100."
          }
        ]
      }
    },
    "/products/{uuid}": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get a product",
        "description": "Descriptions, photos, location, categories and more.",
        "operationId": "getProduct",
        "responses": {
          "200": {
            "description": "The product.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "description": "Everything a product page needs. See the example. `quoteOnly: true` means priced on request: see Priced on request."
                    }
                  }
                },
                "example": {
                  "data": {
                    "uuid": "fb02f58d-4ac4-4b1d-9d14-97c659b10fc2",
                    "updatedAt": "2026-09-28T20:28:34+00:00",
                    "title": "Burj Khalifa L124/125",
                    "titleTranslated": "Burj Khalifa: Level 124 and 125 Timed Entry",
                    "slug": "burj-khalifa-level-124-and-125-timed-entry",
                    "shortDescription": "Skip the ticket desk with a timed slot for the observation decks on levels 124 and 125.",
                    "shortDescriptionTranslated": "Skip the ticket desk with a timed slot for the observation decks on levels 124 and 125.",
                    "description": "The view from level 124 is the one everybody knows, and it earns the reputation. On a clear afternoon you can follow the coast past the Palm and out toward Jebel Ali, and at dusk the whole grid of the city lights up underneath you in about fifteen minutes.\n\nA timed slot means you walk past the ticket desk and into the lift queue. The lift itself takes about a minute. There is no time limit once you are up there, so most people stay somewhere between forty minutes and an hour and a half.\n\nSunset slots sell out first, usually a week or more ahead in the cooler months.",
                    "descriptionTranslated": "The view from level 124 is the one everybody knows, and it earns the reputation. On a clear afternoon you can follow the coast past the Palm and out toward Jebel Ali, and at dusk the whole grid of the city lights up underneath you in about fifteen minutes.\n\nA timed slot means you walk past the ticket desk and into the lift queue. The lift itself takes about a minute. There is no time limit once you are up there, so most people stay somewhere between forty minutes and an hour and a half.\n\nSunset slots sell out first, usually a week or more ahead in the cooler months.",
                    "highlights": "Timed entry, so no ticket desk queue\nLevels 124 and 125, indoor and outdoor viewing\nNo time limit once you are on the deck\nSunset slots available, book early",
                    "highlightsTranslated": "Timed entry, so no ticket desk queue\nLevels 124 and 125, indoor and outdoor viewing\nNo time limit once you are on the deck\nSunset slots available, book early",
                    "priceIncludes": "Timed admission to levels 124 and 125\nAccess to the outdoor terrace",
                    "priceIncludesTranslated": "Timed admission to levels 124 and 125\nAccess to the outdoor terrace",
                    "priceExcludes": "Transport to Dubai Mall\nLevel 148 upgrade\nFood and drink",
                    "priceExcludesTranslated": "Transport to Dubai Mall\nLevel 148 upgrade\nFood and drink",
                    "knowBeforeYouGo": "Arrive fifteen minutes before your slot. Entry is through the lower ground floor of Dubai Mall, follow signs for At The Top. Large bags are not permitted on the deck.",
                    "knowBeforeYouGoTranslated": "Arrive fifteen minutes before your slot. Entry is through the lower ground floor of Dubai Mall, follow signs for At The Top. Large bags are not permitted on the deck.",
                    "additionalInfo": null,
                    "additionalInfoTranslated": null,
                    "itinerary": null,
                    "itineraryTranslated": null,
                    "safety": null,
                    "safetyTranslated": null,
                    "warnings": null,
                    "warningsTranslated": null,
                    "faq": [
                      {
                        "question": "What happens if I miss my slot?",
                        "answer": "Arrive within thirty minutes of your slot and you will usually still be admitted, though you may wait. Beyond that the ticket is not guaranteed."
                      },
                      {
                        "question": "Is level 148 included?",
                        "answer": "No, level 148 is a separate premium product with its own lounge and a much smaller capacity."
                      }
                    ],
                    "address": null,
                    "latitude": "25.2048000",
                    "longitude": "55.2708000",
                    "googlePlaceId": null,
                    "locations": [
                      {
                        "city": "Dubai",
                        "cityUuid": "428986d7-59c6-4dbc-b725-be7485cd4670",
                        "state": null,
                        "stateUuid": null,
                        "country": "United Arab Emirates",
                        "countryUuid": "93e7c9e5-dca8-4e4d-b5f5-e0b0d521f64e",
                        "countryCode": "AE",
                        "latitude": "25.2048000",
                        "longitude": "55.2708000"
                      }
                    ],
                    "basePrice": 51.92,
                    "currency": {
                      "code": "USD",
                      "precision": 2
                    },
                    "minPax": 1,
                    "maxPax": null,
                    "validFrom": null,
                    "validThrough": null,
                    "businessHoursFrom": null,
                    "businessHoursTo": null,
                    "timezone": "Asia/Dubai",
                    "tourType": null,
                    "typeName": "Timed-entry ticket",
                    "productType": {
                      "code": "timed_entry_ticket",
                      "name": "Timed-entry ticket",
                      "family": "ticket"
                    },
                    "hotelPickup": false,
                    "airportPickup": false,
                    "isFlatPaxPrice": false,
                    "pricingPer": "UNIT",
                    "instantConfirmation": true,
                    "hasOptions": false,
                    "allProductTypesHaveOptions": false,
                    "averageDelivery": 0,
                    "reviewAverageScore": 4.7,
                    "reviewCount": 1864,
                    "categories": [
                      {
                        "uuid": "ba9628b3-4840-4569-892d-e9912ddc6609",
                        "name": "Attractions & Tickets",
                        "slug": "attractions-tickets"
                      },
                      {
                        "uuid": "064c8484-1524-4cca-a32a-0ee095972b9e",
                        "name": "Observation Decks",
                        "slug": "observation-decks"
                      }
                    ],
                    "supplier": {
                      "uuid": "9dfdd4c3-426d-49fd-b575-476cbcb08529",
                      "name": "Dunelight Experiences"
                    },
                    "photosUrl": "http://localhost:3000",
                    "photos": [
                      {
                        "uuid": "6cdd3381-790e-4ce3-93f9-030b413a9f52",
                        "caption": null,
                        "alt": "View over Dubai at dusk from the Burj Khalifa observation deck",
                        "url": "http://localhost:3000/media/products/burj-khalifa-hero.jpg",
                        "width": null,
                        "height": null,
                        "paths": {
                          "original": "http://localhost:3000/media/products/burj-khalifa-hero.jpg"
                        }
                      }
                    ],
                    "coverImage": "http://localhost:3000/media/products/burj-khalifa-hero.jpg",
                    "translationLanguages": [
                      {
                        "code": "en"
                      }
                    ],
                    "links": [
                      {
                        "rel": "self",
                        "uri": "https://api.vacotours.com/v2/products/fb02f58d-4ac4-4b1d-9d14-97c659b10fc2"
                      },
                      {
                        "rel": "product-types",
                        "uri": "https://api.vacotours.com/v2/products/fb02f58d-4ac4-4b1d-9d14-97c659b10fc2/product-types"
                      }
                    ],
                    "source": "direct"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/products/{uuid}/product-types": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Product types of a product",
        "description": "The bookable variants.",
        "operationId": "productTypes",
        "responses": {
          "200": {
            "description": "Product types.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/products/{uuid}/restrictions": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Restrictions",
        "description": "Countries a product may not be sold to.",
        "operationId": "restrictions",
        "responses": {
          "200": {
            "description": "Restrictions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/product-types/{uuid}": {
      "get": {
        "tags": [
          "Product types"
        ],
        "summary": "Get a product type",
        "description": "Ticket types, durations, meeting point, pickup, terms, itinerary and booking options.",
        "operationId": "getProductType",
        "responses": {
          "200": {
            "description": "The product type.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ProductType"
                    }
                  }
                },
                "example": {
                  "data": {
                    "uuid": "d7bbe7df-6d64-45a8-b8f9-69dace2d4f9c",
                    "productUuid": "c86ea1c1-a986-4d1f-bd23-6bec906beffa",
                    "title": "Sunrise departure (07:00)",
                    "titleTranslated": "Sunrise departure (07:00)",
                    "description": "The quiet one. Meets at the Hippodrome obelisk.",
                    "descriptionTranslated": "The quiet one. Meets at the Hippodrome obelisk.",
                    "durationDays": 0,
                    "durationHours": 3,
                    "durationMinutes": 0,
                    "daysInAdvance": null,
                    "cutOffTime": null,
                    "cutOffHours": 24,
                    "firstAvailabilityDate": "2026-09-30",
                    "isNonRefundable": false,
                    "instantConfirmation": true,
                    "nonInstantVoucher": false,
                    "directAdmission": true,
                    "voucherRequiresPrinting": false,
                    "isBmgVoucher": true,
                    "voucherUse": null,
                    "voucherUseTranslated": null,
                    "voucherRedemptionAddress": null,
                    "voucherRedemptionAddressTranslated": null,
                    "meetingTime": "06:45",
                    "meetingAddress": "Obelisk of Theodosius, Sultanahmet Square",
                    "meetingLocation": null,
                    "meetingLocationTranslated": null,
                    "meetingLatitude": 41.0082,
                    "meetingLongitude": 28.9784,
                    "meetingGooglePlaceId": null,
                    "timezone": "Europe/Istanbul",
                    "isFlatPaxPrice": false,
                    "pricingPer": "UNIT",
                    "allowAdults": true,
                    "allowChildren": true,
                    "allowSeniors": true,
                    "allowInfant": false,
                    "hasChildPrice": true,
                    "minPax": null,
                    "maxPax": 12,
                    "minGroup": null,
                    "maxGroup": null,
                    "ticketTypes": [
                      {
                        "uuid": "0d04e5e0-67cb-4f6c-aa87-d5d3be2744cb",
                        "type": "adult",
                        "label": "Adult",
                        "allowed": true,
                        "required": false,
                        "min": 0,
                        "max": 20,
                        "minAge": 18,
                        "maxAge": 64,
                        "paxCount": 1,
                        "idRequired": false,
                        "recommendedMarkup": 13.7337,
                        "nettPriceFrom": 33.64,
                        "recommendedPriceFrom": 38.26,
                        "parityPrice": null,
                        "gateRatePrice": 48
                      },
                      {
                        "uuid": "cd1ae236-fe8a-4735-9d82-ba15a1266cfe",
                        "type": "child",
                        "label": "Child",
                        "allowed": true,
                        "required": false,
                        "min": 0,
                        "max": 20,
                        "minAge": 3,
                        "maxAge": 12,
                        "paxCount": 1,
                        "idRequired": false,
                        "recommendedMarkup": 9.7941,
                        "nettPriceFrom": 19.91,
                        "recommendedPriceFrom": 21.86,
                        "parityPrice": null,
                        "gateRatePrice": null
                      },
                      {
                        "uuid": "dc694a09-2fd9-42bd-be08-576f943ced39",
                        "type": "senior",
                        "label": "Senior",
                        "allowed": true,
                        "required": false,
                        "min": 0,
                        "max": 20,
                        "minAge": 65,
                        "maxAge": 120,
                        "paxCount": 1,
                        "idRequired": false,
                        "recommendedMarkup": 12.7967,
                        "nettPriceFrom": 29.07,
                        "recommendedPriceFrom": 32.79,
                        "parityPrice": null,
                        "gateRatePrice": null
                      },
                      {
                        "uuid": "8a6665ad-8df0-4c5c-8d8d-39381ee15944",
                        "type": "student",
                        "label": "Student",
                        "allowed": true,
                        "required": false,
                        "min": 0,
                        "max": 20,
                        "minAge": 13,
                        "maxAge": 17,
                        "paxCount": 1,
                        "idRequired": false,
                        "recommendedMarkup": 12.2479,
                        "nettPriceFrom": 26.78,
                        "recommendedPriceFrom": 30.06,
                        "parityPrice": null,
                        "gateRatePrice": null
                      }
                    ],
                    "cancellationPolicies": [
                      {
                        "numberOfDays": 7,
                        "numberOfHours": 168,
                        "refundPercentage": 100,
                        "cancellationFeePercentage": 0,
                        "serviceFee": 0,
                        "serviceFeePerBooking": true,
                        "serviceFeeCurrency": "USD"
                      },
                      {
                        "numberOfDays": 2,
                        "numberOfHours": 48,
                        "refundPercentage": 50,
                        "cancellationFeePercentage": 0,
                        "serviceFee": 0,
                        "serviceFeePerBooking": true,
                        "serviceFeeCurrency": "USD"
                      },
                      {
                        "numberOfDays": 1,
                        "numberOfHours": 24,
                        "refundPercentage": 0,
                        "cancellationFeePercentage": 0,
                        "serviceFee": 0,
                        "serviceFeePerBooking": true,
                        "serviceFeeCurrency": "USD"
                      }
                    ],
                    "cancellationPolicySummary": null,
                    "validity": {
                      "type": "only_visit_date",
                      "days": null,
                      "date": null,
                      "hasBatchValidityDate": false
                    },
                    "timeslots": [
                      "07:00"
                    ],
                    "pickup": {
                      "available": false,
                      "required": false,
                      "points": []
                    },
                    "itinerary": [
                      {
                        "day": 1,
                        "name": "Hippodrome and the Obelisk",
                        "type": "stop",
                        "description": "Where the chariots ran, and why three monuments from three civilisations stand in a row.",
                        "durationMinutes": 30
                      },
                      {
                        "day": 1,
                        "name": "Blue Mosque courtyard",
                        "type": "stop",
                        "durationMinutes": 40
                      },
                      {
                        "day": 1,
                        "name": "Hagia Sophia exterior",
                        "type": "stop",
                        "durationMinutes": 45
                      },
                      {
                        "day": 1,
                        "name": "Soğukçeşme Street",
                        "type": "stop",
                        "durationMinutes": 25
                      },
                      {
                        "day": 1,
                        "name": "Tea garden, Gülhane",
                        "type": "stop",
                        "durationMinutes": 40
                      }
                    ],
                    "options": {
                      "perBooking": [],
                      "perPax": []
                    },
                    "hasOptions": false,
                    "hasPriceOptions": false,
                    "hasRequiredPriceOptions": false,
                    "hasFileUploadOptions": false,
                    "links": [
                      {
                        "rel": "self",
                        "uri": "https://api.vacotours.com/v2/product-types/d7bbe7df-6d64-45a8-b8f9-69dace2d4f9c"
                      },
                      {
                        "rel": "price-lists",
                        "uri": "https://api.vacotours.com/v2/product-types/d7bbe7df-6d64-45a8-b8f9-69dace2d4f9c/price-lists"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/product-types/{uuid}/price-lists": {
      "get": {
        "tags": [
          "Product types"
        ],
        "summary": "Price lists",
        "description": "The operating days in a range of up to six months, each with its prices, seats and times. Questions are per date, on the single date endpoint.",
        "operationId": "priceLists",
        "responses": {
          "200": {
            "description": "Days.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PriceList"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date_start",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "date_end",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ]
      }
    },
    "/product-types/{uuid}/price-lists/{date}": {
      "get": {
        "tags": [
          "Product types"
        ],
        "summary": "Price list for a date",
        "description": "Everything about one travel date, including the booking options that apply to it.",
        "operationId": "priceListDate",
        "responses": {
          "200": {
            "description": "The day.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PriceList"
                    }
                  }
                },
                "example": {
                  "data": {
                    "date": "2026-10-03",
                    "weekday": "Saturday",
                    "available": true,
                    "status": "AVAILABLE",
                    "currency": "USD",
                    "timezone": "Europe/Istanbul",
                    "availability": null,
                    "prices": [
                      {
                        "id": "593651fd-fb2d-4132-91cf-1764ceb6c885",
                        "rates": [
                          {
                            "type": "nettPrice",
                            "category": "adult",
                            "ticketTypeUuid": "0d04e5e0-67cb-4f6c-aa87-d5d3be2744cb",
                            "currency": "USD",
                            "amount": 33.64,
                            "format": "$33.64",
                            "meta": {}
                          },
                          {
                            "type": "retailPrice",
                            "category": "adult",
                            "ticketTypeUuid": "0d04e5e0-67cb-4f6c-aa87-d5d3be2744cb",
                            "currency": "USD",
                            "amount": 38.26,
                            "format": "$38.26",
                            "meta": {}
                          },
                          {
                            "type": "recommendedPrice",
                            "category": "adult",
                            "ticketTypeUuid": "0d04e5e0-67cb-4f6c-aa87-d5d3be2744cb",
                            "currency": "USD",
                            "amount": 38.26,
                            "format": "$38.26",
                            "meta": {}
                          },
                          {
                            "type": "nettPrice",
                            "category": "child",
                            "ticketTypeUuid": "cd1ae236-fe8a-4735-9d82-ba15a1266cfe",
                            "currency": "USD",
                            "amount": 19.91,
                            "format": "$19.91",
                            "meta": {}
                          },
                          {
                            "type": "retailPrice",
                            "category": "child",
                            "ticketTypeUuid": "cd1ae236-fe8a-4735-9d82-ba15a1266cfe",
                            "currency": "USD",
                            "amount": 21.86,
                            "format": "$21.86",
                            "meta": {}
                          },
                          {
                            "type": "recommendedPrice",
                            "category": "child",
                            "ticketTypeUuid": "cd1ae236-fe8a-4735-9d82-ba15a1266cfe",
                            "currency": "USD",
                            "amount": 21.86,
                            "format": "$21.86",
                            "meta": {}
                          },
                          {
                            "type": "nettPrice",
                            "category": "senior",
                            "ticketTypeUuid": "dc694a09-2fd9-42bd-be08-576f943ced39",
                            "currency": "USD",
                            "amount": 29.07,
                            "format": "$29.07",
                            "meta": {}
                          },
                          {
                            "type": "retailPrice",
                            "category": "senior",
                            "ticketTypeUuid": "dc694a09-2fd9-42bd-be08-576f943ced39",
                            "currency": "USD",
                            "amount": 32.79,
                            "format": "$32.79",
                            "meta": {}
                          },
                          {
                            "type": "recommendedPrice",
                            "category": "senior",
                            "ticketTypeUuid": "dc694a09-2fd9-42bd-be08-576f943ced39",
                            "currency": "USD",
                            "amount": 32.79,
                            "format": "$32.79",
                            "meta": {}
                          },
                          {
                            "type": "nettPrice",
                            "category": "student",
                            "ticketTypeUuid": "8a6665ad-8df0-4c5c-8d8d-39381ee15944",
                            "currency": "USD",
                            "amount": 26.78,
                            "format": "$26.78",
                            "meta": {}
                          },
                          {
                            "type": "retailPrice",
                            "category": "student",
                            "ticketTypeUuid": "8a6665ad-8df0-4c5c-8d8d-39381ee15944",
                            "currency": "USD",
                            "amount": 30.06,
                            "format": "$30.06",
                            "meta": {}
                          },
                          {
                            "type": "recommendedPrice",
                            "category": "student",
                            "ticketTypeUuid": "8a6665ad-8df0-4c5c-8d8d-39381ee15944",
                            "currency": "USD",
                            "amount": 30.06,
                            "format": "$30.06",
                            "meta": {}
                          }
                        ]
                      }
                    ],
                    "timeslots": [
                      {
                        "uuid": "593651fd-fb2d-4132-91cf-1764ceb6c885",
                        "startTime": "07:00",
                        "endTime": "10:00",
                        "available": true,
                        "priceId": "593651fd-fb2d-4132-91cf-1764ceb6c885",
                        "availability": [
                          {
                            "category": "adult",
                            "uuid": "0d04e5e0-67cb-4f6c-aa87-d5d3be2744cb",
                            "quantity": 12,
                            "unlimited": false,
                            "type": "shared"
                          },
                          {
                            "category": "child",
                            "uuid": "cd1ae236-fe8a-4735-9d82-ba15a1266cfe",
                            "quantity": 12,
                            "unlimited": false,
                            "type": "shared"
                          },
                          {
                            "category": "senior",
                            "uuid": "dc694a09-2fd9-42bd-be08-576f943ced39",
                            "quantity": 12,
                            "unlimited": false,
                            "type": "shared"
                          },
                          {
                            "category": "student",
                            "uuid": "8a6665ad-8df0-4c5c-8d8d-39381ee15944",
                            "quantity": 12,
                            "unlimited": false,
                            "type": "shared"
                          }
                        ]
                      }
                    ],
                    "cancellationPolicy": [
                      {
                        "numberOfDays": 7,
                        "numberOfHours": 168,
                        "refundPercentage": 100,
                        "cancellationFeePercentage": 0,
                        "serviceFee": 0,
                        "serviceFeePerBooking": true,
                        "serviceFeeCurrency": "USD"
                      },
                      {
                        "numberOfDays": 2,
                        "numberOfHours": 48,
                        "refundPercentage": 50,
                        "cancellationFeePercentage": 0,
                        "serviceFee": 0,
                        "serviceFeePerBooking": true,
                        "serviceFeeCurrency": "USD"
                      },
                      {
                        "numberOfDays": 1,
                        "numberOfHours": 24,
                        "refundPercentage": 0,
                        "cancellationFeePercentage": 0,
                        "serviceFee": 0,
                        "serviceFeePerBooking": true,
                        "serviceFeeCurrency": "USD"
                      }
                    ],
                    "voucherValidity": {
                      "adults": {
                        "date": "2026-10-03"
                      },
                      "children": {
                        "date": "2026-10-03"
                      },
                      "seniors": {
                        "date": "2026-10-03"
                      },
                      "youth": {
                        "date": "2026-10-03"
                      },
                      "infant": {
                        "date": "2026-10-03"
                      }
                    },
                    "options": {
                      "perBooking": [],
                      "perPax": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ]
      }
    },
    "/product-types/{uuid}/rental-quote": {
      "post": {
        "tags": [
          "Product types"
        ],
        "summary": "Price a rental or a stay",
        "description": "For a product type with `rental`: whether the whole period can be had for this party, and what it costs, from the pickup date to the return.",
        "operationId": "rentalQuote",
        "responses": {
          "200": {
            "description": "The quote.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/RentalQuote"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Nothing on sale on the pickup date.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "arrivalDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "timeSlotUuid": {
                    "type": "string"
                  },
                  "ticketTypes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "uuid": {
                          "type": "string"
                        },
                        "quantity": {
                          "type": "integer"
                        }
                      }
                    }
                  },
                  "rental": {
                    "$ref": "#/components/schemas/RentalRequest"
                  }
                },
                "required": [
                  "arrivalDate"
                ]
              },
              "example": {
                "arrivalDate": "2026-10-03",
                "rental": {
                  "returnDate": "2026-10-10"
                }
              }
            }
          }
        }
      }
    },
    "/quote-requests": {
      "post": {
        "tags": [
          "Quotes"
        ],
        "summary": "Ask for a price",
        "description": "For a product with `quoteOnly: true`. The operator answers with a price for the whole group; you are emailed and the request moves to `quoted`.",
        "operationId": "createQuoteRequest",
        "responses": {
          "201": {
            "description": "Asked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteRequest"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequestBody"
              },
              "example": {
                "productId": "0b8f...",
                "groupSize": 12,
                "travelDate": "2026-11-03",
                "endDate": "2026-11-07",
                "budget": 15000,
                "message": "Incentive group, four nights, one gala dinner.",
                "contact": {
                  "firstName": "Nia",
                  "lastName": "Ko",
                  "emailAddress": "nia@example.com"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Quotes"
        ],
        "summary": "List your requests",
        "description": "Newest first. Filter with `?status=quoted` to find answers waiting for you.",
        "operationId": "listQuoteRequests",
        "responses": {
          "200": {
            "description": "Requests.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/QuoteRequest"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ]
      }
    },
    "/quote-requests/{uuid}": {
      "get": {
        "tags": [
          "Quotes"
        ],
        "summary": "Get a request",
        "description": "Its status and, once answered, the price, the note and how long it stands.",
        "operationId": "getQuoteRequest",
        "responses": {
          "200": {
            "description": "The request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteRequest"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/quote-requests/{uuid}/accept": {
      "post": {
        "tags": [
          "Quotes"
        ],
        "summary": "Book the quoted price",
        "description": "Only while `bookable`. Makes an ordinary booking on hold, with your funds held; confirm it like any other. Accepting again returns the same booking.",
        "operationId": "acceptQuoteRequest",
        "responses": {
          "201": {
            "description": "Booked, on hold.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "409": {
            "description": "Not quoted, or the price has run out.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/quote-requests/{uuid}/withdraw": {
      "post": {
        "tags": [
          "Quotes"
        ],
        "summary": "Withdraw",
        "description": "While open or quoted.",
        "operationId": "withdrawQuoteRequest",
        "responses": {
          "200": {
            "description": "Withdrawn.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteRequest"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/bookings": {
      "post": {
        "tags": [
          "Bookings"
        ],
        "summary": "Create a booking",
        "description": "Reserves: seats and funds are held until `expiresAt`. Every option answer is checked now.",
        "operationId": "createBooking",
        "responses": {
          "201": {
            "description": "Reserved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Booking"
                    }
                  }
                },
                "example": {
                  "data": {
                    "uuid": "dec7793a-d0a9-44da-8488-5a2cedcddd07",
                    "code": "VT260928S0QKT",
                    "status": "reserved",
                    "testMode": true,
                    "createdAt": "2026-09-28T20:28:38+00:00",
                    "updatedAt": "2026-09-28T20:28:38+00:00",
                    "completedAt": null,
                    "expiresAt": "2026-09-28T20:58:38+00:00",
                    "arrivalDate": "2026-10-03",
                    "timeSlot": "07:00",
                    "timeSlotUuid": "593651fd-fb2d-4132-91cf-1764ceb6c885",
                    "adults": 2,
                    "children": 0,
                    "seniors": 0,
                    "youths": 0,
                    "infants": 0,
                    "salutation": null,
                    "firstName": "Hannah",
                    "lastName": "Lindqvist",
                    "email": "hannah@example.com",
                    "phone": "+46 70 123 4567",
                    "message": null,
                    "partnerReference": "NB-2026-00417",
                    "productUuid": "c86ea1c1-a986-4d1f-bd23-6bec906beffa",
                    "productTitle": "Old Istanbul at First Light: Sultanahmet Walking Tour",
                    "productTypeUuid": "d7bbe7df-6d64-45a8-b8f9-69dace2d4f9c",
                    "productTypeTitle": "Sunrise departure (07:00)",
                    "productTypeTitleTranslated": "Sunrise departure (07:00)",
                    "currencyCode": "USD",
                    "currencyUuid": "USD",
                    "totalAmount": 67.28,
                    "recommendedAmount": 76.52,
                    "amountBreakdown": [
                      {
                        "name": "Adult",
                        "price": "33.64",
                        "quantity": 2
                      }
                    ],
                    "ticketTypes": [
                      {
                        "type": "adult",
                        "uuid": "0d04e5e0-67cb-4f6c-aa87-d5d3be2744cb",
                        "quantity": 2
                      }
                    ],
                    "travellers": [
                      {
                        "uuid": "71f72161-9eae-4cd6-854c-e377d20486b5",
                        "type": "adult"
                      },
                      {
                        "uuid": "81befdbf-bb8d-4594-bb44-3d3d6ab48741",
                        "type": "adult"
                      }
                    ],
                    "options": {
                      "perBooking": [],
                      "perPax": []
                    },
                    "pickup": null,
                    "refundAmount": null,
                    "refundDate": null,
                    "refundTransaction": null,
                    "cancellationStatus": null,
                    "cancellationReason": null,
                    "cancellationRequestAt": null,
                    "cancellationRequestStatus": "",
                    "links": [
                      {
                        "rel": "self",
                        "uri": "https://api.vacotours.com/v2/bookings/dec7793a-d0a9-44da-8488-5a2cedcddd07"
                      },
                      {
                        "rel": "vouchers",
                        "uri": "https://api.vacotours.com/v2/bookings/dec7793a-d0a9-44da-8488-5a2cedcddd07/vouchers"
                      }
                    ]
                  }
                }
              }
            }
          },
          "409": {
            "description": "No availability for that date, time or party.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBooking"
              },
              "example": {
                "productTypeUuid": "d7bbe7df-6d64-45a8-b8f9-69dace2d4f9c",
                "arrivalDate": "2026-10-03",
                "adults": 2,
                "customer": {
                  "firstName": "Hannah",
                  "lastName": "Lindqvist",
                  "email": "hannah@example.com",
                  "phone": "+46 70 123 4567"
                },
                "partnerReference": "NB-2026-00417",
                "options": {
                  "perBooking": [
                    {
                      "uuid": "9b0d...14",
                      "value": "Vegetarian"
                    }
                  ],
                  "perPax": [
                    [
                      {
                        "uuid": "6f1c...a2",
                        "value": "X1234567"
                      }
                    ],
                    [
                      {
                        "uuid": "6f1c...a2",
                        "value": "Y7654321"
                      }
                    ]
                  ]
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Bookings"
        ],
        "summary": "List bookings",
        "description": "Your bookings, filtered and paginated.",
        "operationId": "listBookings",
        "responses": {
          "200": {
            "description": "Bookings.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Booking"
                      }
                    },
                    "meta": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "date_start",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date_end",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "created_start",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "created_end",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "partner_reference",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "first_name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "last_name",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/bookings/{uuid}": {
      "get": {
        "tags": [
          "Bookings"
        ],
        "summary": "Get a booking",
        "description": "One of your bookings.",
        "operationId": "getBooking",
        "responses": {
          "200": {
            "description": "The booking.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Booking"
                    }
                  }
                },
                "example": {
                  "data": {
                    "uuid": "dec7793a-d0a9-44da-8488-5a2cedcddd07",
                    "code": "VT260928S0QKT",
                    "status": "confirmed",
                    "testMode": true,
                    "createdAt": "2026-09-28T20:28:38+00:00",
                    "updatedAt": "2026-09-28T20:28:39+00:00",
                    "completedAt": "2026-09-28T20:28:39+00:00",
                    "expiresAt": null,
                    "arrivalDate": "2026-10-03",
                    "timeSlot": "07:00",
                    "timeSlotUuid": "593651fd-fb2d-4132-91cf-1764ceb6c885",
                    "adults": 2,
                    "children": 0,
                    "seniors": 0,
                    "youths": 0,
                    "infants": 0,
                    "salutation": null,
                    "firstName": "Hannah",
                    "lastName": "Lindqvist",
                    "email": "hannah@example.com",
                    "phone": "+46 70 123 4567",
                    "message": null,
                    "partnerReference": "NB-2026-00417",
                    "productUuid": "c86ea1c1-a986-4d1f-bd23-6bec906beffa",
                    "productTitle": "Old Istanbul at First Light: Sultanahmet Walking Tour",
                    "productTypeUuid": "d7bbe7df-6d64-45a8-b8f9-69dace2d4f9c",
                    "productTypeTitle": "Sunrise departure (07:00)",
                    "productTypeTitleTranslated": "Sunrise departure (07:00)",
                    "currencyCode": "USD",
                    "currencyUuid": "USD",
                    "totalAmount": 67.28,
                    "recommendedAmount": 76.52,
                    "amountBreakdown": [
                      {
                        "name": "Adult",
                        "price": "33.64",
                        "quantity": 2
                      }
                    ],
                    "ticketTypes": [
                      {
                        "type": "adult",
                        "uuid": "0d04e5e0-67cb-4f6c-aa87-d5d3be2744cb",
                        "quantity": 2
                      }
                    ],
                    "travellers": [
                      {
                        "uuid": "71f72161-9eae-4cd6-854c-e377d20486b5",
                        "type": "adult"
                      },
                      {
                        "uuid": "81befdbf-bb8d-4594-bb44-3d3d6ab48741",
                        "type": "adult"
                      }
                    ],
                    "options": {
                      "perBooking": [],
                      "perPax": []
                    },
                    "pickup": null,
                    "refundAmount": null,
                    "refundDate": null,
                    "refundTransaction": null,
                    "cancellationStatus": null,
                    "cancellationReason": null,
                    "cancellationRequestAt": null,
                    "cancellationRequestStatus": "",
                    "links": [
                      {
                        "rel": "self",
                        "uri": "https://api.vacotours.com/v2/bookings/dec7793a-d0a9-44da-8488-5a2cedcddd07"
                      },
                      {
                        "rel": "vouchers",
                        "uri": "https://api.vacotours.com/v2/bookings/dec7793a-d0a9-44da-8488-5a2cedcddd07/vouchers"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Currency",
            "in": "header",
            "schema": {
              "type": "string",
              "example": "EUR"
            }
          },
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/bookings/{uuid}/{status}": {
      "put": {
        "tags": [
          "Bookings"
        ],
        "summary": "Confirm or cancel",
        "description": "`confirm` sells a reservation. `cancel` releases one, or cancels a sale with a refund to your wallet on the operator's terms.",
        "operationId": "transition",
        "responses": {
          "200": {
            "description": "The booking.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Booking"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "confirm",
                "cancel"
              ]
            }
          }
        ]
      }
    },
    "/bookings/{uuid}/vouchers": {
      "get": {
        "tags": [
          "Bookings"
        ],
        "summary": "Vouchers",
        "description": "One per ticket, each with a signed PDF link.",
        "operationId": "vouchers",
        "responses": {
          "200": {
            "description": "Vouchers.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Voucher"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "uuid": "d0a1cde7-a6aa-4cc1-abf2-c0f23056d044",
                      "code": "VTNNBREAOKOI",
                      "visualId": "VT260928S0QKT-056",
                      "barcode": "VTNNBREAOKOI",
                      "barcodeType": "QRCODE",
                      "validFrom": "2026-10-03",
                      "validThrough": "2026-10-03",
                      "generatedAt": "2026-09-28T20:28:39+00:00",
                      "downloadedAt": null,
                      "redeemedAt": null,
                      "url": "https://api.vacotours.com/api/vouchers/d0a1cde7-a6aa-4cc1-abf2-c0f23056d044?signature=3b1f...e9a2",
                      "links": [
                        {
                          "rel": "download",
                          "uri": "https://api.vacotours.com/api/vouchers/d0a1cde7-a6aa-4cc1-abf2-c0f23056d044?signature=3b1f...e9a2"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This key may not do that.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found for this key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Refused. The message says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over the rate limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Authorization",
        "description": "Your token, `{key}.{secret}`."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "http_code": {
            "type": "integer"
          }
        }
      },
      "Rate": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "nettPrice",
              "retailPrice",
              "recommendedPrice",
              "minimumSellingPrice"
            ]
          },
          "category": {
            "type": "string",
            "description": "The ticket type."
          },
          "ticketTypeUuid": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "amount": {
            "type": "number",
            "description": "In the requested currency, as a decimal."
          },
          "format": {
            "type": "string"
          },
          "meta": {
            "type": "object",
            "properties": {
              "perBooking": {
                "type": "boolean",
                "description": "The whole party, not one ticket."
              }
            }
          }
        }
      },
      "TicketType": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "description": "Send this in ticketTypes when booking."
          },
          "type": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "allowed": {
            "type": "boolean"
          },
          "required": {
            "type": "boolean"
          },
          "min": {
            "type": "integer"
          },
          "max": {
            "type": "integer"
          },
          "minAge": {
            "type": "integer"
          },
          "maxAge": {
            "type": "integer"
          },
          "paxCount": {
            "type": "integer",
            "description": "Travellers per ticket."
          },
          "idRequired": {
            "type": "boolean"
          },
          "perDeparture": {
            "type": [
              "integer",
              "null"
            ],
            "description": "How many of this one departure has: cabins of a grade, seats in a zone. The seats left are in each price list availability, per ticket type."
          },
          "recommendedMarkup": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent to add to the nett to reach our own price."
          },
          "nettPriceFrom": {
            "type": [
              "number",
              "null"
            ]
          },
          "recommendedPriceFrom": {
            "type": [
              "number",
              "null"
            ]
          },
          "parityPrice": {
            "type": [
              "number",
              "null"
            ]
          },
          "gateRatePrice": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "OptionItem": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "price": {
            "type": "number"
          },
          "recommendedPrice": {
            "type": "number"
          }
        }
      },
      "BookingOption": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "nameTranslated": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "descriptionTranslated": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "addOn": {
            "type": "boolean"
          },
          "formatRegex": {
            "type": "string"
          },
          "inputType": {
            "type": "integer"
          },
          "inputTypeName": {
            "type": "string"
          },
          "minNumber": {
            "type": "integer"
          },
          "maxNumber": {
            "type": "integer"
          },
          "validFrom": {
            "type": [
              "string",
              "null"
            ]
          },
          "validTo": {
            "type": [
              "string",
              "null"
            ]
          },
          "price": {
            "type": [
              "number",
              "null"
            ]
          },
          "recommendedPrice": {
            "type": [
              "number",
              "null"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OptionItem"
            }
          }
        }
      },
      "BookingOptions": {
        "type": "object",
        "properties": {
          "perBooking": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BookingOption"
            }
          },
          "perPax": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BookingOption"
            }
          }
        }
      },
      "CancellationPolicy": {
        "type": "object",
        "properties": {
          "numberOfDays": {
            "type": "integer"
          },
          "numberOfHours": {
            "type": "integer"
          },
          "refundPercentage": {
            "type": "integer"
          },
          "cancellationFeePercentage": {
            "type": "integer"
          },
          "serviceFee": {
            "type": "number"
          },
          "serviceFeePerBooking": {
            "type": "boolean"
          },
          "serviceFeeCurrency": {
            "type": "string"
          }
        }
      },
      "Seats": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string"
          },
          "uuid": {
            "type": "string"
          },
          "quantity": {
            "type": "integer",
            "description": "Seats left; 999 with unlimited true when uncapped."
          },
          "unlimited": {
            "type": "boolean"
          },
          "type": {
            "type": "string",
            "enum": [
              "shared",
              "private"
            ]
          }
        }
      },
      "PriceList": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "weekday": {
            "type": "string"
          },
          "available": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "availability": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/Seats"
            }
          },
          "prices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "rates": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Rate"
                  }
                }
              }
            }
          },
          "timeslots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "description": "Send as timeSlotUuid."
                },
                "startTime": {
                  "type": "string"
                },
                "endTime": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "available": {
                  "type": "boolean",
                  "description": "False when full, or when a boat, vehicle or guide it shares with another option is taken for that time."
                },
                "priceId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "availability": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Seats"
                  }
                }
              }
            }
          },
          "cancellationPolicy": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CancellationPolicy"
            }
          },
          "voucherValidity": {
            "type": "object"
          },
          "options": {
            "$ref": "#/components/schemas/BookingOptions"
          }
        }
      },
      "ProductSummary": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "titleTranslated": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "direct: run by one of our own operators. channel: resold from a partner platform.",
            "enum": [
              "direct",
              "channel"
            ]
          },
          "validFrom": {
            "type": [
              "string",
              "null"
            ]
          },
          "validThrough": {
            "type": [
              "string",
              "null"
            ]
          },
          "basePrice": {
            "type": "number",
            "description": "The traveller \"from\" price."
          },
          "isFlatPaxPrice": {
            "type": "boolean"
          },
          "coverImage": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "typeName": {
            "type": [
              "string",
              "null"
            ]
          },
          "typeUuid": {
            "type": [
              "string",
              "null"
            ]
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "ProductType": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "productUuid": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "titleTranslated": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "descriptionTranslated": {
            "type": [
              "string",
              "null"
            ]
          },
          "durationDays": {
            "type": "integer"
          },
          "durationHours": {
            "type": "integer"
          },
          "durationMinutes": {
            "type": "integer"
          },
          "cutOffHours": {
            "type": "integer"
          },
          "daysInAdvance": {
            "type": [
              "integer",
              "null"
            ]
          },
          "cutOffTime": {
            "type": [
              "string",
              "null"
            ]
          },
          "nonInstantVoucher": {
            "type": "boolean"
          },
          "directAdmission": {
            "type": "boolean"
          },
          "voucherRequiresPrinting": {
            "type": "boolean"
          },
          "isBmgVoucher": {
            "type": "boolean"
          },
          "voucherUse": {
            "type": [
              "string",
              "null"
            ]
          },
          "voucherUseTranslated": {
            "type": [
              "string",
              "null"
            ]
          },
          "voucherRedemptionAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "voucherRedemptionAddressTranslated": {
            "type": [
              "string",
              "null"
            ]
          },
          "meetingLocationTranslated": {
            "type": [
              "string",
              "null"
            ]
          },
          "meetingGooglePlaceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "allowAdults": {
            "type": "boolean"
          },
          "allowChildren": {
            "type": "boolean"
          },
          "allowSeniors": {
            "type": "boolean"
          },
          "allowInfant": {
            "type": "boolean"
          },
          "hasChildPrice": {
            "type": "boolean"
          },
          "cancellationPolicySummary": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasFileUploadOptions": {
            "type": "boolean"
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "firstAvailabilityDate": {
            "oneOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "boolean"
              }
            ]
          },
          "isNonRefundable": {
            "type": "boolean"
          },
          "instantConfirmation": {
            "type": "boolean"
          },
          "meetingTime": {
            "type": [
              "string",
              "null"
            ]
          },
          "meetingAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "meetingLocation": {
            "type": [
              "string",
              "null"
            ]
          },
          "meetingLatitude": {
            "type": [
              "number",
              "null"
            ]
          },
          "meetingLongitude": {
            "type": [
              "number",
              "null"
            ]
          },
          "timezone": {
            "type": "string"
          },
          "isFlatPaxPrice": {
            "type": "boolean"
          },
          "pricingPer": {
            "type": "string",
            "enum": [
              "UNIT",
              "BOOKING"
            ]
          },
          "minPax": {
            "type": [
              "integer",
              "null"
            ]
          },
          "maxPax": {
            "type": [
              "integer",
              "null"
            ]
          },
          "minGroup": {
            "type": [
              "integer",
              "null"
            ]
          },
          "maxGroup": {
            "type": [
              "integer",
              "null"
            ]
          },
          "ticketTypes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TicketType"
            }
          },
          "cancellationPolicies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CancellationPolicy"
            }
          },
          "validity": {
            "type": "object"
          },
          "timeslots": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "pickup": {
            "type": "object",
            "properties": {
              "available": {
                "type": "boolean"
              },
              "required": {
                "type": "boolean"
              },
              "points": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "address": {
                      "type": "string"
                    },
                    "time": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "itinerary": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "options": {
            "$ref": "#/components/schemas/BookingOptions"
          },
          "details": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "section": {
                  "type": "string",
                  "description": "rental_terms, coverage, pass_inclusions, event_details, guide_profile, course_schedule, transfer_route, route, accommodation, cabins, seating or quote_settings."
                },
                "label": {
                  "type": "string",
                  "description": "The section, in words."
                },
                "fields": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "label": {
                        "type": "string"
                      },
                      "type": {
                        "type": "string",
                        "enum": [
                          "text",
                          "textarea",
                          "number",
                          "money",
                          "boolean",
                          "time",
                          "select",
                          "multiselect",
                          "list",
                          "countries"
                        ]
                      },
                      "value": {
                        "description": "The raw value: a number, true or false, a string, or a list. Money is US dollars."
                      },
                      "display": {
                        "description": "The value in words, ready to show."
                      }
                    }
                  }
                }
              }
            },
            "description": "What this kind of product says about itself: a rental's deposit and driver age, an eSIM's countries and data, a pass's attractions, a venue, a route. Self-describing: show display, or read value."
          },
          "rental": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/RentalTerms"
              },
              {
                "type": "null"
              }
            ]
          },
          "hasOptions": {
            "type": "boolean"
          },
          "hasPriceOptions": {
            "type": "boolean"
          },
          "hasRequiredPriceOptions": {
            "type": "boolean"
          }
        }
      },
      "CreateBooking": {
        "type": "object",
        "properties": {
          "productTypeUuid": {
            "type": "string"
          },
          "arrivalDate": {
            "type": "string",
            "format": "date"
          },
          "timeSlotUuid": {
            "type": [
              "string",
              "null"
            ],
            "description": "From the price list timeslots. Omit for the first time on the date."
          },
          "adults": {
            "type": "integer"
          },
          "children": {
            "type": "integer"
          },
          "seniors": {
            "type": "integer"
          },
          "ticketTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "quantity": {
                  "type": "integer"
                }
              }
            }
          },
          "travellers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "firstName": {
                  "type": "string"
                },
                "lastName": {
                  "type": "string"
                },
                "email": {
                  "type": "string"
                },
                "phone": {
                  "type": "string"
                },
                "age": {
                  "type": "integer"
                }
              }
            }
          },
          "customer": {
            "type": "object",
            "properties": {
              "salutation": {
                "type": "string"
              },
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "phone": {
                "type": "string"
              },
              "country": {
                "type": "string"
              }
            },
            "required": [
              "firstName",
              "lastName",
              "email",
              "phone"
            ]
          },
          "partnerReference": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "options": {
            "type": "object",
            "properties": {
              "perBooking": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    }
                  }
                }
              },
              "perPax": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string"
                      },
                      "value": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "pickup": {
            "type": "object",
            "properties": {
              "pointUuid": {
                "type": "string"
              },
              "hotel": {
                "type": "string"
              },
              "room": {
                "type": "string"
              },
              "address": {
                "type": "string"
              },
              "notes": {
                "type": "string"
              }
            }
          },
          "expirationMinutes": {
            "type": "integer"
          },
          "idempotencyKey": {
            "type": "string",
            "description": "A UUID. A retry with it returns the first booking.",
            "format": "uuid"
          },
          "rental": {
            "$ref": "#/components/schemas/RentalRequest"
          }
        },
        "required": [
          "productTypeUuid",
          "arrivalDate",
          "customer"
        ]
      },
      "Booking": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "reserved",
              "waiting",
              "confirmed",
              "cancelled",
              "expired",
              "completed",
              "rejected",
              "no_show"
            ]
          },
          "testMode": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "arrivalDate": {
            "type": "string"
          },
          "timeSlot": {
            "type": [
              "string",
              "null"
            ]
          },
          "timeSlotUuid": {
            "type": [
              "string",
              "null"
            ]
          },
          "adults": {
            "type": "integer"
          },
          "children": {
            "type": "integer"
          },
          "seniors": {
            "type": "integer"
          },
          "youths": {
            "type": "integer"
          },
          "infants": {
            "type": "integer"
          },
          "salutation": {
            "type": [
              "string",
              "null"
            ]
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "partnerReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "productUuid": {
            "type": "string"
          },
          "productTitle": {
            "type": "string"
          },
          "productTypeUuid": {
            "type": "string"
          },
          "productTypeTitle": {
            "type": "string"
          },
          "productTypeTitleTranslated": {
            "type": "string"
          },
          "rental": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "basis": {
                "type": "string"
              },
              "length": {
                "type": "integer"
              },
              "pickup": {
                "type": "string"
              },
              "return": {
                "type": "string"
              },
              "returnLocation": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "currencyCode": {
            "type": "string"
          },
          "currencyUuid": {
            "type": "string"
          },
          "totalAmount": {
            "type": "number",
            "description": "What your wallet was charged."
          },
          "recommendedAmount": {
            "type": "number",
            "description": "What a traveller would pay."
          },
          "amountBreakdown": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "price": {
                  "type": "string"
                },
                "quantity": {
                  "type": "integer"
                }
              }
            }
          },
          "ticketTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string"
                },
                "uuid": {
                  "type": "string"
                },
                "quantity": {
                  "type": "integer"
                }
              }
            }
          },
          "travellers": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "options": {
            "type": "object",
            "properties": {
              "perBooking": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "perPax": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "pickup": {
            "type": [
              "object",
              "null"
            ]
          },
          "refundAmount": {
            "type": [
              "number",
              "null"
            ]
          },
          "refundDate": {
            "type": [
              "string",
              "null"
            ]
          },
          "refundTransaction": {
            "type": [
              "string",
              "null"
            ]
          },
          "cancellationStatus": {
            "type": [
              "string",
              "null"
            ]
          },
          "cancellationReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "cancellationRequestAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "cancellationRequestStatus": {
            "type": "string"
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "Voucher": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "visualId": {
            "type": "string"
          },
          "barcode": {
            "type": "string"
          },
          "barcodeType": {
            "type": "string"
          },
          "validFrom": {
            "type": "string"
          },
          "validThrough": {
            "type": "string"
          },
          "generatedAt": {
            "type": "string"
          },
          "downloadedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "redeemedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": "string",
            "description": "A signed link to the PDF. Opens without a login, so it can be forwarded to the traveller."
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "QuoteRequestBody": {
        "type": "object",
        "properties": {
          "productId": {
            "type": "string"
          },
          "groupSize": {
            "type": "integer"
          },
          "travelDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          },
          "datesFlexible": {
            "type": "boolean"
          },
          "budget": {
            "type": "number",
            "description": "For the whole group, USD."
          },
          "message": {
            "type": "string",
            "description": "What your client wants."
          },
          "answers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "question": {
                  "type": "string"
                },
                "answer": {
                  "type": "string"
                }
              },
              "description": "Answers to the operator's quote settings (their ask list)."
            }
          },
          "option": {
            "type": "string",
            "description": "An option uuid, when the product has several."
          },
          "contact": {
            "type": "object",
            "properties": {
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              },
              "emailAddress": {
                "type": "string"
              },
              "phoneNumber": {
                "type": "string"
              },
              "country": {
                "type": "string"
              }
            },
            "required": [
              "firstName",
              "lastName",
              "emailAddress"
            ]
          },
          "resellerReference": {
            "type": "string"
          }
        },
        "required": [
          "productId",
          "groupSize",
          "contact"
        ]
      },
      "QuoteRequest": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "quoted",
              "accepted",
              "declined",
              "withdrawn",
              "expired"
            ]
          },
          "product": {
            "type": "object",
            "properties": {
              "uuid": {
                "type": "string"
              },
              "slug": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            }
          },
          "option": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "uuid": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            }
          },
          "travelDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          },
          "datesFlexible": {
            "type": "boolean"
          },
          "groupSize": {
            "type": "integer"
          },
          "budget": {
            "type": "integer",
            "description": "USD minor units."
          },
          "message": {
            "type": "string"
          },
          "answers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "question": {
                  "type": "string"
                },
                "answer": {
                  "type": "string"
                }
              }
            }
          },
          "contact": {
            "type": "object"
          },
          "resellerReference": {
            "type": "string"
          },
          "price": {
            "$ref": "#/components/schemas/QuotePrice"
          },
          "quoteMessage": {
            "type": "string",
            "description": "The operator's note: what the price includes."
          },
          "quotedAt": {
            "type": "string",
            "format": "date-time"
          },
          "validUntil": {
            "type": "string",
            "format": "date-time"
          },
          "declineReason": {
            "type": "string"
          },
          "bookingId": {
            "type": "string",
            "description": "The booking, once accepted."
          },
          "bookable": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "QuotePrice": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "description": "What you pay for the whole group, USD minor units."
          },
          "recommendedRetail": {
            "type": "integer",
            "description": "What a traveller would pay."
          },
          "currency": {
            "type": "string"
          }
        }
      },
      "RentalTerms": {
        "type": "object",
        "properties": {
          "basis": {
            "type": "string",
            "enum": [
              "day",
              "night",
              "hour"
            ]
          },
          "minLength": {
            "type": "integer"
          },
          "maxLength": {
            "type": [
              "integer",
              "null"
            ]
          },
          "pricedPer": {
            "type": "string",
            "description": "day, night or hour when each is charged; period when one rate, chosen by length, covers the whole booking."
          },
          "oneWay": {
            "type": "boolean"
          },
          "oneWayFee": {
            "type": [
              "integer",
              "null"
            ],
            "description": "USD minor units."
          },
          "deposit": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Held at pickup, not charged. USD minor units."
          }
        },
        "description": "Booked from one date to another. See Rentals and stays."
      },
      "RentalRequest": {
        "type": "object",
        "properties": {
          "returnDate": {
            "type": "string",
            "format": "date"
          },
          "pickupTime": {
            "type": "string",
            "description": "HH:MM"
          },
          "returnTime": {
            "type": "string",
            "description": "HH:MM"
          },
          "returnLocation": {
            "type": "string"
          }
        }
      },
      "RentalQuote": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why not, in words you can show."
          },
          "rental": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "basis": {
                "type": "string"
              },
              "length": {
                "type": "integer"
              },
              "pickup": {
                "type": "string"
              },
              "return": {
                "type": "string"
              },
              "returnLocation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "oneWayFee": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "currencyCode": {
            "type": "string"
          },
          "ticketTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string"
                },
                "price": {
                  "type": "number",
                  "description": "Each, for the whole period."
                },
                "recommendedPrice": {
                  "type": "number"
                }
              }
            }
          },
          "booking": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Pair"
              },
              {
                "type": "null"
              }
            ]
          },
          "total": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Pair"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Pair": {
        "type": "object",
        "properties": {
          "price": {
            "type": "number",
            "description": "What you pay."
          },
          "recommendedPrice": {
            "type": "number",
            "description": "What a traveller would pay."
          }
        }
      }
    }
  }
}
