Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Viator Partner Auxiliary API
description: 'code { white-space: nowrap; }
a { font-weight: bold; }
figure {
width: 100%;
text-align: center;
font-style: italic;
font-size: smaller;
text-indent: 0;
border: thin silver solid;
margin: 0.5em;
padding: 0.5em;
}
## Updates
### Latest updates:
| Date | Description…'
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 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 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.
Exchange rates should be cached and refreshed based on the expiry timestamp (at the moment daily).
In 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).
Not all supplier currencies are supported, but many are. They comprise:
- 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
While pricing can be in any of the currencies listed above, payments for bookings can only be made using the following four currencies:
- GBP (British Pound)
- EUR (Euros)
- USD (US Dollars)
- AUD (Australian dollars)
In 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).
In 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.
An additional measure to ensure that you charge your customer accurately is to confirm that the pricing details returned by the /availability/check 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.
**Note:** If you attempt to use an unsupported currency when making a booking request, you will receive the following error:
```javascript
Incorrect currency code provided
```
**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.
Learn more about calculating product pricing in this article: Calculating Product Pricing
(Response sample generated on: 2020-09-17)'
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
Reviews 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.
**Non-indexing of reviews**
- 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.
**Availability of reviews**
- 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.
**Viator performs checks on reviews**
- For more information, see Key concepts - Review authenticity
Note: 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.'
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).
**Note**:
- Returns a complete list of Viator destinations, including destination names and parent identifiers
- Used to provide navigation through drill down lists or combo boxes
- Use the data received from this endpoint to resolve the destination identifier(s) in the `destinations[].ref` element in the product content response'
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:
headers:
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.
'
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-Remaining:
required: true
schema:
type: string
description: 'Remaining 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.
'
RateLimit-Limit:
required: true
schema:
type: string
description: 'Total limit of requests for this endpoint for a given window. For informational purposes only.
'
schemas:
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
'
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'
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
LocationsResponse:
type: object
required:
- locations
properties:
locations:
type: array
description: Locations
items:
$ref: '#/components/schemas/Location'
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)
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"
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
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'
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
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'
DestinationsResponse:
type: object
properties:
destinations:
type: array
items:
$ref: '#/components/schemas/DestinationDetails'
totalCount:
type: integer
format: int32
description: Total count of Destinations returned
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
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 wi
# --- truncated at 32 KB (126 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/viator/refs/heads/main/openapi/viator-auxiliary-api-openapi.yml