openapi: 3.2.0 info: title: Viator Partner Auxiliary API description: "\n\n## Updates\n\n### Latest updates: \n\n| Date | Description |\n|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| 5 May 2026 | Added support for product option level logistics resolution via a new optional `logistics` object. |\n| 13 Feb 2025 | Added `videos` object to [/products/{product-code}](#operation/products), [/products/modified-since](#operation/productsModifiedSince), [/products/bulk](#operation/productsBulk), [/products/search](#operation/productsSearch) and [/search/freetext](#operation/searchFreeText) responses. |\n| 4 Feb 2025 | Added `AED`, `ARS`, `CLP`, `CNY`, `COP`, `FJD`, `IDR`, `ILS`, `ISK`, `KRW`, `MXN`, `MYR`, `PEN`, `PHP`, `PLN`, `RUB`, `THB`, `TRY` and `VND` as currency options in the request to [/products/search](#operation/productsSearch) and [/search/freetext](#operation/searchFreeText). \n| 11 Sep 2025 | Updated [/bookings/modified-since](#operation/bookingsModifiedSince) response with new `eventTypes` and enabled endpoint access to all partner types. \n| 01 Jul 2025 | Added [/amendment/check/{booking-reference}](#operation/amendmentCheck), [/amendment/quote](#operation/amendmentQuote) and [/amendment/amend/{quote-reference}](#operation/amendmentAmend) endpoints to [Bookings](#tag/Bookings) section \n| 27 Mar 2025 | Update [/search/freetext](#operation/searchFreeText) request section add filtering by tags for \"searchType\": \"PRODUCTS\" \n| 20 Mar 2025 | Added [/products/recommendations](#operation/productsRecommendations) to [Products](#tag/Products) section. This endpoint will provide product-to-product recommendations to users. |\n| 19 Mar 2025 | Updated endpoints [/availability/schedules/{product-code}](#operation/availabilitySchedules), [/availability/schedules/bulk](#operation/availabilitySchedulesBulk), [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince), [/availability/check](#operation/availabilityCheck), [/search/freetext](#operation/searchFreeText), [/products/search](#operation/productsSearch), [/bookings/cart/hold](#operation/bookingsCartHold) and [/bookings/hold](#operation/bookingsHold) as well as [Inclusions & exclusions](#section/Appendices/Inclusions-and-exclusions) with `Extra Charges` information |\n| 11 Feb 2025 | Removed `TRANSACTION_NOT_ALLOWED`, `CARD_INACTIVE` and `CARD_RESTRICTED` rejection reasons from [/bookings/cart/book](#tag/Bookings/operation/bookingsCartBook). |\n| 4 Dec 2024 | Updated [/bookings/cart/book](#tag/Bookings/operation/bookingsCartBook) response with the following new rejection reason: `PROCESSOR_ISSUE_WITH_PAYMENT`. |\n| 19 Nov 2024 | Updated [/bookings/cart/book](#tag/Bookings/operation/bookingsCartBook) response with the following new rejection reasons: `SUSPECTED_FRAUD`, `SOFT_DECLINE`, `HARD_DECLINE`, `THREE_D_SECURE_REQUIRED`, `INTERNAL_ERROR`, `PROCESSOR_UNAVAILABLE`. |\n| 24 Oct 2024 | Deprecated [/v1/product/photos](#operation/v1ProductPhotos) endpoint |\n| 23 Oct 2024 | Added [/attractions/search](#operation/attractionsSearch) and [/attractions/{attraction-id}](#operation/attractions) to [Attractions](#tag/Attractions) section
Added [/destinations](#operation/destinations) to [Auxiliary](#tag/Auxiliary) section
Updated [Access to endpoints](#section/Access-to-endpoints) section to include new endpoints and removed the ones marked for deprecation
Updated [Resolving references](#section/Workflows/Resolving-references) section |\n| 21 Oct 2024 | Removed `VIATOR_EXCLUSIVE` flag from product search endpoints |\n| 1 Oct 2024 | Removed COVID-19 safety attributes from `AdditionalInfo` schema (part of product content response; e.g., from [/products/{product-code}](#operation/products) endpoint) |\n| 6 Aug 2024 | Changes to behaviour with `DEFAULT` tour grade for product, availability, book hold and confirm endpoints. See note at end of section [Product Option Code](#section/Key-concepts/Product-options). Note: these changes are backwards compatible. |\n| 29 Jul 2024 | Updated [/bookings/modified-since](#operation/bookingsModifiedSince) response with new eventType: CUSTOMER_CANCELLATION, for Customer initiated cancellations. |\n| 14 Mar 2024 | Updated [/bookings/cart/book](#tag/Bookings/operation/bookingsCartBook) response with the following new rejection reasons: `INSUFFICIENT_FUNDS`, `INVALID_PAYMENT_DETAILS`, `TRANSACTION_NOT_ALLOWED`, `CARD_INACTIVE` and `CARD_RESTRICTED`.
Updated [/bookings/status](#tag/Bookings/operation/bookingsStatus) response with `ON_HOLD` status |\n| 13 Feb 2024 | Updated [/suppliers/search/product-codes](#operation/suppliersSearchProductCodes) with the following new attributes: `supplierAgreedToLegalCompliance`, `registrationCountry`, `tradeRegisterName` and `registeredBusinessNumber`. Also updated the `ContactDetails` schema with a new attribute `countryCode`. |\n| 11 Sep 2023 | Added support for PDF vouchers. Made bookerInfo firstName required to match definition. |\n| 5 Jul 2023 | Added [/bookings/cart/hold](#operation/bookingsCartHold) and [/bookings/cart/book](#operation/bookingsCartBook) to [Bookings](#tag/Bookings) section
Added [/v1/checkoutsessions/{sessionToken}/paymentaccounts](#operation/paymentsCreateToken) to [Payments](#tag/Payments) section |\n| 15 May 2023 | Modified [Accept-Language-header-parameter](#section/Localization/Accept-Language-header-parameter) section to accurately reflect currently allowed values |\n| 16 Mar 2023 | Added [/search/freetext](#operation/searchFreeText) and [/suppliers/search/product-codes](#operation/suppliersSearchProductCodes) to [Access to endpoints](#section/Access-to-endpoints) section |\n| 6 Mar 2023 | Added Canadian dollars (CAD) as currency option in request and response to [/bookings/hold](#operation/bookingsHold), [/bookings/book](#operation/bookingsBook) and [/bookings/status](#operation/bookingsStatus) endpoints |\n| 6 Jan 2023 | Added two new COVID-19 safety attributes to `AdditionalInfo` schema (part of product content response; e.g., from [/products/{product-code}](#operation/products) endpoint) |\n| 4 Jan 2023 | Updated or created `ProductSearchFiltering`, `ProductSummary`, `ProductSearchSorting`, `ProductSearchFlag`, `TranslationDetails`, `SearchDurationInfo` and `SearchRatingInfo` schemata for the [/products/search](#operation/productsSearch) endpoint request/response, updated example request and merchant and affiliate response examples, and updated [Postman collections](#section/Testing/Postman-collections-for-testing) in line with these changes |\n| 3 Jan 2023 | Updated example request and response for [/search/freetext](#operation/searchFreeText) endpoint |\n| 12 Dec 2022 | Added [/search/freetext](#operation/searchFreeText) endpoint |\n| 10 Nov 2022 | Updated [/bookings/hold](#tag/Bookings/operation/bookingsHold) and [/bookings/modified-since/acknowledge](#tag/Bookings/operation/bookingsModifiedSinceAcknowledge) descriptions |\n \n\n\n### Update history: \n\n- All significant modifications made to this document since its creation can be found in the [Update history](#section/Appendices/Update-history) section.\n\n# Support\n\n## Onboarding / integration\n\nIf you require help or technical advice while you are carrying out your integration, please contact the onboarding team via email at: affiliateapi@tripadvisor.com\n\n### Integration guides\n\nOur onboarding specialists have put together [in-depth guides](https://partnerresources.viator.com/travel-commerce/implementation/?source=specs) covering various topics to help you during your integration. \n\n### Site certification for merchant partners\n\nIf you are a merchant partner, once your API integration has been completed, it must pass certification prior to going live in order to ensure data integrity and the appropriate use of API services. Please peruse and bear in mind [our certification requirements](https://partnerresources.viator.com/travel-commerce/merchant/certification/?source=specs) prior to and during development.\n\n## Operational support\n\nIf are a merchant partner, have completed your integration and your site is operational, please see the [Partner Help Center - Merchant partner support](https://partnerhelp.viator.com/en/categories/37-merchant-partner-support?source=specs) page for information about what to do if you encounter a problem and require support.\n\n# About\n\n## Viator Partner-API v2\n\n### What is it?\n\nThe Viator Partner API v2 comprises a set of endpoints that can support the operation of a fully-featured tours and experiences booking website or application; or, it can be integrated with your existing travel-booking software.\n\nThe API exposes a variety of services that allow the retrieval of all product details, such as descriptive text and structured metadata, pricing, terms and conditions, photos and reviews. This data can either be ingested and managed on your local system, or calls can be made in real time to retrieve content in response to your users' activity on your systems.\n\nThe API allows product content, pricing and availability data to be retrieved in bulk or queried in real-time, it can perform pricing calculations according to the number and type of traveler and product option combinations available, and it supports availability and pricing holds as part of its booking and booking-cancellation functionality. \n\n### Who is it for?\n\nThe Viator Partner-API is a designed for use by organizations partnered with Viator as [Affiliate partners](https://partnerresources.viator.com/travel-commerce/affiliate/) or [Merchant partners](https://partnerresources.viator.com/travel-commerce/merchant/).\n\n#### Affiliate partners\n\n\nAffiliate partners have full access to the areas of the API relating to content, but sales of Viator products must be carried out on the Viator site itself. \n\nWhen a customer wishes to book a product from an affiliate's site, they are instead redirected to the relevant product page on [viator.com](https://viator.com) via a unique URL in order to complete the purchase. Once on the Viator site, a cookie is set such that all transactions will accrue a commission for that partner until the cookie expires.\n\nPurchases of products originating from the affiliate's site are recorded and a commission on these sales is paid periodically.\n\nFor more information on this partner type, see: [Viator's Affiliate API Solution](https://partnerresources.viator.com/travel-commerce/affiliate/)\n\n#### Merchant partners\n\nThe merchant partner relationship is one in which the partner is the **merchant of record**; i.e., the partner takes full responsibility for all financial records and transactions carried out by their users, as well as providing customer support with regard to providing general assistance, processing cancellations and refunds, and liaising between suppliers and customers when the need to communicate arises.\n\nFor more information on this partner type, see: [Viator's Merchant API Solution](https://partnerresources.viator.com/travel-commerce/merchant/)\n\n\n## New features in this version\n\nThe Viator Partner-API v2.0 is a fully-redesigned system with regard to our previous API products. It includes all key fuctionality available in previous versions, but now provides nearly fully-structured data elements, and a more modern, concise and easily-understandable interface.\n\nIn addition, we have made significant improvements to performance across all functions of the API, and particularly in the area of product content and availability data ingestion.\n\n### Simplified and optimized data ingestion \n\nData ingestion has been greatly improved over previous versions of this API. Now, partners need only perform a single initial ingestion of data; then, only new and updated product content, availability and pricing information is retrieved as a 'delta update' as it becomes available.\n\nIn addition:\n- A single end-point allows both bulk ingestion and delta updates, which can be controlled using a pagination cursor or with a time-stamp parameter to allow for point-in-time ingestion of any new updates and easy recovery from ingestion failure\n- The structure of a product's pricing and availability schedules has been simplified to reduce response size\n\n#### Product content\n\n- All pricing is standardized to the supplier's currency, avoiding the need to update on account of exchange rate fluctuations \n- Structured location, tag, booking question, review and photo data is available from separate endpoints to allow for parallel ingestion, and resusable data can be ingested once and applied globally\n\n#### Availability schedule information\n\nImprovements to availability schedule ingestion performance and usability have been achieved:\n\n- Availability is now communicated by providing an overall schedule season and specifying *unavailable* dates instead of available dates, a significantly more compact format that improves transfer speeds and minimizes storage needs \n\n- Availability and pricing information is given on a days-of-the-week basis, which can help with filtering and improving visibility of product availability for customers.\n\n- Information about special pricing periods that may be running throughout a product's seasons is included and is easy to interpret, allowing partners to surface promotions to customers.\n\n- Accurate pricing and applicability information for products that have 'per unit' (group) pricing is now included in the availability & pricing response; whereas support for this pricing model was limited in previous versions of this API. This allows partners to improve pricing exposure for these products.\n\n### Structure-rich content\n\nProviding structured content is a major focus of this API. Product information that was previously stored as natural-language descriptions in a single, lengthy field is now represented in intuitively-structured, machine-interpretable schemata that empowers partners to apply finely-grained merchandising control, including:\n\n- Tour itineraries with comprehensive location data to allow for graphical display and advanced search\n- Tour details, inclusions and dynamic health & safety information to support changing requirements due to global pandemic response initiatives\n- Machine-parseable booking questions and answers\n\n### Improved real-time availability and pricing checking\n\nThe [real-time availability check endpoint](#operation/availabilityCheck):\n- Allows you to check availability and pricing in real-time for a specific product / [product-option](#section/Key-concepts/Product-options) / date / starting time / pax mix combination\n- Returns the ticket availability status along with a pricing breakdown (by age band) and total price (all age bands) in a simplified format to reduce response size\n- Pricing components are stated explicitly, including the Recommended Retail Price (RRP), partner net price, special-offer pricing and booking fee component details\n\n### Improved booking workflow\n\nThe [booking workflow](#section/Booking-concepts/Making-a-booking) now includes an optional booking-hold step, which allows you greater predictability of a successful booking, thereby increasing conversion rates by decreasing friction in the booking flow.\n\nThe [booking hold](#operation/bookingsCartHold) endpoint supports two kinds of hold:\n- Inventory/availability hold (increased likelihood of receiving a booking confirmation)\n- Pricing hold (mitigates against pricing changes at the time of booking)\n\nThe [real-time availability and pricing endpoint](#operation/availabilityCheck) also delivers \\~5% faster performance than previous versions of this API.\n\n# Access to endpoints\n\nThe API endpoints accessible to you depend on which kind of partner you are; affiliate or merchant. \n\n**Basic-access Affiliate partners** have access to a limited subset of the non-transactional endpoints of the Viator Partner API. The basic-access tier allows affiliates to quickly get started building their site with fewer complexities. The following step-by-step guide explains how to do it: [Golden Path – Basic Access Affiliate Partners](https://partnerresources.viator.com/travel-commerce/affiliate/basic-access/golden-path/?source=specs) \n\n**Full-access Affiliate partners** have access to all non-transactional endpoints; i.e., everything except booking, booking hold and booking cancellation endpoints. This access model applies equally to whitelabel partners.\n\n**Full-access + Booking Affiliate partners** have access to all the same endpoints as **Full-access Affiliate partners** as well as transactional endpoints. i.e., including cart booking, cart booking hold and booking cancellation endpoints.\n\n**Merchant partners** have access to all endpoints.\n\nThe following table describes which partner types have access to which endpoints:\n\n| Endpoint | Basic-access Affiliate | Full-access Affiliate | Full-access + Booking Affiliate | Merchant |\n|-----------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------:|:------------:|\n| [/products/modified-since](#operation/productsModifiedSince) | ❌ | ✅ | ✅ | ✅ |\n| [/products/bulk](#operation/productsBulk) | ❌ | ✅ | ✅ | ✅ |\n| [/products/{product-code}](#operation/products) | ✅ | ✅ | ✅ | ✅ |\n| [/products/tags](#operation/productsTags) | ✅ | ✅ | ✅ | ✅ |\n| [/products/booking-questions](#operation/productsSearch) | ❌ | ❌ | ✅ | ✅ |\n| [/products/search](#operation/productsSearch) | ✅ | ✅ | ✅ | ✅ |\n| [/products/recommendations](#operation/productsRecommendations) | ❌ | ✅ | ✅ | ✅ |\n| [/attractions/search](#operation/attractionsSearch) | ✅ | ✅ | ✅ | ✅ |\n| [/attractions/{attraction-id}](#operation/attractions) | ✅ | ✅ | ✅ | ✅ |\n| [/availability/check](#operation/checkAvailability) | ❌ | ✅ | ✅ | ✅ |\n| [/availability/schedules/{product-code}](#operation/availabilitySchedules) | ✅ | ✅ | ✅ | ✅ |\n| [/availability/schedules/bulk](#operation/availabilitySchedulesBulk) | ❌ | ✅ | ✅ | ✅ |\n| [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) | ❌ | ✅ | ✅ | ✅ |\n| [/bookings/cart/hold](#operation/bookingsCartHold) | ❌ | ❌ | ✅ | ✅ |\n| [/bookings/cart/book](#operation/bookingsCartBook) | ❌ | ❌ | ✅ | ✅ |\n| [/bookings/hold](#operation/bookingsHold) | ❌ | ❌ | ❌ | ✅ |\n| [/bookings/book](#operation/bookingsBook) | ❌ | ❌ | ❌ | ✅ |\n| [/bookings/status](#operation/bookingsBook) | ❌ | ❌ | ✅ | ✅ |\n| [/bookings/cancel-reasons](#operation/bookingsCancelReasons) | ❌ | ❌ | ✅ | ✅ |\n| [/bookings/{booking-reference}/cancel-quote](#operation/bookingsCancelQuote) | ❌ | ❌ | ✅ | ✅ |\n| [/bookings/{booking-reference}/cancel](#operation/bookingsCancel) | ❌ | ❌ | ✅ | ✅ |\n| [/bookings/modified-since](#operation/bookingsModifiedSince) | ✅ | ✅ | ✅ | ✅ |\n| [/bookings/modified-since/acknowledge](#operation/bookingsModifiedSinceAcknowledge) | ❌ | ❌ | ✅ | ✅ |\n| [/amendment/check/{booking-reference}](#operation/amendmentCheck) | ❌ | ❌ | ✅ | ✅ |\n| [/amendment/quote](#operation/amendmentQuote) | ❌ | ❌ | ✅ | ✅ |\n| [/amendment/amend/{quote-reference}](#operation/amendmentAmend) | ❌ | ❌ | ✅ | ✅ |\n| [/v1/checkoutsessions/{sessionToken}/paymentaccounts](#operation/paymentsCreateToken) | ❌ | ❌ | ✅ | ❌ |\n| [/search/freetext](#operation/searchFreeText) | ✅ | ✅ | ✅ | ✅ |\n| [/destinations](#operation/destinations) | ✅ | ✅ | ✅ | ✅ |\n| [/locations/bulk](#operation/locationsBulk) | ✅ | ✅ | ✅ | ✅ |\n| [/exchange-rates](#operation/exchangeRates) | ✅ | ✅ | ✅ | ✅ |\n| [/reviews/product](#operation/reviewsProduct) | ❌ | ✅ | ✅ | ✅ |\n| [/suppliers/search/product-codes](#operation/suppliersSearchProductCodes) | ❌ | ✅ | ✅ | ✅ |\n\n\n# Authentication\n\n## API-key\n\nAccess to the API is managed using an **API key** that is included as a **header parameter** to every call made to all API endpoints described in this document.\n\n| Header parameter name | Example value |\n|-----------------------|---------------|\n| exp-api-key | bcac8986-4c33-4fa0-ad3f-75409487026c |\n\nIf you do not know the API key for your organization, please contact your business development account manager for these details.\n\nPlease note that language localization is now controlled on a per-call basis. Previously, localization settings were configured per API-key; whereas, under the present scheme, organizations have a **single API key**. \n\nLanguage localization is accomplished by specifying the desired language as a header parameter (`Accept-Language`). See [Accept-Language header](#section/Localization/Accept-Language-header-parameter) for available language codes.\n\n# Localization\n\n## Accept-Language header parameter\n\nThe `Accept-Language` header parameter specifies into which language the natural language fields in the response from each endpoint will be translated.\n\n**Note:** All partners using the V2 endpoints have access to all supported languages for their partner type.\n\n### Languages available to all partners\n\n| Language | Accept-Language parameter value |\n|----------|-------|\n| English | `en`, `en-US` `en-AU`, `en-CA`, `en-GB`, `en-HK`, `en-IE`, `en-IN`, `en-MY`, `en-NZ`, `en-PH`, `en-SG`, `en-ZA` |\n| Danish | `da` |\n| Dutch | `nl`, `nl-BE` |\n| Norwegian | `no` |\n| Spanish | `es`, `es-AR`, `es-CL`, `es-CO`, `es-MX`, `es-PE`, `es-VE` |\n| Swedish | `sv`|\n| French | `fr`, `fr-BE`, `fr-CA`, `fr-CH` |\n| Italian | `it`, `it-CH` |\n| German | `de`, `de-DE` |\n| Portuguese | `pt`, `pt-BR` |\n| Japanese | `ja` |\n\n### Additional languages available to merchant partners only\n\n| Language | Accept-Language parameter value |\n|----------|-------|\n| Chinese (traditional) | `zh-TW` |\n| Chinese (simplified) | `zh-CN` |\n| Korean | `ko`, `ko-KR` |\n\n## API versioning strategy\n\nIn order to ensure the predictability of the behavior of this software, we have implemented a versioning strategy to handle updates to the API contract, as well as a mechanism to specify which version of the API you wish to access.\n\nWhen we release a new version of this API, partners have the option of continuing to use the existing version or migrating to the updated version when they are ready.\n\n - **Note**: The version of this API that this document pertains to is that indicated in the title of this document.\n\nThe approach to versioning for this API is as follows:\n\n### Global versioning\n\n- Version numbers are global across all endpoints. When a new version of this API is released, **all** endpoints will increment to the latest version. Viator does not support a heterogenous implementation with calls being made to different endpoints with different version numbers.\n\n### Version release and deprecation\n\n- New versions of this software are released on an ad-hoc basis. Breaking changes will always result in a version increment.\n- Viator will inform partners about all version releases, including details about the new features available and any breaking changes that have been introduced.\n- Once a version of the API is deprecated, you will have a minimum of 12 months from the date of receiving notice of the change in which to modify your systems. Requests made to deprecated endpoint versions may result in a **400 Bad Request** response after 12 months.\n\n### Release candidates\n\n- Release candidate (RC) versions of this API may be made available to allow partners to preview changes in a non-production (sandbox) environment. When available, RC versions will be announced in this documentation, however these will not be subject to version control and breaking changes may be introduced prior to official release.\n\n### Release criteria\n\n#### Backward-compatible changes\n\nThe following types of change are considered backward-compatible, and will not result in a version release when introduced. Therefore, partners must ensure their implementation can handle such changes gracefully. \n\nThese changes comprise:\n\n - Introduction of new API endpoints\n - Addition of any properties to an endpoint's response schema\n - Addition of non-required properties to an endpoint's request schema\n - Unexpected receipt of an HTTP redirect response code (**301 Moved Permanently** or **302 Found**)\n - Addition of new HTTP methods (POST, GET, PUT, PATCH, DELETE, etc.)\n - Addition of new key values to existing fields that represent a set, insofar as no operating logic is likely to be affected\n\n#### Breaking changes\n\nThe following types of change are considered breaking changes and will result in the release of an incremented version of this software:\n\n - Addition of required properties to an endpoint's request schema\n - Removal of required properties from an endpoint's request or response schemata\n - Changing the data-type or format (e.g., date format) of an existing field in an endpoint's request or response schemata\n - Adding, removing or changing the meaning of the HTTP status codes in an endpoint's response\n - Removing or modifying the **Content-Type** on existing endpoints\n - Modifying or removing field key values in a set\n - Modifying the **operationId** of an endpoint\n\n### Version specification mechanism\n\nIt is mandatory to specify which version of the API you wish to use via the **'Accept' header parameter** in the **request** to each API endpoint; e.g., `Accept: application/json;version=2.0`. Omitting the version parameter will result in a **400 Bad Request** response.\n\n**Example valid request**:\n\n```bash\ncurl --location --request GET 'https://api.sandbox.viator.com/partner/products/modified-since?cursor=MTU5MjM1NTM0MXwxMTM5ODZQNA==' \\\n--header 'exp-api-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' \\\n--header 'Accept-Language: en-US' \\\n--header 'Accept: application/json;version=2.0'\n```\n\n**Example error response**:\n\n```json\n{\n \"code\":\"INVALID_HEADER_VALUE\",\n \"message\":\"Accept header is missing or has invalid version information\",\n \"timestamp\":\"2020-09-02T03:43:23.303946Z\",\n \"trackingId\":\"3D45567E:2D25_0A5D03AB:01BB_5F4F14A5_394639:3DB7\"\n}\n```\n\n## Accept-Encoding\n\nThis API supports gzip compression. Therefore, if you include `gzip` in the `Accept-Encoding` header parameter in the request, the API will respond with a gzip-compressed response.\n\n## Endpoint timeout settings\n\nIf you wish to implement internal timeout settings for calls to this API, **we recommend a setting of 120s**.\n\nThis is due to the fact that some of the products in our inventory rely on the operation of external supplier systems, which we do not control. Because of that, it may take up to 120s to receive a response when making a booking. In rare cases, booking response times in excess of 120s can sometimes occur.\n\nThis means that a booking may have actually succeeded even if the [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook) endpoints time-out or respond with a HTTP 500 error. \n\nTherefore, it is strongly recommended that you check the status of the booking using the [/bookings/status](#operation/bookingsStatus) endpoint to make sure the booking was not created before you attempt to make the booking again.\n\nFurthermore, you can avoid creating duplicate bookings by making sure that you supply the same value for `partnerBookingRef` in the request to [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook) as you did for the booking you believe may have failed. The `partnerBookingRef` value must be unique; therefore, a duplicate booking will not be created.\n\n# Key concepts\n\n## Product content and availability endpoints\n\n### Product content endpoints\n\nYou can retrieve the core product-content details from the following endpoints:\n\n- [/products/{product-code}](#operation/products): Retrieve content for a single product in real time when the product is selected by the customer \n - **Used by**: API partners who do not ingest the product database, but instead get each product's details only when required\n- [/products/modified-since](#operation/productsModifiedSince): Retrieve content for all products with filtering according to modification date \n - **Used by**: API partners who ingest the entire product catalog into a local database and perform regular delta updates via this endpoint to keep their local data in-sync with Viator's\n- [/products/bulk](#operation/productsBulk): Retrieve content for multiple products, as specified in the request. \n - **Please note**: This endpoint **must not** be used for ingestion; rather, it should only be used to retrieve product details for the selected products when needed.\n\n### Availability schedules endpoints\n\nYou can retrieve the availability schedules for products using the following endpoints:\n\n- [/availability/schedules/{product-code}](#operation/availabilitySchedules): Retrieve availability schedules for a single product in real time when the product is selected by the customer.\n - **Used by**: API partners who do not ingest the availability database, but instead get the availability schedules associated with a product at the time that it is required\n- [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince): Retrieve future availability schedules for all products with filtering according to modification date \n - **Used by**: API partners who ingest all availability schedules into a local database and perform regular delta updates via this endpoint to keep their local data in-sync with Viator's\n- [/availability/schedules/bulk](#operation/availabilitySchedulesBulk): Retrieve availability schedules for all products specified in the request.\n - **Please note**: This endpoint **must not** be used for ingestion; rather, it should only be used to retrieve the availability schedules for the selected products when needed.\n\n## Product options\n\nAny particular product may consist of a number of variants, each of which is referred to as a 'product option'. In previous versions of this API, and in the tours and activities sector in general, product options are also referred to as 'tour grades'.\n\nFor example, product options might represent different departure times, tour routes, or packaged extras like additional meals, transport and so forth.\n\nThe product options available for a product can be found in the `productOptions` array in the responses from any of the [product content endpoints](#section/Key-concepts/Product-content-and-availability-endpoints).\n\nWhen a product option includes an optional `logistics` object, use that object for start and end points and traveler pickup behaviour for that option; when it is absent, use the product-level `logistics` object instead.\n \nAn example `productOptions` array for the product **5010SYDNEY** is as follows:\n\n```json\n\"productOptions\": [\n {\n \"productOptionCode\": \"48HOUR\",\n \"description\": \"Duration: 2 days: FREE BONUS ENTRY to Sydney Tower with every Deluxe ticket end 31st March
48 Hour Premium Ticket: Unlimited use on Big Bus Sydney & Bondi Tour for 48 hours from time of first use PLUS a guided walking tour of The Rocks, Syd\",\n \"title\": \"48 Hour Premium Ticket \",\n \"languageGuides\": [...]\n },\n {\n \"productOptionCode\": \"TG1\",\n \"description\": \"Hop-on Hop-Off and Attractions: 48hr Big Bus Tours, 1-day Hop-On Hop-Off Harbour Cruise, 4 Attractions: Tower Eye, Madame Tussauds, Wildlife Zoo, Aquarium
Duration: 2 days
Complimentary Walking Tours: Complimentary English-speaking guided walking tour of “The Rocks” historic and harbourside precinct.\",\n \"title\": \"48Hour Deluxe PLUS Attractions\",\n \"languageGuides\": [...]\n },\n {\n \"productOptionCode\": \"24HOUR\",\n \"description\": \"Unlimited use on Big Bus Sydney & Bondi Hop-on Hop-off Tour for 24 hours from time of first use\",\n \"title\": \"24 Hour Classic Ticket \",\n \"languageGuides\": [...]\n },\n {\n \"productOptionCode\": \"DELUXE\",\n \"description\": \"Big Bus and Habour Cruise: Combine two great Sydney experiences into one with a hop-on hop off Big Bus Tours and a hop-on hop-off Sydney Harbour cruise
Duration: 2 days: FREE BONUS ENTRY to Sydney Tower with every Deluxe ticket end 31st March
Complimentary Walking Tour: Complimentary English-speaking 90-minute guided walking tour of “The Rocks” historic and harbourside precinct.\",\n \"title\": \"48 Hour Deluxe Bus and Cruise\",\n \"languageGuides\": [...]\n }\n]\n```\n\nThis product has four product options, each with an identifying code given in the `productOptionCode` field:\n\n- `\"48HOUR\"`\n- `\"TG1\"`\n- `\"24HOUR\"`\n- `\"DELUXE\"`\n\nProduct options are essentially a subcategory of the tour or activity. You will need to specify the product option you wish to book when making a booking.\n\n\n**Note on `DEFAULT` productOptionCodes:**\n\nPreviously, `DEFAULT` productOptionCodes were treated differently from other tour grades and were omitted from requests/responses when only one “DEFAULT” tour grade was present. This special treatment has been removed. All tour grades can be handled consistently. For backward compatibility, `DEFAULT` codes can still be omitted from some requests, but it is recommended to avoid this practice.\n\n\n## Availability schedules\n\nThe [availability schedules endpoints](#section/Key-concepts/Product-content-and-availability-endpoints) provide information about the availability of a product (along with its various product options and starting times, if they exist) and its pricing in the supplier's currency.\n\nThis section explains how to interpret the response from the [availability schedules endpoints](#section/Key-concepts/Product-content-and-availability-endpoints).\n\nExample response snippet from [/availability/schedules/10212P2](#operation/availabilitySchedules) (some starting times were removed for brevity):\n\n```json\n{\n \"productCode\": \"10212P2\",\n \"bookableItems\": [\n {\n \"productOptionCode\": \"TG45\",\n \"seasons\": [\n {\n \"startDate\": \"2019-05-01\",\n \"endDate\": \"2021-12-31\",\n \"pricingRecords\": [\n {\n \"daysOfWeek\": [\n \"MONDAY\",\n \"TUESDAY\",\n \"WEDNESDAY\",\n \"THURSDAY\",\n \"FRIDAY\",\n \"SATURDAY\",\n \"SUNDAY\"\n ],\n \"timedEntries\": [\n {\n \"startTime\": \"11:00\",\n \"unavailableDates\": [\n {\n \"date\": \"2020-09-16\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-23\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-22\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-27\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-29\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-30\",\n \"reason\": \"SOLD_OUT\"\n }\n ]\n },\n {\n \"startTime\": \"10:00\",\n \"unavailableDates\": [\n {\n \"date\": \"2020-09-25\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-26\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-28\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-27\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-30\",\n \"reason\": \"SOLD_OUT\"\n },\n {\n \"date\": \"2020-09-29\",\n \"reason\": \"SOLD_OUT\"\n }\n ]\n },\n {...}\n ],\n \"pricingDetails\": [\n {\n \"pricingPackageType\": \"PER_PERSON\",\n \"minTravelers\": 1,\n \"ageBand\": \"INFANT\",\n \"price\": {\n \"original\": {\n \"recommendedRetailPrice\": 0.00,\n \"partnerNetPrice\": 0.00,\n \"bookingFee\": 0.00,\n \"partnerTotalPrice\": 0.00\n }\n }\n },\n {\n \"pricingPackageType\": \"PER_PERSON\",\n \"minTravelers\": 1,\n \"ageBand\": \"ADULT\",\n \"price\": {\n \"original\": {\n \"recommendedRetailPrice\": 100.02,\n \"partnerNetPrice\": 79.89,\n \"bookingFee\": 4.79,\n \"partnerTotalPrice\": 84.68\n },\n \"special\": {\n \"recommendedRetailPrice\": 90.02,\n \"partnerNetPrice\": 71.90,\n \"bookingFee\": 4.31,\n \"partnerTotalPrice\": 76.21,\n \"offerStartDate\": \"2020-08-28\",\n \"offerEndDate\": \"2020-09-30\"\n }\n }\n }\n ]\n }\n ]\n }\n ]\n }\n ],\n \"currency\": \"USD\",\n \"summary\": {\n \"fromPrice\": 100.02\n }\n}\n```\n\n- Each item in the `bookableItems[]` array contains the availability and pricing data for one of the product's product-options (`productOptionCode`).\n- Each item in the `seasons[]` array describes the availability and pricing for the product-option during the 'season' (period of time) delimited by `startDate` and `endDate`. If `endDate` is not present, this means the season extends 384 days (approximately 12.5 months) into the future from the current date.\n- Each item in the `pricingRecords[]` array describes which days of the week (`daysOfWeek[]`) the availability and pricing data pertains to during the season, as well as which starting times are in operation (`timedEntries[]`) and on which dates (`unavailableDates[]`) each starting time is unavailable (e.g., due to being sold out).\n- Each item in the `pricingDetails[]` array describes the pricing that applies to each age-band during the season.\n\n### Interpreting the availability schedule\n\nWe can thereby interpret the availability schedule snippet above as follows:\n\n- For the product-option code `\"TG45\"` of product `\"10212P2\"`, during the period from `\"2019-05-01\"` to `\"2021-12-31\"`, on **all days of the week**, there are starting times at **10:00** and **11:00**.\n- The **11:00** starting time is unavailable due to being 'sold out' on the following dates:\n - 2020-09-16\n - 2020-09-22\n - 2020-09-23\n - 2020-09-27\n - 2020-09-29\n - 2020-09-30\n- The **10:00** starting time is unavailable due to being 'sold out' on the following dates:\n - 2020-09-25\n - 2020-09-26\n - 2020-09-27\n - 2020-09-28\n - 2020-09-29\n - 2020-09-30\n- Infant tickets are free (USD 0)\n- Adults are charged per-person; the normal recommended retail price (`original`) is USD 100.02\n- A **pricing special** (`special`) is in effect for adults between 2020-08-28 and 2020-09-30; the special recommended retail price is USD 90.02 \n\nUsing this information, a complete schedule – including which product-codes and starting times are available on which dates and the pricing (including special discounts) that applies on each date - can be constructed in your database.\n\n## Itineraries\n\nThe itinerary for a product is used to communicate to customers what to expect with regard to where they will go when participating in the tour or activity. On the [Viator.com website](https://viator.com), this information is displayed in the **What to expect** section on each product's product display page.\n\nItinerary information is available from this API in a machine-interpretable, structured format that facilitates graphical display and advanced search, should you choose to implement it.\n\nThe itinerary information for each product is contained in the `itinerary` object in the response from any of the [product content endpoints](#section/Key-concepts/Product-content-and-availability-endpoints).\n\nThere are five types of itinerary, and the type is specified in the `itinerary.itineraryType` field. They are as follows:\n\n| Itinerary type | `itineraryType` | Meaning |\n|----------------|-----------------------|---------|\n| **Standard** | `\"STANDARD\"` | A tour-based product (focused on visiting and viewing) that occurs at a single location or proceeds through a set of locations on a single day. |\n| **Activity** | `\"ACTIVITY\"` | An activity-based product (focused on the activity rather than the location) that occurs at a single location or proceeds through a set of locations on a single day |\n| **Multi-day tour** | `\"MULTI_DAY_TOUR\"` | A tour or activity that occurs over multiple days, and therefore includes food and accommodation |\n| **Hop-on / hop-off** | `\"HOP_ON_HOP_OFF\"` | A tour that operates continuously, such as a bus tour, wherein passengers can use their ticket to board and alight as they please at any of the stops along the route |\n| **Unstructured** | `\"UNSTRUCTURED\"` | Not all suppliers have upgraded the itinerary information for their products from a text-based description to structured data; therefore, the itinerary information for a small number of products remains unparseable for the time being. | \n\n### Common elements\n\nThe `itinerary` object is polymorphic depending on the `itineraryType`, but all variants contain standard information, as follows:\n\n| Field name | Meaning |\n|------------|---------|\n| `skipTheLine` | `true` if a ticket for this product allows participants to attend a location without having to obtain a separate ticket on the occasion itself |\n| `privateTour` | `true` if only the travelers who have booked this product will be present; `false` if it is a shared tour |\n| `maxTravelersInSharedTour` | If `privateTour` is `false`, this value represents the maximum number of people that will be able to participate in the tour or activity. |\n| `unstructuredDescription` | In the event that structured information is not available, this field will contain a plain-text description of the itinerary. |\n\nAll other elements in the `itinerary` object differ slightly according to the value of `itineraryType`.\n\n### Standard itinerary\n\nProducts with a `\"STANDARD\"` itinerary type are tour-based products (focused on visiting and viewing) that occur at a single location or proceed through a set of locations on a single day.\n\nAn example of a `\"STANDARD\"` itinerary product is [Barossa Valley Highlights from Barossa Valley Including Wine and Cheese Tasting (21381P1)](https://www.viator.com/tours/Barossa-Valley/Barossa-Valley-Highlights-from-Adelaide-or-Barossa-Valley-Including-Wine-and-Cheese-Tasting/d5623-21381P1).\n\nThe `itinerary` object in the product-content response for this tour is as follows (truncated to the first three items for brevity):\n\n```json\n\"itinerary\": {\n \"itineraryType\": \"STANDARD\",\n \"skipTheLine\": false,\n \"duration\": {\n \"fixedDurationInMinutes\": 360\n },\n \"itineraryItems\": [\n {\n \"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-5620ab70-c813-4904-ad13-bcf527540d3e\"\n },\n \"attractionId\": 17873\n },\n \"duration\": {\n \"fixedDurationInMinutes\": 45\n },\n \"passByWithoutStopping\": false,\n \"admissionIncluded\": \"YES\",\n \"description\": \"Guests will experience the majesty of (...) \"\n },\n {\n \"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-7ae41705-fd91-4500-8cde-bbe9b3a00df4\"\n }\n },\n \"duration\": {\n \"fixedDurationInMinutes\": 40\n },\n \"passByWithoutStopping\": false,\n \"admissionIncluded\": \"YES\",\n \"description\": \"Guests will enjoy a truly unique offering (...)\"\n },\n {\n \"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-9494c4cf-f4e4-4e7f-8213-0cf1b9980097\"\n }\n },\n \"duration\": {\n \"fixedDurationInMinutes\": 30\n },\n \"passByWithoutStopping\": false,\n \"admissionIncluded\": \"YES\",\n \"description\": \"No trip to the Barossa would be complete without (...)\"\n }\n (...)\n ]\n}\n```\nThe `itineraryItems[]` array describes the itinerary of locations for this tour and can be used in conjunction with the [/locations/bulk](#operation/locationsBulk) endpoint to contruct a **What to expect** section, similar to what is seen for this product on [viator.com](https://www.viator.com/tours/Barossa-Valley/Barossa-Valley-Highlights-from-Adelaide-or-Barossa-Valley-Including-Wine-and-Cheese-Tasting/d5623-21381P1), as in the following screen-shot:\n\n
\n \"Standard\n
Standard itinerary example from viator.com
\n
\n\nThe elements highlighted in red boxes are sourced as follows:\n\n**\"Stop At: Seppeltsfield\"**\n\nThe name of each location (in the highlighted case, 'Seppeltsfield') is not included in the response and must be determined by submitting the location reference code in the `pointOfInterestLocation.location.ref` field to the [/locations/bulk](#operation/locationsBulk) endpoint.\n\nThe location reference is `\"LOC-5620ab70-c813-4904-ad13-bcf527540d3e\"`:\n\n```json\n\"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-5620ab70-c813-4904-ad13-bcf527540d3e\"\n}\n```\n\nSubmitting this code to the [/locations/bulk](#operation/locationsBulk) endpoint yields the following response:\n\n```json\n{\n \"locations\": [\n {\n \"provider\": \"TRIPADVISOR\",\n \"reference\": \"LOC-5620ab70-c813-4904-ad13-bcf527540d3e\",\n \"name\": \"Seppeltsfield\",\n \"address\": {\n \"street\": \"730 Seppeltsfield Rd\",\n \"administrativeArea\": \"Seppeltsfield\",\n \"state\": \"South Australia\",\n \"country\": \"Australia\",\n \"countryCode\": \"AU\",\n \"postcode\": \"5355\"\n },\n \"center\": {\n \"latitude\": -34.489162,\n \"longitude\": 138.91866\n }\n }\n ]\n}\n```\n\nThe name of the location is in the `name` element; i.e., `\"Seppeltsfield\"`.\n\n**Description**\n\nThe description for each itinerary stop is given in the `description` field; in this case:\n\n```json\n\"description\": \"Guests will experience the majesty of the Seppeltsfield Winery Estate, an historic icon of the Barossa and integral part of its storied history. Learn the story of the Seppelt family, the phenomenal fortified wines upon which they have built their reputation and taste a broad range of their current wine offerings. Don’t forget to ask about the Centennial collection, the only wine collection of wines of its type in the world with more than 120 years of consecutive vintages currently stored in the barrel. \"\n```\n\n**\"Duration: 45 minutes\"**\n\nThe duration spent at an itinerary location is given in the `duration` element. This can be a fixed duration, as in this example and indicated by the `fixedDurationInMinutes` field being filled; i.e.:\n\n```json\n\"duration\": {\n \"fixedDurationInMinutes\": 45\n},\n```\n\nOr, the time spent at the location might be variable, in which case only the `variableDurationFromMinutes` and `variableDurationToMinutes` fields will appear; e.g.:\n\n```json\n\"duration\": {\n \"variableDurationFromMinutes\": 10,\n \"variableDurationToMinutes\": 30\n},\n```\n\n**\"Admission Ticket Included\"**\n\nThis item of information indicates to the traveler whether or not they will be required to pay for admission to a location or whether admission is included in the price of the tour. It is indicated by the `admissionIncluded` field; which in this case is:\n\n```json\n \"admissionIncluded\": \"YES\"\n```\nThe possible values this field can take are:\n- `\"YES\"`\n- `\"NO\"`\n- `\"NOT_APPLICABLE\"`\n\n**Pass by without stopping**\n\nIn this example, the `passByWithoutStopping` element is `false` for all locations. On some tours, however, the vehicle will merely pass by a certain location, without stopping, for viewing purposes. If that is the case, this field will be `true`.\n\n### Activity itinerary\n\nThe \"activity\" itinerary is designed for products where the focus of the experience is the activity itself (e.g., cooking classes), rather than the location(s) at which it occurs.\n\nThe `itinerary` object for this type of product includes the `activityInfo` and `foodMenus` objects, which contain details about the activity and any meals being served (or created), respectively.\n\n**Example activity experience**: [Traditional Cooking Class - 114869P3](https://www.viator.com/tours/Yogyakarta/Traditional-Cooking-Class/d22560-114869P3)\n\n```json\n\"itinerary\": {\n \"itineraryType\": \"ACTIVITY\",\n \"skipTheLine\": false,\n \"privateTour\": true,\n \"duration\": {\n \"fixedDurationInMinutes\": 240\n },\n \"pointsOfInterest\": [\n {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5C7cXoFi13Pb8aiiiEWiVprM1MtQdt/DIeeb7ErQo1SK\"\n }\n ],\n \"activityInfo\": {\n \"location\": {\n \"ref\": \"LOC-dwbUKYXwDvt911EeSQVjwo4itqM47D/JrJBMhEHXctp6Yj8SzOvLCGbeQQ0arbNw8FHTuTEi0SU9RbKNpLx7bw8HP6Pnh1pBwy27irN3vKoTexOgxSlj2+xv9x3k6fZnPrb/zhY5RImUibPpbTET/+atZD8crT0DlPf5hg21QPWNam1RsZKgzF5gb1fPZ6d7WNWIWYsu3m54y2TFqiHaAbo1d2Ps2LFK+DCctmyDmqbgSV7FDpLXv5sL/e0R/Mg+7vLX0lMV8HGW4jisRxqYD5oThATP9j1NRY98SvhXpEI=\"\n },\n \"description\": \"Embark on a culinary adventure unlocking the secrets of authentic Javanese cooking, utilizing traditional ingredients and preparation methods.\\nYour day starts early at the local markets, where you can pick from fresh herbs & spices, crisp vegetables and choice cuts of meat. \\nAfter exploring at the traditional market, you will be warmly welcomed and expertly guided by your host, who will help you to discover how to create your very own delicious authentic Javanese dishes. \\nYour hard work is rewarded when you sit down to have lunch on your tasty creations.\\nAll classes are conducted in English by Javanese chefs fully conversant with Javanese cuisine and culture...and in a relaxed, friendly atmosphere in the beautiful kitchen-garden.\"\n },\n \"foodMenus\": [\n {\n \"course\": \"MAIN\",\n \"dishName\": \"Gado-gado\",\n \"dishDescription\": \"Mixed vegetables with peanut sauce\"\n },\n {\n \"course\": \"MAIN\",\n \"dishName\": \"Opor Ayam\",\n \"dishDescription\": \"Braised Chicken in Coconut Milk\"\n }\n ]\n}\n```\n\nAll information for the 'What to Expect' section on the product display page on Viator.com is can be sourced from this object.\n\n### Multi-day tour itinerary\n\nProducts with a `\"MULTI_DAY_TOUR\"` itinerary type are tours or activities that occur over multiple days, and therefore include a breakdown of the itinerary for each day of the tour, as well as extra information about food and accommodation.\n\n**Example multi-day tour**: [Active Winter Adventure in Yukon | 5 days (7110P7)](https://www.viator.com/tours/Whitehorse/5-Day-Active-Winter-Adventure-in-Yukon/d5420-7110P7)\n\nScreenshot of 'What to expect' section from the viator.com site:\n\n
\n \"Multi-day\n
Multi-day tour itinerary example from viator.com
\n
\n\nSnippet of the `itinerary` object in the product content response for 7110P7 (truncated to first two items of `days[]` array):\n\n```json\n\"itinerary\": {\n \"itineraryType\": \"MULTI_DAY_TOUR\",\n \"skipTheLine\": false,\n \"duration\": {\n \"fixedDurationInMinutes\": 7200\n },\n \"days\": [\n {\n \"title\": \"Arrival Whitehorse\",\n \"dayNumber\": 1,\n \"items\": [\n {\n \"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-99b0f435-fa6a-469f-8f96-f983b82f74c5\"\n }\n },\n \"duration\": {},\n \"admissionIncluded\": \"NOT_APPLICABLE\",\n \"description\": \"From the airport we drive you to your hotel located in the centre of Whitehorse.\"\n }\n ],\n \"accommodations\": [\n {\n \"description\": \"Overnight in downtown Whitehorse Hotel\"\n }\n ]\n },\n {\n \"title\": \"Wildlife and Hot Springs, a Bird's-Eye-View and Northern Lights\",\n \"dayNumber\": 2,\n \"items\": [\n {\n \"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-799e6c90-d0bb-4ec4-9cf6-c40459ff0463\"\n },\n \"attractionId\": 25942\n },\n \"duration\": {\n \"fixedDurationInMinutes\": 90\n },\n \"admissionIncluded\": \"YES\",\n \"description\": \"Later we drive to the Yukon Wildlife Preserve where we can see up close inhabitant game like the Elk, Moose, Caribou, Mountain Goats and Porcupines in their natural surrounding.\"\n },\n {\n \"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-cf8d0f7a-54d6-4cc1-9911-480b4934c752\"\n },\n \"attractionId\": 25951\n },\n \"duration\": {\n \"fixedDurationInMinutes\": 90\n },\n \"admissionIncluded\": \"YES\",\n \"description\": \"Not far from here we will visit the Takhini Hotsprings and endulge ourself in the natural hot waters and relax in a breathtaking winter mountain setting.\"\n },\n {\n \"pointOfInterestLocation\": {\n \"location\": {\n \"ref\": \"LOC-3251a39d-aa69-4229-9ba4-57d5b417e6db\"\n }\n },\n \"duration\": {\n \"fixedDurationInMinutes\": 240\n },\n \"admissionIncluded\": \"YES\",\n \"description\": \"After a relaxed dinner in Whitehorse, you’ll be back on the road again, this time to seek views of the stunning Northern Lights. Relax in sheltered comfort, or under the starry sky beside a warm fire at one of our tailor-made aurora viewing locations. \"\n }\n ],\n \"accommodations\": [\n {\n \"description\": \"Overnight in downtown Whitehorse Hotel\"\n }\n ]\n },\n (...)\n ]\n}\n```\n\nWithin the `days[]` array, each day of the multi-day tour is described. The `items[]` array within each item of the `days[]` array largely follows the structure of the items in the `itineraryItems[]` array of the `\"STANDARD\"` itinerary and can be interpreted for display.\n\nThe `fixedDurationInMinutes` in the `itinerary[]` array represents the total duration of the tour. \n\n**Note**: The example above does not include the `foodAndDrinks[]` element, as it is not relevant to this product.\n\n### Hop-on / hop off itinerary\n\nA hop-on/hop-off product is one that typically operates continuously during its hours of operation, such as a bus tour, and passengers can use their ticket to board and alight as they please at any of the stops along the route.\n\nSuch products may also operate multiple routes simultaneously.\n\n**Example hop-on / hop-off tour**:[Big Bus Sydney and Bondi Hop-on Hop-off Tour (5010SYDNEY)](https://www.viator.com/tours/Sydney/Sydney-and-Bondi-Hop-on-Hop-off-Tour/d357-5010SYDNEY)\n\n
\n \"Hop-on\n
Hop-on / hop-off itinerary example from viator.com
\n
\n\nSnippet of `itinerary` object in the product content response for 5010SYDNEY (`operatingSchedule`, `stops` and `pointsOfInterest` truncated in first route):\n\n```json\n\"itinerary\": {\n \"itineraryType\": \"HOP_ON_HOP_OFF\",\n \"skipTheLine\": false,\n \"privateTour\": false,\n \"duration\": {\n \"fixedDurationInMinutes\": 120\n }, \n \"routes\": [\n {\n \"operatingSchedule\": \"1st bus departs from Stop 1 Circular Quay at 9.00am.. (...)\",\n \"duration\": {\n \"fixedDurationInMinutes\": 120\n },\n \"name\": \"Red Route - Sydney Icons\",\n \"stops\": [...],\n \"pointsOfInterest\": [...]\n ]\n },\n {\n \"operatingSchedule\": \"1st bus departs from Stop 12/24 Central Station at 10.00am.\\nFrequency every 60 minutes\\nLast bus departs from stop 12/24 at 4.00pm\",\n \"duration\": {\n \"fixedDurationInMinutes\": 120\n },\n \"name\": \"Blue Route - Bondi Lifestyle\",\n \"stops\": [\n {\n \"stopLocation\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5Psa0O7zv6as2RgNgIaUx0EFjKH/7fL3wV6nAS8iPXkO\"\n },\n \"description\": \"Central Station, Pitt Street, Bus Bay 18\"\n },\n {\n \"stopLocation\": {\n \"ref\": \"LOC-RaYlfRSLaIsd0SlazqDQk19G5f6qNrg0gjGUG4TKX09ebeQFQmF/tcZGYdP+hZ8qHiX/vcPkkKKpDcocShqAYEgNFI1CfF3En+N9VrOAxKQUrgoRQ1Va78q0+ItmaNr/WbsMTE8jgepUMa6GSjKvLkRhjHJbm/8KZDt9vri/bomquCnoZMFCjkrjxqrlpEp5m2qWwkCxg5iRffRLuhG/YQ==\"\n },\n \"description\": \"Australian Museum \"\n },\n {\n \"stopLocation\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5Nh4BzPY4JhOxIuD4/Do8pUJ7t+9MCl62rbq6KVnaek/\"\n },\n \"description\": \"\"\n },\n {\n \"stopLocation\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5HyrAalNU3M4hS1T1NGhMtCdFsSEh+RkFpJBmFZX9No8\"\n },\n \"description\": \"\"\n },\n {\n \"stopLocation\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5ADNeEAMR25x+3AtosA/mPk102O66T1JygFmomnS5cve\"\n },\n \"description\": \"\"\n },\n {\n \"stopLocation\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5DlsAklW6JtKr4LQsnhsvv7JxEYbLQWAsKDqTrCu41p4\"\n },\n \"description\": \"\"\n },\n {\n \"stopLocation\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5BLsCa3M6INxXNpkE2r1BTHxvB0gY1MP6WB9Yxso16Ot\"\n },\n \"description\": \"\"\n },\n {\n \"stopLocation\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5PrdhQ/J96Gq+dweFD3sOSrkBFH5QSJjP1VJ0a/86OPO\"\n },\n \"description\": \"\"\n }\n ],\n \"pointsOfInterest\": [\n {\n \"location\": {\n \"ref\": \"LOC-6eKJ+or5y8o99Qw0C8xWyIiKlXuqcCaUR/8Ng7CZSLI=\"\n },\n \"attractionId\": 14159\n },\n {\n \"location\": {\n \"ref\": \"LOC-6eKJ+or5y8o99Qw0C8xWyOEUrjaNrfQuPK4sfYmEGio=\"\n }\n },\n {\n \"location\": {\n \"ref\": \"LOC-6eKJ+or5y8o99Qw0C8xWyPTry/4ZvItH2jj+ziZ16zY=\"\n }\n },\n {\n \"location\": {\n \"ref\": \"LOC-6eKJ+or5y8o99Qw0C8xWyCs+n26oP6pvXz2mRpQ6QlA=\"\n }\n },\n {\n \"location\": {\n \"ref\": \"LOC-6eKJ+or5y8o99Qw0C8xWyI5+u+JgfxCzNB+Yaph1xug=\"\n }\n }\n ]\n }\n ]\n}\n```\n\nBy comparing the response snippet with the screenshot above, you can see that:\n\n- There are two routes – \"Red Route - Sydney Icons\" and \"Blue Route - Bondi Lifestyle\"\n- The Blue Route has 8 stops and 5 points of interest\n- Only the first two stops on the Blue Route have descriptive text entered by the supplier, as seen in the screenshot and in the snippet (`description` field)\n\nAll location details (including the name) must be retrieved by sending the location reference to the [/locations/bulk](#operation/locationsBulk) endpoint. \n\nThe total duration of the tour can be found in the `itinerary[]` array. \nIf all tour routes have the same duration, the `fixedDurationInMinutes` field will be returned. \nWhen tour routes have different duration, only the `variableDurationFromMinutes` and `variableDurationToMinutes` fields will appear.\n\n### Unstructured itinerary\n\nAlthough our systems have been upgraded to support structured itinerary information, this feature is only availabe once the supplier manually updates their product details. A small number of suppliers have not yet made these updates. As such, some products retain their legacy itinerary information, and this case is handled with the `\"UNSTRUCTURED\"` itinerary type.\n\nSnippet of `itinerary` object in the product content response for [5524GOLD - Private Tour: 4-Day Golden Triangle Trip to Agra and Jaipur from Delhi](https://www.viator.com/tours/New-Delhi/Private-Tour-4-Day-Golden-Triangle-Trip-to-Agra-and-Jaipur-from-Delhi/d804-5524GOLD):\n\n```json\n\"itinerary\": {\n \"itineraryType\": \"UNSTRUCTURED\",\n \"skipTheLine\": false,\n \"privateTour\": false,\n \"unstructuredDescription\": \"Please read the Itinerary section for details on your Golden Triangle tour from Delhi to Agra and Jaipur.\",\n \"unstructuredItinerary\": \" Day 1: Delhi – AgraMorning departure from your hotel in Delhi. Traveling in the comfort your own air-conditioned vehicle, accompanied by a driver, the journey to Agra will take approximately four to five hours. Upon arrival in Agra, check in at your hotel. In Agra, your local guide who will take you to visit the famous and majestic Red Agra Fort, followed by the romantic Taj Mahal at sunset. The remainder of the evening is free for your own personal exploration.\\n\\nOvernight: 3- or 4-star hotel in Agra\\n\\nDay 2: Agra – Jaipur (B)After breakfast, travel by road to Fatehpur Sikri, located approximately 40 kilometers from Agra. Fatehpur Sikri was the capital of the Mughal Empire between 1571 and 1585 during the reign of Akbar. Continue to the 'pink city' of Jaipur. The rest of your day is free for your own exploration of Jaipur's action packed streets and magnificent palaces. Jaipur is a shopper's paradise. There is an amazing range of crafts available, and Jaipur is also famous for its precious and semi-precious stones. \\n\\nOvernight: 3- or 4-star hotel in Jaipur\\n\\nDay 3: Jaipur (B)After breakfast, visit Amber Fort located 12 kilometers from Jaipur. The magnificent Amber Fort is a fine blend of Hindu and Muslim architecture. Return to Jaipur and visit the City Palace, situated in the heart of Jaipur's old city. The palace is a blend of Rajput and Mughal architecture; it houses a 7-storied Chandra Mahal in the center. Also visit Hawa Mahal (Palace of Winds), Jaipur's most distinctive landmark. Built in 1799, this is an amazing example of Rajput architecture.\\n\\nOvernight: 3- or 4-star hotel in Jaipur\\n\\nDay 4: Jaipur – Delhi (B)After breakfast, travel back to your Delhi hotel or the airport.\",\n \"duration\": {\n \"fixedDurationInMinutes\": 5760\n },\n \"pointOfInterestLocations\": [\n {\n \"location\": {\n \"ref\": \"LOC-6eKJ+or5y8o99Qw0C8xWyJUIMZqLxZiFQx5hWjqMeXg=\"\n }\n }\n ]\n},\n```\n\nUse the `unstructuredDescription` and `unstructuredItinerary` fields to create the section on your site that corresponds to the **What to expect** section on the Viator product display page. Note that the `unstructuredItinerary` field is not always populated – in that case, just use the `unstructuredDescription` field.\n\nAll products with an `\"UNSTRUCTURED\"` itinerary type are in the process of being updated to the appropriate structured type. Eventually, all products will support structured itinerary information.\n\n## Protecting unique content\n\nIn order to prevent our unique content from being utilized by unauthorized third parties, we require that you design your site in such a way that this content will not be indexed by search engines.\n\nThe content that must be protected comprises:\n\n- **Product reviews** – This includes all review text (from any provider) as obtained via the [/reviews/product](#operation/reviewsProduct) endpoint; and, that in the `reviews` element in the product content response. \n- **Viator unique content** – This includes all data in all elements within the `viatorUniqueContent` element in the product content response.\n\n### Guidelines to prevent indexing of unique content\n\nIn order to properly protect reviews and other unique content, you must ensure that the protected content **never** appears directly in the source code of the loaded page. This includes both HTML and Javascript.\n\nIn order to do this correctly, the unique content must be loaded via a call to an **external** Javascript, and that Javascript must be blocked in [robots.txt](https://moz.com/learn/seo/robotstxt) so that search engines can not see or index it.\n\n### How to check\n\nA simple way to check that the unique content does not appear in the source code of the loaded page – and, therefore, cannot be indexed – is to copy a snippet of the unique content text that is displayed when you load the page normally in your browser. Approximately 10 words will suffice.\n\nThen, access the source code of that page using the **View Source** feature in your browser. Use your browser's in-page search feature to search for the text snippet copied in the previous step. If the text is found anywhere in the source code of the page, then your implementation is **not** correctly protecting the content, as it will be able to be indexed by search enginges. \n\n### Example implementations\n\n❌ **Unacceptable implementation**: pure HTML\n\nHere the protected content appears directly in the HTML and can be indexed by search engines:\n\n```html\n\n \n \n \n
”I had a great time at this hotel”
\n \n\n```\n\n❌ **Unacceptable implementation**: Javascript in the page source\n\nHere, the protected content still appears in the page source, even though it is in the 'script' section, and will therefore be indexed by search engines:\n\n\n```html\n\n \n \n \n \n
\n \n\n```\n\n✅ **Acceptable implementation:** protected content is loaded using an **external** Javascript and access to that endpoint is blocked using robots.txt:\n\n```html\n\n \n \n \n \n
\n \n\n```\n\nRobots.txt in the document root for `https://api.hello.xyz`:\n\n```bash\nUser-Agent: *\nDisallow: /getReviewContentForHotel\n```\n\n**Note**: The robots.txt file must be in the root directory for whichever domain or subdomain the call is being made to. Please review the [robots.txt guidelines](https://developers.google.com/search/docs/advanced/robots/create-robots-txt) to determine the correct syntax for your site.\n\n## Review authenticity\n\n### Viator performs checks on reviews\n\nYou can only submit a review or rating of an experience to Viator if you were the person who made the booking through Viator. Before publication, each review goes through an automated tracking system, which collects information for each of the following criteria: who, what, how, and when. \n\nIf the system detects something that contradicts our publication criteria, the review is not published. When the system detects a problem with a review, it may be automatically rejected, sent to the reviewer for validation, or manually reviewed by our team of content specialists who work 24/7 to maintain the quality of the reviews on our site. In some cases, we will also send Viator customers an email asking them to validate their review before it is published.

All Viator customers need to do is to click on the link provided in the email. \n\nAfter publication, our team checks each review reported to it as not meeting our publication criteria. Tripadvisor reviews that appear on the Viator site are subject to the same checks and moderation processes as set out above. It is not necessary to have booked an experience through Viator (or Tripadvisor) to submit a review of an experience to the Tripadvisor site.\n\n# Booking concepts\n\n## Working with age bands\n\n### Why have age bands?\n\nTour and experience product suppliers can set different prices for (and impose different rules on) customers according to how old they are. \n\nFor example, suppliers might choose to charge people 18 years and older ('adults') the full ticket price, while 'children' can book at a lower price. \n\nOr, the tour operator may only allow children to make a group booking for the tour so long as the group contains 'at least one adult'.\n\nViator provides six age-band categories that product suppliers can use to segregate travelers into age groups (the limits of which they also define) in order to set pricing and traveler-count participation rules for their product according to the age band categories.\n\nThe age-bands available for a particular product, such as *adult*, *child*, *infant*, etc., are returned by the [/products/{product-code}](#operation/products) service. Your customer should be able to select a different number of people from each available age-band during the price check and checkout process.\n\nTo learn more about how to implement age bands, see the following guide: [Implementing age bands & pax mix](https://partnerresources.viator.com/travel-commerce/merchant/agebands-pax-mix?source=specs)\n\n### Age-band categories\n\nThe age bands supported by the Viator API are as follows:\n\n| bandId | Description |\n|------:|-------|\n| `\"ADULT\"` | Adult |\n| `\"CHILD\"` | Child |\n| `\"INFANT\"` | Infant |\n| `\"YOUTH\"` | Youth |\n| `\"SENIOR\"` | Senior |\n| `\"TRAVELER`\" | Catch-all age-band for unit-priced products |\n\nNote that the `\"TRAVELER\"` is only used for bookings with [unit pricing](#section/Booking-concepts/Per-person-and-unit-pricing), in which case it will be the only age-band available.\n\nThe exact age range to which each category pertains is defined by the supplier, and the maximum and minimum ages that each age band describes for each product can be found in the product content response; e.g.:\n\n```json\n\"ageBands\": [\n {\n \"ageBand\": \"INFANT\",\n \"startAge\": 0,\n \"endAge\": 2,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 15\n },\n {\n \"ageBand\": \"CHILD\",\n \"startAge\": 3,\n \"endAge\": 11,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 15\n },\n {\n \"ageBand\": \"ADULT\",\n \"startAge\": 12,\n \"endAge\": 80,\n \"minTravelersPerBooking\": 1,\n \"maxTravelersPerBooking\": 15\n }\n]\n\n```\n\nFor this product, the age bands have been defined as follows:\n\n| `ageBand` | `ageFrom` | `ageTo` |\n|:--------:|:-------:|:-----:|\n| ADULT | 13 | 64 |\n| SENIOR | 65 | 99 |\n| CHILD | 4 | 12 |\n\n\nProduct suppliers must define at least one age band for their tour, and there are no 'default' age ranges. Therefore, if the supplier has only specified a single 'adult' age band covering ages 18-99, it must be assumed that only people aged 18-99 are eligible to book the tour, essentially excluding children and centenarians in this case.\n\n### When you will use age-bands\n\nThe age-band of a customer needs to be communicated via the API in the following situations:\n\n1. When placing a booking-hold\n - you will need to supply the age-band of each of the travelers being booked for in the `paxMix` element in the request to [/bookings/hold](#operation/bookingsHold) or [/bookings/cart/hold](#operation/bookingsCartHold).\n2. When making a booking \n - As with the booking hold, age-bands must be supplied in the `paxMix` element \n - If the supplier has specified `\"AGEBAND\"` as a booking question, you must additionally provide these details in the `bookingQuestionAnswers` array in the request to [/bookings/book](#operation/bookingBook) or [/bookings/cart/book](#operation/bookingsCartBook). Note that these details are verified by the booking server and the booking will be rejected if the details do not match. For more information about answering the `\"AGEBAND\"` booking question, see [Booking concepts – Booking questions](#section/Booking-concepts/Booking-questions).\n\n## Cancellation policy\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nAs well as *making* bookings, affiliate and merchant partners are also able to *cancel* bookings through the Viator API using the [/bookings/cancel-reasons](#operation/bookingsCancelReasons), [/bookings/{booking-ref}/cancel-quote](#operation/bookingsCancelQuote) and [/bookings/{booking-ref}/cancel](#operation/bookingsCancel) endpoints. Items cancelled via the [/bookings/{booking-ref}/cancel](#operation/bookingsCancel) endpoint will be cancelled in full, and only one booking can be cancelled at a time.\n\nFor more information about how to perform cancellations using this API, see the [Cancellation API workflow](#section/Booking-concepts/Cancellation-API-workflow) section and our in-depth guide about cancellation policies and how to handle cancellations: [All you need to know about cancellation policies](https://partnerresources.viator.com/travel-commerce/merchant/cancellation-policies?source=specs).\n\n\n### Cancellation policies\n\nAll products can be cancelled by the affiliate or merchant partner; however, the refund granted by the supplier depends on the cancellation policy for the product in question.\n\nThere are three cancellation policy categories, **standard**, **custom** and **all sales final**, indicated by the `type` element of the `cancellationPolicy` object in the responses from the [product content endpoints](#section/Key-concepts/Product-content-and-availability-endpoints).\n\n**Note:** *These policies are those provided by Viator to you, the merchant partner. As the merchant of record, you can choose whether to extend these terms to your customers unchanged; or, set your own cancellation terms. For example, you might choose to make all products non-refundable; or, you might extend the full-refund cancellation window to 72 hours instead of 24 hours, and so forth. However, you will still be invoiced according to Viator's cancellation policies communicated via the API*\n\n### Standard cancellation policy (`\"STANDARD\"`)\nProducts in this category can be cancelled up to 24 hours before the travel time (local supplier time) and a full refund will be granted. However, a 100% cancellation penalty applies for cancellations submitted less than 24 hours before the start time. Most products (about 85%) fall into this category.\n\n#### Example response snippet\n\n- **Source endpoint**: [/products/{product-code}](#operation/products)\n- **Product**: `5010SYDNEY`\n\n```json\n{\n \"cancellationPolicy\": {\n \"type\": \"STANDARD\",\n \"description\": \"For a full refund, cancel at least 24 hours before the scheduled departure time.\",\n \"cancelIfBadWeather\": false,\n \"cancelIfInsufficientTravelers\": false,\n \"refundEligibility\": [\n {\n \"dayRangeMin\": 1,\n \"percentageRefundable\": 100\n },\n {\n \"dayRangeMin\": 0,\n \"dayRangeMax\": 1,\n \"percentageRefundable\": 0\n }\n ]\n },\n```\n\nThis product has the *standard* cancellation policy; i.e., when a booking is cancelled:\n\n| Policy | `dayRangeMin` | `dayRangeMax` | Logic | `percentageRefundable` |\n|--------|:-----------:|:-----------:|-------|:--------------------------:|\n| *less than* one day (24 hours) before the start time | 0 | 1 | (product_start_time - cancellation_time) >= 0 days && (product_start_time - cancellation_time) < 1 days | 0 |\n| *more than* one day (24 hours) before the start time | 1 | (absent) | (product_start_time - cancellation_time) >= 1 day | 100 |\n\n### Custom cancellation policy (`\"CUSTOM\"`)\nThe refund amount for products in this category varies depending on how long before its start time the product is cancelled. Many products on a custom policy are multi-day tours, which require more sophisticated planning on the supplier’s end. Only a small number of products (around 5%) fall into this category.\n\n - **Note**: the `description` field contains a natural-language (and therefore language-localized) description of the policy described in the `refundEligibility` array. You can use this description for customer-messaging directly, or implement your own natural-language generation techique. With the cancellation policy encoded in a structured way, it would also be possible to display this information graphically.\n\n#### Example response snippet\n\n- **Source endpoint**: [/products/{product-code}](#operation/products)\n- **Product**: `40944P355`\n\n```json\n\"cancellationPolicy\": {\n \"type\": \"CUSTOM\",\n \"description\": \"If you cancel at least 30 day(s) in advance of the scheduled departure, there is no cancellation fee.
If you cancel between 10 and 29 day(s) in advance of the scheduled departure, there is a 50 percent cancellation fee.
If you cancel within 9 day(s) of the scheduled departure, there is a 100 percent cancellation fee.\",\n \"cancelIfBadWeather\": false,\n \"cancelIfInsufficientTravelers\": false,\n \"refundEligibility\": [\n {\n \"dayRangeMin\": 10,\n \"dayRangeMax\": 30,\n \"percentageRefundable\": 50\n },\n {\n \"dayRangeMin\": 30,\n \"percentageRefundable\": 100\n },\n {\n \"dayRangeMin\": 0,\n \"dayRangeMax\": 10,\n \"percentageRefundable\": 0\n } \n ]\n },\n```\n\nThis product has a complex cancellation policy; where cancellations processed:\n\n| Policy | `dayRangeMin` | `dayRangeMax` | Logic | `percentageRefundable` |\n|--------|:-----------:|:-----------:|-------|:--------------------------:|\n| 30 days or more before the start time | 30 | (absent) | (product_start_time - cancellation_time) >= 30 days | 100 |\n| 10 days and *less than* 30 days (10 to 30 days) *before* the start time or more | 10 | 30 | (product_start_time - cancellation_time) >= 10 days && (product_start_time - cancellation_time) < 30 days | 50 |\n| *less than* 10 days *before* the start time | 0 | 10 | (product_start_time - cancellation_time) < 10 days | 0 |\n\n**Note:** When the `dateRangeMax` field is absent, this means infinity. Therefore, the second element in the `refundEligibility` array above indicates that the time period begins infinitely far in the past *until* 30 days prior to the tour or activity commencing.\n\n### `3` – All sales final (100% cancellation penalty / no refund offered)\n\nProducts in this category cannot be cancelled or amended without incurring a 100% penalty; i.e., the refund amount will be zero. Around 10% of products fall into this category.\n\n#### Example response snippet\n\n- **Source endpoint**: [/products/{product-code}](#operation/products)\n- **Product**: `100014P7`\n\n```json\n{\n \"cancellationPolicy\": {\n \"type\": \"ALL_SALES_FINAL\",\n \"description\": \"All sales are final and incur 100% cancellation penalties\",\n \"cancelIfBadWeather\": false,\n \"cancelIfInsufficientTravelers\": false,\n \"refundEligibility\": [\n {\n \"dayRangeMin\": 0,\n \"percentageRefundable\": 0\n }\n ]\n },\n```\n\nProducts in this category can be cancelled, but no refund will be granted.\n\n### startTimeStamp and endTimeStamp\n\nWithin the `cancellationPolicy` object in the response from [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook), the `refundEligibility.startTimestamp` and `refundEligibility.endTimestamp` fields contain time-stamps (UTC) that indicate the exact times between which the different cancellation refund rates apply.\n\n**Note**: \n * `refundEligibility.startTimestamp` will always be further in the past than `refundEligibility.endTimestamp`. \n * Please use `startTimestamp` and `endTimestamp`, rather than `dayRangeMin` and `dayRangeMax`, to determine which cancellation policy is in effect.\n\n**Example response snippet from [/bookings/book](#operation/bookingsBook) and [/bookings/cart/book](#operation/bookingsCartBook)**:\n\n```json\n\"cancellationPolicy\": {\n \"type\": \"STANDARD\",\n \"description\": \"For a full refund, cancel at least 24 hours before the scheduled departure time.\",\n \"cancelIfBadWeather\": false,\n \"cancelIfInsufficientTravelers\": false,\n \"refundEligibility\": [\n {\n \"dayRangeMin\": 1,\n \"percentageRefundable\": 100,\n \"startTimestamp\": \"2020-08-25T00:36:49.69005Z\",\n \"endTimestamp\": \"2020-11-28T13:00:00Z\"\n },\n {\n \"dayRangeMin\": 0,\n \"dayRangeMax\": 1,\n \"percentageRefundable\": 0,\n \"startTimestamp\": \"2020-11-28T13:00:00Z\",\n \"endTimestamp\": \"2020-11-29T13:00:00Z\"\n }\n ]\n}\n```\n\n### Post-travel cancellations\n\nOccasionally, customers seek a refund for a product **after** completing their travels.\n\nThe reason for this might be because they were unable to attend the tour due to the supplier having cancelled the tour due to bad weather or other reasons beyond the customer's control; or, the customer might have been extremely dissatisfied with the tour itself, felt that it was misrepresented in its advertising, or some other serious complaint.\n\nWhen this occurs, you will need to [send a refund request by email to dpsupport](mailto:dpsupport@viator.com) and include both \"CANCEL\" and the booking reference number in the subject line.\n\nFor **all** post-travel cancellation requests, you will need to include a detailed description of the issue. \n\nExcept in cases of known service interruptions (e.g., due to\ \ extreme weather events), we will first verify the issue and seek authorization from the product supplier. \n\nOnce a decision regarding the refund has been made, we will notify your Customer Services Department with this information. You will then need to advise your customer directly and process the refund if granted.\n\n### Partial refunds\n\nWhile we recommend that merchant partners support the processing of partial refunds for their customers, it is ultimately up to the partner whether to implement this functionality. \n\nIf you would prefer to only grant the full (100%) refund that is offered on most products so long as the cancellation is processed more than 24 hours prior to the product's start time, we recommend that you implement logic that checks whether a 100% refund is available for the product at the time the customer wishes to cancel their booking.\n\n| **Type 1: Standard policy** (`cancellationPolicy.type` is `\"STANDARD\"`) |\n|-------------------------------------------------------------|\n| The 100% refund is available so long as the cancellation is performed more than 24 hours prior to the product start time |\n\n| **Type 2: Custom policy** (`cancellationPolicy.type` is `\"CUSTOM\"`) |\n|-----------------------------------------------------------|\n| You will need to check whether any of the canellation policy objects in the `refundEligibility` array have: |\n\n| **Type 3: All sales final** (`cancellationPolicy.type` is `\"ALL_SALES_FINAL\"`)|\n|-------------------------------------------------------------|\n| No refunds are available (except in the case of manual confirmation products that are still in a 'pending' state and special exceptions for post-trip cancellations); therefore, under normal conditions, if you grant a refund to your customer for this kind of product, it will be solely at *your* expense (i.e., you will still be invoiced for the cost of the product by Viator). Therefore, we recommend that you do not allow refunds for products with this policy. |\n\n## Per-person and unit pricing\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nThe products in our catalogue fall into two pricing categories: **per-person** and **unit** pricing.\n\nA product's pricing category is given in the `pricingInfo.type` field of the product content response. Depending on whether the product has per-person or unit pricing, this value will be `\"PER_PERSON\"` or `\"UNIT\"`, respectively.\n\nFor more information, see this article: [Per-person and unit pricing](https://partnerresources.viator.com/travel-commerce/merchant/pricing/?source=specs#per-person-unit-pricing).\n\n### Per-person pricing\n\nIf the pricing is *per-person*, then the total price of the booking will be directly proportional to the number of participants (passengers) of each age-band type that are being booked for the product; i.e., a direct multiple of the per-person price.\n\nFor example:\n\n```json\n\"pricingInfo\": {\n \"type\": \"PER_PERSON\",\n \"ageBands\": [\n {\n \"ageBand\": \"CHILD\",\n \"startAge\": 3,\n \"endAge\": 12,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 6\n },\n {\n \"ageBand\": \"ADULT\",\n \"startAge\": 13,\n \"endAge\": 99,\n \"minTravelersPerBooking\": 2,\n \"maxTravelersPerBooking\": 6\n }\n ]\n},\n```\n\n### Per-unit pricing\n\nIf the product has *unit* pricing, then the total price of the booking will depend on the number of units (groups) and types of unit that ideally accommodate the participant mix. Additionally, the `pricingInfo` object in the response will specify the type of unit in the `unitType` field; e.g., in this case, `\"VEHICLE\"`:\n\n```json\n\"pricingInfo\": {\n \"type\": \"UNIT\",\n \"ageBands\": [\n {\n \"ageBand\": \"TRAVELER\",\n \"startAge\": 0,\n \"endAge\": 99,\n \"minTravelersPerBooking\": 1,\n \"maxTravelersPerBooking\": 8\n }\n ],\n \"unitType\": \"VEHICLE\"\n}\n``` \n\nThe `unitType` will be one of:\n\n\n| `unitType` | Example product | Meaning |\n|-------------|-----------------|---------|\n| `\"GROUP\"` | [10847P42](https://www.viator.com/tours/Berlin/In-Search-of-Jewish-Berlin-3-hour-Private-History-Tour-with-a-Scholar-Guide/d488-10847P42) | **Per-group** pricing – the unit price is calculated according to the number of groups the specified passenger mix will fit into rather than the exact number of participants. `minTravelersPerBooking` and `maxTravelersPerBooking` must be considered as these fields relate to the available group sizes. |\n| `\"ROOM\"` | [16621P2](https://www.viator.com/tours/Maharashtra/Stay-package-with-amusement-park-for-2pax-for-2-nights/d25170-16621P2) | **Per-room** pricing relates the room price, which depends on the number of participants making the booking. |\n| `\"PACKAGE\"` | [186385P1](https://www.viator.com/tours/Slovenia/VIP-wellness-to-rent/d734-186385P1) | **Per-package** pricing refers to products that are sold as part of a package; for example a family package stipulating a passenger mix of two adults and two children. |\n| `\"VEHICLE\"` | [10175P10](https://www.viator.com/tours/Cannes/Private-Departure-Transfer-from-Cannes-to-Nice-Airport/d786-10175P10) | **Per-vehicle** pricing is calculated according to the number of vehicles required for the specified passenger mix rather than the exact number of participants. `minTravelersPerBooking` and `maxTravelersPerBooking` must be considered as these fields relate to the occupancy limitations for each vehicle. The minimum price will depend on the rate for a single vehicle. |\n| `\"BIKE\"` | [153074P3](https://www.viator.com/tours/Adelaide/Adelaide-90-Minute-Pedicab-Tour-Scenic-Green-and-River-Experience/d376-16810P4) | **Per-bike** pricing – identical to \"per vehicle\", but refers specifically to vehicles that are bikes. |\n| `\"BOAT\"` | [35157P2](https://www.viator.com/tours/British-Virgin-Islands/Private-Sunset-Sail/d809-35157P2) | **Per-boat** pricing – identical to \"per vehicle\", but refers specifically to vehicles that are boats. |\n| `\"AIRCRAFT\"` | [14876P5](https://www.viator.com/tours/Niagara-Falls-and-Around/Air-Taxi-Tour-from-Niagara-to-Toronto-including-Ground-Transport-from-Niagara-Hotels/d773-14876P5) | **Per-aircraft** pricing – identical to \"per vehicle\", but refers specifically to vehicles that are aircraft. | \n\n\n## Low-margin products\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nWhen setting the price at which you sell products on your site, it’s important to remember that the `recommendedRetailPrice` is just the price at which the product is currently advertised on the Viator site and is only a recommendation. \n\nHowever, the `recommendedRetailPrice` may be **less than** the `partnerTotalPrice` (i.e., the amount you will be invoiced for the sale).\n\nIf you sell the product for less than the `partnerTotalPrice`, you will make a loss on that sale.\n\nTherefore, to ensure that you sell the product at a price which guarantees that you receive at least as much as you will be invoiced for, as well as any extra profit margin that you desire to generate, we recommend you include logic to check that these requirements are satisfied by comparing `recommendedRetailPrice` and `partnerTotalPrice` and adjusting the price at which you advertise and sell the product accordingly.\n\n**For example:** If the `partnerTotalPrice` for a product is $100, the `recommendedRetailPrice` is $101, and you require a minimum margin of 5%, you should adjust the price at which you advertise the product to $105.\n\nWhile we do recommend that you set your prices according to the value of `recommendedRetailPrice`, it is ultimately up to you what price you set for the product, bearing in mind that the amount Viator will invoice you for the sale will be the value of `partnerTotalPrice`.\n\nFor more information, see this article about how to deal with [Low-margin products](https://partnerresources.viator.com/travel-commerce/merchant/pricing/?source=specs#low-margin-products).\n\n## Supplier communications\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\n### How can suppliers communicate with end customers?\n\nSuppliers occasionally need to reach out to customers for a variety of reasons, such as:\n\n* Requesting pickup locations, flight details or passenger weight information\n* Providing weather alerts, sold-out notifications or general messaging\n\nTo allow suppliers to contact customers directly, Viator provides **Closed-Loop Communication (CLC)**.\n\n### How to set up CLC for a booking\n\nThe recipient(s) of suppliers' CLC messages is set for each booking at the time of booking by supplying the customer’s email address (`email`) as well as their phone number (`phone`) in the `communication` object in the request sent to the [/booking/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook) endpoints when making a booking.\n\nThis will direct CLC messages sent by suppliers directly to that customer's email; no action from your support team will be necessary for suppliers to communicate with customers.\n\nPartners choosing this option should mention to their customers that they are purchasing a product from a third-party supplier, and that they may, therefore, receive communications regarding the purchase directly from that supplier.\n\n#### Note:\n\n* To have a CC of each message a supplier sends to their customer sent to *your* (the partner's) customer support email address (in case further assistance is required) you must include your customer support email address in the `email` field, after the customer's email and separated from that address with a comma.\n\n\n#### Example request body snippet to enable direct CLC\n```json\n{\n ...\n \"communication\": {\n \"email\": \"john.smith@tripadvisor.com\",\n \"phone\": \"+61 4121121121\"\n}\n```\n\n#### Example request body snippet to enable direct CLC with a CC of each message sent to your customer support\n```json\n{\n ...\n \"communication\": {\n \"email\": \"john.smith@tripadvisor.com,customersupport@bookatrip4me.com\",\n \"phone\": \"+61 4121121121\"\n}\n```\n\n\n### Supplier communications without CLC\n\nTo have CLCs from the supplier sent only to your (the merchant's) customer support team, supply the email address of your customer support function in the `email` field of the `communication` object in the request to the [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook) endpoints when making a booking.\n\n**Note:** Utilizing this option requires you, the merchant, to manage the final loop of communication with the end customer to ensure that their tour/activity can be fulfilled successfully.\n\n#### Example request body snippet to disable CLC\n```json\n{\n ...\n \"communication\": {\n \"email\": \"customersupport@bookatrip4me.com\",\n \"phone\": \"+61 4121121121\"\n}\n```\n\n### Default behavior\n\nIf an email address is not supplied in the communications object, the default behavior will be to use the partner's customer support email address for correspondence regarding this booking. Please contact your account manager to set or change the customer support email address for your organization. \n\n#### Example request body snippet that would trigger the default behavior\n\n```json\n{\n ...\n \"communication\": {\n \"phone\": \"+61 4121121121\"\n}\n```\n\n### More information\n\nFor additional information about all communications sent by Viator, including CLC, see: [All you need to know about cancellation policies – Managing Communications](https://partnerresources.viator.com/travel-commerce/merchant/cancellation-policies?source=specs#managing-communications).\n\n## Booking questions\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nThe booking-questions functionality of this API allows vital information specified by the supplier about the individual travelers or the group as a whole to be sent to the supplier as part of the request when making a booking using the [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook) endpoints.\n\nThe booking questions available for a product are specified in the `bookingQuestions` array in the response from any of the [product content endpoints](#section/Key-concepts/Product-content-and-availability-endpoints) for that product. For example, for the product [10212P2 (Taste of Miami Helicopter Tour)](https://www.viator.com/tours/Miami/Taste-of-Miami-Helicopter-Tour/d662-10212P2), the `bookingQuestions` array is as follows:\n\n```json\n\"bookingQuestions\": [\n \"FULL_NAMES_LAST\",\n \"SPECIAL_REQUIREMENTS\",\n \"FULL_NAMES_FIRST\",\n \"WEIGHT\",\n \"AGEBAND\"\n],\n```\nEach key string (`\"FULL_NAMES_LAST\"`, etc.) identifies a booking question, details about which can be found in the response from the [/products/booking-questions](#operation/productsBookingQuestions) endpoint.\n\nRelevant booking question details in example response snippet from [/products/booking-questions](#operation/productsBookingQuestions):\n\n```json\n\"bookingQuestions\": [\n {\n \"legacyBookingQuestionId\": 23,\n \"id\": \"WEIGHT\",\n \"type\": \"NUMBER_AND_UNIT\",\n \"group\": \"PER_TRAVELER\",\n \"label\": \"Traveler weight in pounds or kilograms (required for safety reasons)\",\n \"hint\": \"E.g. 130lbs, 60kg\",\n \"units\": [\n \"kg\",\n \"lbs\"\n ],\n \"required\": \"MANDATORY\"\n },\n {\n \"legacyBookingQuestionId\": 24,\n \"id\": \"FULL_NAMES_FIRST\",\n \"type\": \"STRING\",\n \"group\": \"PER_TRAVELER\",\n \"label\": \"First name\",\n \"required\": \"MANDATORY\"\n },\n {\n \"legacyBookingQuestionId\": 25,\n \"id\": \"FULL_NAMES_LAST\",\n \"type\": \"STRING\",\n \"group\": \"PER_TRAVELER\",\n \"label\": \"Last name\",\n \"required\": \"MANDATORY\"\n },\n {\n \"legacyBookingQuestionId\": 30,\n \"id\": \"AGEBAND\",\n \"type\": \"STRING\",\n \"group\": \"PER_TRAVELER\",\n \"label\": \"Age band\",\n \"allowedAnswers\": [\n \"ADULT\",\n \"SENIOR\",\n \"YOUTH\",\n \"CHILD\",\n \"INFANT\",\n \"TRAVELER\"\n ],\n \"required\": \"MANDATORY\"\n },\n {\n \"legacyBookingQuestionId\": 27,\n \"id\": \"SPECIAL_REQUIREMENTS\",\n \"type\": \"STRING\",\n \"group\": \"PER_BOOKING\",\n \"label\": \"Special requirements\",\n \"required\": \"OPTIONAL\"\n },\n ...\n]\n```\n\nThe `required` field indicates whether an answer to the booking question must be provided in the booking request. It is necessary to provide an answer to all specified booking questions for which `required` is `MANDATORY`. \n\nAdditionally, the `group` field indicates whether an answer to the booking question must be answered for each traveler (`\"PER_TRAVELER\"`) or for the booked group as a whole (`\"PER_BOOKING\"`).\n\nIn this case:\n\n| Booking question id | required | group |\n|---------------------|----------|-------|\n| `\"WEIGHT\"` | `\"MANDATORY\"` | `\"PER_TRAVELER\"` |\n| `\"FULL_NAMES_FIRST\"` | `\"MANDATORY\"` | `\"PER_TRAVELER\"` |\n| `\"FULL_NAMES_LAST\"` | `\"MANDATORY\"` | `\"PER_TRAVELER\"` |\n| `\"AGEBAND\"` | `\"MANDATORY\"` | `\"PER_TRAVELER\"` |\n| `\"SPECIAL_REQUIREMENTS\"` | `\"OPTIONAL\"` | `\"PER_BOOKING\"` |\n\nTherefore, to book this product, you must provide an answer to the `\"WEIGHT\"`, `\"FULL_NAMES_FIRST\"`,`\"FULL_NAMES_LAST\"` and `\"AGEBAND\"` questions for each traveler, and, optionally (if specified by the user at the time of booking) `\"SPECIAL_REQUIREMENTS\"` for the booked group.\n\nAnswers to the booking questions are sent in the `bookingQuestionAnswers[]` array in the request to [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook). The following example shows a valid and complete set of booking-question answers for this product.\n\n| Traveler number | First name | Last name | age band |\n|-----------------|------------|-----------|----------|\n| 1 | John | Smith | ADULT |\n| 2 | Mary | Jones | ADULT | \n\n```json\n\"bookingQuestionAnswers\": [ \n {\n \"question\": \"AGEBAND\",\n \"answer\": \"ADULT\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"FULL_NAMES_LAST\",\n \"answer\": \"Smith\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"FULL_NAMES_FIRST\",\n \"answer\": \"John\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"AGEBAND\",\n \"answer\": \"ADULT\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"FULL_NAMES_LAST\",\n \"answer\": \"Jones\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"FULL_NAMES_FIRST\",\n \"answer\": \"Mary\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"SPECIAL_REQUIREMENTS\",\n \"answer\": \"NO\"\n }\n]\n```\n\n### When to use `travelerNum`\n\nPlease note that `travelerNum` indicates which traveler the answer pertains to. All `PER_TRAVELER` questions must be answered for all travelers in the booking. `travelerNum` **must** be omitted for `PER_BOOKING` booking questions.\n\n### Booking questions with units\n\nSome booking questions require you to specify the unit type when providing an answer to the questions.\n\n**Example: 'HEIGHT' booking question**\n\n\nDefinition of question from [/products/booking-questions](#operation/productsBookingQuestions):\n```json\n{\n \"legacyBookingQuestionId\": 2,\n \"id\": \"HEIGHT\",\n \"type\": \"NUMBER_AND_UNIT\",\n \"group\": \"PER_TRAVELER\",\n \"label\": \"Traveler height in feet or centimeters (required for safety reasons)\",\n \"hint\": \"E.g. 5'2\\\", 158cm\",\n \"units\": [\n \"cm\",\n \"ft\"\n ],\n \"required\": \"MANDATORY\"\n},\n```\n\nA valid answer to this booking question for a traveler who is 193 centimetres tall is as follows:\n\n```json\n\"bookingQuestionAnswers\": [ \n {\n \"question\": \"HEIGHT\",\n \"answer\": \"193\",\n \"unit\": \"cm\",\n \"travelerNum\": 1\n }\n]\n```\n\n**Example: 'WEIGHT' booking question**\n\nDefinition of question from [/products/booking-questions](#operation/productsBookingQuestions):\n\n```json\n{\n \"legacyBookingQuestionId\": 23,\n \"id\": \"WEIGHT\",\n \"type\": \"NUMBER_AND_UNIT\",\n \"group\": \"PER_TRAVELER\",\n \"label\": \"Traveler weight in pounds or kilograms (required for safety reasons)\",\n \"units\": [\n \"kg\",\n \"lbs\"\n ],\n \"required\": \"MANDATORY\",\n \"maxLength\": 50\n},\n```\n\nA valid answer to this booking question for a traveler who weighs 69 kilograms would be as follows:\n\n```json\n\"bookingQuestionAnswers\": [ \n {\n \"question\": \"WEIGHT\",\n \"answer\": \"69\",\n \"unit\": \"kg\",\n \"travelerNum\": 1\n }\n]\n```\n\n\n### Booking questions with allowed answers\n\nSome booking questions must be answered in a specific way. These questions include an `allowedAnswers` array containing the set of valid answers to the question.\n\nExample booking question with allowed answers:\n\n```json\n{\n \"legacyBookingQuestionId\": 31,\n \"id\": \"TRANSFER_ARRIVAL_MODE\",\n \"type\": \"STRING\",\n \"group\": \"PER_BOOKING\",\n \"label\": \"Arrival mode\",\n \"allowedAnswers\": [\n \"AIR\",\n \"RAIL\",\n \"SEA\",\n \"OTHER\"\n ],\n \"required\": \"MANDATORY\"\n}\n```\n\nA valid answer to this booking question would be:\n\n```json\n{\n \"question\": \"TRANSFER_ARRIVAL_MODE\",\n \"answer\": \"AIR\"\n},\n```\n\nNote:\n\n- Not all allowed answers are applicable to all products, so you should not always display all 4 arrival/departure modes for all products. You should validate the arrival/departure modes based on the presence of questions applicable to a specific arrival/departure mode for each product.\n- These questions will help you identify arrival modes available for a product:\n + `\"AIR\"`: `\"TRANSFER_AIR_ARRIVAL_AIRLINE\"`, `\"TRANSFER_AIR_ARRIVAL_FLIGHT_NO\"`\n + `\"SEA\"`: `\"TRANSFER_PORT_ARRIVAL_TIME\"` (`\"TRANSFER_PORT_CRUISE_SHIP\"` applies also to departure mode)\n + `\"RAIL\"`: `\"TRANSFER_RAIL_ARRIVAL_LINE\"`, `\"TRANSFER_RAIL_ARRIVAL_STATION\"`\n- If any of these questions is returned (even just one), the relevant option for arrival mode applies. Once an arrival mode is selected, travellers are required to answer all questions related to the selected arrival mode that are returned for the product in the bookingQuestions array (see the table below).\n- The same applies in case of departure modes, you need to look for these questions specific to each departure mode:\n + `\"AIR\"`: `\"TRANSFER_AIR_DEPARTURE_AIRLINE\"`, `\"TRANSFER_AIR_DEPARTURE_FLIGHT_NO\"`\n + `\"SEA\"`: `\"TRANSFER_PORT_DEPARTURE_TIME\"` (`\"TRANSFER_PORT_CRUISE_SHIP\"` applies also to arrival mode)\n + `\"RAIL\"`: `\"TRANSFER_RAIL_DEPARTURE_LINE\"`, `\"TRANSFER_RAIL_DEPARTURE_STATION\"`\n- If these questions are not returned, the departure mode doesn't apply. Once a departure mode is selected, travellers are required to answer all questions related to the selected departure mode that are returned for the product in the bookingQuestions array (see the table below).\n\nWe recommend partners to translate these answers to natural language on their platforms, see recommendation below:\n\n- `\"AIR\"` - airport\n- `\"RAIL\"` - train station\n- `\"SEA\"` - port\n- `\"OTHER\"` - hotel / specific address\n\n\n### Conditional booking questions\n\nThere are some booking questions that may or may not have to be answered, depending on the presence of – or answer to – another booking question. These questions are 'conditional', as indicated by the `required` field containing `\"CONDITIONAL\"`; e.g.:\n\n```json\n{\n \"legacyBookingQuestionId\": 7,\n \"id\": \"TRANSFER_AIR_ARRIVAL_AIRLINE\",\n \"type\": \"STRING\",\n \"group\": \"PER_BOOKING\",\n \"label\": \"Name of arrival airline\",\n \"hint\": \"E.g. United Airlines\",\n \"required\": \"CONDITIONAL\",\n \"maxLength\": 255\n},\n```\n\nSo, when is an answer to a `\"CONDITIONAL\"` booking question required?\n\nAt present, the logic cannot be inferred from the response from the [/products/booking-questions](#operation/productsBookingQuestions) endpoint, but it can be explained here. You will need to hard-code this logic into your implementation in order to correctly present the required booking questions to the user.\n\nThe logic runs as follows:\n\n| For this booking question | if the user's answer is | these questions must also be answered |\n|--------------------|----------------|-------------------------------|\n| `\"TRANSFER_ARRIVAL_MODE\"` | `\"AIR\"` | `\"TRANSFER_AIR_ARRIVAL_AIRLINE\"`
`\"TRANSFER_AIR_ARRIVAL_FLIGHT_NO\"`
`\"TRANSFER_ARRIVAL_TIME\"`
`\"TRANSFER_ARRIVAL_DROP_OFF\"` (see condition 1)
`\"PICKUP_POINT\"` (see condition 1) |\n| `\"TRANSFER_ARRIVAL_MODE\"` | `\"RAIL\"` | `\"TRANSFER_RAIL_ARRIVAL_LINE\"`
`\"TRANSFER_RAIL_ARRIVAL_STATION\"`
`\"TRANSFER_ARRIVAL_TIME\"`
`\"TRANSFER_ARRIVAL_DROP_OFF\"` |\n| `\"TRANSFER_ARRIVAL_MODE\"` | `\"SEA\"` | `\"TRANSFER_PORT_ARRIVAL_TIME\"`
`\"TRANSFER_PORT_CRUISE_SHIP\"`
`\"TRANSFER_ARRIVAL_DROP_OFF\"` (see condition 2)
`\"PICKUP_POINT\"` (see condition 2)|\n| `\"TRANSFER_ARRIVAL_MODE\"` | `\"OTHER\"` | `\"PICKUP_POINT\"` (see condition 3) |\n| `\"TRANSFER_DEPARTURE_MODE\"` | `\"AIR\"` | `\"TRANSFER_AIR_DEPARTURE_AIRLINE\"`
`\"TRANSFER_AIR_DEPARTURE_FLIGHT_NO\"`
`\"TRANSFER_DEPARTURE_DATE\"`
`\"TRANSFER_DEPARTURE_TIME\"`
`\"TRANSFER_DEPARTURE_PICKUP\"` |\n| `\"TRANSFER_DEPARTURE_MODE\"` | `\"RAIL\"` | `\"TRANSFER_RAIL_DEPARTURE_LINE\"`
`\"TRANSFER_RAIL_DEPARTURE_STATION\"`
`\"TRANSFER_DEPARTURE_DATE\"`
`\"TRANSFER_DEPARTURE_TIME\"`
`\"TRANSFER_DEPARTURE_PICKUP\"` |\n| `\"TRANSFER_DEPARTURE_MODE\"` | `\"SEA\"` | `\"TRANSFER_PORT_CRUISE_SHIP\"`
`\"TRANSFER_DEPARTURE_DATE\"`
`\"TRANSFER_PORT_DEPARTURE_TIME\"`
`\"TRANSFER_DEPARTURE_PICKUP\"`|\n| `\"TRANSFER_DEPARTURE_MODE\"` | `\"OTHER\"` | n/a (see condition 4) |\n\n**Conditions**:\n\n1. Rule applies only if `logistics.travelerPickup.locations[]` includes an item with `pickupType`: `\"AIRPORT\"`; **or**, if `logistics.travelerPickup.allowCustomTravelerPickup` is **true**. `\"PICKUP_POINT\"` answer must be a location for which `pickupType` is `\"AIRPORT\"` if answer to `\"TRANSFER_ARRIVAL_MODE\"` is `\"AIR\"`.\n2. Rule applies only if `logistics.travelerPickup.locations[]` includes an item with `pickupType`: `\"PORT\"`; **or**, if `logistics.travelerPickup.allowCustomTravelerPickup` is **true**. `\"PICKUP_POINT\"` answer must be a location for which `pickupType` is `\"PORT\"` if answer to `\"TRANSFER_ARRIVAL_MODE\"` is `\"SEA\"`.\n3. Rule applies only if `logistics.travelerPickup.locations[]` includes an item with `pickupType`: `\"HOTEL\"` or `pickupType`: `\"LOCATION\"` or `pickupType`: `\"OTHER\"`; **or**, if `logistics.travelerPickup.allowCustomTravelerPickup` is **true**.\n4. This question may only be answered `\"OTHER\"` if `\"OTHER\"` is also an available option for the `\"TRANSFER_ARRIVAL_MODE\"` booking question.\n\n**Extra notes**:\n\n- Not all allowed answers are applicable to all products, so you don’t have to always display all 4 arrival/departure modes. For each prodyct, you must validate if arrival/departure modes apply by checking if questions applicable to a specific arrival/departure are present. Read more about this validation here: [Booking questions with allowed answers](#section/Booking-concepts/Booking-questions).\n- All `\"CONDITIONAL\"` booking questions that depend on the answer given to either `\"TRANSFER_ARRIVAL_MODE\"` or `\"TRANSFER_DEPARTURE_MODE\"` (i.e., those questions in the right-hand column in the table above) should be considered `\"MANDATORY\"` if they are stipulated in the `\"bookingQuestions\"` array of the product content response, and the respective transfer mode question **is not** stipulated. That is to say, for example, if `\"TRANSFER_AIR_ARRIVAL_AIRLINE\"` is present, but `\"TRANSFER_ARRIVAL_MODE\"` is absent from `\"bookingQuestions\"`, then `\"TRANSFER_AIR_ARRIVAL_AIRLINE\"` should be considered `\"MANDATORY\"`.\n- The `\"TRANSFER_PORT_CRUISE_SHIP\"` question is required to be answered when the customer's response to either `\"TRANSFER_ARRIVAL_MODE\"` or `\"TRANSFER_DEPARTURE_MODE\"` is `\"SEA\"`; however, this question must only be answered **once** per booking. I.e., the answer for `\"TRANSFER_PORT_CRUISE_SHIP\"` pertains to both questions. There is no provision for the customer to specify different cruise ships for arrival and departure.\n- Please note that the inclusion of the `\"TRANSFER_ARRIVAL_MODE\"`, `\"TRANSFER_DEPARTURE_MODE\"` or their corollary conditional booking questions **does not necessarily imply that pickup is offered** for the product or product option being booked. It may be that these relate to another aspect of the service being offered; for example, an airport greeting product. When returned for a product, these questions must be answered.\n- The `\"TRANSFER_ARRIVAL_DROP_OFF\"` and `\"TRANSFER_DEPARTURE_PICKUP\"` questions are related to locations (arrival drop off and departure pickup) however there are no specific location references or conditions that apply to these questions (see the table). Therefore, customers should be provided with a freetext input field for these questions and the answers must include the FREETEXT designation if the customer answered freely, via text.\n- Whether or not pickup is available should be determined at the product level by the value of `logistics.travelerPickup.pickupOptionType` being either `\"PICKUP_EVERYONE\"` or `\"PICKUP_AND_MEET_AT_START_POINT\"` and not `\"MEET_EVERYONE_AT_START_POINT\"`; or, the presence of the phrase `\"pickup included\"` in the `productOptions[].description` field for the product option.\n- Pickup must be validated on the product option level. It’s possible that the product has multiple product options with a different setup for each one - i.e. one product option offers pickup, another product option requires to meet at the meeting point. The correct validation must be applied as described here: [How to determine if a product option supports pickup.](#section/Booking-concepts/Booking-questions)\n- `logistics.travelerPickup.pickupOptionType` in the product content response could return `\"PICKUP_AND_MEET_AT_START_POINT\"` for products that don't have product options. In such cases travelers should be allowed to either select a pickup location, or decide to meet at the meeting point.\n- Pickup locations shouldn't be displayed at checkout for product options without pickup (this includes the option to contact the supplier later). Please refer to the 'Pickup point question' section below for further details on how to handle pickups.\n\n### Pickup point question\n\nThe booking question that requests the location for pickup is as follows:\n\n```json\n{\n \"legacyBookingQuestionId\": 6,\n \"id\": \"PICKUP_POINT\",\n \"type\": \"LOCATION_REF_OR_FREE_TEXT\",\n \"group\": \"PER_BOOKING\",\n \"label\": \"Hotel pickup\",\n \"hint\": \"E.g. 1234 Cedar Way, Brooklyn NY 00123\",\n \"units\": [\n \"LOCATION_REFERENCE\",\n \"FREETEXT\"\n ],\n \"required\": \"CONDITIONAL\",\n \"maxLength\": 1000\n}\n```\n\nAs you can see, this question can be answered using a location reference or 'freetext' (i.e., a written address in this context). Whether freetext is allowed for this answer depends on the value of `logistics.travelerPickup.allowCustomTravelerPickup` in the response from any of the [product content endpoints](#section/Key-concepts/Product-content-and-availability-endpoints). If `true`, freetext is allowed. Otherwise, a location reference – in particular, one of the location references included in the `logistics.travelerPickup.locations[]` array – must be supplied.\n\nExample `\"FREETEXT\"` answer:\n\n```json\n\"bookingQuestionAnswers\": [ \n {\n \"question\": \"PICKUP_POINT\",\n \"answer\": \"1234 Cedar Way, Brooklyn NY 00123\",\n \"unit\": \"FREETEXT\"\n }\n]\n```\n\nExample `\"LOCATION_REFERENCE\"` answer:\n\n```json\n\"bookingQuestionAnswers\": [ \n {\n \"question\": \"PICKUP_POINT\",\n \"answer\": \"LOC-6cb31b00-1fb4-4218-9b50-63f66531d735\",\n \"unit\": \"LOCATION_REFERENCE\"\n }\n]\n```\n\n#### Special pickup-point location references\n\nThe `logistics.travelerPickup.locations[]` array in the response from the product content endpoints contains the location references for all available pickup locations for a product.\n\nAs well as standard location reference codes; e.g., \"LOC-6cb31b00-1fb4-4218-9b50-63f66531d735\", there are two special codes that specify **instructions** rather than locations. \n\nThese are:\n\n- `\"MEET_AT_DEPARTURE_POINT\"`\n- `\"CONTACT_SUPPLIER_LATER\"`\n\nWhen selecting available pickup points, our suppliers also have the option of specifying one or both of these pseudo-locations. These instruct the customer to either meet at one of the locations specified in `logistics.start[]`, or to contact the supplier later to arrange a pickup point, respectively.\n\nWhen building a list of available pickup locations for the customer to select at the time of booking, the descriptive text for these locations can be used. This is available from the [/locations/bulk](#operation/locationsBulk) endpoint in the `name` field, as follows:\n\n```json\n{\n \"locations\": [\n {\n \"provider\": \"TRIPADVISOR\",\n \"reference\": \"CONTACT_SUPPLIER_LATER\",\n \"name\": \"I will contact the supplier later\"\n },\n {\n \"provider\": \"TRIPADVISOR\",\n \"reference\": \"MEET_AT_DEPARTURE_POINT\",\n \"name\": \"I will meet at the departure point\"\n }\n ]\n}\n```\n\nOr, you can provide a selection button in your UI, as we have done on the [viator.com](https://viator.com) site:\n\n
\n \"I\n
\"I will select my pickup location later\" example from viator.com
\n
\n\nThis button appears when the `\"CONTACT_SUPPLIER_LATER\"` location reference is included in the `logistics.travelerPickup.locations[]` array.\n\n\n#### How to determine if a product option supports pickup\n\nWhen the value of `logistics.travelerPickup.pickupOptionType` in the product content response is `\"PICKUP_AND_MEET_AT_START_POINT\"`, it means that the product includes both 'hotel pickup' and 'meet at the departure point' variants in its product options. One product option may be for hotel pickup while another is for meeting at the start/departure point, so you must always check each option's logistics details. To determine which product options offer what, it is necessary to inspect each product option's details in the `productOptions[]` array in the product content response.\n\n**Scenario 1, Pickup included:** \nIf pickup is included for a product option, the `productOptions.logistics.travelerPickup.pickupOptionType` returns `\"PICKUP_AND_MEET_AT_START_POINT\"`. \n\nWhen booking a **product option with pickup included**, such as this, you must collect a pickup point from the user that corresponds to one of the entries in the `productOptions.logistics.travelerPickup.locations[]` array in the product option content response. In this scenario you must not use the data returned at product-level.\n\n```json\n{\n \"productOptionCode\": \"TG13\",\n \"description\": \"Guide anglophone : Guide parlant anglais avec prise en charge à l'hôtel.\\nService de prise en charge compris\",\n \"title\": \"Visite Anglaise avec prise en charge\",\n \"logistics\": {\n \"start\": [\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5JOkQupk6XB3ZGmKbXXsO/YJsoMrLjHKBLlR6YXSp+r2\"\n },\n \"description\": \"Rencontre avec le groupe au Samsen Centre Restaurant ( Samsen Soi 2 , près de Nouvo City Hotel ) \"\n },\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5IZzQLYGZXKNHze5ORom1qIr4+647kvt/tTz68opRtEL\"\n },\n \"description\": \"Notre point de rendez-vous à BigCountry Old Town situé à côté du Starbucks Coffee @ The Old Siam Plaza pour le créneau horaire de 8h30, pour les clients séjournant à Khaosan, Pra Nakorn, China Town\"\n },\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5NtB8oYNy1V51j3wDEuW3eLTBY+WpoKX+Etl8hTKccw6\"\n },\n \"description\": \"River City Bangkok, The Anchor of Arts & Antiques est un centre commercial de Bangkok, en Thaïlande. Il se trouve sur la rivière Chao Phraya, sur la jetée de Si Phraya, à proximité de nombreux grands hôtels. Il est accessible en voiture ou en bateau. Le créneau horaire de 9h00 correspond aux clients qui séjournent dans les quartiers de Silom, Sathorn et Bangrak.\"\n }\n ],\n \"end\": [\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5JOkQupk6XB3ZGmKbXXsO/YJsoMrLjHKBLlR6YXSp+r2\"\n },\n \"description\": \"Déposer au restaurant Samsen Centre pour le client qui part de Khaosan Area\"\n },\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5O9X4lT3Avg+rvKxoSJGnTIJr39qTywftTM5SgCNpowi\"\n },\n \"description\": \"Déposer au MBK Center , facile à connecter au BTS (train Sky) pour le client qui part du point de rendez-vous de River City\"\n }\n ],\n \"travelerPickup\": {\n \"pickupOptionType\": \"PICKUP_AND_MEET_AT_START_POINT\",\n \"allowCustomTravelerPickup\": true,\n \"locations\": [\n {\n \"location\": {\n \"ref\": \"MEET_AT_DEPARTURE_POINT\"\n },\n \"pickupType\": \"OTHER\"\n },\n {\n \"location\": {\n \"ref\": \"CONTACT_SUPPLIER_LATER\"\n },\n \"pickupType\": \"OTHER\"\n },\n {\n \"location\": {\n \"ref\": \"LOC-6eKJ+or5y8o99Qw0C8xWyKrhcZh+/RSI01IBRs/OIZo=\"\n },\n \"pickupType\": \"HOTEL\"\n }\n ]\n }\n }\n}\n```\n\nAll booking questions related to arrival/departure must be displayed as normal to allow customers to select the desired arrival/departure mode and provide all relevant information to the supplier before travel. All answers provided by the customer must be captured and submitted in the booking request following the logic for conditional booking questions from the [**table in the API documentation**](https://docs.viator.com/partner-api/technical/#section/Booking-concepts/Booking-questions).\n\n**Scenario 2, No Pickup (Meeting Point Only):** \nIf the productOption doesn't support pickup, the API will now explicitly return `\"MEET_EVERYONE_AT_START_POINT\"` at the Tour Grade level instead and should be considered to follow a `\"MEET_AT_DEPARTURE_POINT\"` arrangement, reducing all ambiguity. \nThe following product option (also from product [**8374P24**](https://www.viator.com/tours/Bangkok/Train-Market-and-Damnoensaduak-Floating-Market-with-small-group/d343-8374P24)) requires meeting at the departure point and does not include pickup:\n\n```json\n{\n \"productOptionCode\": \"TG3\",\n \"description\": \"Point de rencontre : Rendez-vous au River City Bangkok, dépose au MBK Mall. Créneau horaire 9h00.\\nPoint de départ :\\nRiver City Bangkok, 23 Soi Charoen Krung 24, Khwaeng Talat Noi, Khet Samphanthawong, Krung Thep Maha Nakhon 10100, Thaïlande\",\n \"title\": \"Ville fluviale Bangkok\",\n \"logistics\": {\n \"start\": [\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5NtB8oYNy1V51j3wDEuW3eLTBY+WpoKX+Etl8hTKccw6\"\n },\n \"description\": \"River City Bangkok, The Anchor of Arts & Antiques est un centre commercial de Bangkok, en Thaïlande. Il se trouve sur la rivière Chao Phraya, sur la jetée de Si Phraya, à proximité de nombreux grands hôtels. Il est accessible en voiture ou en bateau. Le créneau horaire de 9h00 correspond aux clients qui séjournent dans les quartiers de Silom, Sathorn et Bangrak.\"\n }\n ],\n \"end\": [\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5JOkQupk6XB3ZGmKbXXsO/YJsoMrLjHKBLlR6YXSp+r2\"\n },\n \"description\": \"Déposer au restaurant Samsen Centre pour le client qui part de Khaosan Area\"\n },\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5O9X4lT3Avg+rvKxoSJGnTIJr39qTywftTM5SgCNpowi\"\n },\n \"description\": \"Déposer au MBK Center , facile à connecter au BTS (train Sky) pour le client qui part du point de rendez-vous de River City\"\n }\n ],\n \"travelerPickup\": {\n \"pickupOptionType\": \"MEET_EVERYONE_AT_START_POINT\",\n \"allowCustomTravelerPickup\": false,\n \"locations\": [\n {\n \"location\": {\n \"ref\": \"MEET_AT_DEPARTURE_POINT\"\n },\n \"pickupType\": \"OTHER\"\n }\n ]\n }\n }\n}\n```\n\nIn case of product options without pickup, you shouldn't ask arrival or departure-related questions at checkout (but you will still need to answer the questions returned in the API using values hardcoded into your implementation). If you wish, you can display at checkout the meeting point location(s) for informational purposes (not collecting answers) but not the pickup locations and no questions related to arrival/departure should be displayed in that case.\n\nThe option to contact the supplier later (`\"CONTACT_SUPPLIER_LATER\"`) doesn't apply to this scenario either and should not be present as it applies only to product options with pickup.\n\nIn the answer to the `\"PICKUP_POINT\"` question, you will need to send the location reference `\"MEET_AT_DEPARTURE_POINT\"` (returned under `travelerPickup.locations`). In case the product returns the `\"TRANSFER_ARRIVAL_MODE\"` or `\"TRANSFER_DEPARTURE_MODE\"` questions, these must be answered with `\"OTHER\"`. \n\nProduct examples for testing: [**9025P51**](https://www.viator.com/tours/Belize-City/Private-Cave-Tubing-and-Zipline-Adventure-from-Belize-City/d5094-9025P51), [**62450P1**](https://www.viator.com/tours/Curacao/Guided-paddleboarding-SUP-mangrove-ECO-tour-for-beginners/d725-62450P1).\n\n**When other product options support transfer pickup**: \n\nWhile you might be booking a product option that **does not** support pickup, if the overall product itself supports, for example, pickup from an airport, in one of its *other* product options, it will contain the `\"TRANSFER_ARRIVAL_MODE\"` booking question in the `bookingQuestions[]` array in the product content response. \n\nThis means that this booking question, because it is `\"MANDATORY\"`, **must be answered** in order to make a valid booking, even though such information would be irrelevant in this context.\n\nTransfer arrival mode question details from [/products/booking-questions](#operation/productsBookingQuestions):\n\n```json\n{\n \"legacyBookingQuestionId\": 31,\n \"id\": \"TRANSFER_ARRIVAL_MODE\",\n \"type\": \"STRING\",\n \"group\": \"PER_BOOKING\",\n \"label\": \"Arrival mode\",\n \"allowedAnswers\": [\n \"AIR\",\n \"RAIL\",\n \"SEA\",\n \"OTHER\"\n ],\n \"required\": \"MANDATORY\"\n}\n```\n\nAs you can see, one of the allowed answers to this question is `\"OTHER\"`.\n\nTherefore, in the case that you must answer this booking question because it is stipulated at the product level, but it does not pertain to the product option being booked, **please do not prompt the user to provide an answer to this question**, rather, have your internal logic send the value `\"OTHER\"` as the answer; i.e.:\n\n ```json\n\"bookingQuestionAnswers\": [ \n {\n \"question\": \"TRANSFER_ARRIVAL_MODE\",\n \"answer\": \"OTHER\"\n },\n ...\n]\n```\n\nThe same applies for the `\"TRANSFER_DEPARTURE_MODE\"` booking question, as it is also mandatory and can be validly answered as `\"OTHER\"`. \n\nThe only `\"CONDITIONAL\"` booking question that must be answered for a product option without pickup (in addition to `\"MANDATORY\"` questions) is `\"PICKUP_POINT\"` (answer: `\"MEET_AT_DEPARTURE_POINT\"`)\n\n**Examples of booking requests**\n\nProduct: 9025P51\n\nProduct option details returned in the product content response:\n\n ```json\n\"productOptions\": [\n {\n \"productOptionCode\": \"TG1\",\n \"description\": \"share Group\",\n \"title\": \"Share Group Tour\",\n \"languageGuides\": [\n {\n \"type\": \"GUIDE\",\n \"language\": \"en\",\n \"legacyGuide\": \"en/SERVICE_GUIDE\"\n },\n {\n \"type\": \"GUIDE\",\n \"language\": \"es\",\n \"legacyGuide\": \"es/SERVICE_GUIDE\"\n }\n ]\n },\n {\n \"productOptionCode\": \"TG2\",\n \"description\": \"From 2 to 25 people traveling together on a private tour
Pickup included\",\n \"title\": \"Private Tour\",\n \"languageGuides\": [\n {\n \"type\": \"GUIDE\",\n \"language\": \"en\",\n \"legacyGuide\": \"en/SERVICE_GUIDE\"\n },\n {\n \"type\": \"GUIDE\",\n \"language\": \"es\",\n \"legacyGuide\": \"es/SERVICE_GUIDE\"\n }\n ]\n }\n],\n```\n\nExample booking request for product option with pickup (TG2):\n\n ```json\n{\n \"productCode\": \"9025P51\",\n \"productOptionCode\": \"TG2\",\n \"startTime\": \"08:00\",\n \"currency\": \"USD\",\n \"travelDate\": \"2024-11-27\",\n \"paxMix\": [\n {\n \"ageBand\": \"ADULT\",\n \"numberOfTravelers\": 2\n }\n ],\n \"partnerBookingRef\": \"test123456\",\n \"languageGuide\": {\n \"type\": \"GUIDE\",\n \"language\": \"en\"\n },\n \"bookerInfo\": {\n \"firstName\": \"XXXX\",\n \"lastName\": \"XXXX\"\n },\n \"bookingQuestionAnswers\": [\n {\n \"question\": \"FULL_NAMES_FIRST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"FULL_NAMES_LAST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"AGEBAND\",\n \"answer\": \"ADULT\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"AGEBAND\",\n \"answer\": \"ADULT\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"FULL_NAMES_FIRST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"FULL_NAMES_LAST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"TRANSFER_ARRIVAL_MODE\",\n \"answer\": \"OTHER\"\n },\n {\n \"question\": \"TRANSFER_DEPARTURE_MODE\",\n \"answer\": \"OTHER\"\n },\n {\n \"question\": \"PICKUP_POINT\",\n \"answer\": \"LOC-6eKJ+or5y8o99Qw0C8xWyGStvfcGJMWF/jrN0iaZD8s=\",\n \"unit\": \"LOCATION_REFERENCE\"\n }\n ],\n \"communication\": {\n \"phone\": \"+44 987667889\",\n \"email\": \"noreply@test.com\"\n },\n \"additionalBookingDetails\": {\n \"voucherDetails\": {\n \"companyName\": \"Test\",\n \"email\": \"customerservice@test.com\",\n \"phone\": \"+44 876778998\",\n \"voucherText\": \"Thank you for booking with us!\"\n }\n }\n}\n```\n\nExample booking request for product option without pickup (TG1):\n\n ```json\n{\n \"productCode\": \"9025P51\",\n \"productOptionCode\": \"TG1\",\n \"startTime\": \"08:00\",\n \"currency\": \"USD\",\n \"travelDate\": \"2024-11-27\",\n \"paxMix\": [\n {\n \"ageBand\": \"ADULT\",\n \"numberOfTravelers\": 2\n }\n ],\n \"partnerBookingRef\": \"test12345\",\n \"languageGuide\": {\n \"type\": \"GUIDE\",\n \"language\": \"en\"\n },\n \"bookerInfo\": {\n \"firstName\": \"XXXX\",\n \"lastName\": \"XXXX\"\n },\n \"bookingQuestionAnswers\": [\n {\n \"question\": \"FULL_NAMES_FIRST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"FULL_NAMES_LAST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"AGEBAND\",\n \"answer\": \"ADULT\",\n \"travelerNum\": 1\n },\n {\n \"question\": \"AGEBAND\",\n \"answer\": \"ADULT\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"FULL_NAMES_FIRST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"FULL_NAMES_LAST\",\n \"answer\": \"XXXX\",\n \"travelerNum\": 2\n },\n {\n \"question\": \"TRANSFER_ARRIVAL_MODE\",\n \"answer\": \"OTHER\"\n },\n {\n \"question\": \"TRANSFER_DEPARTURE_MODE\",\n \"answer\": \"OTHER\"\n },\n {\n \"question\": \"PICKUP_POINT\",\n \"answer\": \"MEET_AT_DEPARTURE_POINT\",\n \"unit\": \"LOCATION_REFERENCE\"\n }\n ],\n \"communication\": {\n \"phone\": \"+44 987667889\",\n \"email\": \"noreply@test.com\"\n },\n \"additionalBookingDetails\": {\n \"voucherDetails\": {\n \"companyName\": \"Test\",\n \"email\": \"customerservice@test.com\",\n \"phone\": \"+44 876778998\",\n \"voucherText\": \"Thank you for booking with us!\"\n }\n }\n}\n```\n\nTo learn more about booking questions and get a step-by-step guide on how to implement conditional booking questions, see this guide: Implementing Booking Questions.\n\n### Age-bands\n\nIf `\"AGEBAND\"` is specified as a booking question in the `bookingQuestions` array in the product content response, you must supply the age-band for each traveler in `bookingQuestionAnswers` when making the booking using [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook). \n\nFurthermore, the answer(s) to the `\"AGEBAND\"` booking question that you submit in the request to [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook) must match the age-bands given in the `paxMix` element in the request to [/bookings/hold](#operation/bookingsHold) or [/bookings/cart/hold](#operation/bookingsCartHold). Otherwise, the booking server will reject the booking on account of the booking and booking-hold not matching.\n\nThe valid age-bands for the product are given in the `pricingInfo` array in the product content response; e.g.:\n\n```json\n\"pricingInfo\": {\n \"type\": \"PER_PERSON\",\n \"ageBands\": [\n {\n \"ageBand\": \"INFANT\",\n \"startAge\": 0,\n \"endAge\": 4,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 9\n },\n {\n \"ageBand\": \"CHILD\",\n \"startAge\": 5,\n \"endAge\": 15,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 9\n },\n {\n \"ageBand\": \"ADULT\",\n \"startAge\": 16,\n \"endAge\": 99,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 9\n }\n ]\n},\n```\n\nNote that if `bookingRequirements.requiresAdultForBooking` is `true` in the product content response, at least one traveler must have an `\"ADULT\"` or `\"SENIOR\"` age-band.\n\nTo learn more about how age-bands are used during the booking process, see the following guide: [Implementing age bands & pax mix](https://partnerresources.viator.com/travel-commerce/merchant/agebands-pax-mix?source=specs).\n\n#### Age-bands with unit pricing\n\nIn the case that the product uses unit pricing; i.e., pricing based on the number of groups of travelers, then the product will have a single available age-band: `\"TRAVELER\"`, as given in the `pricingInfo` array in the product content response; e.g.:\n\n```json\n\"pricingInfo\": {\n \"type\": \"UNIT\",\n \"ageBands\": [\n {\n \"ageBand\": \"TRAVELER\",\n \"startAge\": 0,\n \"endAge\": 99,\n \"minTravelersPerBooking\": 1,\n \"maxTravelersPerBooking\": 10\n }\n ],\n \"unitType\": \"GROUP\"\n}\n```\n\nFor such products, even if `\"AGEBAND\"` is specified as a booking question, the only applicable age-band is `\"TRAVELER\"`. However, you must still supply this value for the age-band booking question for each traveler when making the booking using [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook). Even if `bookingRequirements.requiresAdultForBooking` is `true` for such products, you must still supply the `\"TRAVELER\"` value.\n\n## Booking cutoff times\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nThis section describes how the booking cutoff time information given by the product supplier, which may affect a product's availability (and therefore its ability to be booked) is communicated via this API. While you are welcome to develop logic to support the display and utilisation of this information, **it is not necessary to do so**. Indeed, as most implementations are unlikely to benefit, we recommend simply using the real-time [/availability/check](#operation/availabilityCheck) endpoint as the primary means to determine and communicate a product's availability in your product booking workflow.\n\nMany products in our inventory are subject to a booking cutoff time. Tickets for such products may only be purchased up until a certain time. This information is given in the `bookingConfirmationSettings` object in the [product content response](#section/Key-concepts/Product-content-and-availability-endpoints).\n\nExample `bookingConfirmationSettings` object:\n\n```json\n\"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"START_TIME\",\n \"bookingCutoffInMinutes\": 0,\n \"confirmationType\": \"INSTANT\"\n},\n```\n\nThere are four booking cutoff types, indicated by the value of the `bookingCutoffType` element; they are:\n - `\"START_TIME\"` – booking cutoff is relative to the product's start time\n - `\"OPENING_TIME\"` – booking cutoff is relative to the product's opening time\n - `\"CLOSING_TIME\"` – booking cutoff is relative to the product's closing time\n - `\"FIXED_TIME\"` – booking cutoff is relative to the time given in the `bookingCutoffFixedTime` element\n\nIn addition, the booking cutoff time may be offset by the number of minutes given in `bookingCutoffInMinutes`; for example, product 57377P9's booking cutoff is 120 minutes prior to its start time:\n\n```json\n\"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"START_TIME\",\n \"bookingCutoffInMinutes\": 120,\n \"confirmationType\": \"INSTANT\"\n}\n```\n\nThe availability of products that have a `bookingCutoffType` of `\"START_TIME\"` can be determined by inspecting the `pricingRecords[].timedEntries[].startTime` field in the response from [/availability/schedules/{product-code}](#operation/availabilitySchedules). This type of product can be booked up until `bookingCutoffInMinutes` prior to its starting time in the time-zone in which the product operates, which is given in the `timeZone` field in the [product content response](#section/Key-concepts/Product-content-and-availability-endpoints).\n\nThe booking cutoff time for products with a `\"FIXED_TIME\"` type is that given in the `bookingCutoffFixedTime` element, offset by the number of minutes given in `bookingCutoffInMinutes`. In the fixed time scenario, `bookingCutoffInMinutes` can only be 0, 1440 (24 hours) or 2880 (48 hours). This means that the booking cutoff time is at a certain time on the day on which the product operates; or, at that same time but one or two days before the tour date, respectively.\n\nIn the following example, the booking cutoff is 10:00am on the day before the tour or activity operates:\n\n```json\n\"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"FIXED_TIME\",\n \"bookingCutoffInMinutes\": 1440,\n \"confirmationType\": \"INSTANT\",\n \"bookingCutoffFixedTime\": \"10:00:00\"\n}\n```\n\nYou may not be able to book a product (using [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook)) or place a booking hold on a product using [/bookings/hold](#operation/bookingsHold) or [/bookings/cart/hold](#operation/bookingsCartHold) after it is past the booking cutoff time. However, this is not always the case. Always check real-time availability using the [/availability/check](#operation/availabilityCheck) endpoint.\n\nNonetheless, in displaying the availability of a product on your site, you may wish to mark products as 'unavailable' for a particular day or starting time if it is presently past the booking cutoff time if you feel that doing so will improve your site's UX.\n\nHowever, because the availability schedule data in general can rapidly fall out of date, **we again encourage you to always utilise the real-time [/availability/check](#operation/availabilityCheck) endpoint as the primary means to determine and communicate a product's availability in your product booking workflow.**\n\n## Booking confirmation types\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nA product's booking confirmation type indicates whether the booking will be confirmed or rejected immediately and automatically; or, whether it will remain in a 'pending' state until actioned manually by the supplier.\n\nThe product's booking confirmation type can be identified by the value of `bookingConfirmationSettings.confirmationType` in the product content response. There are three confirmation types: **instant**, **manual** and **instant-then-manual**, represented by the `confirmationType` values `\"INSTANT\"`, `\"MANUAL\"` and `\"INSTANT_THEN_MANUAL\"`, respectively.\n\n### Booking confirmation type in the API\n\n#### Instant confirmation:\n\nInstant confirmation products are confirmed automatically at the time of booking, and the customer should be charged immediately.\n\nE.g. (product-code: 5010SYDNEY):\n\n```json\n\"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"CLOSING_TIME\",\n \"bookingCutoffInMinutes\": 0,\n \"confirmationType\": \"INSTANT\"\n}\n```\n\n#### Manual confirmation\n\nManual confirmation products are those that only operate at the discretion of the supplier, who must confirm or reject each booking request manually. Once the booking is requested, it will remain in a 'pending' state until actioned by the supplier; or, if no action is taken by the supplier, the time-out period (72 hours) is exceeded. The customer should only be charged once confirmation is received.\n\nE.g. (product-code: 161500P1):\n\n```json\n\"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"START_TIME\",\n \"bookingCutoffInMinutes\": 1440,\n \"confirmationType\": \"MANUAL\"\n}\n```\n\n#### Instant-then-manual confirmation\n\nInstant-then-manual confirmation products behave like instant confirmation products up until a certain time prior to the product's starting time. From that point on, the product will require manual confirmation by the supplier.\n\nE.g. (product-code: 100035P1):\n\n```json\n\"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"START_TIME\",\n \"bookingCutoffInMinutes\": 720,\n \"confirmationType\": \"INSTANT_THEN_MANUAL\",\n \"manualConfirmationPeriod\": 2880\n}\n```\n\nThe `manualConfirmationPeriod` indicates when the product changes from instant to manual confirmation. In the example above, this period is 2880 minutes (48 hours or 2 days). Therefore, this product will be confirmed instantly if the booking is made more than 2 days in advance of the start time (in the time zone in which the product operates); if the booking is made less than 2 days in advance, it will require manual confirmation from the supplier.\n\n### How to support manual confirmation products\n\nIn order to support manual confirmation products on your site, you will need to introduce support for an asynchronous flow that monitors the booking's status, determines when its status changes and notifies the customer when their booking has been confirmed or rejected by the supplier.\n\nYou will need to:\n\n- Create back-end logic that periodically checks the status of pending bookings using the [/bookings/status](#operation/bookingsStatus) endpoint (we recommend polling no more than once every 3 minutes)\n- Establish and support an extra, email-based communications channel with your customers\n- Create email templates for the various scenarios that may arise\n- Ensure that your platform's front end accommodates the extra steps required in the booking process\n- Ensure that customers clearly understand that they are booking a product that will not be confirmed or charged immediately\n\n#### Product detail page\n\nManaging customer expectations is a key factor in supporting manual confirmation products on your booking platform. \n\nMake clear mention on the product detail page that confirmation will not be received immediately, but rather within 72 hours of making the booking.\n\nYou are free to include this note in the **Additional Info** section, or elsewhere on your product display page; for example:\n\n
\n \"Manual\n
Manual confirmation info displayed on a product page on the Viator site\n
\n
\n\n#### Check-out\n\nAs you will only charge the customer's credit card once the booking is confirmed by the product's supplier, it's best to display a message to this effect at a prominent point of the check-out flow for all manual confirmation products.\n\n
\n \"Example\n
Example checkout-flow instruction on the Viator site
\n
\n\nIn this way, customers can be reassured that they are not being charged for a booking that may never be confirmed, thereby helping to reduce the number of calls to your customer service team.\n\n#### Combination purchases\n\nIf your customer has both instant and manual booking confirmation products in their shopping cart, only the amount for the confirmed booking(s) should be charged immediately; the portion corresponding to the pending bookings should be held as a pre-authorization against the customer’s credit card, and the transaction completed only once confirmation is received. \n\nIt is important that you clearly differentiate between bookings that have been confirmed and those that are pending confirmation and communicate the status of each item. Also, be sure to make clear that the pre-authorization will only finalize once the manual confirmation bookings are confirmed.\n\n#### Confirmation page\n\nChanges will need to be made to your confirmation page because it will not be possible for your customer to download their voucher immediately after completing a manual confirmation booking. Rather, the voucher will be made available after the booking is confirmed.\n\nVouchers for instant confirmation products, however, must be made available immediately following the completion of the booking process.\n\n#### Customer communications\n\nConfirmation message (e.g., email) templates for manual confirmation bookings should indicate that the item is pending confirmation from the supplier; and, that confirmation for this activity will take up to 72 hours, depending on availability.\n\nYou will also need to create templates for the following scenarios:\n\n- When the manual confirmation booking is confirmed by the supplier (this time including the voucher details)\n- If the manual confirmation booking is rejected\n- If multiple manual confirmation products have been booked:\n + When all items have been accepted/confirmed\n + When there are mixed statuses; i.e., 'pending' + 'rejected' + 'canceled'\n + If all items were rejected\n- If a mixture of instant and manual confirmation products are booked at the same time; i.e., in the same cart\n\n**Note**: When a booking is declined, it is useful to mention that the customer's card was not charged.\n\n##### Example email for a manual confirmation booking pending confirmation:\n\n
\n \"Viator\n \"Viator\n \"Viator\n
\n\n### Confirmation time-outs resulting in rejection\n\nAs mentioned above, when a booking request for a manual confirmation product is made, it will have a status of 'pending' until it is confirmed by the supplier. The supplier has the option of confirming or rejecting the booking.\n\nIf the supplier does not confirm the booking within 72 hours – or, if they have not confirmed the booking by the time it reaches `bookingCutoffInMinutes` from the product's start time or whichever is specified in the `bookingCutoffType` – our systems will automatically reject the booking, and this will be reflected in the response from the [/bookings/status](#operation/bookingsStatus) endpoint.\n\n### Building in the sandbox environment\n\nUpgrading your booking platform to support manual confirmation products will require you to build and test this functionality in the sandbox environment.\n\nThe testing workflow depends on which endpoint you’re using to perform bookings:\n\n\n#### [/bookings/book](#operation/bookingsBook) Endpoint\nIn the sandbox environment, booking requests are not sent to the supplier’s system.\n\nBy default, manual-confirmation products behave like instant-confirmation products and return:\n\n- `bookingStatus = CONFIRMED`\n\nTo simulate the correct manual-confirmation behavior, you must set the request header:\n\n- `exp-demo: false`\n\nWhen `exp-demo` is set to `false, the response will return:\n\n- `bookingStatus = PENDING` (expected behavior for manual-confirmation products)\n\n#### [/bookings/cart/book](#operation/bookingsCartBook) Endpoint\nFor manual-confirmation products, you must set the following request header:\n\n- `exp-demo: false`\n\nThe response will return:\n\n- `bookingStatus = PENDING` (expected manual-confirmation behavior)\n\n#### Completing the Test Flow\n\nTo simulate the final supplier decision, contact API Tech Support at apitechsupport@viator.com and provide the bookingRef to request a status update to:\n\n- `CONFIRMED`, or\n- `REJECTED`\n\n## Making a booking\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nBroadly speaking, to book a product via this API, you must do the following:\n\n1. **Check availability and pricing**: Determine that a ticket for the desired tour or activity is available for a specific date, time and passenger mix combination using the [/availability/check](#operation/availabilityCheck) endpoint. Accurate pricing details in the currency that you wish to be invoiced in (one of GBP, EUR, USD, CAD or AUD) are also returned in the response from this endpoint. This includes `recommendedRetailPrice` and `partnerNetPrice`.

\n2. **Request a booking hold**: If a ticket is available, request a pricing/availability hold for the booking using the [/bookings/hold](#operation/bookingsHold) or [/bookings/cart/hold](#operation/bookingsCartHold) endpoints.

\n3. **Collect payment**: With a booking hold requested and suitable to proceed, collect payment using the iframe solution or via your own payment details form and submit using the API solution. Note: These payment options are only available to affiliate partners with API access level \"Full Access + Booking\".

\n4. **Confirm the booking**: Confirm/finalize the held booking using the [/bookings/book](#operation/bookingsBook) or [/bookings/cart/book](#operation/bookingsCartBook) endpoints.\n\nSee Getting availability and pricing for products and Creating a seamless booking experience for more information.\n\n\n\n## Cancellation API workflow\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nAll booking cancellations (except for those requested after the date of travel) must now be performed via the API. Viator no longer offers ordinary cancellation services via our customer support function. To cancel a booking after the tour or activity has occurred, please contact [Viator Partner Support](mailto:dpsupport@viator.com) \n\nSee our in-depth guide about cancellation policies and how to handle cancellations: [All you need to know about cancellation policies](https://partnerresources.viator.com/travel-commerce/merchant/cancellation-policies/?source=specs).\n\n### Getting cancellation reasons\n\n\nWhen canceling a booking, you are required to submit a valid 'reason for the cancellation' to assist with Viator's internal processes. This is accomplished via the inclusion of a valid reason code in the body of the request. The reason codes can be retrieved from the [/bookings/cancel-reasons](#operation/bookingsCancelReasons) endpoint.\n\nAs the acceptable reasons for cancellation may be altered at any point, we recommend retrieving an up-to-date list from this endpoint at least weekly.\n\nThe output from the [/bookings/cancel-reasons](#operation/bookingsCancelReasons) endpoint at the time of writing is as follows:\n\n```json\n{\n \"reasons\": [\n {\n \"cancellationReasonText\": \"Supplier No Show\",\n \"cancellationReasonCode\": \"Customer_Service.Supplier_no_show\"\n },\n {\n \"cancellationReasonText\": \"Chose a different/cheaper tour\",\n \"cancellationReasonCode\": \"Customer_Service.Chose_a_different_cheaper_tour\"\n },\n {\n \"cancellationReasonText\": \"Unexpected medical circumstances\",\n \"cancellationReasonCode\": \"Customer_Service.Unexpected_medical_circumstances\"\n },\n {\n \"cancellationReasonText\": \"Weather\",\n \"cancellationReasonCode\": \"Customer_Service.Weather\"\n },\n {\n \"cancellationReasonText\": \"Booked wrong tour date\",\n \"cancellationReasonCode\": \"Customer_Service.Booked_wrong_tour_date\"\n },\n {\n \"cancellationReasonText\": \"Duplicate Booking\",\n \"cancellationReasonCode\": \"Customer_Service.Duplicate_Booking\"\n },\n {\n \"cancellationReasonText\": \"Significant global event\",\n \"cancellationReasonCode\": \"Customer_Service.Significant_global_event\"\n },\n {\n \"cancellationReasonText\": \"I canceled my entire trip\",\n \"cancellationReasonCode\": \"Customer_Service.I_canceled_my_entire_trip\"\n }\n ]\n}\n```\n\n### Canceling a booking\n\n#### Getting a cancellation quote\n\nBefore canceling the booking, call the [/bookings/{booking-reference}/cancel-quote](#operation/bookingsCancelQuote) endpoint to get information about whether the booking can be canceled using this endpoint and what the refund will be, for example:\n\n```\nGET https://api.viator.com/partner/bookings/BR-580254558/cancel-quote\n```\n\n- **Note**: For bookings made with v1 of this API, this code corresponds to `data.itemSummaries[].itemId` (in the response from v1's [/booking/book](https://docs.viator.com/partner-api/merchant/technical/#tag/Booking-services/paths/~1booking~1book/post) endpoint) but prepended with `BR-`. For example, if the `itemId` is `580254558`, this field should be `BR-580254558`.\n\nYou will receive a cancellation quote object, e.g.:\n\n```json\n{\n \"bookingId\": \"BR-580254558\",\n \"status\": \"CANCELLABLE\",\n \"refundDetails\": {\n \"itemPrice\": 109.77,\n \"refundAmount\": 109.77,\n \"currencyCode\": \"USD\",\n \"refundPercentage\": 100.00\n }\n}\n```\n\n **Note**: Bookings that have not been confirmed by the supplier and have a status of `\"PENDING\"` will report an `itemPrice`, `refundAmount` and `refundPercentage` of `0`, as no fees are charged until the booking's status is `\"CONFIRMED\"`.\n \n\nThe data elements in this object have meanings as follows:\n\n| Element | Meaning | Example |\n|---------|---------|---------|\n| `bookingId` | the booking reference number prepended with `BR-` | `BR-580254556` |\n| `status` | One of the following: | `CANCELLABLE` |\n| `refundDetails` | object containing information about the refund | |\n| `itemPrice` | the **merchant net price** + **transaction fee** for this product at the time of booking in the currency specified by `currencyCode` | `109.77` |\n| `refundAmount` | the amount that will be deducted from your invoice if the booking is cancelled now | `109.77` |\n| `currencyCode` | the currency code for the currency in which pricing information is displayed | `USD` |\n| `refundPercentage` | the refund amount expressed as a percentage of the `itemPrice` | `100.00` |\n\n\n**Will there ever be a discrepancy between the amount charged for a tour and the amount refunded due to currency exchange-rate fluctuations?**\n\n- In short: no. I.e., if the cost of the booking was USD 100 and the refund percentage is 100% (full refund, as per the response from [/bookings/{booking-reference}/cancel-quote](#operation/bookingsCancelQuote)), Viator will simply **not invoice you** for that USD 100 that we would have if the booking had not been canceled. Furthermore, we do not invoice you for the cost of a booking prior to its departure date.\n\n\n\n#### Requesting the cancellation\n\nIf the `status` field has a value of `CANCELLABLE` and you are happy with the `refundAmount`, call the [/bookings/{booking-reference}/cancel](#operation/bookingsCancel) endpoint to cancel the booking, e.g.:\n\n```\nPOST https://api.viator.com/partner/bookings/BR-580254558/cancel\n```\n\nA reason code corresponding to the reason for cancellation must be included in the request body; e.g.:\n\n```json\n{\n \"reasonCode\":\"Customer_Service.Chose_a_different_cheaper_tour\"\n}\n```\n\nYou should receive a response indicating that the cancellation was successful, e.g.:\n\n```json\n{\n \"bookingId\": \"BR-580254558\",\n \"status\": \"ACCEPTED\"\n}\n```\n\nA `status` of `ACCEPTED` indicates that the booking was successfully canceled.\n\n\n## Checking booking status\n\n**Note**: This section applies to affiliate partners with API access level \"Full Access + Booking\" and merchant partners only.\n\nOnce a booking has been made, you can check on its status using the [/bookings/status](#operation/bookingsStatus) endpoint.\n\nYou can use **either** the `bookingRef` **or** `partnerBookingRef` in the request to this service.\n\n- If the booking was made using v1 of the Viator Partner API, you will receive a HTTP 400 Bad Request response. Only bookings made using v2 or later of this API are compatible with this endpoint.\n- If the booking is the subject of a booking hold (via [/bookings/hold](#operation/bookingsHold) or [/bookings/cart/hold](#operation/bookingsCartHold)) but the booking has not yet been confirmed using [/bookings/book](#operation/bookingsBook), you will receive a HTTP 404 Not Found response.\n- If the booking was confirmed but later canceled, you will receive a HTTP 200 Success response that indicates the canceled status.\n- If the booking has been confirmed and has not been canceled, you will receive a response with the same structure as the response from [/bookings/book](#operation/bookingsBook)\n\n### Confirmed booking\n\n**Example request**: Get the status of the booking with the booking reference `\"BR-791143912\"`\n\n```json\n{\n \"bookingRef\": \"BR-791143912\"\n}\n```\n\n**Example response**: The status of this booking is `\"CONFIRMED\"`\n\n```json\n{\n \"status\": \"CONFIRMED\",\n \"bookingRef\": \"BR-791143912\",\n \"partnerBookingRef\": \"BR-791143912\",\n \"currency\": \"USD\",\n \"lineItems\": [\n {\n \"ageBand\": \"ADULT\",\n \"numberOfTravelers\": 2,\n \"subtotalPrice\": {\n \"price\": {\n \"recommendedRetailPrice\": 21.4,\n \"partnerNetPrice\": 20.52\n }\n }\n }\n ],\n \"totalPrice\": {\n \"price\": {\n \"recommendedRetailPrice\": 21.4,\n \"partnerNetPrice\": 20.52,\n \"bookingFee\": 1.23,\n \"partnerTotalPrice\": 21.75\n }\n },\n \"cancellationPolicy\": {\n \"type\": \"STANDARD\",\n \"description\": \"For a full refund, cancel at least 24 hours before the scheduled departure time.\",\n \"cancelIfBadWeather\": false,\n \"cancelIfInsufficientTravelers\": false,\n \"refundEligibility\": [\n {\n \"dayRangeMin\": 2,\n \"percentageRefundable\": 100,\n \"startTimestamp\": \"2020-11-10T02:04:15Z\",\n \"endTimestamp\": \"2021-03-30T23:00:00Z\"\n },\n {\n \"dayRangeMin\": 0,\n \"dayRangeMax\": 1,\n \"percentageRefundable\": 0,\n \"startTimestamp\": \"2021-03-31T23:00:00Z\",\n \"endTimestamp\": \"2021-04-01T23:00:00Z\"\n }\n ]\n },\n \"voucherInfo\": {\n \"url\": \"https://www.viator.com/ticket?code=1187186744:8ac3e6308555ab632fe89e8a6b83c41620e840a3bc485f6e0d836192eae1ffc4\",\n \"format\": \"HTML\",\n \"type\": \"STANDARD\"\n }\n}\n```\n\n\n### Canceled booking\n\n**Example request**: Get the status of the booking with the partner booking reference `\"test-partner-ref-aejsmont-num-1604985575\"`\n\n```json\n{\n \"partnerBookingRef\": \"test-partner-ref-aejsmont-num-1604985575\"\n}\n```\n\n**Example response**: The status of this booking is `\"CANCELED\"`\n\n```json\n{\n \"bookingRef\": \"BR-582323272\",\n \"status\": \"CANCELED\",\n \"partnerBookingRef\": \"test-partner-ref-aejsmont-num-1604985575\"\n}\n```\n\n# Testing\n\n## Postman collections for testing\n\nPlease use one of the following [Postman](https://www.getpostman.com/) collections, depending on which type of partner you are. The collections are configured for the **sandbox** base URL (`api.sandbox.viator.com`).\n\n - [Viator Basic-access Affiliate API Postman collection](Viator-Basic-Access-Affiliate-API-v2.postman_collection.json)\n - [Viator Full-access Affiliate API Postman collection](Viator-Affiliate-API-v2.postman_collection.json)\n - [Viator Full-access + Booking Affiliate API Postman collection](Viator-Affiliate-Booking-API-v2.postman_collection.json)\n - [Viator Merchant API Postman collection](Viator-Merchant-API-v2.postman_collection.json)\n\nTo access the **production** environment, replace `api.sandbox.viator.com` with `api.viator.com` in the endpoint URLs provided in the Postman collections for testing.\n\n**All testing must be done in Sandbox.** Production endpoints are for live bookings only and must not be used for testing under any circumstances. Sandbox provides access to the same products and functionality as Production unless stated otherwise.\n\n### Set up the `your-api-key` environment variable\n\nAs all services in this API require that your API-key be passed as a header parameter in every request made to this API, this value has been set to reference a Postman environment variable called `your-api-key`.\n\nOnce you import the collection into Postman, [set this variable](https://learning.getpostman.com/docs/postman/environments_and_globals/variables#defining-collection-variables) to your organization's API-key and save the collection.\n\n# Workflows\n\n## Ingesting and updating the product catalogue\n\nThe recommended way to initialize and keep your local copy of our products database up-to-date is by using the [/products/modified-since](#operation/productsModifiedSince) endpoint in the following way:\n\n### Initialize your local copy of our products database by ingesting all product records\n\nMake a request to [/products/modified-since](#operation/productsModifiedSince), but only include the `count` parameter. Do not supply values for `modified-since` or `cursor`. This instructs the system to return any products modified since the beginning of time; i.e., all of them.\n\n**Note**: This is the only occasion on which you will need to call [/products/modified-since](#operation/productsModifiedSince) without the `modified-since` or `cursor` parameter.\n\n`count` specifies how many product records will be returned per page. For practical purposes, setting `count` to its maximum value (500) is advised. However, for the purposes of brevity, I am using a `count` of `5` in this example; i.e.:\n\n```\nGET https://api.sandbox.viator.com/partner/products/modified-since?count=5\n```\n\nYou will receive a response similar to the following:\n\n```json\n{\n \"products\": [\n {\n \"status\": \"ACTIVE\",\n \"productCode\": \"92457P4\",\n \"language\": \"en-US\",\n \"createdAt\": \"2020-06-16T12:49:29.519174Z\",\n \"lastUpdatedAt\": \"2020-11-08T16:26:16Z\",\n \"title\": \"Ecuador Parapente Quito\",\n \"ticketInfo\": {\n \"ticketTypes\": [\n \"MOBILE_ONLY\"\n ],\n \"ticketTypeDescription\": \"Mobile or paper ticket accepted\",\n \"ticketsPerBooking\": \"ONE_PER_BOOKING\",\n \"ticketsPerBookingDescription\": \"One per booking\"\n },\n \"pricingInfo\": {\n \"type\": \"PER_PERSON\",\n \"ageBands\": [\n {\n \"ageBand\": \"INFANT\",\n \"startAge\": 6,\n \"endAge\": 17,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 4\n },\n {\n \"ageBand\": \"ADULT\",\n \"startAge\": 18,\n \"endAge\": 60,\n \"minTravelersPerBooking\": 0,\n \"maxTravelersPerBooking\": 4\n }\n ]\n },\n \"images\": [\n {\n \"imageSource\": \"SUPPLIER_PROVIDED\",\n \"caption\": \"\",\n \"isCover\": true,\n \"variants\": [...\n ],\n \"logistics\": {\n \"start\": [\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5Cdd0Y9TkTxkcosDq0rJgjR12IzpogNi5POX+yGLXEoq\"\n },\n \"description\": \"The meeting point is on the way to Lumbisí km 1 at the entrance to La Primavera at 8:30 am.\"\n }\n ],\n \"end\": [\n {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5Cdd0Y9TkTxkcosDq0rJgjR12IzpogNi5POX+yGLXEoq\"\n },\n \"description\": \"The meeting point is on the way to Lumbisí km 1 at the entrance to La Primavera at 8:30 am.\"\n }\n ],\n \"redemption\": {\n \"redemptionType\": \"NONE\",\n \"specialInstructions\": \"\"\n },\n \"travelerPickup\": {\n \"pickupOptionType\": \"MEET_EVERYONE_AT_START_POINT\",\n \"\ allowCustomTravelerPickup\": true\n }\n },\n \"timeZone\": \"America/Guayaquil\",\n \"description\": \"the only legal paragliding operator in ecuador. See an amazing view of Quito and its surroundings from above.\",\n \"inclusions\": [\n {\n \"category\": \"OTHER\",\n \"categoryDescription\": \"Other\",\n \"type\": \"OTHER\",\n \"typeDescription\": \"Other\",\n \"otherDescription\": \"Paragliding Kit\"\n },\n {\n \"category\": \"OTHER\",\n \"categoryDescription\": \"Other\",\n \"type\": \"OTHER\",\n \"typeDescription\": \"Other\",\n \"otherDescription\": \"Air-conditioned vehicle\"\n }\n ],\n \"additionalInfo\": [\n {\n \"type\": \"STROLLER_ACCESSIBLE\",\n \"description\": \"Infants and small children can ride in a pram or stroller\"\n },\n {\n \"type\": \"NO_PREGNANT\",\n \"description\": \"Not recommended for pregnant travelers\"\n },\n {\n \"type\": \"NO_HEART_PROBLEMS\",\n \"description\": \"Not recommended for travelers with poor cardiovascular health\"\n },\n {\n \"type\": \"PHYSICAL_EASY\",\n \"description\": \"Suitable for all physical fitness levels\"\n }\n ],\n \"cancellationPolicy\": {\n \"type\": \"STANDARD\",\n \"description\": \"For a full refund, cancel at least 24 hours before the scheduled departure time.\",\n \"cancelIfBadWeather\": true,\n \"cancelIfInsufficientTravelers\": false,\n \"refundEligibility\": [\n {\n \"dayRangeMin\": 1,\n \"percentageRefundable\": 100\n },\n {\n \"dayRangeMin\": 0,\n \"dayRangeMax\": 1,\n \"percentageRefundable\": 0\n }\n ]\n },\n \"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"FIXED_TIME\",\n \"bookingCutoffInMinutes\": 1440,\n \"confirmationType\": \"INSTANT\",\n \"bookingCutoffFixedTime\": \"16:00:00\"\n },\n \"bookingRequirements\": {\n \"minTravelersPerBooking\": 1,\n \"maxTravelersPerBooking\": 4,\n \"requiresAdultForBooking\": false\n },\n \"bookingQuestions\": [\n \"FULL_NAMES_LAST\",\n \"PASSPORT_EXPIRY\",\n \"PASSPORT_PASSPORT_NO\",\n \"SPECIAL_REQUIREMENTS\",\n \"FULL_NAMES_FIRST\",\n \"WEIGHT\",\n \"AGEBAND\",\n \"HEIGHT\",\n \"PASSPORT_NATIONALITY\"\n ],\n \"tags\": [\n 20234\n ],\n \"destinations\": [\n {\n \"ref\": \"735\",\n \"primary\": true\n }\n ],\n \"itinerary\": {\n \"itineraryType\": \"ACTIVITY\",\n \"skipTheLine\": false,\n \"privateTour\": true,\n \"duration\": {\n \"fixedDurationInMinutes\": 15\n },\n \"activityInfo\": {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5Cdd0Y9TkTxkcosDq0rJgjR12IzpogNi5POX+yGLXEoq\"\n },\n \"description\": \"We take off from the hill of Lumbisi towards the City, we observe the landscape of the city of Quito you can observe the mountains. We landed at the foot of the hill.\\n\\nThe meeting point is on the way to Lumbisí km 1 at the entrance to La Primavera at 8:30 am. From there we got on a vehicle to the mountain. \"\n }\n },\n \"productOptions\": [\n {\n \"productOptionCode\": \"TG1\",\n \"description\": \"\",\n \"title\": \"Ecuador Parapente Quito\"\n }\n ],\n \"translationInfo\": {\n \"containsMachineTranslatedText\": false\n },\n \"supplier\": {\n \"name\": \"Opeturmo - Parapente Montanita\"\n }\n },\n {\n \"status\": \"INACTIVE\",\n \"productCode\": \"141567P21\",\n \"language\": \"en-US\",\n \"createdAt\": \"2019-10-08T13:12:21.535614Z\",\n \"lastUpdatedAt\": \"2020-11-13T13:41:18Z\"\n },\n {\n \"status\": \"INACTIVE\",\n \"productCode\": \"8932P17\",\n \"language\": \"en-US\",\n \"createdAt\": \"2019-06-03T13:29:09.131851Z\",\n \"lastUpdatedAt\": \"2020-11-13T13:42:38Z\"\n },\n {\n \"status\": \"INACTIVE\",\n \"productCode\": \"58593P53\",\n \"language\": \"en-US\",\n \"createdAt\": \"2020-11-13T13:46:39.927509Z\",\n \"lastUpdatedAt\": \"2020-11-13T13:51:43Z\"\n },\n {\n \"status\": \"INACTIVE\",\n \"productCode\": \"164413P1\",\n \"language\": \"en-US\",\n \"createdAt\": \"2019-06-14T00:29:29.039245Z\",\n \"lastUpdatedAt\": \"2020-11-13T14:22:08Z\"\n }\n ],\n \"nextCursor\": \"MTYwNTI3NzMyOHwxNjQ0MTNQMXxJTkFDVElWRQ==\"\n}\n```\n\nThe example above gives the first five product records in the catalogue, with modification dates in chronological order. Note that products with a `\"status\"` of `\"INACTIVE\"` are products that have been temporarily disabled by the supplier and are therefore unavailable – when this is the case, all other requests for this product should be avoided. \n\nIncluded in the response is the `nextCursor` element, which contains an identification code that points to the next page of product records; i.e.:\n\n```json\n\"nextCursor\": \"MTYwNTI3NzMyOHwxNjQ0MTNQMXxJTkFDVElWRQ==\"\n```\n\nIn your next call to [/products/modified-since](#operation/productsModifiedSince), provide the value of `nextCursor` in the `cursor` parameter to get the next page of results:\n\n```\nGET https://api.sandbox.viator.com/partner/products/modified-since?count=500&cursor=MTYwNTI3NzMyOHwxNjQ0MTNQMXxJTkFDVElWRQ==\n```\n\nThe response will be similar to the initial response shown above, except it will contain the **next** 500 product records and a new `nextCursor` that points to the following page, and so on.\n\nContinue calling [/products/modified-since](#operation/productsModifiedSince) using the `nextCursor` value in the `cursor` parameter to retrieve all pages of results. You will eventually receive a response that contains an empty `products` array and does not contain a `nextCursor` element. The absence of the `nextCursor` element indicates that you have, for the time being, reached the end of the list and have received all product records from our catalogue.\n\n**Example final page response**\n\n```json\n{\n \"products\": []\n}\n```\n\n### Periodically update your product records\n\nNow that you have all product records from our catalogue, you can keep it up-to-date by periodically polling the service using the most-recent `nextCursor` code you received. Regardless of how frequently you call [/products/modified-since](#operation/productsModifiedSince), you will always receive all product update information so long as you keep track of the last cursor you received and use that in your subsequent call.\n\nYou should never need to re-ingest the entire product catalogue unless you need to re-initialize your database. This may happen frequently during development, but never (or rarely) in production. Due to the large volume of data, we strongly recommend keeping it to a minimum.\n\nProducts are considered updated when the supplier makes any changes to the product's details, excluding pricing and availability changes, which are retrieved from the [availability schedules](#section/Key-concepts/Product-content-and-availability-endpoints) endpoints. \n\nWhen the supplier publishes their product detail updates, the modified product [/products/modified-since](#operation/productsModifiedSince) service will respond to this same call with newly-modified products in the `products` array and a new `nextCursor` element with which to poll the service for future updates in the same way.\n\nIt would be reasonable to poll this service on an hourly basis, updating those records in your local copy of the product catalogue as they become available.\n\nNote that the `nextCursor` code is valid indefinitely; it will not expire.\n\n### Filtering out products\n\nYou are free to choose which products to store on your system and sell. As the product content endpoints return all available products, you will need to perform the filtering step yourself at the time of ingestion. If a product contains attributes that you do not desire; e.g., the type of product, where it operates, etc., simply discard the update and do not add it to your database.\n\n#### Filtering out manual-confirmation products\n\nUnless you have established the required functionality on your site to sell [manual confirmation products](#section/Booking-concepts/Booking-confirmation-types) you will need to **exclude** all non-instant confirmation products from your catalogue.\n\nInstant confirmation products can be identified by the value of `bookingConfirmationSettings.confirmationType` being `\"INSTANT\"` in the response [product content response](#section/Key-concepts/Product-content-and-availability-endpoints); e.g.:\n\n```json\n\"bookingConfirmationSettings\": {\n \"bookingCutoffType\": \"CLOSING_TIME\",\n \"bookingCutoffInMinutes\": 0,\n \"confirmationType\": \"INSTANT\"\n}\n```\n\nProducts wih a `confirmationType` of `\"MANUAL\"` or `\"INSTANT_THEN_MANUAL\"` should be excluded if you do not wish to sell manual confirmation products.\n\n**Please note**:\n\n- The product catalog must be ingested and updated using the [/products/modified-since](#operation/productsModifiedSince) endpoint, unless you are only selling a relatively small subset of the products available in the Viator catalog. If that is the case, you may prefer to use the [/products/bulk](#operation/productsBulk) endpoint to ingest your selected products. \n\n- **Important**: the [/products/{product-code}](#operation/products) endpoint should not be used for bulk ingestion purposes. Your product ingestion/update strategy is one of our certification requirements and must be verified by us prior to your accessing the production server. To find out what our certification requirements are, see: [Viator Merchant API Certification](https://partnerresources.viator.com/travel-commerce/merchant/certification/?source=specs).\n\n\n## Resolving references\n\nSome information in the product content response is not communicated explicity; but rather, by reference, and therefore requires an extra de-referencing step to acquire the full details of the element.\n\nThese data types comprise:\n\n- locations\n- destinations\n- tags\n\nThe following sections describe how to de-reference these elements using the API.\n\n### Location references\n\nAll locations within the product content response are given as a location reference; e.g.:\n\n```json\n \"activityInfo\": {\n \"location\": {\n \"ref\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5Cdd0Y9TkTxkcosDq0rJgjR12IzpogNi5POX+yGLXEoq\"\n },\n```\n\nThese location references can be resolved using the [/locations/bulk](#operation/locationsBulk) endpoint; for example:\n\n**Request**:\n\n```json\n{\n \"locations\": [\n \"LOC-o0AXGEKPN4wJ9sIG0RAn5Cdd0Y9TkTxkcosDq0rJgjR12IzpogNi5POX+yGLXEoq\",\n \"LOC-6eKJ+or5y8o99Qw0C8xWyK8Z2imHSU8Ozi+NYupJVyI=\"\n ]\n}\n```\n\n**Response**:\n\n```json\n{\n \"locations\": [\n {\n \"provider\": \"GOOGLE\",\n \"reference\": \"LOC-o0AXGEKPN4wJ9sIG0RAn5Cdd0Y9TkTxkcosDq0rJgjR12IzpogNi5POX+yGLXEoq\",\n \"providerReference\": \"ChIJS1UFbTyX1ZER0vTgCLKWCEQ\"\n },\n {\n \"provider\": \"TRIPADVISOR\",\n \"reference\": \"LOC-6eKJ+or5y8o99Qw0C8xWyK8Z2imHSU8Ozi+NYupJVyI=\",\n \"name\": \"Valley of the Roses\",\n \"address\": {\n \"street\": \"Dades Valley, near Bouteghrar\",\n \"administrativeArea\": \"El Kelaa M'gouna\",\n \"country\": \"Morocco\",\n \"countryCode\": \"MA\",\n \"postcode\": \"43000\"\n },\n \"center\": {\n \"latitude\": 34.00061,\n \"longitude\": -6.84494\n }\n }\n ]\n}\n```\n\nNote that there are two different location information providers, `\"TRIPADVISOR\"` and `\"GOOGLE\"`, referring to locations in the Tripadvisor location database or locations provided by the [Google Maps platform](https://cloud.google.com/maps-platform/) via the [Google Places API](https://developers.google.com/maps/documentation/places/web-service/overview), respectively. \n\nTripadvisor locations include full details of the location in the response from [/locations/bulk](#operation/locationsBulk), including address and geolocation information. However, you will need to use the [Google Places API](https://developers.google.com/maps/documentation/places/web-service/overview) to retrieve details for Google Maps locations.\n\nThe purpose of referring to locations by reference is to avoid the unnecessary transmission of duplicate data, as multiple products may include the same location reference. Therefore, we recommend caching the data received from this endpoint, checking this first to see if a particular location's details have been retrieved by your system in the past before making a request to [/locations/bulk](#operation/locationsBulk).\n\nRequests can be made to [/locations/bulk](#operation/locationsBulk) asynchronously; e.g., during the content ingestion process.\n\n\n### Destination references\n\nEvery product in the Viator catalogue is categorized according to the destination/locale in which it operates. \n\nThere are multiple kinds of destination, which includes cities, regions, countries and others\n\n**Example destinations***:\n\n| type | destinationId | destinationName |\n|-----------------|---------------|----------------------------|\n| AREA | 51912 | Machame |\n| CITY | 343 | Bangkok |\n| COUNTRY | 749 | Panama |\n| COUNTY | 51632 | Xiahe County |\n| DISTRICT | 51921 | Hunza |\n| HAMLET | | |\n| ISLAND | 51220 | Syros |\n| NATIONAL PARK | 51196 | Death Valley National Park |\n| NEIGHBORHOOD | 60465 | Kensington |\n| PENINSULA | 51769 | Michamwi |\n| PROVINCE | 51255 | Mendoza Province |\n| REGION | 4431 | Northern China |\n| STATE | | |\n| TOWN | 50971 | Swansea |\n| UNION TERRITORY | 51542 | Daman and Diu |\n| VILLAGE | 51011 | Pyrgos |\n| WARD | 52140 | Shibuya |\n\n* Notes:\n The examples above are subject to change.\n These are all currently supported destination types, though for some there are no live examples at the moment\n\n\nEvery product has one or more destinations associated with it by way of its destination reference. This is given in the `destinations` object in the response from any of the product content endpoints; e.g.:\n\n```json\n\"destinations\": [\n {\n \"ref\": \"34198\",\n \"primary\": true\n }\n],\n```\n\nTo de-reference destination identifiers, you must use our destination taxonomy, which can be retrieved from the [/destinations](#operation/destinations) endpoint.\n\nYou may wish to filter products according to destination.\n\nA call to [/destinations](#operation/destinations) will return data for **all** available destinations. \nYou must store a local copy of this mapping information, as destination data does not change frequently – i.e., new destinations are rarely added. \nOn-demand updates can be done in the event you encounter a product associated to a destination reference for which you do not have the details.\n\n\n**Example snippet of destination taxonomy**:\n\n```json\n{\n \"destinationId\": 34198,\n \"name\": \"Seminyak\",\n \"type\": \"CITY\",\n \"parentDestinationId\": 98,\n \"lookupId\": \"2.15.98.34198\",\n \"defaultCurrencyCode\": \"IDR\",\n \"timeZone\": \"Asia/Makassar\",\n \"center\": {\n \"latitude\": -8.68877,\n \"longitude\": 115.161267\n }\n},\n{\n \"destinationId\": 901,\n \"name\": \"Buenos Aires\",\n \"type\": \"CITY\",\n \"parentDestinationId\": 22280,\n \"lookupId\": \"9.78.22280.901\",\n \"destinationUrl\": \"https://shop.live.rc.viator.com/x/d901-ttd?mcid=42383&pid=P00108950&medium=api&api_version=2.0\",\n \"defaultCurrencyCode\": \"ARS\",\n \"timeZone\": \"America/Argentina/Buenos_Aires\",\n \"iataCode\": \"BUE\",\n \"center\": {\n \"latitude\": -34.6084175,\n \"longitude\": -58.3731613\n }\n},\n...\n```\n\nNote that destinations are organized into a hierarchy. The destination's position in the hierarchy can be determined according to the `parentDestinationId` and `lookupId` fields.\n\nIn the second example above, Buenos-Aires is a `\"CITY\"`, and it has a `parentDestinationId` of `22280`, which is the `destinationId` of \"The Pampas\" – the `\"REGION\"` in South America where Buenos-Aires is located.\n\nThe destination's full lineage with respect to the hierarchy is given in `lookupId`, which is a series of destination ids separated by periods - in this case:\n\n```json\n \"lookupId\": \"9.78.22280.901\"\n```\n\n| Component | Destination name | Destination type |\n|-----------|------------------|------------------|\n| 9 | (unnamed) | (broad continental designation) | \n| 78 | Argentina | \"COUNTRY\" |\n| 22280 | The Pampas | \"REGION\" |\n| 901 | Buenos-Aires | \"CITY\" |\n\nUsing this information, you are able to categorize each product into its geographical location for display and search purposes.\n\n### Tag references\n\nEach product is also categorized according to its content, features or theme. Each attribute has a corresponding identifier called a 'tag'. The tag references for each product are contained in the `tags` array, in the response from any of the product content endpoints.\n\n**Example tags array** (product [250380P1 – Surf lessons Bali, Canggu](https://www.viator.com/tours/Seminyak/Surf-lessons-Bali-Canggu/d34198-250380P1)): \n\n```json\n\n\"tags\": [\n 20246,\n 21946,\n 20244\n],\n```\n\nThese numeric tag identifiers can be de-referenced using information available from the [/products/tags](#operation/productsTags) endpoint. This service takes no parameters and retrieves information for **all** available tags.\n\nTo learn more about tags, see this article: [Viator tags, explained](https://partnerresources.viator.com/travel-commerce/tags?source=specs)\n\nWe recommend you store a local copy of this information, as tags do not change frequently. It is only necessary to re-ingest from this endpoint in the event you encounter a product that references a tag for which you do not have the details.\n\nAs with destinations, tags are organized into a hierarchy. A tag's relative position within that hierarchy can be determined by tracing back through its parent tag ids, which (if the tag has any) are listed in its `parentTagIds` element. Each tag can have multiple parent tags, and each tag can eventually be traced back to its parent. Parent tags are tags that have no parents; i.e., they are at the top of the hierachy.\n\nFor example, tag: **20244 (Sports Lessons)** in [/products/tags](#operation/productsTags) response:\n\n```json\n{\n \"tagId\": 20244,\n \"parentTagIds\": [\n 21478,\n 21909,\n 21915\n ],\n \"allNamesByLocale\": {\n \"de\": \"Sportkurse\",\n \"no\": \"Treningskurs\",\n \"sv\": \"Idrottslektioner\",\n \"pt\": \"Aulas de esportes\",\n \"en_AU\": \"Sports Lessons\",\n \"en\": \"Sports Lessons\",\n \"it\": \"Lezioni di sport\",\n \"fr\": \"Cours de sport\",\n \"en_UK\": \"Sports Lessons\",\n \"es\": \"Sesiones deportivas\",\n \"zh\": \"运动课\",\n \"zh_HK\": \"體育課程\",\n \"zh_TW\": \"運動課程\",\n \"ja\": \"スポーツ教室\",\n \"zh_CN\": \"运动课\",\n \"da\": \"Sportsundervisning\",\n \"nl\": \"Sportlessen\"\n }\n},\n\n```\n\nThe `parentTagIds` for 20244 - Sports lessons are:\n\n- **21478** – \"Active & Outdoor Classes\"\n- **21909** – \"Outdoor Activities\"\n- **21915** – \"Classes & Workshops\"\n\nThese three tags have no parent tags, and are therefore at the top of the hierarchy. Applying this same process to the other tags in the `tags` array, we can determine the full set of tags for this product, in this case:\n\n- **21909** – \"Outdoor Activities\"\n - **21478** – \"Active & Outdoor Classes\"\n - **20244** - \"Sports lessons\"\n- **21915** – \"Classes & Workshops\" \n- **21946** – \"Good for avoiding crowds\"\n- **21442** – \"On the water\"\n - **20246** – \"Surfing lessons\"\n\nBy traversing the hierarchy in this way, we have surfaced seven tags that pertain to this product with different levels of generality; i.e. it is an 'active and outdoor class', and it is a 'sports lesson'. More generally, it is an 'outdoor activity', a class or workshop, and is 'good for avoiding crowds':\n\nIn this way, you can categorize products for search and recommendation purposes, or to create category display and search buttons as seen on [viator.com 'things to do' pages](https://www.viator.com/Adelaide/d363-ttd); e.g.:\n\n![tag categories on viator.com](img/ttd-tags.png)\n\n\n## Ingesting and updating availability schedules\n\nAvailability schedule information for all products is available to be ingested and updated via the [/availablity/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) endpoint. This endpoint functions in a similar manner to the [/products/modified-since](#operation/productsModifiedSince) endpoint; i.e., an initial call is made that returns all availability data in bulk, and then calls are made periodically to that same endpoint, which will return a delta update.\n\nTherefore, to initialize your local copy of our availability schedule information, make a call to [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince), including only the `count` query parameter, which we recommend setting to `500`. \n\nFor the sake of brevity, in the following example, `count` is set to `5`\n\n**Example request**\n\n```\nGET https://api.viator.com/partner/availability/schedules/modified-since?count=5\n```\n\nYou will receive a response similar to the following:\n\n```json\n{\n \"availabilitySchedules\": [\n {\n \"productCode\": \"3320STOLZadvaft\",\n \"bookableItems\": [\n {\n \"seasons\": [\n {\n \"startDate\": \"2020-11-23\",\n \"endDate\": \"2020-12-22\",\n \"pricingRecords\": [\n {\n \"daysOfWeek\": [\n \"WEDNESDAY\",\n \"THURSDAY\",\n \"FRIDAY\",\n \"SATURDAY\",\n \"SUNDAY\"\n ],\n \"timedEntries\": [\n {\n \"startTime\": \"15:30\"\n }\n ],\n \"pricingDetails\": [\n {\n \"pricingPackageType\": \"PER_PERSON\",\n \"minTravelers\": 1,\n \"ageBand\": \"INFANT\",\n \"price\": {\n \"original\": {\n \"recommendedRetailPrice\": 0.00,\n \"partnerNetPrice\": 0.00,\n \"bookingFee\": 0.00,\n \"partnerTotalPrice\": 0.00\n }\n }\n },\n {\n \"pricingPackageType\": \"PER_PERSON\",\n \"minTravelers\": 1,\n \"ageBand\": \"ADULT\",\n \"price\": {\n \"original\": {\n \"recommendedRetailPrice\": 17.20,\n \"partnerNetPrice\": 11.50,\n \"bookingFee\": 0.69,\n \"partnerTotalPrice\": 12.19\n }\n }\n }\n ]\n }\n ]\n }\n ]\n }\n ],\n \"currency\": \"EUR\"\n },\n {\n \"productCode\": \"14093P1\",\n \"bookableItems\": [],\n \"currency\": \"EUR\"\n },\n {\n \"productCode\": \"3567AKL_SAF\",\n \"bookableItems\": [],\n \"currency\": \"NZD\"\n },\n {\n \"productCode\": \"5855RIPLEYS\",\n \"bookableItems\": [],\n \"currency\": \"USD\"\n },\n {\n \"productCode\": \"3033ENTRY_TR\",\n \"bookableItems\": [],\n \"currency\": \"USD\"\n }\n ],\n \"nextCursor\": \"MTU3ODA2Njc4NnwzMDMzRU5UUllfVFI=\"\n}\n```\n\nThe endpoint returns an array (`availabilitySchedules`) where each item contains all availabilty schedule information for a single product, and a cursor (`nextCursor`) that is to be used in subsequent calls to this endpoint to retrieve the next page of results.\n\nFor details on how to interpret the availability schedule object, see [Availability schedules](#section/Key-concepts/Availability-schedules).\n\n**Note**: An empty `bookableItems` array means that the product indicated by `productCode` is not active, has no availability, and therefore cannot be booked. This fact will be reflected if the product details are requested from the [/products/{product-code}](#operation/products) endpoint; e.g., for product `3033ENTRY_TR`:\n\n```json\n{\n \"status\": \"INACTIVE\",\n \"productCode\": \"3033ENTRY_TR\",\n \"language\": \"en\",\n \"createdAt\": \"2006-05-01T07:00:00Z\"\n}\n```\n\n### Pagination\n\nAs with the [/products/modified-since](#operation/productsModifiedSince) endpoint, you will receive as many records as requested via the `count` request parameter. Included in the response is the `nextCursor` element, which contains a code that points to the next page of availability records.\n\nAfter receiving this first response, your next request to the [/availablity/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) service should include the value of `nextCursor` in the `cursor` request parameter; i.e.:\n\n```\nGET https://api.sandbox.viator.com/partner/availability/schedules/modified-since?count=5&cursor=MTU3ODA2Njc4NnwzMDMzRU5UUllfVFI=\n```\n\nThe response will be similar to the initial response shown above, except it will contain the next `count` number of availability schedule records and a new `nextCursor` that points to the following page.\n\nLoop through this process until you receive a response that contains an empty `availabilitySchedules` array and does not contain a `nextCursor` element. The absence of the `nextCursor` element indicates that you have, for the time being, reached the end of the list and your availability information is fully up-to-date.\n\n**Example final page response**\n\n```json\n{\n \"availabilitySchedules\": []\n}\n```\n\n### Periodically update your availability information\n\nOnce your availability schedule information ingestion is complete, you can keep it up-to-date by periodically polling the service using the latest `nextCursor` code you received; i.e., from the page prior to the final, empty page. \n\nIf new availability schedule information is available, the service will respond with new availability information in the `availabilitySchedules` array and a new `nextCursor` element with which to poll the service for future updates in the same way. Note that the `nextCursor` code is valid indefinitely; it will not expire.\n\nAs with the [/products/modified-since](#operation/productsModifiedSince) endpoint, we recommend polling this service on an hourly basis. The longer the interval between updates, the more likely your availability information will be out of date, raising the likelihood of availability differences when you make a real-time availability check using the [/availability/check](#operation/availabilityCheck) service.\n\nAgain, you should only need to call [/availablity/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) without a `cursor` parameter **once**, for the first call of the initial ingestion. All future calls should include the `cursor` parameter and the results used to update your database.\n\n### Filtering out availability schedules\n\nAs you may not be offering Viator's full product catalogue for sale on your site, you are only required to store availability information for the products you support. Therefore, if you are filtering out products from our catalogue, you should also perform a check with regard to the availability schedule information received from the [/availablity/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) to ensure that it pertains to a product in your catalogue.\n\nThis can be done by checking the `productCode` field in the ProductAvailabilitySchedule object response.\n\n**Please note**:\n\n- The availability and pricing schedules must be ingested and updated using the [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) endpoint, unless you are only selling a relatively small subset of the products available in the Viator catalog. If that is the case, you may prefer to use the [/availability/schedules/bulk](#operation/availabilitySchedulesBulk) endpoint to ingest your selected product availability schedules. \n\n- **Important**: the [/availability/schedules/{product-code}](#operation/availabilitySchedules) endpoint should not be used for bulk ingestion purposes. Your availability schedule ingestion/update strategy is one of our certification requirements and must be verified by us prior to your accessing the production server. To find out what our certification requirements are, see: [Viator Merchant API Certification](https://partnerresources.viator.com/travel-commerce/merchant/certification/?source=specs).\n\n\n## Update frequency\n\nWe expect that your update frequency will not be more frequent than the following guidelines. More frequent updates will place an excessive burden on our systems and may result in your integration being shut off.\n\nSee section on [Rate Limiting](#section/Workflows/Rate-limiting) for more information.\n\n### Fixed-cadence delta updates\n\nIn order to keep your local databases up-to-date without placing an excessive burden on our servers, we expect you use the following fixed cadences at which you should poll the content-ingestion endpoints:\n\n| Endpoint | Update cadence |\n|-----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [/products/modified-since](#operation/productsModifiedSince) | Every 15-30 minutes following initial ingestion |\n| [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) | Every 15-30 minutes following initial ingestion |\n| [/bookings/modified-since](#operation/bookingsModifiedSince) | Every 5-10 minutes following initial ingestion to stop notification emails sent by Viator for supplier cancellations of bookings made through the API (merchant partners only).

Hourly for all other scenarios |\n| [/bookings/modified-since/acknowledge](#operation/bookingsModifiedSinceAcknowledge) | Right after ingesting the booking modifications |\n\n### Fixed-cadence full updates\n\nTo ensure your systems reflect any removals of or changes to existing destinations, locations or booking questions, we expect that you retrieve full updates from these endpoints as follows:\n\n| Endpoint | Update cadence |\n|---------------------------------------------------------------------------|----------------|\n| [/destinations](#operation/destinations) | Weekly |\n| [/attractions/search](#operation/attractionsSearch) | Weekly |\n| [/products/booking-questions](#operation/productsBookingQuestions) | Monthly |\n| [/products/tags](#operation/productsTags) | Weekly | \n| [/products/recommendations](#operation/productsRecommendations) | Weekly | \n| [/locations/bulk](#operation/locationsBulk) | Monthly |\n| [/reviews/product](#operation/reviewsProduct) | Weekly |\n| [/bookings/cancel-reasons](#operation/bookingsCancelReasons) | Monthly |\n| [/suppliers/search/product-codes](#operation/suppliersSearchProductCodes) | Weekly |\n| [/bookings/status](#operation/bookingsStatus) | Hourly |\n| [/exchange-rates](#operation/exchangeRates) | Daily |\n\n### On-demand updates\n\nWhen ingesting product content, in the event that you encounter an unknown reference – i.e., a new location reference, booking question, tag or destination id – or, if you need to perform a currency conversion for which the last exchange rate you retrieved has expired, we expect you to call the relevant endpoint to resolve the new reference immediately or just after completing the product content update.\n\n| Endpoint | When to update |\n|--------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [/exchange-rates](#operation/exchangeRates) | Whenever you encounter a currency that you need to convert, but the last-retrieved exchange-rate for that currency-pair is no longer valid due to having expired (according to the `expiry` value in the response from this endpoint) |\n| [/locations/bulk](#operation/locationsBulk) | Whenever you encounter a location reference code that you do not yet have the details for (we recommend retrieving location details in batches using this endpoint; therefore, the retrieval of new location data can commence after all new product content is retrieved) |\n| [/products/tags](#operation/productsTags) | Whenever you encounter a tag reference code that you do not yet have the details for |\n| [/destinations](#operation/destinations) | Whenever you encounter a destination id that you do not yet have the details for |\n| [/products/booking-questions](#operation/productsBookingQuestions) | Whenever you encounter a booking question identifier that you do not yet have the details for |\n| [/attractions/{attraction-id}](#operation/attractions) | Whenever you encounter an attraction identifier that you do not yet have the details for |\n| [/reviews/product](#operation/reviewsProduct) | If the number of reviews available for a product, which is reported in the `reviews.totalReviews` element in the [product content response](#section/Key-concepts/Product-content-and-availability-endpoints), has changed compared with its previous value, the reviews for that product should also be refreshed by calling the [/reviews/product](#operation/reviewsProduct) endpoint. We request that you rate-limit your use of this service to 30 requests per minute. |\n| [/bookings/status](#operation/bookingsStatus) | Whenever you encounter a booking waiting for manual confirmation. Must not be called more than once every 3 minutes. |\n\n## Rate limiting\n\nWe impose rate limits on the usage of this API to prevent excessive demands being made of our system that might otherwise affect its availability for all users.\n\nOur methodology involves applying a rate-limit on a per-endpoint / per-PUID (Partner Unique ID) basis; therefore, reaching the rate-limit with respect to your usage of one endpoint will only affect the availability of that endpoint, not the others.\n\nIn addition, we apply an additional security layer of rate limiting based on client IP address. This limits bursts of consecutive requests from the same IP over a short period of time and may trigger temporary request rejection even when per-endpoint / per-PUID limits have not been reached.\n\nWe do not have a universal rate limit that applies to all users. The rate limit you are required to operate within is based on a standard commensurate with the scale of your operation.\n\nThis is to say that if the volume of traffic to your site is such that under normal conditions your operations are causing you to frequently receive HTTP 429 (Too Many Requests) responses, you can ask for your rate-limit to be increased. If that is the case, please speak to your account manager to discuss whether increasing your rate limit would be the appropriate solution.\n\n### Interpreting the HTTP 429 response\n\nIf a request to an endpoint yields an HTTP 429 (Too Many Requests) response, information regarding your present usage status can be located in the following four header fields:\n\n- `RateLimit-Limit` \n - Total limit of requests for this endpoint per rolling 10s time window\n- `RateLimit-Remaining`:\n - The number of requests that remain available to you in the present 10s period \n- `RateLimit-Reset`:\n - How long (in seconds) from the present moment it would take for the number of available requests to reach its maximum value\n- `Retry-After`:\n - A recommendation regarding how long (in seconds) it would be optimal to wait before making a subsequent call to that endpoint\n\n**Example HTTP 429 response:**\n\n```json\nHTTP/1.1 429\n...\n..\nRateLimit-Limit: 16\nRateLimit-Remaining: 0\nRateLimit-Reset: 10\nRetry-After: 10\n...\n..\n \n{ \n \"code\":\"TOO_MANY_REQUESTS\",\n \"message\":\"Too many requests, please try again\",\n \"timestamp\":\"2022-09-13T13:25:26.179433Z\",\n \"trackingId\":\"4badb933-ad65-4464-ae9c-c20e4a70c0d2\"\n}\n```\n\nThis can interpreted as:\n\n`RateLimit-Limit: 16`\n- You can make 16 requests to this endpoint per 10s rolling time window\n\n`RateLimit-Remaining: 0`\n- You have no remaining requests available in the current 10s epoch (as you would expect, since it is for this reason that you are receiving this response in the first place)\n\n`RateLimit-Reset: 10`\n- If you were to wait 10s, your `RateLimit-Remaining` value would reach its maximum; which, in this case, is 16 requests\n\n`Retry-After: 10`\n- It is recommended you pause for 10s before re-attempting to call this endpoint\n\nNote that these rate-limit-related values will also be returned in the HTTP 200 (success) response. Inspect these values if you wish to estimate whether your method of implementing this API will remain sustainable at scale.\n\n### Concurrency-based rate limiting\n\nWhile rate-limiting is imposed per API key, if our system reaches its capacity on account of high demand overall, you may be rate limited even though you have not personally exceeded your individual rate limit.\n\nIn this case, you will receive a HTTP 503 (Service Unavailable) response. The header of this response will include the `Retry-After` field. In the example below, the recommendation is to pause for 60s before retrying the request:\n e.g.:\n\n```json\nHTTP/1.1 503\n...\n..\nRetry-After: 60\n...\n..\n \n{\"code\":\"SERVICE_UNAVAILABLE\",\"message\":\"Service is currently unavailable, please try again\",\"timestamp\":\"2022-09-13T08:52:48.693734Z\",\"trackingId\":\"fc342644-e48f-4fd9-96e3-a6860607d405\"}\n```\n\n# Appendices\n\n## Inclusions & exclusions\n\nThe `inclusions` and `exclusions` arrays are returned for active products in the response from the [product content endpoints](#section/Key-concepts/Product-content-and-availability-endpoints). The array items for both `inclusions` and `exclusions` are objects defined by the same schema, `InclusionExclusionItem`.\n\nThe following table describes the mapping of the possible combinations of `category`, `categoryDescription`, `type`, and `typeDescription` elements of the object in the response that you may encounter. \n\nNew Categories and types can be added over time, allowing flexibility for different use cases.\n\nNote: Changes on the table below become effective by the end of April 2025, see Notes column for details.\n\n\n\n \n \n \n \n \n\n\n \n \n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n \n \n\n\n \n \n \n\n\n \n \n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n \n \n\n\n \n \n \n\n\n \n \n \n \n \n\n
categorycategoryDescriptiontypetypeDescriptionnotes
\"FEES_AND_TAXES\"Fees\"AIRPORT_AND_DEPARTURE_TAX\"Airport/Departure Tax
\"ALL_FEES_AND_TAXES\"All Fees and TaxesDeprecated - April 2025
\"FUEL_SURCHARGE\"Fuel surcharge
\"GRATUITIES\"Gratuities
\"GST\"GST (Goods and Services Tax)Deprecated - April 2025
\"LANDING_AND_FACILITY_FEES\"Landing and facility fees
\"PARKING_FEES\"Parking Fees
\"ADMISSION_FEES\"Admission FeesNew - start April 2025
\"ENTRANCE_FEES\"Entrance FeesNew - start April 2025
\"GOVERNMENT_FEES\"Government FeesNew - start April 2025
\"FOOD_AND_DRINK\"Food and drink\"ALCOHOLIC_BEVRAGES\"
\"ALCOHOLIC_BEVERAGES\"
Alcoholic Beverages
\"BOTTLED_WATER\"Bottled water
\"BREAKFAST\"Breakfast
\"BRUNCH\"Brunch
\"COFFEE_AND_TEA\"Coffee and/or Tea
\"DINNER\"Dinner
\"LUNCH\"Lunch
\"REFRESHMENTS\"RefreshmentsDeprecated - April 2025
\"SNACKS\"Snacks
\"SODA_POP\"Soda/Pop
\"MEALS\"MealsNew - start April 2025
\"SOUVENIRS\"Souvenirs\"CERTIFICATE\"CertificateDeprecated - April 2025
\"RECIPE_BOOKLET\"Recipe bookletDeprecated - April 2025
\"TRANSPORT_AMENITIES\"Transportation amenities\"AIR_CONDITIONED_VEHICLE\"Air-conditioned vehicle
\"PRIVATE_TRANSPORTATION\"Private transportation
\"RESTROOM_ON_BOARD\"Restroom on board
\"WIFI_ONBOARD\"WiFi on board
\"PUBLIC_TRANSPORTATION\"Public transportation (bus, subway, cable car, etc.)New - start April 2025
\"EQUIPMENT\"Use of Equipment\"ALL_INGREDIENTS\"All ingredientsDeprecated - April 2025
\"USE_OF_OTHER_EQUIPMENT\"OtherDeprecated - April 2025
\"USE_OF_BICYCLE\"Use of bicycle
\"USE_OF_COOKING_UTENSILS\"Use of cooking utensilsDeprecated - April 2025
\"USE_OF_SCUBA_EQUIPMENT\"Use of SCUBA equipment
\"USE_OF_SEGWAY\"Use of Segway
\"USE_OF_SNORKELING_EQUIPMENT\"Use of snorkelling equipment
\"USE_OF_TRIKKE\"Trikke
\"BOOSTER_SEAT\"Booster seatNew - start April 2025
\"LOCKER\"LockerNew - start April 2025
\"EXCESS_CHARGES\"Excess charges\"EXCESS_BAGGAGE\"Excess baggageNew - start April 2025
\"OVER_WEIGHT_LIMIT\"Over weight limitNew - start April 2025
\"OTHER\"Other\"OTHER\"Other
\n\n## Update history\n\n| Date | Description |\n|------|-------------|\n| 31 Oct 2022 | Removed v1-v2 migration reference section |\n| 14 Sep 2022 | Revised [Workflows – Rate limiting](#section/Workflows/Rate-limiting) and HTTP 429 response description with respect to new rate-limiting policy |\n| 23 Aug 2022 | Clarified new standard rate-limiting policy that applies to all endpoints in new section: [Workflows – Rate limiting](#section/Workflows/Rate-limiting) |\n| 15 Aug 2022 | Altered advice regarding the recommended frequency for fixed cadence full updates for various endpoints in [Workflows – Update frequency](#section/Workflows/Update-frequency) section | \n| 3 Aug 2022 | Updated descriptions of [/products/modified-since](#operation/productsModifiedSince), [/products/bulk](#operation/productsBulk) and [/products/{product-code}](#operation/products) to highlight the polymorphism in the response / discriminator drop-down on `status` element |\n| 1 Aug 2022 | Renamed **Key Concepts – Content ingestion endpoints** to [Key Concepts – Product Content and availability endpoints](#section/Key-concepts/Product-content-and-availability-endpoints) and updated this section with usage recommendations |\n| 27 July 2022 | Updated [conditonal booking questions logic table](#section/Booking-concepts/Booking-questions) to include advice about `TRANSFER_DEPARTURE_MODE` booking question |\n| 18 July 2022 | Modifed [/bookings/cancel-reasons](#operation/bookingsCancelReasons) endpoint to accept a query parameter to specify customer or supplier-initiated cancellation reasons |\n| 18 July 2022 | Added two new endpoints to allow merchant partners to manage supplier-initiated booking cancellations: [/bookings/modified-since](#operation/bookingsModifiedSince) and [/bookings/modified-since/acknowledge](#operation/bookingsModifiedSinceAcknowledge) |\n| 6 July 2022 | Improved descriptions of `lineItems` and `totalPrice` elements of `bookableItems[]` object array in [/availability/check](#operation/availabilityCheck) endpoint response |\n| 30 June 2022 | Clarified conditions in conditional booking questions section of [Booking concepts - Booking questions](#section/Booking-concepts/Booking-questions) section |\n| 29 June 2022 | Added `target-lander` query parameter to [/products/{product-code}](#operation/products), [/products/modified-since](#operation/productsModifiedSince), [/products/bulk](#operation/productsBulk) and [/products/search](#operation/productsSearch) endpoints |\n| 23 June 2022 | Added `attractionId` to filtering options in [/products/search](#operation/productsSearch) endpoint |\n| 22 June 2022 | Updated string length specifications in VoucherInfo schema and `partnerBookingRef` in [/bookings/book](#operation/bookingsBook) request object |\n| 20 June 2022 | Updated maximum string length specifications for [/bookings/book](#operation/bookingsBook) request object (BookerInfo and CommunicationInfo schemata) |\n| 3 June 2022 | Added new supplier search endpoint: [/suppliers/search/product-codes](#operation/suppliersSearchProductCodes) |\n| 1 June 2022 | Added links to various articles on the [Viator Partner Resource Center](https://partnerresources.viator.com/) throughout document |\n| 26 May 2022 | Added advice about review authenticity: [Key concepts - Review authenticity](#section/Key-concepts/Review-authenticity) |\n| 23 May 2022 | Added `partnerNetFromPrice` property to `ProductSearchPricing` schema spec in response from [/products/search](#operation/productsSearch) endpoint |\n| 20 May 2022 | Added advice regarding whether or not an endpoint should be used to ingest details about the entire product catalog to [/products/{product-code}](#operation/products), [/products/bulk](#operation/productsBulk), [/availability/schedules/{product-code}](#operation/availabilitySchedules) and [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince) endpoint descriptions. |\n| 17 May 2022 | Added note about extra validation requirements for `communication.phone` field in request to [/bookings/book](#operation/bookingsBook) endpoint |\n| 11 May 2022 | Modified [update frequency recommendation](#section/Workflows/Update-frequency) for [/locations/bulk](#operation/locationsBulk) endpoint from 'weekly' to 'monthly' due to the relatively changeless nature of locations data. |\n| 10 May 2022 | Modified description of [/exchange-rates](#operation/exchangeRates) endpoint to include additional currencies (ARS, CLP, COP, ILS, PEN, PHP) available for conversion |\n| 1 Apr 2022 | Modified note to [Booking questions – Conditional booking questions](#section/Booking-concepts/Booking-questions) (third bullet in 'Extra notes') |\n| 22 Mar 2022 | Added note to [Booking questions – Conditional booking questions](#section/Booking-concepts/Booking-questions) (third bullet in 'Extra notes') |\n| 8 Mar 2022 | Corrected `\"OTHER_HEALTH\"` to `\"HEALTH_OTHER\"` in `AdditionalInfo` schema used in the product response |\n| 11 Feb 2022 | Removed note about no-index policy from [/v1/attraction/products](#operation/v1AttractionProducts) endpoint |\n| 9 Feb 2022 | Added [Booking concepts – Low-margin products](/#section/Booking-concepts/Low-margin-products) section | \n| 1 Feb 2022 | Added [Conventions - Endpoint timeout settings](#section/Conventions/Endpoint-timeout-settings) section |\n| 5 Jan 2022 | Corrected response schema details in [/bookings/{booking-reference}/cancel](#operation/bookingsCancel) and [/bookings/{booking-reference}/cancel-quote](#operation/bookingsCancelQuote) to indicate that `status` and `bookingId` are required properties |\n| 15 Nov 2021 | Added Basic-access Affiliate postman collection to [Testing section](#section/Testing) |\n| 5 Nov 2021 | Clarified description of exp-demo header parameter |\n| 2 Nov 2021 | Added `\"LOCATION\"` as option for `logistics.travelerPickup.locations[].pickupType` in product content response |\n| 5 Jan 2022 | Corrected response schema details in [/bookings/{booking-reference}/cancel](#operation/bookingsCancel) and [/bookings/{booking-reference}/cancel-quote](#operation/bookingsCancelQuote) to indicate that `status` and `bookingId` are required properties |\n| 15 Nov 2021 | Added Basic-access Affiliate postman collection to [Testing section](#section/Testing) |\n| 5 Nov 2021 | Clarified description of exp-demo header parameter |\n| 2 Nov 2021 | Added `\"LOCATION\"` as option for `logistics.travelerPickup.locations[].pickupType` in product content response |\n| 28 Oct 2021 | Updated [Booking Concepts – Booking questions – Conditional booking questions](#conditional-booking-questions) table |\n| 15 Oct 2021 | Modified PriceObject schema in response from /availabililty/* endpoints to include provision for commission-payment-model merchants. See [/availability/check](#operation/availabilityCheck) for example |\n| 13 Oct 2021 | Added section: [How to determine if a product option supports pickup](#product-option-pickup) |\n| 7 Oct 2021 | Added `\"TRANSFER_ARRIVAL_DROP_OFF\"` booking question details in [Booking details – conditional booking concepts](#section/Booking-concepts/Booking-questions) section |\n| 1 Oct 2021 | Changed 'standard access' to 'full access' in [Access to endpoints](#section/Access-to-endpoints) section |\n| 1 Oct 2021 | Added note about `\"TRANSFER_PORT_CRUISE_SHIP\"` booking question to [Booking concepts – Booking questions section](#section/Booking-concepts/Booking-questions) |\n| 27 Sep 2021 | Added note about time-out recommendation to [/bookings/book](#operation/bookingsBook) |\n| 16 Sep 2021 | Removed `topX` and modified options for `sortOrder` request parameters in [/attraction/reviews/](#operation/v1AttractionReviews) endpoint |\n| 13 Sep 2021 | Added `reference` element to `Supplier` schema of `ActiveProduct` | \n| 6 Sep 2021 | Modified available options for `sortOrder` request parameter in [/v1/taxonomy/attractions](#operation/v1TaxonomyAttractions) and [/v1/search/attractions](#operation/v1SearchAttractions) endpoints |\n| 27 Aug 2021 | Added basic and full-access affiliate types to [Access to endpoints](#section/Access-to-endpoints) section |\n| 26 Aug 2021 | Added [Key concepts – Protecting unique content](#section/Key-concepts/Protecting-unique-content) section |\n| 23 Aug 2021 | Added [Key concepts – v1 to v2 migration reference – Mapping categories to tags](#section/Key-concepts/V1-to-V2-migration-reference) section |\n| 19 Aug 2021 | Added Tripadvisor as an additional reviews provider in [/reviews/product](#operation/reviewsProduct) endpoint | \n| 12 Aug 2021 | Updated [Access to endpoints](#section/Access-to-endpoints) section to include [/products/booking-questions](#operation/productsBookingQuestions) and [/bookings/status](#operation/bookingsStatus) |\n| 10 Aug 2021 | Bugfix – `provider` element in request to [/reviews/product](#operation/reviewsProduct) now listed as 'required' |\n| 5 Aug 2021 | Added new sorting options to [/reviews/product](#operation/reviewsProduct) endpoint |\n| 1 Jul 2021 | Added [Workflows - Update frequency](#section/Workflows/Update-frequency) section |\n| 22 Jun 2021 | Deprecated [/v1/product/reviews](#operation/v1ProductReviews) endpoint |\n| 21 Jun 2021 | Added [/reviews/product](#operation/reviewsProduct) endpoint |\n| 18 Jun 2021 | Added [/products/search](#operation/productsSearch) endpoint |\n| 9 Jun 2021 | Added [Booking concepts – supplier communications](#section/Booking-concepts/Supplier-communications)\n| 9 Jun 2021 | Added [Booking concepts – working with age bands](#section/Booking-concepts/Working-with-age-bands) section |\n| 4 Jun 2021 | Added premium `viatorUniqueContent` element to ActiveProduct |\n| 27 May 2021 | Added [Booking-concepts – Per-person and unit pricing](#section/Booking-concepts/Per-person-and-unit-pricing) section | \n| 21 May 2021 | Added `reviews` element to responses of [product content endpoints](#section/Key-concepts/Product-content-and-availability-endpoints) |\n| 14 May 2021 | Added **Age-bands** section to [Booking concepts - Booking questions](#section/Booking-concepts/Booking-questions) section |\n| 5 May 2021 | Updated Conditional booking questions table in [Booking concepts - Booking questions](#section/Booking-concepts/Booking-questions) section |\n| 25 Mar 2021 | Added v1 endpoints for affiliate partners |\n| 23 Mar 2021 | Added [Resolving references](#section/Workflows/Resolving-references) section |\n| 11 Mar 2021 | Added `campaign-value` parameter to [/products/modified-since](#operation/productsModifiedSince), [/products/bulk](#operation/productsBulk) and [/products/{product-code}](#operation/products) endpoints; added AvailabilityScheduleSummary `summary` schema to /availability/schedules/* endpoint responses |\n| 16 Feb 2021 | Added [Determining ratings](#section/Workflows/Determining-ratings) section; added [Conventions - Accept-Encoding](#section/Conventions/Accept-Encoding) section |\n| 21 Jan 2021 | Extended BookingBookRequest schema (used in [/bookings/book](#operation/bookingsBook)) to include new AdditionalBookingDetails schema to allow custom voucher text |\n| 18 Jan 2021 | Modified `rejectionReasonCode` in responses from [/bookings/book](#operation/bookingsBook) and [/bookings/status](#operation/bookingsStatus) endpoints |\n| 12 Jan 2021 | Added [Key concepts – Booking confirmation types](#section/Booking-concepts/Booking-confirmation-types) section as sale of manual confirmation products has now been enabled. |\n| 7 Dec 2020 | Added DayOperatingHours schema array to BookableItemSeason schema in availability-schedules endpoints | \n| 24 Nov 2020 | Added [Key concepts – Booking cutoff times](#section/Booking-concepts/Booking-cutoff-times) section |\n| 12 Nov 2020 | Added [Workflows – Checking booking status](#section/Booking-concepts/Checking-booking-status) section |\n| 6 Nov 2020 | Added [/bookings/status](#operation/bookingsStatus) endpoint specification |\n| 5 Nov 2020 | Added [Workflows – Ingesting and updating availability schedules](#section/Workflows/Ingesting-and-updating-availability-schedules) section |\n| 4 Nov 2020 | Updated `id` values in [/products/booking-questions](#operation/productsBookingQuestions) endpoint |\n| 3 Nov 2020 | Added [Key concepts – V1 to V2 migration reference](#section/Key-concepts/V1-to-V2-migration-reference) section |\n| 28 Oct 2020 | Added sections for [Activity](#activity-itinerary), [Hop-on hop-off](#hop-on--hop-off-itinerary) and [Unstructured](#unstructured-itinerary) itinerary types |\n| 13 Oct 2020 | - Added `maxLength` field to BookingQuestion schema in response from [/products/booking-questions](#operation/productsBookingQuestions)
- Updated AdditionalInfo schema |\n| 6 Oct 2020 | - Added [Appendices - Inclusions and exclusions](#section/Appendices/Inclusions-and-exclusions)
- Modified ActiveProduct schema to include new required `Supplier` element |\n| 1 Oct 2020 | Added [About](#section/About) section |\n| 29 Sep 2020 | Added [Key concepts - Availability Schedules](#section/Key-concepts/Availability-schedules) section
Added legacy helper endpoints [/v1/taxonomy/destinations](#operation/v1TaxonomyDestinations), [/v1/taxonomy/attractions](#operation/v1TaxonomyAttractions), [v1/product/reviews](#operation/v1ProductReviews), [/v1/product/photos](#operation/v1ProductPhotos) |\n| 28 Sep 2020 | Updated response schema for [/products/tags](#operation/productsTags) |\n| 23 Sep 2020 | Added [Key concepts – Booking questions](#section/Booking-concepts/Booking-questions) section |\n| 22 Sep 2020 | Added [Versioning](#section/Versioning) section |\n| 22 Sep 2020 | Fixed typo in StandardItineraryItem schema (`pointsOfInterestLocation` -> `pointOfIterestLocation`); added explanation of policy window time-stamps & updated response samples in [Workflows - Cancellation policy](#section/Booking-concepts/Cancellation-policy) section | \n| 21 Sep 2020 | Added [Making a booking](#section/Booking-concepts/Making-a-booking) section under Workflows |\n| 20 Sep 2020 | Added `currency` element to [/bookings/hold](#operation/bookingsHold) response schema |\n| 17 Sep 2020 | Breaking change: [/exchange-rates](/#operation/exchangeRates) endpoint refactored |\n| 16 Sep 2020 | **Note**: ONLY freesale products (those with a confirmation type of \"INSTANT\") are presently able to be booked. See [Ingesting and updating the product catalogue](#section/Workflows/Ingesting-and-updating-the-product-catalogue) (Filtering-out on-request products) for instructions on how to filter-out on-request products from your catalogue |\n| 16 Sep 2020 | Breaking change: `languageGuideDetails` element in ActiveProduct schema changed to `languageGuides` (array of LanguageGuide schema) |\n| 15 Sep 2020 | Breaking change: removed `travelerPickup` element from [/booking/book](#operation/bookingsBook) request |\n| 10 Sep 2020 | Added [/bookings/book](#operation/bookingsBook) endpoint specification |\n| 1 Sep 2020 | Added `description` element to `MultiDayTourFoodAndDrinks` and `InclusionExclusionItem` schemata; added `version=2.0` to `Accept` request header parameter across all endpoints |\n| 26 Aug 2020 | `CancellationConditionType` schema key strings updated (now \"STANDARD\", \"MODERATE\", \"STRICT\" & \"ALL_SALES_FINAL\"; `PricingLineItem` updated (affects /availability/check and /bookings/hold-confirm responses); /availability/* endpoints moved to separate 'Availability' section |\n| 25 Aug 2020 | **Breaking changes**: see below |\n| 25 Aug 2020 | Regenerated response samples |\n| 11 Aug 2020 | Updated `paxMix` schema in [/availability/check](#operation/checkAvailability) |\n| 6 Aug 2020 | Added COVID-safety-measure keys to `additionalInfo` schema |\n| 4 Aug 2020 | Added [/bookings/hold](#operation/bookingsHold) endpoint |\n| 28 July 2020 | Added [Ingesting and updating the product catalogue](#section/Workflows/Ingesting-and-updating-the-product-catalogue) section |\n| 23 July 2020 | Added [Product options](), [Cancellation policy](#section/Booking-concepts/Cancellation-policy) sections | \n| 16 Jul 2020 | Added [/bookings/hold](#operation/bookingsHold) endpoint |\n| 3 Jul 2020 | Modified availability endpoint schema and regenerated examples |\n| 1 Jul 2020 | Removed internal-only markup for release |\n| 16 Jun 2020 | Added [Workflows->Cancellation API workflow](#section/Booking-concepts/Cancellation-API-workflow) section\n| 15 Jun 2020 | Removed enum data type specification from `UnavailableDate`, `ageBand`, `CancellationQuoteBookingStatus`, `CancellationResultItemReason` and `CancellationBookingStatus` schemata |\n| 18 May 2020 | Refactored LHS nav to use 'summary' name instead of operationId name |\n| 28 April 2020 | Added `legacyGuide` field to `LanguageGuide` object specification |\n\n### 25 August breaking changes\n\nThe following breaking changes have been made. Please update your OpenAPI specification by downloading from the link at the top of the page.\n\n#### Endpoint URL changes\n\n- /availability-schedule/{product-code} -> [/availability/schedules/{product-code}](#operation/availabilitySchedules)\n- /availability-schedule/bulk -> [/availability/schedules/bulk](/#operation/availabilitySchedulesBulk)\n- /availability-schedule/modified-since -> [/availability/schedules/modified-since](#operation/availabilitySchedulesModifiedSince)\n\n#### Element name changes\n\nA number of name changes have been made to the `Product` schema. This affects the following endpoints:\n\n- [/products/modified-since](#operation/productsModifiedSince)\n- [/products/bulk](#operation/productsBulk)\n- [/products/{product-code}](#operation/products)\n\n| Element | Old name | New name |\n|----------|---------|----------|\n| `cancellationPolicy.badWeather` | `badWeather` | `cancelIfBadWeather` | \n| `cancellationPolicy.insufficientTravelers` | `insufficientTravelers` | `cancelIfInsufficientTravelers` |\n| `translationInfo.translationAttributions` | `translationAttributions` | `translationAttribution` | \n| `destinations.isPrimary` | `isPrimary` | `primary` |\n| `inclusions[].otherText` | `otherText` | `otherDescription` | \n| `itinerary.routes[].pois` | `pois` | `pointsOfInterest` |\n| `itinerary.itineraryItems[].poiLocation` | `poiLocation` | `pointsOfInterestLocation` |\n| `itinerary.routes[].duration.fixedValueinMinutes` | `fixedValueInMinutes` | `fixedDurationInMinutes` |\n| `itinerary.routes[].duration.fromMinutes` | `fromMinutes` | `variableDurationFromMinutes` |\n| `itinerary.routes[].duration.toMinutes` | `toMinutes` | `variableDurationToMinutes` |" version: '2.0' license: name: CC BY 4.0 url: https://creativecommons.org/licenses/by/4.0/au/ servers: - url: https://api.viator.com/partner description: Production server (uses live data) - url: https://api.sandbox.viator.com/partner description: Sandbox server (uses test data) security: - API-key: [] tags: - name: Auxiliary paths: /search/freetext: post: tags: - Auxiliary description: 'Perform a search for products, attractions and/or destinations that contain a free-text search term. Product results can be filtered and sorted according to various criteria. This endpoint must not be used to ingest the catalog of products, the [/products/modified-since](#operation/productsModifiedSince) endpoint must be used for that purpose. **Note**: Only **active** products are returned in the response from this endpoint. ' operationId: searchFreeText summary: /search/freetext parameters: - name: Accept-Language in: header description: 'Specifies the language into which the natural-language fields in the response from this service will be translated. ' required: true schema: type: string example: en, en-AU - $ref: '#/components/parameters/campaignValueProduct' - name: target-lander in: query description: 'Target lander page for affiliate productUrl ' required: false schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/FreetextSearchRequest' example: searchTerm: big productFiltering: destination: '77' dateRange: from: '2023-01-01' to: '2023-01-31' price: from: 0 to: 1000 rating: from: 0 to: 5 durationInMinutes: from: 0 to: 1000 tags: - 21972 flags: - LIKELY_TO_SELL_OUT includeAutomaticTranslations: true productSorting: sort: PRICE order: DESCENDING searchTypes: - searchType: PRODUCTS pagination: start: 1 count: 3 - searchType: ATTRACTIONS pagination: start: 1 count: 1 - searchType: DESTINATIONS pagination: start: 1 count: 1 currency: USD responses: '200': description: Success headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' content: application/json;version=2.0: schema: $ref: '#/components/schemas/FreetextSearchResponse' examples: '1': $ref: '#/components/examples/search-freetext-example' extra charges: $ref: '#/components/examples/search-freetext-extra-charges-example' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '406': $ref: '#/components/responses/NotAcceptable' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' /locations/bulk: post: tags: - Auxiliary summary: /locations/bulk description: 'Get full location details for the requested location references. Locations should be cached and refreshed monthly. Additionally, the [/locations/bulk](#operation/locationsBulk) endpoint should be used on demand for any new location references returned in the product content response. **Note**: If no response is received for a given location reference, this means that the location was either removed from our database or replaced by a different one. If this occurs, please disregard the removed location reference and make sure you update the associated product information. (Response sample generated on: 2020-08-25) ' operationId: locationsBulk requestBody: content: application/json;version=2.0: schema: $ref: '#/components/schemas/BulkLocationReferencesRequest' example: locations: - LOC-f698f2a1-a53a-46bb-8708-3d45bf740f59 - LOC-9e88ac35-2e2c-4ecc-af8d-10b76770785f - LOC-453b3cd4-4afa-414d-a8d8-bedb458d73fe - CONTACT_SUPPLIER_LATER - MEET_AT_DEPARTURE_POINT parameters: - $ref: '#/components/parameters/acceptLanguage' - $ref: '#/components/parameters/accept' responses: '200': description: Success headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json;version=2.0: schema: $ref: '#/components/schemas/LocationsResponse' examples: '1': $ref: '#/components/examples/locations-bulk-example' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' /exchange-rates: post: tags: - Auxiliary summary: /exchange-rates description: "This endpoint gets the exchange rates for conversions between specified currencies.\nExchange rates should be cached and refreshed based on the expiry timestamp (at the moment daily).\n\nIn this API, all pricing is denominated in the currency of the supplier. For example, if a tour operates in Thailand, its prices will be given in Thai Baht (THB). \n\nNot all supplier currencies are supported, but many are. They comprise:\n\n- AED, ARS, AUD, BRL, CAD, CHF, CLP, CNY, COP, DKK, EUR, FJD, GBP \n- HKD, IDR, ILS, INR, ISK, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PHP, PLN, \n- RUB, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR\n\nWhile pricing can be in any of the currencies listed above, payments for bookings can only be made using the following four currencies:\n\n- GBP (British Pound)\n- EUR (Euros)\n- USD (US Dollars)\n- AUD (Australian dollars)\n\nIn order that you display the correct price to the user and charge accordingly, it is important that you perform the currency conversion based on the exchange rates given in the response from this endpoint and that these conversion rates are valid at the time of conversion (as given in the `expiry` field).\n\nIn doing so, you ensure the amount that you, the merchant, will be invoiced by Viator for this product matches your records. Discrepancies are bound to occur if you perform the calculations using expired exchange rates or those from an alternative source.\n\nAn additional measure to ensure that you charge your customer accurately is to confirm that the pricing details returned by the [/availability/check](../#operation/availabilityCheck) endpoint (in the billing currency specified in the request) conform to your expectations. The information provided by this service is the definitive source of truth with regard to product pricing.\n\n**Note:** If you attempt to use an unsupported currency when making a booking request, you will receive the following error:\n\n```javascript\nIncorrect currency code provided\n```\n\n**Note**: In order to reduce the number of calls made to this service, we recommend retrieving the exchange rate for the currency pair in question just once for the time period during which it is valid, and then applying that rate to all products with pricing denominated in that currency rather than calling this endpoint for each product requiring currency conversion.\n\nLearn more about calculating product pricing in this article: [Calculating Product Pricing](https://partnerresources.viator.com/travel-commerce/merchant/pricing/?source=specs)\n\n(Response sample generated on: 2020-09-17)\n" operationId: exchangeRates requestBody: content: application/json;version=2.0: schema: $ref: '#/components/schemas/ExchangeRatesRequest' example: sourceCurrencies: - AUD - EUR - USD - GBP targetCurrencies: - AUD - EUR - USD - GBP responses: '200': description: Success headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json;version=2.0: schema: $ref: '#/components/schemas/ExchangeRatesResponse' examples: '1': $ref: '#/components/examples/exchange-rates-example' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' /reviews/product: post: tags: - Auxiliary description: "Retrieves and filters reviews for a **single** product\nReviews should be cached and refreshed weekly, as well as on-demand when you see that the product content endpoint returns a different review count than saved in your database for the product.\n\n**Non-indexing of reviews**\n\n- Review content is protected proprietary information; therefore, you may not allow review content to be indexed by search engines. In order for your site to be certified, you will need to demonstrate that you have implemented systems to ensure that review content is non-indexed. For more information, see [Key concepts - Protecting unique content](#section/Key-concepts/Protecting-unique-content).\n\n**Availability of reviews**\n\n- Occasionally, reviews are deleted due to inauthenticity, offensive language, etc. Furthermore, we cannot guarantee that non-Viator reviews (i.e., those for which the `provider` is not `\"VIATOR\"`) will remain available in future (however, you will receive a notification email to inform you should this occurr). As such, we require that you implement a mechanism by which locally-cached reviews are automatically deleted from your records (and are not displayed on your site) if they do not appear in the most recent response from this endpoint. \n\n**Viator performs checks on reviews**\n\n- For more information, see [Key concepts - Review authenticity](#section/Key-concepts/Review-authenticity)\n\nNote: Changing `Accept-Language`, `showMachineTranslated`, or `reviewsForNonPrimaryLocale` may change review ordering, pagination, and the apparent set of reviews returned for the same product. Partners should not assume stable pagination across different locale/translation settings.\n" operationId: reviewsProduct summary: /reviews/product parameters: - $ref: '#/components/parameters/acceptLanguage' - $ref: '#/components/parameters/accept' requestBody: content: application/json;version=2.0: schema: $ref: '#/components/schemas/ProductReviewsRequest' example: productCode: 5010SYDNEY provider: ALL count: 10 start: 1 showMachineTranslated: true reviewsForNonPrimaryLocale: true ratings: - 1 - 2 - 3 - 4 - 5 sortBy: MOST_RECENT_PER_LOCALE responses: '200': description: Success headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json;version=2.0: schema: $ref: '#/components/schemas/ProductReviewsResponse' examples: '1': $ref: '#/components/examples/products-reviews-example' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '406': $ref: '#/components/responses/NotAcceptable' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' /suppliers/search/product-codes: post: tags: - Auxiliary summary: /suppliers/search/product-codes description: 'Gets a collection of supplier information objects for the provided products. Limited to 500 products per request. Supplier details should be cached and refreshed weekly. ' operationId: suppliersSearchProductCodes requestBody: content: application/json;version=2.0: schema: $ref: '#/components/schemas/BulkSupplierProductRequest' example: productCodes: - 2855KENNEDY_TKTS parameters: - $ref: '#/components/parameters/acceptLanguage' - $ref: '#/components/parameters/accept' responses: '200': description: Success headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json;version=2.0: schema: $ref: '#/components/schemas/SupplierProductResponse' examples: Certified Business: $ref: '#/components/examples/suppliers-search-product-codes-certified-business-example' Business: $ref: '#/components/examples/suppliers-search-product-codes-business-example' Individual: $ref: '#/components/examples/suppliers-search-product-codes-individual-example' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' /destinations: get: tags: - Auxiliary operationId: destinations summary: /destinations description: "Get details of all destinations supported by the API. Destinations should be refreshed weekly (in addition to on-demand updates when a new destination is returned in the product content response).\n\n\n**Note**:\n\n - Returns a complete list of Viator destinations, including destination names and parent identifiers\n - Used to provide navigation through drill down lists or combo boxes\n - Use the data received from this endpoint to resolve the destination identifier(s) in the `destinations[].ref` element in the product content response\n" parameters: - $ref: '#/components/parameters/acceptLanguage' - $ref: '#/components/parameters/accept' - $ref: '#/components/parameters/campaignValueDestination' responses: '200': description: Success headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json;version=2.0: schema: $ref: '#/components/schemas/DestinationsResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '406': $ref: '#/components/responses/NotAcceptable' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' components: examples: suppliers-search-product-codes-business-example: summary: Business value: suppliers: - reference: SUPPLIER-5VKSuubSdpsjjT67V9h0aA== name: City Sightseeing Orlando type: BUSINESS productCode: 2855KENNEDY_TKTS supplierInfoVerified: true contact: email: email@example.com address: 1 Example Drive , Suite 100 Orlando Florida 32819 US phone: '+1123456789' suppliers-search-product-codes-individual-example: summary: Individual - Supplier agreed to legal compliance value: suppliers: - reference: SUPPLIER-Ydyu2Yd4RacdUHUUwvWuQA== name: Phú Lành Travel supplierAgreedToLegalCompliance: true type: INDIVIDUAL productCode: 383247P2 search-freetext-extra-charges-example: summary: /search/freetext - ExtraCharges value: destinations: totalCount: 1 results: - id: 50204 name: Abu Simbel parentDestinationId: 722 parentDestinationName: Egypt translationInfo: containsMachineTranslatedText: false translationSource: ORIGINAL url: https://shop.live.int.viator.com/x/d50204-ttd?mcid=42383&pid=P00108950&medium=api&api_version=2.0 attractions: totalCount: 0 products: totalCount: 185 results: - productCode: 128216P66 title: 4-Days Nile Cruise From Aswan To Luxor including Abu Simbel and Hot Air Balloon description: The Beauty of Egypt Upper Nile Valley, is best appreciated from the deck of a Nile Cruise ship. Enjoy the riverside scenery and discover the ancient wonders of Egypt passing by pharaonic sites en route between Aswan and Luxor. Explore the highlights of the sightseeing in Luxor and Aswan, two stops in the way to visit the pharaonic sites of interest such as; Kom Ombo and Edfu Temples. Discover one of the most impressive temples in Egypt by visiting Abu Simbel 285 km south of Aswan. Experience the exciting trip of the Hot Air Balloon in Luxor. Have fun and enjoy plenty of night entertainments of the belly dancing show, galabiya party, Nubian show or disco and more. images: - imageSource: SUPPLIER_PROVIDED caption: '' isCover: true variants: - height: 50 width: 50 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-50x50/0b/9b/c9/c9.jpg - height: 100 width: 100 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-100x100/0b/9b/c9/c9.jpg - height: 200 width: 200 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-200x200/0b/9b/c9/c9.jpg - height: 400 width: 400 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-400x400/0b/9b/c9/c9.jpg - height: 40 width: 60 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-60x40/0b/9b/c9/c9.jpg - height: 80 width: 120 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-120x80/0b/9b/c9/c9.jpg - height: 120 width: 180 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-180x120/0b/9b/c9/c9.jpg - height: 160 width: 240 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-240x160/0b/9b/c9/c9.jpg - height: 240 width: 360 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-360x240/0b/9b/c9/c9.jpg - height: 320 width: 480 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-480x320/0b/9b/c9/c9.jpg - height: 360 width: 540 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-540x360/0b/9b/c9/c9.jpg - height: 446 width: 674 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-674x446/0b/9b/c9/c9.jpg - height: 480 width: 720 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-720x480/0b/9b/c9/c9.jpg - height: 118 width: 210 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-210x118/0b/9b/c9/c9.jpg - height: 75 width: 75 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-75x75/0b/9b/c9/c9.jpg - height: 109 width: 154 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-154x109/0b/9b/c9/c9.jpg reviews: sources: - provider: VIATOR totalCount: 903 averageRating: 4.7 - provider: TRIPADVISOR totalCount: 1857 averageRating: 4.8 totalReviews: 2760 combinedAverageRating: 4.7710147 duration: fixedDurationInMinutes: 5760 confirmationType: INSTANT itineraryType: MULTI_DAY_TOUR pricing: summary: fromPrice: 570.56 fromPriceBeforeDiscount: 570.56 extraChargesSummary: fromPrice: 579.98 extraCharges: 9.42 currency: AUD productUrl: https://shop.live.int.viator.com/tours/Aswan/04-Days-03-Nights-Nile-Cruise-from-Aswan-to-Luxor/d796-128216P66?mcid=42383&pid=P00108950&medium=api&api_version=2.0 destinations: - ref: '796' primary: true tags: - 12029 - 22046 - 12011 - 22169 - 12027 - 22170 - 11922 - 12028 - 12083 - 20255 - 21972 flags: - FREE_CANCELLATION translationInfo: containsMachineTranslatedText: false translationSource: ORIGINAL exchange-rates-example: summary: /exchange-rates value: rates: - sourceCurrency: EUR targetCurrency: EUR rate: 1 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: AUD targetCurrency: AUD rate: 1 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: EUR targetCurrency: USD rate: 1.2145889436 lastUpdated: '2020-09-16T06:55:00Z' expiry: '2020-09-18T07:05:00Z' - sourceCurrency: USD targetCurrency: GBP rate: 0.78444221728675 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: GBP targetCurrency: GBP rate: 1 lastUpdated: '2020-09-10T07:00:10Z' expiry: '2020-09-12T07:05:10Z' - sourceCurrency: AUD targetCurrency: GBP rate: 0.56872265726375 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: USD targetCurrency: AUD rate: 1.4034428375 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: GBP targetCurrency: AUD rate: 1.8204061975 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: AUD targetCurrency: EUR rate: 0.6257333533055 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: EUR targetCurrency: AUD rate: 1.65454861 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: USD targetCurrency: USD rate: 1 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: EUR targetCurrency: GBP rate: 0.924811674699 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: GBP targetCurrency: USD rate: 1.3234666156 lastUpdated: '2020-09-16T06:55:00Z' expiry: '2020-09-18T07:05:00Z' - sourceCurrency: USD targetCurrency: EUR rate: 0.863156412382 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: GBP targetCurrency: EUR rate: 1.11947792 lastUpdated: '2020-09-10T07:00:09Z' expiry: '2020-09-12T07:05:09Z' - sourceCurrency: AUD targetCurrency: USD rate: 0.7376903585645 lastUpdated: '2020-09-10T07:00:10Z' expiry: '2020-09-12T07:05:10Z' search-freetext-example: summary: /search/freetext value: destinations: totalCount: 1 results: - id: 50762 name: Big Bear parentDestinationId: 272 parentDestinationName: California translationInfo: containsMachineTranslatedText: false attractions: totalCount: 1174 results: - id: 10674 name: Big Sur primaryDestinationId: 5250 description:

Big Sur, a stunning 71-mile (114-kilometer) stretch of California’s Central Coast, boasts epic views of the mighty Pacific and jagged, dramatic coastline. Running from the Carmel Highlands to San Simeon, the unincorporated area is very lightly populated—in fact it’s the longest stretch of undeveloped coastline in the lower United States.

destinationName: Monterey & Carmel productsCount: 41 translationInfo: containsMachineTranslatedText: false reviews: sources: - provider: VIATOR reviewCounts: - rating: 1 count: 3 - rating: 2 count: 1 - rating: 3 count: 0 - rating: 4 count: 4 - rating: 5 count: 9 totalCount: 17 averageRating: 3.882353 reviewCountTotals: - rating: 1 count: 3 - rating: 2 count: 1 - rating: 3 count: 0 - rating: 4 count: 4 - rating: 5 count: 9 totalReviews: 17 combinedAverageRating: 3.882353 images: - imageSource: SUPPLIER_PROVIDED isCover: true variants: - height: 800 width: 3200 url: https://hare-media-cdn.tripadvisor.com/media/attractions-content--1x-1/0b/27/ac/ce.jpg - height: 400 width: 1600 url: https://hare-media-cdn.tripadvisor.com/media/attractions-content--1x-1/0b/27/ac/ce.jpg - height: 720 width: 1200 url: https://hare-media-cdn.tripadvisor.com/media/attractions-content--1x-1/0b/27/ac/ce.jpg - height: 248 width: 414 url: https://hare-media-cdn.tripadvisor.com/media/attractions-content--1x-1/0b/27/ac/ce.jpg - height: 50 width: 50 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-50x50/0b/27/ac/d0.jpg - height: 100 width: 100 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-100x100/0b/27/ac/d0.jpg - height: 200 width: 200 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-200x200/0b/27/ac/d0.jpg - height: 400 width: 400 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-400x400/0b/27/ac/d0.jpg - height: 40 width: 60 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-60x40/0b/27/ac/d0.jpg - height: 80 width: 120 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-120x80/0b/27/ac/d0.jpg - height: 120 width: 180 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-180x120/0b/27/ac/d0.jpg - height: 160 width: 240 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-240x160/0b/27/ac/d0.jpg - height: 240 width: 360 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-360x240/0b/27/ac/d0.jpg - height: 320 width: 480 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-480x320/0b/27/ac/d0.jpg - height: 360 width: 540 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-540x360/0b/27/ac/d0.jpg - height: 446 width: 674 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-674x446/0b/27/ac/d0.jpg - height: 480 width: 720 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-720x480/0b/27/ac/d0.jpg - height: 118 width: 210 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-210x118/0b/27/ac/d0.jpg - height: 75 width: 75 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-75x75/0b/27/ac/d0.jpg - height: 109 width: 154 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-154x109/0b/27/ac/d0.jpg products: totalCount: 184 results: - productCode: 318847P2 title: Sunset Cruise & Manta Night Snorkeling Charter description: You enjoy sunset cruising, and then, You enjoy the world famous Manta ray night snorkeling by private charter on our comfortable Luxury boat. It will be a wonderful and unforgettable experience of your life! images: - imageSource: SUPPLIER_PROVIDED caption: '' isCover: true variants: - height: 50 width: 50 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-50x50/0c/0c/0a/16.jpg - height: 100 width: 100 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-100x100/0c/0c/0a/16.jpg - height: 200 width: 200 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-200x200/0c/0c/0a/16.jpg - height: 400 width: 400 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-400x400/0c/0c/0a/16.jpg - height: 40 width: 60 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-60x40/0c/0c/0a/16.jpg - height: 80 width: 120 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-120x80/0c/0c/0a/16.jpg - height: 120 width: 180 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-180x120/0c/0c/0a/16.jpg - height: 160 width: 240 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-240x160/0c/0c/0a/16.jpg - height: 240 width: 360 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-360x240/0c/0c/0a/16.jpg - height: 320 width: 480 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-480x320/0c/0c/0a/16.jpg - height: 360 width: 540 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-540x360/0c/0c/0a/16.jpg - height: 446 width: 674 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-674x446/0c/0c/0a/16.jpg - height: 480 width: 720 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-720x480/0c/0c/0a/16.jpg - height: 118 width: 210 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-210x118/0c/0c/0a/16.jpg - height: 75 width: 75 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-75x75/0c/0c/0a/16.jpg - height: 109 width: 154 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-154x109/0c/0c/0a/16.jpg reviews: sources: - provider: TRIPADVISOR totalCount: 1 averageRating: 5 totalReviews: 1 combinedAverageRating: 5 duration: fixedDurationInMinutes: 180 confirmationType: INSTANT itineraryType: ACTIVITY pricing: summary: fromPrice: 990 fromPriceBeforeDiscount: 990 partnerNetFromPrice: 822.39 currency: USD destinations: - ref: '669' primary: true tags: - 21956 - 21951 - 21949 - 22049 - 21959 - 21954 - 22144 - 21464 - 20757 - 21442 - 11912 - 21952 - 22083 - 12052 flags: - FREE_CANCELLATION - PRIVATE_TOUR - LIKELY_TO_SELL_OUT translationInfo: containsMachineTranslatedText: false translationSource: ORIGINAL - productCode: 35441P11 title: Jackson Hole & Grand Teton Park - Full-Day Wildlife Tour description: 'Join us for an Amazing day in Jackson Hole as we explore the wildlife sweet spots of the area to search for Elk, Big Horn Sheep, Moose, Bison, Bald Eagles, Coyotes, Foxes and maybe more!  Your guide will pick you up in one of our tall, comfortable vans or SUVs at 8:00am from your lodging in Teton Village or the Town of Jackson, WY and drop you back off around 4:00pm.  Your guide will educate you on the many features of the area including the history, wildlife & more. Cost includes:  Transportation, Tour Guide, Light Breakfast, Lunch, Park Entry Fee, Elk Refuge Sleigh Ride (Dec 15-Apr 5) and use of Binoculars.  Guide gratuity not included. ' images: - imageSource: SUPPLIER_PROVIDED caption: '' isCover: true variants: - height: 50 width: 50 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-50x50/0b/9b/c1/b3.jpg - height: 100 width: 100 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-100x100/0b/9b/c1/b3.jpg - height: 200 width: 200 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-200x200/0b/9b/c1/b3.jpg - height: 400 width: 400 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-400x400/0b/9b/c1/b3.jpg - height: 40 width: 60 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-60x40/0b/9b/c1/b3.jpg - height: 80 width: 120 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-120x80/0b/9b/c1/b3.jpg - height: 120 width: 180 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-180x120/0b/9b/c1/b3.jpg - height: 160 width: 240 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-240x160/0b/9b/c1/b3.jpg - height: 240 width: 360 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-360x240/0b/9b/c1/b3.jpg - height: 320 width: 480 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-480x320/0b/9b/c1/b3.jpg - height: 360 width: 540 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-540x360/0b/9b/c1/b3.jpg - height: 446 width: 674 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-674x446/0b/9b/c1/b3.jpg - height: 480 width: 720 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-720x480/0b/9b/c1/b3.jpg - height: 118 width: 210 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-210x118/0b/9b/c1/b3.jpg - height: 75 width: 75 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-75x75/0b/9b/c1/b3.jpg - height: 109 width: 154 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-154x109/0b/9b/c1/b3.jpg reviews: sources: - provider: TRIPADVISOR totalCount: 3 averageRating: 5 totalReviews: 3 combinedAverageRating: 5 duration: fixedDurationInMinutes: 480 confirmationType: INSTANT itineraryType: UNSTRUCTURED pricing: summary: fromPrice: 975 fromPriceBeforeDiscount: 975 partnerNetFromPrice: 809.93 currency: USD destinations: - ref: '51006' primary: true tags: - 12029 - 21946 - 20757 - 22083 - 21860 - 12028 flags: - LIKELY_TO_SELL_OUT translationInfo: containsMachineTranslatedText: false translationSource: ORIGINAL - productCode: 30433P3 title: Kona Sport-Fishing Private Charter - 6 Hours description: Enjoy 6 hours out on the water off the Kona Coast on this private chartered fishing and boating excursion. Sit back, relax and drink in the amazing blue scenery or, pole in hands, wait to hopefully catch a big one. All fishing equipment is complimentary so it doesn't matter if you're a beginner or an expert. Not into fishing? Then request a fishing and snorkeling combo which makes for a fun-family excursion. images: - imageSource: SUPPLIER_PROVIDED caption: Mahimahi isCover: true variants: - height: 50 width: 50 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-50x50/06/e5/a5/4e.jpg - height: 100 width: 100 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-100x100/06/e5/a5/4e.jpg - height: 200 width: 200 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-200x200/06/e5/a5/4e.jpg - height: 400 width: 400 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-400x400/06/e5/a5/4e.jpg - height: 40 width: 60 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-60x40/06/e5/a5/4e.jpg - height: 80 width: 120 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-120x80/06/e5/a5/4e.jpg - height: 120 width: 180 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-180x120/06/e5/a5/4e.jpg - height: 160 width: 240 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-240x160/06/e5/a5/4e.jpg - height: 240 width: 360 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-360x240/06/e5/a5/4e.jpg - height: 320 width: 480 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-480x320/06/e5/a5/4e.jpg - height: 360 width: 540 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-540x360/06/e5/a5/4e.jpg - height: 446 width: 674 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-674x446/06/e5/a5/4e.jpg - height: 480 width: 720 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-720x480/06/e5/a5/4e.jpg - height: 118 width: 210 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-210x118/06/e5/a5/4e.jpg - height: 75 width: 75 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-75x75/06/e5/a5/4e.jpg - height: 109 width: 154 url: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-154x109/06/e5/a5/4e.jpg reviews: sources: - provider: VIATOR totalCount: 1 averageRating: 5 - provider: TRIPADVISOR totalCount: 19 averageRating: 4 totalReviews: 20 combinedAverageRating: 4.2 duration: fixedDurationInMinutes: 360 confirmationType: INSTANT itineraryType: STANDARD pricing: summary: fromPrice: 969.41 fromPriceBeforeDiscount: 969.41 partnerNetFromPrice: 774.31 currency: USD destinations: - ref: '669' primary: true tags: - 21946 - 20757 - 11889 - 22083 - 11929 - 11941 - 20255 flags: - FREE_CANCELLATION - PRIVATE_TOUR - LIKELY_TO_SELL_OUT translationInfo: containsMachineTranslatedText: false translationSource: ORIGINAL products-reviews-example: summary: /products/reviews value: reviews: - reviewReference: REV-q6mwlHKh14wicyE6pG4nptLgIzdbv1Mmpuq6xA1q7hc= language: en publishedDate: '2021-06-05T03:28:52Z' userName: junehV5012PE rating: 5 text: We thoroughly enjoyed our 2 days on the bus. James and the other two drivers were so friendly and helpful with where we wanted to go. Can't recommend them highly enough. The online price was great too title: Great way to see Sydney machineTranslated: false provider: TRIPADVISOR ownerResponse: reviewReference: REV-Nf8eTVCosx7+S3kjeNef6f4akSq5yUt+15A5Xvv+fCQ= language: en publishedDate: '2021-06-15T03:06:31Z' userName: PamelaS3823 text: 'Thank you for joining the Big Bus tours and for your feedback: I will be certain to pass on your compliments to the drivers. ' machineTranslated: false helpfulVotes: 0 - reviewReference: REV-9TpCW7MX6+wdcvBsEvCaNbYGb/umSSBgT1YYS/a4PnI= language: en publishedDate: '2021-04-05T06:03:51Z' userName: G4377PJstephenb rating: 1 text: It's not exactly hop.on hop off. If you get off there is a 2 hour wait for the next bus. Also they advertise 24 hr pass , this is not true last bus is 2 or 2.30pm . Very disappointing title: Disappointed machineTranslated: false provider: TRIPADVISOR helpfulVotes: 2 - reviewReference: REV-7GMRfrA79CGhRAmjwU+4lIXU/a48chrbfdax19evxL8= language: en publishedDate: '2021-01-02T11:17:12Z' userName: Michele_H rating: 5 text: 'Loved the fact that I was outdoors while riding on the upstairs section of the bus. Especially important during Covid to have the fresh air in my face. ' title: 'Loved Being Outdoors While Tiding The Bus ' machineTranslated: false provider: VIATOR helpfulVotes: 0 - reviewReference: REV-ytLmIiqg7xWUqJIyCX5x2IXU/a48chrbfdax19evxL8= language: en publishedDate: '2020-12-17T18:31:11Z' userName: Susanna_L rating: 3 text: The staff are fantastic but due to COVID the service is only running from 10.00 am to 3.00 pm so I don't think it is worth booking the Hop on Hop off as a way to enjoy Sydney. The train and ferry system in Sydney is amazing so it is better to simply top up an Opal card and go. title: Not good value with COVID restrictions machineTranslated: false provider: VIATOR helpfulVotes: 3 - reviewReference: REV-fcMOcpu9m1A///1mQytKvIXU/a48chrbfdax19evxL8= language: en publishedDate: '2020-12-10T15:30:35Z' userName: Michele_H rating: 5 text: 'It was a fantastic trip. The driver was friendly, kind and helpful and went out of his way to ensure I got the return connection from Bondi to the Opera House so I could get back to my hotel. ' title: 'A Must Do Trip Around Sydney!! ' machineTranslated: false provider: VIATOR helpfulVotes: 0 photosInfo: - photoVersions: - height: 0 width: 0 url: https://hare-dynamic-image-cutter.media.tamg.cloud/media/photo-o/1c/69/c5/02/caption.jpg?w=100&h=100&s=1 - height: 50 width: 50 url: https://hare-media-cdn.tripadvisor.com/media/photo-t/1c/69/c5/02/caption.jpg - height: 150 width: 150 url: https://hare-media-cdn.tripadvisor.com/media/photo-l/1c/69/c5/02/caption.jpg - height: 205 width: 154 url: https://hare-media-cdn.tripadvisor.com/media/photo-f/1c/69/c5/02/caption.jpg - height: 200 width: 180 url: https://hare-media-cdn.tripadvisor.com/media/photo-i/1c/69/c5/02/caption.jpg - height: 450 width: 338 url: https://hare-media-cdn.tripadvisor.com/media/photo-s/1c/69/c5/02/caption.jpg - height: 733 width: 550 url: https://hare-media-cdn.tripadvisor.com/media/photo-p/1c/69/c5/02/caption.jpg - height: 1280 width: 960 url: https://hare-media-cdn.tripadvisor.com/media/photo-m/1280/1c/69/c5/02/caption.jpg - height: 1365 width: 1024 url: https://hare-media-cdn.tripadvisor.com/media/photo-w/1c/69/c5/02/caption.jpg - reviewReference: REV-Q6yPvQx0JhE3xui8rRV/AIXU/a48chrbfdax19evxL8= language: en publishedDate: '2020-09-02T05:51:57Z' userName: Denise_H rating: 5 text: I am a local and have always wondered about the commentary. It was fantastic. I would recommend it to anyone. title: Sydney hop on hop off machineTranslated: false provider: VIATOR helpfulVotes: 1 - reviewReference: REV-R789jtQQPSIwzjyKLg/rawQdD4ih+e6prjHzsnWBJwI= language: en publishedDate: '2020-08-29T03:24:22Z' userName: kathryno455 rating: 4 text: This is a great way to see Sydney and Bondi. All hop on hop off buses do take 1-2 hours to complete one whole loop which can get annoying when you only have the ticket for one day and you have many sights to explore. We purchased this ticket to get to Bondi hassle free which we did. Good planning is needed for one day ticket holders! title: Transportation machineTranslated: false provider: TRIPADVISOR helpfulVotes: 2 - reviewReference: REV-kEBAXEIoQIFpcgFvYmHv5YXU/a48chrbfdax19evxL8= language: en publishedDate: '2020-08-12T22:20:31Z' userName: Bertha_B rating: 5 text: 'This experience is one memorable one for me and husband. Regardless of the weather we enjoyed the tour. Listening to the history and seeing it at the time was so beautiful. I highly recommend the Hop-on-Hop-off bus if you want to know Sydney CDB well and the History. i will take my kids and Family back there at anytime. Regards Bex & Fred' title: MEMORABLE EXPERIENCE machineTranslated: false provider: VIATOR helpfulVotes: 2 - reviewReference: REV-BA/XoUwy8zr88uv6QaX4a4XU/a48chrbfdax19evxL8= language: en publishedDate: '2020-07-26T18:18:03Z' userName: Peter_Vassallo rating: 5 text: We travelled by train from Penrith to Sydney to do some sight seeing . Travelling by bus we covered a lot of ground and the commentary informed us about the many sights . My wife Marina and I Highly Recommend Hop on Hop off Bus Tours . title: Time Out in the City . machineTranslated: false provider: VIATOR helpfulVotes: 1 - reviewReference: REV-5CoEYhO9Rr28J4y9YflxxoXU/a48chrbfdax19evxL8= language: en publishedDate: '2020-07-21T20:56:43Z' userName: Jenny_V rating: 5 text: Great time. Even the 24 year old, who lives in Sydney, enjoyed the commentary. We have been twice and there is new information each time....Great for overseas travellers..A snapshot of Sydney for a small cost title: Hop on and off...best idea ever machineTranslated: false provider: VIATOR helpfulVotes: 1 totalReviewsSummary: sources: - provider: VIATOR reviewCounts: - rating: 1 count: 36 - rating: 2 count: 100 - rating: 3 count: 169 - rating: 4 count: 390 - rating: 5 count: 578 totalCount: 1273 - provider: TRIPADVISOR reviewCounts: - rating: 1 count: 35 - rating: 2 count: 25 - rating: 3 count: 49 - rating: 4 count: 74 - rating: 5 count: 147 totalCount: 330 reviewCountTotals: - rating: 1 count: 71 - rating: 2 count: 125 - rating: 3 count: 218 - rating: 4 count: 464 - rating: 5 count: 725 totalReviews: 1603 filteredReviewsSummary: sources: - provider: VIATOR totalCount: 1273 - provider: TRIPADVISOR totalCount: 330 totalReviews: 1603 suppliers-search-product-codes-certified-business-example: summary: Certified Business - Supplier agreed to legal compliance value: suppliers: - reference: SUPPLIER-Hy8bCJznTmRf+DsMECR0rw== name: London Executive Airport Transfer supplierInfoVerified: false supplierAgreedToLegalCompliance: true logo: https://hare-media-cdn.tripadvisor.com/media/attractions-splice-spp-720x480/14/2b/81/16.jpg registrationCountry: GB tradeRegisterName: Companies House registeredBusinessNumber: '15201398' type: BUSINESS productCode: 472736P32 contact: email: 2a7b09a6ef152b85412e5a0aa5a9744e@tripadvisor.com address: 18B Otley Road London E16 3JT GB phone: '+442081294557' countryCode: GB locations-bulk-example: summary: /locations/bulk value: locations: - provider: GOOGLE reference: LOC-f698f2a1-a53a-46bb-8708-3d45bf740f59 providerReference: ChIJi96kKfceB3wRhQLL_6FzrSg - provider: GOOGLE reference: LOC-9e88ac35-2e2c-4ecc-af8d-10b76770785f providerReference: ChIJ--9uPvceB3wR-4BkkxaaWEI - provider: TRIPADVISOR reference: LOC-453b3cd4-4afa-414d-a8d8-bedb458d73fe name: Hanalei Bay address: street: ', ' state: Hawaii country: United States countryCode: US postcode: '' center: latitude: 22.207436 longitude: -159.49841 - provider: TRIPADVISOR reference: CONTACT_SUPPLIER_LATER name: I will contact the supplier later - provider: TRIPADVISOR reference: MEET_AT_DEPARTURE_POINT name: I will meet at the departure point schemas: ErrorResponse: type: object properties: code: type: string message: type: string timestamp: type: string format: date-time description: "Timestamp of the request. \n\n**Example**: `\"2019-09-17T03:20:45.737043Z\"`\n" trackingId: type: string description: "Tracking identifier for this error response. \n\n**Example**: `\"0A871A13:DE2A_0A8712F9:01BB_5DCCC98C_260DAA:0D5B\"`\n" ProductSearchPricing: type: object description: "High-level summary of product prices\n \n - **Note**: This price may not be available during the date range specified in the `filtering` section of the request\n" required: - fromPrice - currency properties: summary: allOf: - type: object properties: fromPriceBeforeDiscount: type: number description: If the product is presently discounted, this field shows what the value of `fromPrice` would be if no discount had been applied; otherwise, it will be equal to `fromPrice`. - $ref: '#/components/schemas/AvailabilityScheduleSummary' currency: type: string description: Currency code for the currency in which the prices in `summary` are denominated partnerNetFromPrice: type: number description: "Lowest per-person price for this product expressed as the amount (excluding the booking fee)that merchant partners using the markup/booking-fee pricing scheme would be invoiced. \n\nThis value is calculated according to the price for a group of at least two standard participants (or, the smallest bookable group if more than two participants are required) for a period not exceeding 384 days into the future.\n\n**Note**: This property is only relevant to you and will only be returned if you are a markup merchant partner (i.e., you are a merchant and are not using the commission-based pricing model).\n" extraChargesSummary: $ref: '#/components/schemas/AvailabilityScheduleExtraChargesSummary' ProductReviewCount: type: object description: Breakdown of number of reviews for each rating of this product required: - rating - count properties: rating: type: number description: Rating given in the review for this product format: float count: type: integer description: How many reviews of this product have this rating format: int64 ProductReviewsSummaryCount: type: object required: - rating - count properties: rating: type: number description: This object refers to reviews with this star-rating format: float count: type: integer description: Number of reviews for this product with a star-rating of `rating` format: int64 FreetextSearchRequest: type: object required: - searchTerm - currency - searchTypes properties: searchTerm: type: string description: 'Return results that contain this free-text search term ' productFiltering: $ref: '#/components/schemas/FreetextSearchProductFiltering' productSorting: $ref: '#/components/schemas/FreetextSearchProductSorting' searchTypes: type: array description: 'Specifies the domain(s) in which to search for the `searchTerm` and the respective pagination details for each type of search results ' minItems: 1 maxItems: 3 items: $ref: '#/components/schemas/SearchType' currency: type: string format: currency description: 'Currency code of price range in request filter and the prices in response. One of: `"AED"`, `"ARS"`, `"AUD"`, `"BRL"`, `"CAD"`, `"CHF"`, `"CLP"`, `"CNY"`, `"COP"`, `"DKK"`, `"EUR"`, `"FJD"`, `"GBP"`, `"HKD"`, `"IDR"`, `"ILS"`, `"INR"`, `"ISK"`, `"JPY"`, `"KRW"`, `"MXN"`, `"MYR"`, `"NOK"`, `"NZD"`, `"PEN"`, `"PHP"`, `"PLN"`, `"RUB"`, `"SEK"`, `"SGD"`, `"THB"`, `"TRY"`, `"TWD"`, `"USD"`, `"VND"`, `"ZAR"`. ' ProductReviewsSummarySource: type: object required: - provider - totalCount properties: provider: type: string description: 'Provider for this set of reviews; one of: - `"VIATOR"` - `"TRIPADVISOR"` ' reviewCounts: type: array description: Breakdown of number of reviews per rating for reviews sourced from this provider items: $ref: '#/components/schemas/ProductReviewsSummaryCount' totalCount: type: integer format: int64 description: Total number of reviews for this product sourced from this provider Video: type: object description: Product video required: - variants properties: language: type: string description: "The language of the video content or audio track, expressed as a locale or language code (e.g., `\"en\"`, `\"es\"`, `\"fr\"`). \nIt enables localization, filtering, and correct playback selection based on user preferences.\n" variants: $ref: '#/components/schemas/VideoVariants' ContactDetails: type: object properties: email: type: string description: Email address of this supplier (for the office managing this product) address: type: string description: Address of this supplier (for the office managing this product) phone: type: string description: Phone number of this supplier (for the office managing this product) countryCode: type: string description: Country code of this supplier (for the office managing this product) ImageVariant: type: object required: - height - width - url properties: height: type: integer description: "Height of this image in pixels\n\n - Example: `'480'`\n" width: type: integer description: 'Width of this image in pixels - Example `''720''` ' url: type: string pattern: (?s).*[\S].* description: 'URL from which this image can be retrieved. ' Destination: type: object description: 'Reference details about a destination associated with this product ' required: - ref - primary properties: ref: type: string pattern: (?s).*[\S].* description: 'Unique numeric identifier for this destination - **Note**: Full details about the destination associated with this reference can be found in the response from the [/destinations](#operation/destinations) endpoint. ' primary: type: boolean description: '**True** if this is the primary destination associated with this product' ProductReviews: type: object description: "Summary of reviews and ratings for this product\n\n**Note**: \n\n - Review data is updated daily; i.e., all reviews received on a day will be added and averages re-calculated in a single event.\n - Viator performs checks on reviews - for more information, see [Key concepts - Review authenticity](#section/Key-concepts/Review-authenticity)\n" required: - totalReviews properties: sources: type: array items: $ref: '#/components/schemas/ProductReviewSource' description: Breakdown of ratings, counts and the sources of the reviews of this product reviewCountTotals: type: array items: $ref: '#/components/schemas/ProductReviewCount' description: Combined total number of reviews per rating across all sources for this product totalReviews: type: integer description: Total number of reviews from all sources for this product format: int64 combinedAverageRating: description: Average rating for all reviews from all sources for this product type: number format: float ProgressiveVideoVariant: type: object description: Progressive video variant required: - format - quality - url properties: format: type: string description: File format of the video (e.g. `MP4`). example: MP4 quality: type: string description: Fixed playback quality or resolution of the video (e.g. `1080`, `720`). example: '1080' url: type: string description: Direct URL to the video file. example: https://hare-dynamic-media-cdn.tripadvisor.com/media/video-v/31/1f/5b/68/vid-693-rome-2017-vatican_1080.mp4 ReviewPhotoInfo: type: object required: - photoVersions properties: photoVersions: type: array description: Width and height variants of this review image and associated URLs items: $ref: '#/components/schemas/ReviewPhoto' VideoVariants: type: object description: 'An object of available video delivery options for the same content, structured by delivery strategy. Each variant defines how the video can be retrieved and played, optimized for different playback capabilities and network conditions. Clients should select the best-supported variant and ignore unknown variant keys for forward compatibility. ' required: - streaming - progressive properties: streaming: type: array description: "Streaming-optimized video source, intended for real-time playback. \nStreaming variants provide a single entry point that allows the player to automatically select bitrate and resolution based on network conditions and device capabilities.\n" items: $ref: '#/components/schemas/StreamingVideoVariant' progressive: type: array description: Progressive download video source intended for immediate or offline playback items: $ref: '#/components/schemas/ProgressiveVideoVariant' ConfirmationType: type: string description: "Machine-interpretable value encoding when bookings for this product will be confirmed; one of: \n\n - `\"INSTANT\"` (instantly) \n - `\"MANUAL\"` (requires manual action prior to confirmation)\n - `\"INSTANT_THEN_MANUAL\"` (combination – subject to cutoff time)\n" ProductReviewSource: type: object required: - provider - totalCount properties: provider: type: string description: "Source of the review; one of:\n - `\"VIATOR\"`\n - `\"TRIPADVISOR\"`\n" reviewCounts: type: array items: $ref: '#/components/schemas/ProductReviewCount' description: Breakdown of ratings and counts for reviews from this source for this product totalCount: type: integer description: Total number of reviews for all ratings of this product format: int64 averageRating: description: 'Average rating across all reviews from this source for this product This average is equal to the sum of the product of each rating and its count divided by the sum of the counts. ' type: number format: float DestinationDetails: type: object required: - destinations - destinationId - name - type - parentDestinationId - images - lookupId properties: destinationId: type: integer format: int64 description: 'Unique numeric identifier of the destination Use this value as the `destinationId` input field for other Partner API services. It matches the `destinations[].ref` in /products endpoints. ' name: type: string description: Name of the destination type: type: string description: 'Destination type specifier. One of: - `"AREA"` - `"CITY"` - `"COUNTRY"` - `"COUNTY"` - `"DISTRICT"` - `"HAMLET"` - `"ISLAND"` - `"NATIONAL PARK"` - `"NEIGHBORHOOD"` - `"PENINSULA"` - `"PROVINCE"` - `"REGION"` - `"STATE"` - `"TOWN"` - `"UNION TERRITORY"` - `"VILLAGE"` - `"WARD"` **Note**: New values can be added and consumers should be prepared to handle this in a future-proof manner. ' parentDestinationId: type: integer format: int64 description: Unique numeric identifier of the destination's parent destination lookupId: type: string description: 'Hierarchy location specifier for the destination that is a concatenation of all parentDestinationId and destinationId codes. Hierarchy has no limitation as to the amount of levels. - **Example**: `"8.77.278.672.59070"` for Honolulu - **Format**: [top level parentDestinationId].[any additional parentDestinationId].[destinationId] ' destinationUrl: type: string description: "**URL** to forward users to in order to complete their purchase on the Viator site\n\nThis URL includes all the necessary information for Viator to correctly attribute and pay commission for the sale to the referring partner.\n\nIf `campaign-value` is included in the request, this URL will also include the campaign tracking value that you set.\n\nFor more information, see our guide to Affiliate Attribution on the Viator Partner Resource Center.\n\n**Note**:\n - This element is only returned for affiliate partners.\n - **You must use the full URL and not modify it in any way – any changes could result in failure to attribute the sale to you, which means you will not be paid a commission for this sale.**\n - For whitelabel partners, the destinationUrl will dynamically retrieve the partners custom **domain URL**, instead of defaulting to viator.com\n\nExample:\n - https://www.viator.com/Las-Vegas/d684-ttd?mcid=42383&pid=P00045135&medium=api&version=2.0&campaign=example\n" defaultCurrencyCode: type: string description: 'Main currency used in the destination - Example: `"EUR"` ' timeZone: type: string pattern: (?s).*[\S].* description: 'Main time zone of the destination - Example: `"US/Pacific"` ' iataCodes: type: array items: type: string description: 'IATA airport code(s) for the destination: a three-letter code defined by the International Air Transport Association (IATA) used to identify many airports around the world - **Example**: [`"VCE"`] - **Note**: if `type` is `"COUNTRY"` this field will return all available IATA codes in destination child items. ' countryCallingCode: type: string description: 'International call prefix used to call phone numbers in this destination. - Example: `"+351"` ' languages: type: array items: type: string description: 'Official language(s) of this destination. If more than one languages spoken, they’ll be concatenated in the response **Note**: it uses ISO-639 Set 1 and ISO-3166 Alpha-2 (optional) standards - Example: [`"en-GB"`, `"es"`] ' center: $ref: '#/components/schemas/LocationCenter' SupplierProductInfo: type: object required: - reference - name - type - productCode properties: reference: type: string pattern: (?s).*[\S].* description: Unique reference code for this supplier name: type: string pattern: (?s).*[\S].* description: Name of this supplier supplierInfoVerified: type: boolean description: Supplier has passed Viator's 'know your business customer' checks required by the DSA. supplierAgreedToLegalCompliance: type: boolean description: 'The operator has self-certified that they are committed to only offer services that comply with applicable laws, including EU law Note: If no information is passed, it means Supplier is still going through self-certification ' registrationCountry: type: string pattern: (?s).*[\S].* description: Country where the supplier is registered (if supplier operates through a registered business entity) tradeRegisterName: type: string pattern: (?s).*[\S].* description: Name of business register (if supplier operates through a registered business entity) registeredBusinessNumber: type: string pattern: (?s).*[\S].* description: A unique identifier assigned to a business entity by a government authority for the purpose of regulatory compliance, taxation, and other official transactions type: type: string pattern: (?s).*[\S].* description: "Whether this supplier is a business or an individual\n\nOne of:\n - `\"BUSINESS\"`\n - `\"INDIVIDUAL\"`\n\nNote: BUSINESS includes individuals who are acting as sole traders\n" logo: type: string pattern: (?s).*[\S].* description: Supplier logo / trademark productCode: type: string pattern: (?s).*[\S].* description: Product code to which this supplier search result pertains contact: $ref: '#/components/schemas/ContactDetails' AvailabilityScheduleSummary: type: object description: 'Information about the lowest price available for this product **Note**: The pricing information given here is based on the recommended retail price (RRP). While affiliate partners must sell at this price, merchant partners set their own prices according to their own margins and booking fees; therefore, merchant partners must calculate their own from-price for display, rather than using these values, unless they have elected to sell at the RRP. ' required: - fromPrice properties: fromPrice: type: number description: 'Lowest per-person retail price for this product, calculated according to the price for a group of at least two standard participants (or, the smallest bookable group if more than two participants are required) for a period not exceeding 384 days into the future. This value can be used to advertise a ''from''-price; e.g., "From $99 per person" ' fromPriceBeforeDiscount: type: number description: 'If the product is presently discounted, this field shows what the value of `fromPrice` would be if no discount had been applied; otherwise, it will be absent. ' BulkSupplierProductRequest: type: object required: - productCodes properties: productCodes: type: array items: type: string pattern: (?s).*[\S].* description: Product code of the product you wish to find the supplier information for BulkLocationReferencesRequest: type: object required: - locations properties: locations: type: array maxItems: 500 description: 'List of location reference identifiers for which to retrieve full location details. ' items: type: string pattern: (?s).*[\S].* ItineraryDuration: type: object description: 'Duration information for this itinerary **Note**: Depending on whether this itinerary has a fixed or variable duration, this object will include either the `fixedValueInMinutes` element alone; or, both the `fromMinutes` and `toMinutes` elements, respectively. ' properties: fixedDurationInMinutes: type: integer description: Duration of this itinerary (in minutes) in the case that it takes a fixed amount of time variableDurationFromMinutes: type: integer description: Lower limit of the duration of this itinerary (in minutes) in the case that this product's duration varies variableDurationToMinutes: type: integer description: Upper limit of the duration of this itinerary (in minutes) in the case that this product's duration varies unstructuredDuration: type: string DestinationsResponse: type: object properties: destinations: type: array items: $ref: '#/components/schemas/DestinationDetails' totalCount: type: integer format: int32 description: Total count of Destinations returned SupplierProductResponse: type: object required: - suppliers description: Supplier details for the given product code properties: suppliers: type: array items: $ref: '#/components/schemas/SupplierProductInfo' ProductReviewsResponse: type: object required: - reviews - totalReviewsSummary - totalReviewCount - filteredReviewCountByProvider properties: reviews: type: array description: 'Reviews and review metadata for this product, from `start` to (`start`+`count`) ' items: $ref: '#/components/schemas/ProductReview' totalReviewsSummary: type: object description: Summary of the set of all reviews available for this product properties: sources: type: array description: Breakdown of review summaries for each review source items: $ref: '#/components/schemas/ProductReviewsSummarySource' reviewCountTotals: type: array description: Breakdown of number of reviews per rating for all reviews of this product from all sources items: $ref: '#/components/schemas/ProductReviewsSummaryCount' totalReviews: description: Total number of reviews available for this product from all sources type: integer format: int64 filteredReviewsSummary: type: object description: Summary of the set of reviews available for this product filtered by `provider`, `ratings`, `reviewsForNonPrimaryLocale` and `showMachineTranslated` in the request properties: sources: type: array description: Breakdown of review summaries for each review source items: type: object properties: provider: type: string description: 'Provider for this set of reviews; one of: - `"VIATOR"` - `"TRIPADVISOR"` ' totalCount: type: integer format: int64 description: Total number of reviews for this product sourced from this provider totalReviews: description: Total number of reviews available for this product from all sources type: integer format: int64 ProductSearchPagination: type: object description: Pagination details specifying which search results to return based on start position and item count properties: start: type: integer minimum: 1 default: 1 description: Position of first filtered and ordered search result to be included in the response (1-based) count: type: integer minimum: 1 default: 10 maximum: 50 description: Number of filtered and ordered search results to be returned in the response ExchangeRatesRequest: type: object properties: sourceCurrencies: type: array description: List of three-letter currency codes for the source currencies for which to retrieve exchange rate data items: type: string targetCurrencies: type: array description: List of three-letter currency codes for the target currencies for which to retrieve exchange rate data items: type: string Image: type: object description: Image information required: - variants - isCover properties: imageSource: $ref: '#/components/schemas/ImageSourceType' caption: type: string description: 'Description of this photo - **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter ' isCover: type: boolean description: '`true` if this photo is considered to be the cover (leading) photo for this product from this `imageSource`' variants: type: array description: Dimension/resolution variants available for this image items: $ref: '#/components/schemas/ImageVariant' Location: type: object description: Location detail required: - reference - provider properties: reference: type: string pattern: (?s).*[\S].* description: Unique identifier for this location as given in the request provider: $ref: '#/components/schemas/LocationProvider' discriminator: propertyName: provider mapping: TRIPADVISOR: '#/components/schemas/ResolvedLocation' GOOGLE: '#/components/schemas/ProvidedLocation' ImageSourceType: type: string description: "Machine-interpretable value indicating the source of this image; one of:\n\n - `\"SUPPLIER_PROVIDED\"`\n - `\"PROFESSIONAL\"`\n" TranslationDetails: type: object description: Information about whether the text in this response was machine-translated required: - containsMachineTranslatedText - translationSource properties: containsMachineTranslatedText: type: boolean description: Indicates whether this product description utilizes text in any of its natural language fields that was automatically machine-translated with no human oversight translationSource: type: string description: "One of:\n- `\"MACHINE\"` – The text provided by the supplier is in a **different language** and has been **automatically translated** by our systems with no human oversight.\n- `\"ORIGINAL\"` – The text provided by the supplier is in the language that is standard for their locale.\n- `\"MANUAL\"` – The text provided by the supplier was in a different language to the standard for their locale; however, whether this is a direct translation of the original text (performed either by machine or human) or whether it is a customised description for speakers of this language is not known. \n" translationAttribution: type: string description: "Value specifying the machine-translation service vendor. At present, translation attribution is not a requirement.\n\n - **Example**: `\"GOOGLE\"`\n" ProductReviewsSummary: type: object description: "Summary of reviews and ratings for this attraction\n\n**Note**:\n - Review data is updated daily; i.e., all reviews received on a day will be added and averages re-calculated in a single event.\n - Viator performs checks on reviews - for more information, see [Review authenticity](#section/Key-concepts/Review-authenticity)\n" required: - totalReviews properties: sources: type: array description: Breakdown of review summaries for each review source items: $ref: '#/components/schemas/ProductReviewsSummarySource' reviewCountTotals: type: array description: Breakdown of number of reviews per rating for all reviews of this product items: $ref: '#/components/schemas/ProductReviewsSummaryCount' totalReviews: description: Total number of reviews available for this product from all sources type: integer format: int64 combinedAverageRating: description: Combined average rating for this product across all reviews from all sources type: number format: float SearchType: type: object properties: searchType: type: string description: 'Specifies a domain within which the search should be performed One of: - `"ATTRACTIONS"` - `"DESTINATIONS"` - `"PRODUCTS"` ' pagination: $ref: '#/components/schemas/ProductSearchPagination' FreetextSearchProductSorting: type: object description: 'Specify the sorting method for product results (i.e., when `searchTypes` includes `"PRODUCTS"`) ' properties: sort: type: string description: "The method of sorting product search results. One of:\n- `\"DEFAULT\"`: sorts based on search term to result relevancy in descending order.\n - **Note**: What Viator gets paid impacts this sort order). Custom ordering is not supported; therefore, the `order` field should be omitted when this sort order is chosen.\n- `\"ITINERARY_DURATION\"`: sort by `duration`. Allow custom order.\n- `\"PRICE\"`: sort by `fromPrice`. Allow custom order.\n- `\"REVIEW_AVG_RATING\"`: sort by average review ratings in descending order . Custom order is not allowed.\n- `\"DATE_ADDED\"`: sort according to when the product was added to the viator catalogue. Allow custom order.\n" order: type: string description: "The direction of sorting search results.\nOne of: \n- `\"ASCENDING\"`\n- `\"DESCENDING\"`\n" ProductReview: type: object required: - reviewReference - language - publishedDate - text - title - machineTranslated - provider - helpfulVotes properties: reviewReference: type: string pattern: (?s).*[\S].* description: Unique identification code for this review language: type: string pattern: (?s).*[\S].* description: Language code for the language in which this review is written avatarUrl: type: string description: URL for the avatar image (if available) for the reviewer that authored this review publishedDate: type: string format: date-time description: 'Date-time stamp indicating when this review was published E.g.: `2021-01-02T11:17:12Z` ' userName: type: string description: Username of the reviewer who submitted this review rating: type: integer format: int32 description: Star-rating for this product given by this reviewer in this review text: type: string pattern: (?s).*[\S].* description: 'Main text of this review - **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter. ' title: type: string pattern: (?s).*[\S].* description: 'Title of this review - **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter. ' machineTranslated: type: boolean description: Indicates whether the natural-language elements of this review have been machine translated provider: type: string pattern: (?s).*[\S].* description: "Provider for this review; one of:\n\n - `\"VIATOR\"`\n - `\"TRIPADVISOR\"`\n" ownerResponse: type: object description: Response to this review from the supplier of this product if available required: - reviewReference - language - publishedDate - text - machineTranslated properties: reviewReference: type: string description: Unique identification code for this owner-response-review language: type: string description: Language code for the language in which this owner-response-review is written publishedDate: type: string format: date-time description: 'Date-time stamp indicating when this owner-response-review was published E.g.: `2021-01-02T11:17:12Z` ' userName: type: string description: Username of the supplier who submitted this owner-response-review text: type: string description: 'Main text of this owner-response-review - **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter. ' machineTranslated: type: boolean description: Indicates whether the natural-language elements of this review have been machine translated helpfulVotes: type: integer format: int32 description: Number of times this review has been labeled 'helpful' by other users photosInfo: type: array description: Information about any photographs that were submitted with this review items: $ref: '#/components/schemas/ReviewPhotoInfo' DestinationSearchResult: type: object properties: id: type: integer description: "**unique numeric identifier** of the destination\n - use this value as the `destination` input field for other Viator API services.\n" format: int64 name: type: string description: '**natural-language name** of the destination ' parentDestinationId: type: integer format: int64 description: '**unique numeric identifier** of the destination''s parent destination ' parentDestinationName: type: string description: '**natural-language name** of the destination''s parent destination ' translationInfo: $ref: '#/components/schemas/TranslationDetails' url: type: string description: 'URL of destination ' ProductSearchFlag: type: string description: "One of:\n\n - `\"NEW_ON_VIATOR\"` – products that have been added to Viator's catalogue within the past 270 days\n - `\"SKIP_THE_LINE\"` – products that allow participants to attend a location without having to obtain a separate ticket on the occasion itself (`itinerary.skipTheLine` is `true`)\n - `\"PRIVATE_TOUR\"` – products where only the travelers who have booked the product will be present (`itinerary.privateTour` is `true`)\n - `\"SPECIAL_OFFER\"` – products that have a pricing discount available (i.e., `summary.fromPriceBeforeDiscount` will be present in the response from [/availability/schedules/{product-code}](#operation/availabilitySchedules))\n - `\"LIKELY_TO_SELL_OUT\"` - popular products that routinely sell out (this is equivalent to filtering by tag `20757`).\n" ProductSummary: type: object required: - productCode - destinations - tags - flags properties: productCode: type: string description: 'Code that is the unique identifier for this product. - Example: `"5657BRIDGECLIMB"` ' title: type: string description: "Natural-language title of this product\n\n - **Example**: `\"Sydney BridgeClimb\"`\n - **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter\n" description: type: string description: 'Description of this product - **Example**: "Climb the Sydney Harbour Bridge with an expert guide for the ultimate Sydney experience..." - **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter ' images: type: array items: $ref: '#/components/schemas/Image' description: Images for this product. videos: type: array items: $ref: '#/components/schemas/Video' description: Videos for this product. reviews: $ref: '#/components/schemas/ProductReviews' duration: $ref: '#/components/schemas/ItineraryDuration' pricing: $ref: '#/components/schemas/ProductSearchPricing' productUrl: type: string description: "URL for this product on the viator.com site, where the customer will complete their booking.\n\nThis URL includes all the necessary information for viator to correctly attribute and pay commission for the sale to the referring partner.\n\nIf `campaign-value` is included in the request, this URL will also include the campaign tracking value that you set.\n\nFor more information, see our guide to [Affiliate Attribution](https://partnerresources.viator.com/travel-commerce/affiliate/attribution/) on the Viator Partner Resource Center.\n\n**Note**: \n\n- This element is only returned for affiliate partners. \n- **You must use the full URL and not modify it in any way – any changes could result in failure to attribute the sale to you, which means you will not be paid a commission for this sale.**\n- For whitelabel partners, the productUrl will dynamically retrieve the partners custom **domain URL**, instead of defaulting to viator.com\n\n**Example format**: https://www.viator.com/tours/Sydney/Sydney-and-Bondi-Hop-on-Hop-off-Tour/d357-5010SYDNEY?mcid=42383&pid=P00045135&medium=api&version=2.0&campaign=example\n" destinations: type: array items: $ref: '#/components/schemas/Destination' description: 'Destinations in which this product operates. - **Note**: At present, only the primary destination ID is returned; i.e., the item in the `destinations` array of the product content response for which `primary` is `true`. Therefore, `primary` will always be `true` in this response. Furthermore, the destination given here may differ from the destination specified in the request. ' tags: type: array items: type: integer description: "Array of numeric tag identifiers indicating the product categories into which this product falls \n\nTo retrieve details about which tags these identifiers refer to, please use the [/products/tags](#operation/productsTags) endpoint.\n\nSee the [Resolving references](#section/Workflows/Resolving-references) section and this article: [Viator tags, explained](https://partnerresources.viator.com/travel-commerce/tags?source=specs) for more information about tags.\n" flags: type: array items: $ref: '#/components/schemas/ProductSearchFlag' description: "List of product attribute flags specified in the request\n\nMay include any of:\n\n - `\"NEW_ON_VIATOR\"` - products that have been added to Viator's catalogue within the past 270 days\n - `\"FREE_CANCELLATION\"` – products that have a cancellation policy that allows for free cancellation (i.e., excludes products for which `cancellationPolicy.type` is `\"ALL_SALES_FINAL\"` in the product content response)\n - `\"SKIP_THE_LINE\"` – products that allow participants to attend a location without having to obtain a separate ticket on the occasion itself (`itinerary.skipTheLine` is `true`)\n - `\"PRIVATE_TOUR\"` – products where only the travelers who have booked the product will be present (`itinerary.privateTour` is `true`)\n - `\"SPECIAL_OFFER\"` – products that have a pricing discount available (i.e., `summary.fromPriceBeforeDiscount` will be present in the response from [/availability/schedules/{product-code}](#operation/availabilitySchedules))\n - `\"LIKELY_TO_SELL_OUT\"` - popular products that routinely sell out (this is equivalent to filtering by tag `20757`).\n" confirmationType: $ref: '#/components/schemas/ConfirmationType' itineraryType: $ref: '#/components/schemas/ItineraryType' translationInfo: $ref: '#/components/schemas/TranslationDetails' FreetextSearchProductFiltering: type: object required: - searchTerm description: 'Criteria by which to filter product search results (i.e., when `searchTypes` includes `"PRODUCTS"`) ' properties: destination: type: string description: 'Match results that are assigned this destination. Only Viator destination integer ID is accepted for now. ' dateRange: type: object description: 'Match products that are available to be booked on one or more of the days included in this date range ' properties: from: type: string format: date description: 'Match results that are available from `from` to `to`. - **Format**: ISO-8601 (YYYY-MM-DD) in time-zone of supplier and cannot be in the past. ' example: '2020-05-29' to: type: string format: date description: "Match results that are available from `from` to `to`.\n\n- **Format**: ISO-8601 (YYYY-MM-DD) in time-zone of supplier\n- **Note**:\n - `to` cannot be in the past and is limited to one year from the date on which the request is made. \n - Multi-day tours that conclude after this date will still appear in the results, so long as the tour commences prior to this date, even if they conclude on a date that is further into the future than `to`. If you wish to exclude such products from the search results, the following options are available:\n 1. Exclude all multi-day tours from the search results by filtering out any items that contain `\"itineraryType\": \"MULTI_DAY_TOUR\"`\n 2. Implement your own logic to calculate whether a product concludes after the `endDate` specified in the request by requesting full product details for the multi-day tour using [/products/{product-code}](#operation/products), determining the duration of the tour in days by the length of the `itinerary.days[]` array, and filtering this product from the search results in the event that (`from` + duration) occurs after `to`.\n" example: '2020-06-29' price: type: object description: 'Match products which have a ''from price'' within the range indicated here ' properties: from: type: number minimum: 0 description: 'Match results that with price within `from` to `to` ' to: type: number minimum: 0.01 description: 'Match results that with price within `from` to `to` ' rating: type: object description: 'Match products that have an average rating within the range indicated here ' properties: from: type: number minimum: 0 description: 'Match results that with rating within `from` to `to` ' to: type: number minimum: 0.01 description: 'Match results that with rating within `from` to `to` ' durationInMinutes: type: object description: 'Match products that have a duration (length of time the experience lasts) within the range indicated here ' properties: from: type: integer minimum: 0 description: 'Match results that with duration within `from` to `to` ' to: type: integer minimum: 1 description: 'Match results that with duration within `from` to `to` ' tags: type: array items: type: integer description: 'Only return products that include **all** tag identifiers provided here. Products with child tags of any parent tags specified here will also be returned. See the [Resolving references](#section/Workflows/Resolving-references) section and this article: [Viator tags, explained](https://partnerresources.viator.com/travel-commerce/tags?source=specs) for more information about tags. ' flags: type: array description: "Match products that have the following attributes:\n\nAny of:\n\n - `\"NEW_ON_VIATOR\"` – products that have been added to Viator's catalogue within the past 270 days\n - `\"SKIP_THE_LINE\"` – products that allow participants to attend a location without having to obtain a separate ticket on the occasion itself (`itinerary.skipTheLine` is `true`)\n - `\"PRIVATE_TOUR\"` – products where only the travelers who have booked the product will be present (`itinerary.privateTour` is `true`)\n - `\"LIKELY_TO_SELL_OUT\"` - popular products that routinely sell out (this is equivalent to filtering by tag `20757`).\n" items: $ref: '#/components/schemas/ProductSearchFlag' includeAutomaticTranslations: type: boolean description: 'Specifies whether proucts with automatically machine-translated content (no human oversight) should be included in the results ' default: true ExchangeRateItem: type: object properties: sourceCurrency: type: string description: Base currency for this conversion rate targetCurrency: type: string description: Target currency for this conversion rate rate: type: number description: Value of `targetCurrency` per unit of `sourceCurrency` lastUpdated: type: string format: date-time description: 'Timestamp (UTC) indicating the last time this currency exchange rate was updated ' expiry: type: string format: date-time description: 'Timestamp (UTC) indicating until when this rate will apply ' AvailabilityScheduleExtraChargesSummary: type: object description: Information about the lowest price with extra charges available for this product required: - fromPrice - extraCharges properties: fromPrice: type: number description: '`fromPrice` value including `extraCharges` value to be paid in destination by the traveler based on their age, day of the week, time of the year or any other criteria defined by the supplier. This value will only be returned if the product has Extra Charges in at least one `bookableItem`. ' fromPriceBeforeDiscount: type: number description: 'If the product is presently discounted, this field shows what the value of `fromPrice` would be if no discount had been applied; otherwise, it will be absent. ' extraCharges: type: number description: 'The highest amount that a traveler could be asked to pay in-destination based on their age, day of the week, time of the year or any other criteria defined by the supplier for the `bookableItem` used to calculate the starting price. ' ProductReviewsRequest: type: object required: - productCode - start - count - provider properties: productCode: type: string description: Retrieve reviews for the product identified by this product code count: type: integer format: int32 description: Number of reviews to be returned in the response; used for pagination start: type: integer format: int32 description: Position of first review to be returned in the response; used for pagination provider: type: string description: 'Limit the reviews returned in the response to those associated with this provider; one of: - `"VIATOR"` – only include reviews submitted on viator.com - `"TRIPADVISOR"` – only include reviews submitted on tripdavisor.com - `"ALL"` - include reviews from all providers ' sortBy: type: string description: 'One of: - `"HIGHEST_RATING_PER_LOCALE"` – sort by rating (descending) *for each locale* - `"MOST_RECENT_PER_LOCALE"` – sort by publication date (descending) *for each locale* - `"MOST_HELPFUL_PER_LOCALE"` – sort by the number of ''helpful'' votes (descending) *for each locale* - `"HIGHEST_RATING"` – sort by rating (descending) *across all locales* - `"MOST_RECENT"` – sort by publication date (descending) *across all locales* - `"MOST_HELPFUL"` – sort by the number of ''helpful'' votes (descending) *across all locales* If this element is omitted, the default sort option is `"MOST_RECENT"` ' reviewsForNonPrimaryLocale: type: boolean description: 'Controls whether reviews that cannot be provided in the requested language are included. When `false`, returns only reviews that can be provided in the requested language, either originally or via machine translation. When `true`, additional reviews may be returned in their original language when no requested-language version is available. ' showMachineTranslated: type: boolean description: 'When `true`, returns machine-translated review text in the requested language, where available, based on `Accept-Language`. When `false`, reviews are returned in their original language, even if a machine translation exists. This does not filter reviews by their original language. ' ratings: type: array description: 'Only include reviews with these ratings **Example**: `[3,4,5]` to receive reviews with a rating of 3 or above ' items: type: integer format: int32 AttractionResult: type: object properties: id: type: integer description: unique numeric identifier of the attraction name: type: string description: 'natural-language title of the attraction **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter ' primaryDestinationId: type: integer description: unique numeric identifier of this attraction's primary destination description: type: string description: "natural-language descriptive text for this attraction\n\n**Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter\n - Access to this information is only available if it is enabled for your account. Please [reach out to our support team](#section/Support) if you would like to take advantage of our unique content.\n - You must ensure that your site is configured such that **no Viator Unique Content is indexed by any search engine**. This is a requirement for site certification. For more information, see [Key concepts – Protecting unique content](#section/Key-concepts/Protecting-unique-content)\n" destinationName: type: string description: 'natural-language name of the primary destination associated with this attraction **Note**: This field contains natural language suitable for display to the user; content will be translated (if necessary) into the language specified in the Accept-Language header parameter ' productsCount: type: integer description: Number of products associated with this attraction translationInfo: $ref: '#/components/schemas/TranslationDetails' reviews: $ref: '#/components/schemas/ProductReviewsSummary' images: type: array items: $ref: '#/components/schemas/Image' FreetextSearchResponse: type: object properties: destinations: type: object description: 'Destinations that include the `searchTerm` when `"DESTINATIONS"` results are requested via `searchTypes` ' properties: totalCount: type: integer format: int64 description: Total number of destinations that may be returned if pagination is not specified in the request. results: type: array description: 'List of matching destinations ' items: $ref: '#/components/schemas/DestinationSearchResult' attractions: type: object description: 'Attractions that include the `searchTerm` when `"ATTRACTIONS"` results are requested via `searchTypes` ' properties: totalCount: type: integer format: int64 description: Total number of attractions that may be returned if pagination is not specified in the request. results: type: array description: 'List of matching attractions ' items: $ref: '#/components/schemas/AttractionResult' products: type: object description: 'Products that include the `searchTerm` when `"PRODUCTS"` results are requested via `searchTypes` ' properties: totalCount: type: integer format: int64 description: Total number of products that may be returned if pagination is not specified in the request. results: description: 'List of matching products ' type: array items: $ref: '#/components/schemas/ProductSummary' ExchangeRatesResponse: type: object properties: rates: type: array description: Currency exchange rates items: $ref: '#/components/schemas/ExchangeRateItem' LocationsResponse: type: object required: - locations properties: locations: type: array description: Locations items: $ref: '#/components/schemas/Location' ItineraryType: type: string description: "Machine-interpretable value specifying the type of itinerary available for this product; one of:\n\n - `\"STANDARD\"`\n - `\"ACTIVITY\"`\n - `\"MULTI_DAY_TOUR\"`\n - `\"HOP_ON_HOP_OFF\"`\n - `\"UNSTRUCTURED\"`\n" LocationCenter: type: object description: Geographic coordinates (latitude/longitude) for this location properties: latitude: type: number description: "Latitude of this location\n\n - **Example**: `-33.870037`\n" longitude: type: number description: "Longitude of this location\n\n - **Example**: `151.20955`\n" ReviewPhoto: type: object required: - height - width - url properties: height: type: integer format: int32 description: Height of image in pixels width: type: integer format: int32 description: Width of image in pixels url: type: string description: URL at which this image is located LocationProvider: type: string description: "Name of the location services provider, one of:\n\n - `\"TRIPADVISOR\"` – location details will be provided in this response\n - `\"GOOGLE\"` – in order to retrieve details for these locations, you will need to use [Google's Places API](https://cloud.google.com/maps-platform/places).\n" StreamingVideoVariant: type: object description: Streaming video variant required: - protocol - format - url properties: protocol: type: string description: The streaming protocol used to deliver the video (e.g. `HLS`). This defines how the playlist and media segments are interpreted by the player. example: HLS format: type: string description: The playlist or manifest format for the streaming protocol (e.g. `M3U8`). example: M3U8 url: type: string description: The URL of the streaming playlist that serves as the entry point for video playback. example: https://hare-dynamic-media-cdn.tripadvisor.com/media/video-v/31/1f/5b/68/vid-693-rome-2017-vatican_1080.m3u8 headers: RateLimit-Limit: required: true schema: type: string description: 'Total limit of requests for this endpoint for a given window. For informational purposes only. ' Retry-After: required: true schema: type: string description: 'The fixed window in time, in seconds, which represents when a limit is fully replenished. For informational purposes only. ' XUniqueId: required: true schema: type: string description: 'Tracking identifier for this response. Please include the value of this field when making help requests. - **Example**: `"0A871A13:DE2A_0A8712F9:01BB_5DCCC98C_260DAA:0D5B"` ' RateLimit-Reset: required: true schema: type: string description: 'The fixed window in time, in seconds, which represents when a limit is fully replenished. For informational purposes only. ' RateLimit-Remaining: required: true schema: type: string description: 'Remaining requests for this endpoint for a given window. For informational purposes only ' responses: TooManyRequests: description: Too Many Requests headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"TOO_MANY_REQUESTS"` See [Workflows - Rate limiting](#section/Workflows/Rate-limiting) for more information about this error. ' message: description: 'Details of this error **Example**: `"Too many requests, please try again"` ' - type: object example: code: TOO_MANY_REQUESTS message: Too many requests timestamp: '2019-09-17T03:20:45.737043Z' NotFound: description: Not Found headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"NOT_FOUND"` ' message: description: 'Details of this error **Example**: `"The specified resource was not found"` ' - type: object example: code: NOT_FOUND message: The specified resource was not found timestamp: '2019-09-17T03:20:45.737043Z' Forbidden: description: Forbidden headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"FORBIDDEN"` ' message: description: 'Details of this error **Example**: `"Request is forbidden"` ' example: code: FORBIDDEN message: Request is forbidden timestamp: '2019-09-17T03:20:45.737043Z' Unauthorized: description: Unauthorized headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"UNAUTHORIZED"` ' message: description: 'Details of this error **Example**: `"Invalid API Key"` ' - type: object example: code: UNAUTHORIZED message: Invalid API Key timestamp: '2019-09-17T03:20:45.737043Z' BadRequest: description: Bad Request headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"BAD_REQUEST"` ' message: description: 'Details of this error **Example**: `"Invalid request"` ' - type: object example: code: BAD_REQUEST message: Invalid request timestamp: '2019-09-17T03:20:45.737043Z' NotAcceptable: description: Not Acceptable headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"NOT_ACCEPTABLE"` ' message: description: 'Details of this error **Example**: `"Not acceptable"` ' - type: object example: code: NOT_ACCEPTABLE message: Not acceptable timestamp: '2019-09-17T03:20:45.737043Z' InternalServerError: description: Internal Server Error headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"INTERNAL_SERVER_ERROR"` ' message: description: 'Details of this error **Example**: `"Internal server error"` ' - type: object example: code: INTERNAL_SERVER_ERROR message: Internal Server Error timestamp: '2019-09-17T03:20:45.737043Z' ServiceUnavailable: description: Service Unavailable headers: X-Unique-ID: $ref: '#/components/headers/XUniqueId' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: allOf: - $ref: '#/components/schemas/ErrorResponse' - type: object properties: code: description: 'Code for this error type **Example**: `"SERVICE_UNAVAILABLE"` ' message: description: 'Details of this error **Example**: `"Service unavailable"` ' - type: object example: code: SERVICE_UNAVAILABLE message: Service Unavailable timestamp: '2019-09-17T03:20:45.737043Z' parameters: accept: in: header name: Accept description: 'Specifies the version of this API to access ' required: true schema: type: string example: application/json;version=2.0 acceptLanguage: in: header name: Accept-Language description: 'Specifies the language into which the natural-language fields in the response from this service will be translated (see [Accept-Language header](#section/Localization/Accept-Language-header-parameter) for available language codes) ' required: true schema: type: string example: en-US campaignValueDestination: name: campaign-value in: query description: '**Affiliate partners only**: Specifies the campaign tracking identifier that will be appended to the URL returned in `destinationUrl` as a query parameter. Campaigns allow you to track how specific links perform, with metrics such as sessions, bookings, and commission. Reports are available via the Viator Partner Platform. **Note**: If you wish to use a campaign value that includes non-alphanumeric characters (e.g., ''+'', ''-'', etc.), you must URL-encode these characters. ' required: false schema: type: string maxLength: 200 campaignValueProduct: name: campaign-value in: query description: '**Affiliate partners only**: Specifies the campaign tracking identifier that will be appended to the URL returned in `productUrl` as a query parameter. Campaigns allow you to track how specific links perform, with metrics such as sessions, bookings, and commission. Reports are available via the Viator Partner Platform. **Note**: If you wish to use a campaign value that includes non-alphanumeric characters (e.g., ''+'', ''-'', etc.), you must URL-encode these characters. ' required: false schema: type: string maxLength: 200 securitySchemes: API-key: type: apiKey in: header name: exp-api-key