Viator API Documentation & Specification - Viator Affiliates (bookings) (1.0)

Download OpenAPI specification:Download

Viator Partner Support Team: affiliateapi@tripadvisor.com License: CC BY 4.0

Updates

Date Description
17 June 2022 Added /util/countrymap service
26 May 2022 Added advice about review authenticity: Key concepts - Review authenticity
6 May 2022 Added product-content endpoints (which are not exclusive to transactional affiliates but return booking-related data elements) so that descriptions for these fields appear in this document; i.e., /search/products, /search/products/codes, /search/freetext, /product and /attraction/products
11 Dec 2020 Added Key concepts – Booking references , Key concepts – Cancellation policy and Common workflows and data validation – API workflow sections
9 Dec 2020 Added /bookings/cancel-reasons, /bookings/{booking-reference}/cancel-quote and /bookings/{booking-reference}/cancel endpoints
28 Oct 2020 Updated FAQ section re booking questions, traveler names, and pricing
2 June 2020 Updated Postman collections and Testing section
20 May 2020 Recompiled document with ReDoc 0.9.8 to resolve Chrome 80 incompatibility
20 Apr 2020 Regenerated response samples for most endpoints; updated postman collection

Overview

This manual is an addendum to the Viator affiliate technical manual, covering booking-related topics.

Who is the API for?

Transactional affiliates

VBAs with booking capability, or 'transactional affiliates' also have the option of allowing their customers to process bookings directly from their site and via the API – similar to a merchant partner – without being redirected to viator.com to complete their transaction. This partner type sends customer details, product details and credit card payment information via the API, but Viator retains control of and responsibility for processing payments and customer support.


Authentication

Note:

  • The authentication mechanism for this API has been updated recently. Now, partners can also authenticate using a new style of API key that is included in each call as a header parameter. Previously, authentication was accomplished by including an API key as a query parameter.

  • Partners who are currently authenticating via the API key query parameter can continue to authenticate in this way; however, access to the new booking cancellation endpoints does require the new-style of API key. All other endpoints remain compatible with both authentication methods.

  • If you would like to switch to the new style of key, please speak to your business development account manager.

API key

Access 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.

Header parameter name Example value
exp-api-key bcac8986-4c33-4fa0-ad3f-75409487026c

If you do not know the API key for your organization, please contact your business development account manager for these details.

Please note that language localization is now controlled on a per-call basis. Previously, language localization was controlled via API-key configuration, with one language available per API key. Under the present scheme, you can access any language enabled for your organization's point of sale via a single API key.

Language selection is accomplished by specifying the desired language as a header parameter (Accept-Language). See Accept-Language header for available language codes. If you would like access to additional languages, please contact your business development account manager.

Legacy API key

Previously, authenticating to this API was accomplished by passing an API-key as a query parameter appended to the URI for each call; e.g.:

GET https://viatorapi.sandbox.viator.com/service/taxonomy/destinations?apiKey=xxxxxxxxxxxxxxxxxx

This method of authentication remains available for backwards-compatibility with existing implementations. If you would like to upgrade to the new style of API key, please contact your business development account manager.

Key concepts

Review authenticity

Viator performs checks on reviews

You 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.

If 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 click on the link provided in the email.

After 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.

Booking

Booking types – on-request and freesale

Bookings made with Viator can be either freesale (immediate confirmation) or on-request, which require us to confirm with our product supplier that the product has not sold out and is still available. This difference must be clearly communicated to the customer during the price check and on the order summary post-purchase page.

For freesale bookings, the voucher becomes available immediately, and the customer's credit card will be charged at the time of booking. For on-request bookings, confirmation will be sent to the customer within a timeframe supplied in the /booking/calculateprice and /bookingBook service responses.

The customer's credit card will be charged once their on-request booking is confirmed.

Tour grades

Products can have one or more tour grades. Each tour grade might represent a departure time or different tour option, such as additional meals, transport and so forth. If the tour grade code is "DEFAULT", do not display this to the customer, simply hide the product's tour grade information.

Language options

Many tours delivery a commentary in multiple languages using multilingual tour guides or with written or prerecorded information. Where available, the customer can preselect their preferred language option.

Age bands

The available age bands for a product, such as adult, child, infant, etc., are returned by the /product service. The customer can select a different number of people from each age band during the price check and checkout process.

Traveler mix (pax)

Some tour grades have defined traveler mixes used to price family passes; or, they might have special mixes for limited passenger tours, such as small buggies or weddings.

These traveler mixes are provided by the /booking/availability/tourgrades service. You may need to display these to your customers so that they are able to understand why they can or cannot select a particular tour grade if there is a traveler mix mismatch.

Pick-up location and hotel lists

Some products have pick-up and return shuttle bus services. For these tours, you will need the customer to supply a pick-up hotel, or they must select live locally or hotel not yet booked options.

Viator maintains pick-up hotel lists for many popular destinations. These lists are available for customers to select their pick-up location for various tours. For destinations without hotel lists, customers can enter the name of their hotel. If a customer's hotel is not listed, they should be able to enter a hotel name; however, pick-up may not be possible for that hotel.

Lead traveler

Each tour booking requires a lead traveler to be identified. To identify the lead traveler in your request, set the leadTraveller flag to true in the traveler class.

Booking questions

Some products have a list of one or more booking questions that need to be asked. Some are mandatory. The question, a description, etc. are provided in the product details object. The answers need to be included with the booking request.

SSL/HTTPS

Calls to the /booking/book service must use a secure channel (https) as they contain credit card information.

Promo codes

Viator can create promotional (promo) codes for discounts and other purposes. As it's unlikely for you to wish to support this feature, we recommend supplying null in the promoCode field and not including any customer-entered fields during the checkout process.

Partner data

Partners can also supply additional information for their own internal purposes. These are attached to booking reports and other materials for use in allocating commissions to agents and so forth.

Understanding the pricingUnit field

This section explains the meaning and function of the pricingUnit field in the response object received from the /booking/availability/tourgrades/pricingmatrix service.

Request body

This service takes the following parameters as input in its request body:

Parameter Type Meaning
productCode string unique alphanumeric identifier of the product to enquire about
month string month of the year by which to filter results
year string year by which to filter results
currencyCode string code for the currency in which to display pricing information

Example request body

{
  "productCode": "10040WORLD",
  "currencyCode": "USD",
  "month": "06",
  "year": "2019"
}

Response object

Within each object item of the tourGrades array – each giving pricing details for a specific tour grade – is a pricingMatrix array, the object items each detailing the per-age-band pricing for a specific pricing unit (pricingUnit) associated with that product.

Using this information, you should be able to calculate the total cost of the booking – considering any booking options – with regard to the number of participants.

How to identify the fundamental unit prices for a booking, which are then summed in order to calculate a total price, is detailed below.

Note that in the response object received from the service, pricing schedules are organized hierarchically as follows:

bookingDate
--tourGrade
----ageBand
------price

Types of pricing unit

There are two fundamental types of pricing unit – per-person and per-group.

Per-person pricing schedule

If the pricing is per-person, then the total price of the booking will be directly proportional to the number of participants (passengers) of each type that are booking the product; i.e., a multiple of the per-person price.

The only pricing unit specifier for per-person pricing is “per person”; i.e.:

  • "pricingUnit": "per person"
Pricing unit Example product Meaning
"per person" 10040WORLD Per-person pricing – the unit price refers to the price for an individual participant.
Some products have tiered pricing arrangements; i.e., a different per-person price can apply if certain numbers and combinations of participants in a particular age band are booking the product; e.g.:
  • 1-2 adults: $50 per person
  • 3-4 adults: $45 per person

Whether a range is available to be booked depends on whether the customer’s desired passenger mix satisfies the minimumCountRequired and maximumCountRequired fields in each item of the ageBandPrices array.

Per-group pricing

If the pricing is per-group, then the total price of the booking will depend on the number of groups and types of group that ideally accommodate the participant mix.

The following pricing schedules follow “per-group” logic:

  • "pricingUnit": "per vehicle"
  • "pricingUnit": "per car"
  • "pricingUnit": "per group"
  • "pricingUnit": "per boat"
  • "pricingUnit": "per package"
  • "pricingUnit": "per jetski"
  • "pricingUnit": "per vessel"
  • "pricingUnit": "per helicopter"
  • "pricingUnit": "per room"
  • "pricingUnit": "per bike"
  • "pricingUnit": "per flight"
  • "pricingUnit": "per plane"
  • "pricingUnit": "per couple"

Eligibility for a certain individual pricing schedule; or, for inclusion in a particular group type, depends on the tour grade for the product, the type of participant (e.g., the age-band they fall into) and the date of the booking.

Group pricing schedules

Pricing unit Example product Meaning
"per group" 10847P42 Per-group pricing – the unit price is calculated according to the number of groups the specified passenger will fit into rather than the exact number of participants. minimumCountRequired and maximumCountRequired must be considered as these fields relate to the available group sizes.
"per room" 6279P26 Per-room pricing relates the room price, which depends on the number of participants making the booking.
"per package" 25941P70 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
"per vehicle" 6154SHOP Per-vehicle pricing is calculated according to the number of vehicles required for the specified passenger mix rather than the exact number of participants. minimumCountRequired and maximumCountRequired 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.
"per car" 10175P10 Per-car pricing – identical to "per vehicle", but refers specifically to vehicles that are cars.
"per boat" 11121P40 Per-boat pricing – identical to "per vehicle", but refers specifically to vehicles that are boats.
"per jetski" 28965P127 Per-jetski pricing – identical to "per vehicle", but refers specifically to vehicles that are jet-skis.
"per vessel" 17295P24 Per-vessel pricing – identical to "per vehicle", but refers specifically to maritime vessels that are not strictly boats.
"per helicopter" 12189P23 Per-helicopter pricing – identical to "per vehicle", but refers specifically to vehicles that are helicopters.
"per bike" 17448P8 Per-bike pricing – identical to "per vehicle", but refers specifically to vehicles that are bikes.
"per flight" 28965P134 Per-flight pricing – identical to "per vehicle", but refers specifically to the act of being aboard a flying vehicle.
"per plane" 14876P5 Per-plane pricing – identical to "per vehicle", but refers specifically to vehicles that are aeroplanes.

Interpreting response objects by example

In this section, we’ll have a look at snippets from the response objects received from the /booking/availability/tourgrades/pricingmatrix service and interpret the results.

Per-person pricing

Request object
{
  "productCode": "10040WORLD",
  "currencyCode": "USD",
  "month": "06",
  "year": "2019"
}

Response snippet

Note: pricingMatrix is an array of objects that detail the available pricing schedules for the product:

"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per person",
    "bookingDate": "2019-06-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 13.85,
            "priceFormatted": "$13.85",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 0,
        "maximumCountRequired": 15
      },
      {
        "bandId": 2,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 6.92,
            "priceFormatted": "$6.92",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          }
        ],
        "sortOrder": 2,
        "minimumCountRequired": 0,
        "maximumCountRequired": 15
      },
      {
        "bandId": 3,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 0,
            "priceFormatted": "$0.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          }
        ],
        "sortOrder": 3,
        "minimumCountRequired": 0,
        "maximumCountRequired": 15
      },
      {
        "bandId": 5,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 10.39,
            "priceFormatted": "$10.39",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          }
        ],
        "sortOrder": 4,
        "minimumCountRequired": 0,
        "maximumCountRequired": 15
      }
    ]
  }
]

In this example, four age bands (1, 2, 3 and 5) have pricing information available. These numerically-identified age bands are the age bands allowed to book the product. Details of the age ranges that the product operator has defined are available from the /product service.

A call to /product regarding 10040WORLD yields the following information:

"ageBands": [
  {
    "sortOrder": 1,
    "ageFrom": 13,
    "ageTo": 64,
    "adult": true,
    "bandId": 1,
    "pluralDescription": "Adults",
    "treatAsAdult": true,
    "count": 0,
    "description": "Adult"
  },
  {
    "sortOrder": 2,
    "ageFrom": 65,
    "ageTo": 99,
    "adult": false,
    "bandId": 5,
    "pluralDescription": "Seniors",
    "treatAsAdult": true,
    "count": 0,
    "description": "Senior"
  },
  {
    "sortOrder": 3,
    "ageFrom": 4,
    "ageTo": 12,
    "adult": false,
    "bandId": 2,
    "pluralDescription": "Children",
    "treatAsAdult": false,
    "count": 0,
    "description": "Child"
  },
  {
    "sortOrder": 4,
    "ageFrom": 0,
    "ageTo": 3,
    "adult": false,
    "bandId": 3,
    "pluralDescription": "Infants",
    "treatAsAdult": false,
    "count": 0,
    "description": "Infant"
  }

Product operators choose the age bands available for their product from the following five categories and define the age ranges that pertain to each band; i.e.:

bandId description
1 Adult
2 Child
3 Infant
4 Youth
5 Senior

For this product, the age bands have been defined as follows:

bandId description ageFrom ageTo
1 Adult 13 64
5 Senior 65 99
2 Child 4 12
3 Infant 0 3

Therefore, for this product, the following pricing applies:

Passenger type Number Price
Adult 1-15 $13.85 per person
Senior 1-15 $10.39 per person
Child 1-15 $6.92 per person
Infant 1-15 free ($0)

Per-person pricing might depend on the mix of passengers booking the tour. In the following example (5010SYDNEY), a "48 Hour Family Pass Ticket" has a different price for children depending on how many are participating, which we'll see in the following snippet.

Response snippet
"tourGrades": [
  {
    "sortOrder": 1,
    "gradeCode": "14HFAM",
    "gradeTitle": "48 Hour Family Pass Ticket",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 133.47,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$133.47",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 1
          },
          {
            "bandId": 2,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 0,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$0.00",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 2,
            "minimumCountRequired": 2,
            "maximumCountRequired": 2
          },
          {
            "bandId": 3,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 0,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$0.00",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 3,
            "minimumCountRequired": 0,
            "maximumCountRequired": null
          }
        ]
      },
      {
        "sortOrder": 2,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 133.47,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$133.47",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 1
          },
          {
            "bandId": 2,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 3.71,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$3.71",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 2,
            "minimumCountRequired": 3,
            "maximumCountRequired": 4
          },
          {
            "bandId": 3,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 0,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$0.00",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 3,
            "minimumCountRequired": 0,
            "maximumCountRequired": null
          }
        ]
      }
    ]
  },]
Interpretation

To be eligible for a family pass ticket, the group must consist of an adult and at least two children.

Passenger mix Adult price Child price Infant price
1 Adult +
1 Child
N/A N/A N/A
1 Adult +
2 Children +
Any infants
$133.47 FREE FREE
1 Adult +
3-4 Children +
Any infants
$133.47 $3.71 FREE

Tiered per-person pricing

In this example, we see a per-person pricing schedule with a tiered arrangement, where the per-person price decreases depending on how many people are booking the tour, but the total price is still calculated as the sum of the individual per-person prices rather than an overall 'group' price.

Request object
{
  "productCode": "17972P102",
  "currencyCode": "USD",
  "month": "08",
  "year": "2019"
}
Response snippet
"tourGrades": [
  {
    "sortOrder": 1,
    "gradeCode": "TG1",
    "gradeTitle": "Arrival transfer",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 52.45,
                "priceFormatted": "$52.45",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "maximumCountRequired": 1,
            "minimumCountRequired": 1
          }
        ]
      },
      {
        "sortOrder": 2,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 26.22,
                "priceFormatted": "$26.22",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "maximumCountRequired": 2,
            "minimumCountRequired": 2
          }
        ]
      },
      {
        "sortOrder": 3,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 17.91,
                "priceFormatted": "$17.91",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "maximumCountRequired": 3,
            "minimumCountRequired": 3
          }
        ]
      },
      {
        "sortOrder": 4,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 19.19,
                "priceFormatted": "$19.19",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "maximumCountRequired": 4,
            "minimumCountRequired": 4
          }
        ]
      },
      {
        "sortOrder": 5,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 15.35,
                "priceFormatted": "$15.35",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "maximumCountRequired": 5,
            "minimumCountRequired": 5
          }
        ]
      },
      {
        "sortOrder": 6,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 12.66,
                "priceFormatted": "$12.66",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "0",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "maximumCountRequired": 6,
            "minimumCountRequired": 6
          }
        ]
      },
      {
        "sortOrder": 7,
        "pricingUnit": "per person",
        "bookingDate": "2019-08-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 10.94,
                "priceFormatted": "$10.94",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "maximumCountRequired": 7,
            "minimumCountRequired": 7
          }
        ]
      }
    ]
  }
Interpretation
Travelers Per-person price Total price
1 $52.45 $52.45
2 $26.22 $52.44
3 $17.91 $53.73
4 $19.19 $76.76
5 $15.35 $76.75
6 $12.66 $75.96
7 $10.94 $76.58

Per-group pricing

Request object
{
  "productCode": "10847P42",
  "currencyCode": "USD",
  "month": "06",
  "year": "2019"
}
Response snippet
"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per group",
    "bookingDate": "2019-06-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 390,
            "minNoOfTravellersRequiredForPrice": 1,
            "priceFormatted": "$390.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 390,
            "minNoOfTravellersRequiredForPrice": 2,
            "priceFormatted": "$390.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 10
      }
    ]
  }
]
Interpretation
  • "$390 per group of up to 10 adults"

Per-room pricing

Request object
{
  "productCode": "100245P40",
  "currencyCode": "USD",
  "month": "08",
  "year": "2019"
}
Response snippet
"pricingMatrix": [
{
    "sortOrder": 1,
    "pricingUnit": "per room",
    "bookingDate": "2019-08-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 110,
            "minNoOfTravellersRequiredForPrice": 1,
            "priceFormatted": "$110.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 110,
            "minNoOfTravellersRequiredForPrice": 2,
            "priceFormatted": "$110.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 10
      }
    ]
  }
]
Interpretation
  • "$110 per group of up to 10 adults"

Per-package pricing

Request object
{
  "productCode": "25941P70",
  "currencyCode": "USD",
  "month": "02",
  "year": "2019"
}
Response snippet
"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per package",
    "bookingDate": "2019-02-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 87.7,
            "minNoOfTravellersRequiredForPrice": 1,
            "priceFormatted": "$87.70",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 87.7,
            "minNoOfTravellersRequiredForPrice": 2,
            "priceFormatted": "$87.70",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 10
      }
    ]
  }
]
Interpretation
  • "$87.70 per group of up to 10 adults"

Per-vehicle pricing

Request object
{
  "productCode": "20190P4",
  "currencyCode": "USD",
  "month": "06",
  "year": "2019"
}
Response snippet
"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per vehicle",
    "bookingDate": "2019-06-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 250,
            "minNoOfTravellersRequiredForPrice": 1,
            "priceFormatted": "$250.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 250,
            "minNoOfTravellersRequiredForPrice": 2,
            "priceFormatted": "$250.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": ""
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 7
      }
    ]
  }
]
Interpretation
  • "$250 per group of up to 7 adults"

Per-car pricing

Request object
{
  "productCode": "10175P10",
  "currencyCode": "USD",
  "month": "06",
  "year": "2019"
}

Response snippet

"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per car",
    "bookingDate": "2019-06-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 98.08,
            "priceFormatted": "$98.08",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 98.08,
            "priceFormatted": "$98.08",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 2
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 3
      }
    ]
  }
]
Interpretation
  • "$98.08 per group of up to 3 adults"

Per-boat pricing

Request object
{
  "productCode": "11121P40",
  "currencyCode": "USD",
  "month": "08",
  "year": "2018"
}
Response snippet
"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per boat",
    "bookingDate": "2018-06-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 266.21,
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "priceFormatted": "$266.21",
            "minNoOfTravellersRequiredForPrice": 1
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 266.21,
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "priceFormatted": "$266.21",
            "minNoOfTravellersRequiredForPrice": 2
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 2
      }
    ]
  }
]
Interpretation
  • "$266.21 per group of up to 2 adults"

Per-jetski pricing

Request object
{
  "productCode": "28965P127",
  "currencyCode": "USD",
  "month": "08",
  "year": "2018"
}
Response snippet
"tourGrades": [
  {
    "sortOrder": 1,
    "gradeCode": "TG1",
    "gradeTitle": "20 minutes for 1 person",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per jetski",
        "bookingDate": "2018-06-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 55.46,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$55.46",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 1
          }
        ]
      }
    ]
  },
  {
    "sortOrder": 2,
    "gradeCode": "TG3",
    "gradeTitle": "20 minutes for 2 persons",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per jetski",
        "bookingDate": "2018-06-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 66.55,
                "minNoOfTravellersRequiredForPrice": 1,
                "priceFormatted": "$66.55",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              },
              {
                "sortOrder": 2,
                "currencyCode": "USD",
                "price": 66.55,
                "minNoOfTravellersRequiredForPrice": 2,
                "priceFormatted": "$66.55",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": ""
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 2
          }
        ]
      }
    ]
  }
]
Interpretation

This example shows how group prices can differ according to the size of the group in question. In this case, two adults can ride together on a two-person jet ski, whereas a single adult requires his or her own jet ski, and therefore the unit price is slightly higher for the single adult.

Travelers Vehicle type Price per jet ski Price per person
1 Single-person jet ski $55.46 $55.46
2 Two-person jet ski $66.55 $33.275

Per-vessel pricing

Request object
{
  "productCode": "17295P24",
  "currencyCode": "USD",
  "month": "06",
  "year": "2019"
}
Response snippet
"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per vessel",
    "bookingDate": "2019-06-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 799,
            "priceFormatted": "$799.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 799,
            "priceFormatted": "$799.00",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 2
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 12
      }
    ]
  }
]
Interpretation
  • "$799.00 per group of up to 12 adults"

Per-helicopter pricing

Request object
{
  "productCode": "12189P23",
  "currencyCode": "USD",
  "month": "08",
  "year": "2018"
}
Response snippet
"tourGrades": [
  {
    "sortOrder": 1,
    "gradeCode": "TG1",
    "gradeTitle": "Private Helicopter 1 to 2 Pax",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per helicopter",
        "bookingDate": "2018-06-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 1714.83,
                "priceFormatted": "$1,714.83",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              },
              {
                "sortOrder": 2,
                "currencyCode": "USD",
                "price": 1714.83,
                "priceFormatted": "$1,714.83",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 2
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 2
          }
        ]
      }
    ]
  },
  {
    "sortOrder": 2,
    "gradeCode": "TG2",
    "gradeTitle": "Private Helicopter 1 to 3 Pax",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per helicopter",
        "bookingDate": "2018-06-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 2047.41,
                "priceFormatted": "$2,047.41",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 1
              },
              {
                "sortOrder": 2,
                "currencyCode": "USD",
                "price": 2047.41,
                "priceFormatted": "$2,047.41",
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "minNoOfTravellersRequiredForPrice": 2
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 3
          }
        ]
      }
    ]
  }
]
Interpretation
Travelers Vehicle type Price per helicopter Price per person
1 1-2-person helicopter $1,714.83 $1,714.83
2 1-2-person helicopter $1,714.83 $857.415
3 1-3-person helicopter $2,047.41 $682.47

Per-bike pricing

Request object
{
  "productCode": "17448P8",
  "currencyCode": "USD",
  "month": "08",
  "year": "2018"
}

Response snippet

"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per bike",
    "bookingDate": "2018-06-01",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 208.53,
            "priceFormatted": "$208.53",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 208.53,
            "priceFormatted": "$208.53",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 2
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 2
      }
    ]
  }
]
Interpretation
  • "$208.53 per bike, with up to two adults per bike"

Per-flight pricing

Request object
{
  "productCode": "28965P134",
  "currencyCode": "USD",
  "month": "08",
  "year": "2018"
}
Response snippet
"tourGrades": [
  {
    "sortOrder": 1,
    "gradeCode": "TG1",
    "gradeTitle": "Individual flight",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per flight",
        "bookingDate": "2018-06-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 61.01,
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "priceFormatted": "$61.01",
                "minNoOfTravellersRequiredForPrice": 1
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 1
          }
        ]
      }
    ]
  },
  {
    "sortOrder": 2,
    "gradeCode": "TG2",
    "gradeTitle": "Double",
    "pricingMatrix": [
      {
        "sortOrder": 1,
        "pricingUnit": "per flight",
        "bookingDate": "2018-06-01",
        "ageBandPrices": [
          {
            "bandId": 1,
            "prices": [
              {
                "sortOrder": 1,
                "currencyCode": "USD",
                "price": 94.28,
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "priceFormatted": "$94.28",
                "minNoOfTravellersRequiredForPrice": 1
              },
              {
                "sortOrder": 2,
                "currencyCode": "USD",
                "price": 94.28,
                "merchantNetPrice": 0,
                "merchantNetPriceFormatted": "",
                "priceFormatted": "$94.28",
                "minNoOfTravellersRequiredForPrice": 2
              }
            ],
            "sortOrder": 1,
            "minimumCountRequired": 1,
            "maximumCountRequired": 2
          }
        ]
      }
    ]
  }
]
Interpretation
Travelers gradeTitle Price per flight Price per person
1 Individual flight $61.01 $61.01
2 Double $94.28 $47.14

Per-plane pricing

Request object
{
  "productCode": "14876P5",
  "currencyCode": "USD",
  "month": "06",
  "year": "2019"
}
Response snippet
"pricingMatrix": [
  {
    "sortOrder": 1,
    "pricingUnit": "per plane",
    "bookingDate": "2019-01-02",
    "ageBandPrices": [
      {
        "bandId": 1,
        "prices": [
          {
            "sortOrder": 1,
            "currencyCode": "USD",
            "price": 433.03,
            "priceFormatted": "$433.03",
            "merchantNetPrice": 0
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 1
          },
          {
            "sortOrder": 2,
            "currencyCode": "USD",
            "price": 433.03,
            "priceFormatted": "$433.03",
            "merchantNetPrice": 0,
            "merchantNetPriceFormatted": "",
            "minNoOfTravellersRequiredForPrice": 2
          }
        ],
        "sortOrder": 1,
        "minimumCountRequired": 1,
        "maximumCountRequired": 3
      }
    ]
  }
]
Interpretation
  • "$433.03 per group of up to three people"

Working with age bands

Why have age bands?

Tour and experience product operators can set different prices for (and impose different rules on) those wishing to make a booking for their product according to how old they are.

For example, suppliers might choose to charge people 18 years and older ('adults') the full ticket price, while 'children' can book at a lower price.

Or, 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'.

Viator provides five categories (age bands) that product operators 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.

Supported age band categories

The age bands supported by the Viator API are as follows:

bandId Description
1 Adult
2 Child
3 Infant
4 Youth
5 Senior

The names and corresponding numeric identifiers of these categories are fixed as in the table above (i.e., 1 is always Adult); however, the exact age range to which each category pertains must be defined manually by the supplier.

The maximum and minimum ages that each age band describes for each product can be retrieved from the /product service.

Example of age band definitions

For example, a call to /product regarding 10040WORLD yields the following ageBands array within its response object:

"ageBands": [
  {
    "sortOrder": 1,
    "ageFrom": 13,
    "ageTo": 64,
    "adult": true,
    "bandId": 1,
    "pluralDescription": "Adults",
    "treatAsAdult": true,
    "count": 0,
    "description": "Adult"
  },
  {
    "sortOrder": 2,
    "ageFrom": 65,
    "ageTo": 99,
    "adult": false,
    "bandId": 5,
    "pluralDescription": "Seniors",
    "treatAsAdult": true,
    "count": 0,
    "description": "Senior"
  },
  {
    "sortOrder": 3,
    "ageFrom": 4,
    "ageTo": 12,
    "adult": false,
    "bandId": 2,
    "pluralDescription": "Children",
    "treatAsAdult": false,
    "count": 0,
    "description": "Child"
  },
  {
    "sortOrder": 4,
    "ageFrom": 0,
    "ageTo": 3,
    "adult": false,
    "bandId": 3,
    "pluralDescription": "Infants",
    "treatAsAdult": false,
    "count": 0,
    "description": "Infant"
  }

For this product, the age bands have been defined as follows:

bandId description ageFrom ageTo
1 Adult 13 64
5 Senior 65 99
2 Child 4 12
3 Infant 0 3

Product operators must define at least one age band for their tour, and there are no 'default' age ranges. Therefore, if the product operator 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.

bandId must be supplied in the request body of the following services:

Age bands are referenced by their bandId in the responses from the following services:

Cancellation policy

As well as making bookings, transactional affiliate partners are also able to cancel bookings through the Viator API using the /bookings/cancel-reasons, /bookings/{booking-ref}/cancel-quote and /bookings/{booking-ref}/cancel endpoints. Items cancelled via the /bookings/{booking-ref}/cancel endpoint will be cancelled in full, and only one booking can be cancelled at a time.

For information about how to cancel bookings, see Cancellation API workflow.

Cancellation policies

All products can be cancelled; however, the refund granted by the supplier to the customer differs depending on the cancellation policy for the product in question.

There are three cancellation policy categories, standard, custom and all sales final, represented by an integer in the merchantTermsAndConditionsType field in the merchantTermsAndConditions object returned by /product: 1, 2 or 3, respectively.

Note: These policies are those provided by Viator to our partners. Partners can choose whether to extend these terms to their customers unchanged or set their own cancellation terms. For example, the partner can choose to make all products non-refundable; or, they might change the full-refund cancellation window to 72 hours instead of 24 hours, and so forth.

1 – Standard cancellation policy

Products in this category are cancellable up to 24 hours before the travel date (local supplier time) for a full refund. 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.

Example response snippet

  • Source endpoint: /product
  • Product: 5010SYDNEY
{
  "data": {
    "merchantTermsAndConditions": {
      "termsAndConditions": "For a full refund, cancel at least 24 hours in advance of the start date of the experience.",
      "merchantTermsAndConditionsType": 1,
      "amountRefundable": null,
      "cancellationFromTourDate": [
        {
          "dayRangeMin": 0,
          "dayRangeMax": 1,
          "percentageRefundable": 0,
          "policyStartTimestamp": null,
          "policyEndTimestamp": null
        },
        {
          "dayRangeMin": 1,
          "dayRangeMax": null,
          "percentageRefundable": 100,
          "policyStartTimestamp": null,
          "policyEndTimestamp": null
        }
      ]
    },
    "...": "..."
  }
}

This product has the standard cancellation policy; i.e., when a booking is cancelled:

Policy dayRangeMin dayRangeMax Logic percentageRefundable
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
more than one day (24 hours) before the start time 1 null (product_start_time - cancellation_time) >= 1 day 100

2 – Custom cancellation policy

The 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.

Example response snippet

  • Source endpoint: /product
  • Product: 2264RJ410
"data": {
  "merchantTermsAndConditions": {
    "termsAndConditions": "If you cancel at least 30 day(s) in advance of the scheduled departure, there is no cancellation fee.<br>If you cancel between 10 and 29 day(s) in advance of the scheduled departure, there is a 50 percent cancellation fee.<br>If you cancel within 9 day(s) of the scheduled departure, there is a 100 percent cancellation fee.<br>",
    "merchantTermsAndConditionsType": 2,
    "amountRefundable": null,
    "cancellationFromTourDate": [
      {
        "dayRangeMin": 10,
        "dayRangeMax": 30,
        "percentageRefundable": 50,
        "policyStartTimestamp": null,
        "policyEndTimestamp": null
      },
      {
        "dayRangeMin": 30,
        "dayRangeMax": null,
        "percentageRefundable": 100,
        "policyStartTimestamp": null,
        "policyEndTimestamp": null
      },
      {
        "dayRangeMin": 0,
        "dayRangeMax": 10,
        "percentageRefundable": 0,
        "policyStartTimestamp": null,
        "policyEndTimestamp": null
      }
    ]
  },
  "...": "..."
}

This product has a complex cancellation policy; where cancellations processed:

Policy dayRangeMin dayRangeMax Logic percentageRefundable
30 days or more before the start time 30 null (product_start_time - cancellation_time) >= 30 days 100
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
less than 10 days before the start time 0 10 (product_start_time - cancellation_time) < 10 days 0

Note: null in the dateRangeMax field means negative infinity; i.e., infinitely far in the past with respect to dateRangeMin.

Additional clauses will be included in the termsAndConditions field in natural language. This field is for human consumption and is not classically machine-interpretable.

3 – All sales final (100% cancellation penalty / no refund offered)

Products 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.

Example response snippet

  • Source endpoint: /product
  • Product: 5985P7
{
  "data": {
    "merchantTermsAndConditions": {
      "termsAndConditions": "All sales are final and incur 100% cancellation penalties.<br>",
      "merchantTermsAndConditionsType": 3,
      "amountRefundable": null,
      "cancellationFromTourDate": [
        {
          "dayRangeMin": 0,
          "dayRangeMax": null,
          "percentageRefundable": 0,
          "policyStartTimestamp": null,
          "policyEndTimestamp": null
        }
      ]
    },
    "...": "..."
  }
}

Products in this category can be cancelled, but in most cases no refund will be granted.

Canceling items with a 'pending' booking status

As alluded, there is an exception to this rule. Products with an 'on-request' booking type can still be cancelled when their booking status is "pending" – i.e., before the supplier has confirmed the booking – and a full refund will be granted.

It is impossible to predict how long an 'on-request' booking will remain 'pending'. However, it is possible to check by enquiring about the booking using one of the post-booking services; i.e.:

An 'all sales final' product in a 'pending' state that can be cancelled and a refund granted will have the following characteristics:

  1. The bookingStatus object returned from one of the services above will have a type of "PENDING", and pending will be true.
  2. The amountRefundable field of the merchantTermsAndConditions object will be non-zero and non-null. Rather, it will contain a currency-formatted string showing the amount that would be refunded if the cancellation were performed immediately; e.g., "USD 55.33".

Policy start and end times

Within the merchantTermsAndConditions object, the amountRefundable field shows the amount of money in the selected currency that will be refunded if the cancellation is processed now. Because no booking has been made at this point, the value of this field in the response from /product will be null.

Within the cancellationFromTourDate object, the policyStartTimestamp and policyEndTimestamp fields indicate the exact times between which the different cancellation refund rates apply.

  • Note: these fields are null in the response from /product, as they pertain to the cancellation policy time windows for a specific confirmed booking, and no booking is being made or enquired about at the point of retrieving product information. However, the fields will be populated in the responses from the following services that relate to making or retrieving actual bookings:

Example response snippet (merchantTermsAndConditions) from /booking/book

  • Product: 5010SYDNEY
  • Note: observe that amountRefundable, policyStartTimestamp and policyEndTimestamp are populated here.
"data": {
  "merchantTermsAndConditions": {
    "termsAndConditions": "For a full refund, cancel at least 24 hours in advance of the start date of the experience.",
    "amountRefundable": "USD 55.33",
    "cancellationFromTourDate": [
      {
        "dayRangeMin": 1,
        "dayRangeMax": null,
        "percentageRefundable": 100,
        "policyStartTimestamp": null,
        "policyEndTimestamp": 1551513600000
      },
      {
        "dayRangeMin": 0,
        "dayRangeMax": 1,
        "percentageRefundable": 0,
        "policyStartTimestamp": 1551340800000,
        "policyEndTimestamp": 1551427200000
      }
    ]
  },
  "...": "..."
}

Identically-structured merchantTermsAndConditions data structures will be returned by:

Post-travel cancellations

Occasionally, customers seek a refund for a product after completing their travels.

The 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 some other reason out of 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.

When this occurs, you will need to send a refund request by email to dpsupport and include both "CANCEL" and the booking reference number in the subject line.

For all post-travel cancellation requests, you will need to include a detailed description of the issue.

Except 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.

Once 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.

Interpreting policyStartTimestamp and policyEndTimestamp

The integers that populate the policyStartTimestamp and policyEndTimestamp fields express points in time in the Unix time format; i.e., the number of seconds that have elapsed since 00:00:00 Thursday, 1 January 1970, Coordinated Universal Time (UTC), minus leap seconds.

Unix timestamps can be easily read and interpreted using the 'time' (or similar) library of your favorite programming language. For human purposes, an online conversion tool can be used.

As per the example above, canceling this booking between the following times yields zero refund (because it is within the 24 hour window):

policyStartTimestamp policyEndTimestamp
Unix time 1551340800000
Human readable time GMT: Thursday, February 28, 2019 8:00:00 AM

Partial refunds

While we recommend that you, as a merchant partner, support the processing of partial refunds for your customers, it is up to your whether you implement this functionality.

If 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.

Type 1: Standard policy (merchantTermsAndConditionsType is 1)
The 100% refund is available so long as the cancellation is performed more than 24 hours prior to the product start time
Type 2: Custom policy (merchantTermsAndConditionsType is 2)
You will need to check whether any of the object-items in the cancellationFromTourDate array have:
  • a percentageRefundable value of 100, and
  • dayRangeMin and dayRangeMax or policyStartTimestamp and policyEndTimestamp values that include the present time
Type 3: All sales final (merchantTermsAndConditionsType is 3)
No refunds are available; therefore, granting a refund to your customer for this kind of product will be solely at your expense (i.e., you will still be invoiced for the cost of the tour by Viator). Therefore, we recommend that you do not allow refunds for products with this policy.

Booking references

When a booking is made successfully via the /booking/book endpoint, Viator assigns it a numeric identifier, now known as the booking reference.

This booking reference is returned in the service's response in the itemId field; however, this itemId is found in different locations depending on the endpoint used:

Endpoint itemId element location
/booking/book data.itemSummaries[].itemId
/booking/status data.itemSummaries[].itemId
/booking/status/items data[].itemId
/booking/pastbooking data.itemSummaries[].itemId
/booking/mybookings data[].itemSummaries[].itemId

The booking reference can used in the request in the following endpoints as the value in the itemId field or in the itemIds array:

New booking references

The new booking cancellation endpoints; i.e.:

...use this booking reference value as an in-URL request parameter, but its format is slightly different.

Essentially, it is the booking's numeric identifier (itemId), but prepended with BR-. For example, if the itemId is 580254558, the bookingId value in the cancellation request should be BR-580254558.

The booking cancellation endpoints confirm the booking reference in the response in the bookingId field; e.g.:

{
  "bookingId": "BR-580669678",
  "refundDetails": {
    "itemPrice": 412.04,
    "refundAmount": 412.04,
    "refundPercentage": 100,
    "currencyCode": "USD"
  },
  "status": "CANCELLABLE"
}

Common workflows and data validation

Users of the API usually implement a booking process workflow. The common workflows are:

Add to cart

Summary

Because the Viator API is both stateless and does not include services for managing a customer's shopping cart, this functionality must be fully managed on the partner's side.

Viator's servers can generate a price quote for one or several items, but this collection will not be saved by the server.

We recommend the following process:

  1. View product - allow the customer to browse products and product details
  2. Select date and passengers - allow the customer to check available dates and select the type and number of passengers
  3. Select tourgrade - display the available tour grades
  4. View cart -> price quote - display a total price (including multiple items)

View product

From your view product details section, a button should be presented to check availability or book now or something similar. Use the /product service to retrieve product details and schedules.

Select date and passengers

Here, the customer is presented with the dates that remain available for the product. Available dates can be obtained via a request to /booking/availability/dates. The list of age bands (i.e.: 'adult', 'child'; and, each band's maximum and minimum age) is available from the /product service.

Validation – ensure that:

  1. The total number of travelers being booked does not exceed the limit returned in the maxTravellerCount field of the /product service
  2. At least one adult (or adult equivalent) passenger has been selected
  3. The selected dates are available (use /booking/availability/dates)

Select tour grade

Once the date and traveler mix have been selected, the customer may need to select a tour grade. Products that do not have this information recorded in the Viator database are assigned a tour grade of "DEFAULT". For these products, it is unnecessary to select a tour grade.

Tour grade options must be displayed to the customer when the product has multiple tour grades, due to:

  • different departure times
  • traveler mix price deals, like family passes
  • different inclusions and prices - e.g., limo pickup, different language delivery options), or...
  • non-default tour grades – these tour grades must be presented to the customer.

The tour grades for a product are retrieved with the /booking/availability/tourgrades service. If a tour grade is available (check the available flag), an 'add to cart' button can be displayed. For unavailable tour grades (available is false), a reason (unavailableReason) is provided, which will be one of:

  • "TRAVELLER_MISMATCH"
  • "BLOCKED_OUT", or
  • "UNAVAILABLE"

You may choose to hide the blocked-out tour grades (if all tour grades are unavailable on a particular day, a day's tour grades are all "BLOCKED_OUT", or the product is not operating that day, the /booking/availability/dates service will not return that date).

You may also find that a product has no bookable tour grades on a day if the traveler mix does not meet that tour grade's traveler mix restrictions. For example, a honeymoon might require two adults as the only possible traveler mix.

You can choose to hide the "BLOCKED_OUT" tour grades, but you will probably want to display the "TRAVELLER_MISMATCH" grades with the traveler mix requirements listed so that the customer can elect to alter their traveler mix to suit (e.g., for family passes, etc.) You cannot allow the passenger to book with an incompatible traveler mix.

The return object includes information about tour grade restrictions:

ageBandsRequired:

  • minimumCountRequired: minimum number of travelers for an age band
  • maximumCountRequired: maximum number of travelers for an age band. If this field is null, any number of travelers may be booked.

You will need to present the ageBandsRequired information as in the following examples:

In 'Adult' age band Meaning
minimumCountRequired = 1
maximumCountRequired = 3
From 1 to 3 adults
minimumCountRequired = 0
maximumCountRequired = 3
up to three adults
minimumCountRequired = 3
MaximumCountRequired =
3 or more adults
minimumCountRequired = 2
MaximumCountRequired = 2
2 adults

Note: There is a singular and plural version for each age band definition. We recommend automatically generating language that ensures the samples above are grammatically correct using this information.

The user can click back and change their traveler mix; or, they can try selecting another day.

View cart / price quote

Once the item has been added to the cart, you will need to preserve this information as part of the session data in your back-end, or as a browser cookie. In particular, you will need to store the product code and age band to quantity traveler mix.

Sample PHP shopping cart item class

Note: this is only an example and is implementation dependent. Alternatively, you could use the item class (as used in the API calls), but much of the information it contains does not need to be stored:

class shoppingCartItem {
  var $productCode;
  var $tourGrade;
  var $date;
  var $ageBandIdToQty; // assoc array
}

To obtain a price quote, you must call the /booking/calculateprice service. This service requires a currency code and an array of items to be specified. Each item contains the date, product code, tour grade code and an associative array of ageBandIds -> quantity.

Validation – the data must contain valid age bands, tour codes, dates, etc. acquired in previous requests to the API.

Note: A product's availability can change in the time between API calls as tour grades or products may be blocked out, or the booking window may close for upcoming dates.

Checkout

Summary

The checkout process can be accomplished using the /booking/book service, but you may need to make requests to other services to calculate prices, display product information (age-band names, etc.) and list available pick-up hotels for user selection.

The Viator mobile website breaks the workflow down into three steps. For multiple items, some steps will need to be repeated, such as capturing the traveler names for each tour. In your implementation, you can reorganize/reorder the data collection to better suit your needs.

Example workflow:

  1. Collect traveler details - collect the names of the lead traveler and all other travelers
  2. Collect travel details - ask any additional questions, including those about any special requirements, and select pick-up options.
  • Note: the aforementioned steps will need to be repeated for each item)
  1. Collect booking details
  • Note: billing and payment details should not be sent to Viator.

The classes for the booking request are defined here in Booking Data Classes. You will need implement these in your chosen programming language and verify that the correct JSON objects are generated during serialization.

Traveler details

The traveler details are used to populate the booking->items[]->travellers[] objects.

One passenger must be identified as the "lead traveler". A boolean field in the traveler object represents this flag. The lead traveler must be an adult or have the age band treatAsAdult flag set to true.

All other travelers must be included.

Validation requirements

Field Requirements
bandId a valid age band ID for the product
firstname less than 16 characters
surname less than 36 characters
title optional / not required
leadTraveller set to true for one of the travelers who is in an age band that has the treatAsAdult flag set to true
cellPhoneCountryCode optional / not required
cellPhone either 0 or 6-25 characters long

Other details

Booking questions

The travel details include the booking questions that are supplied in the /product service.

Sample question

Note: There may be more than one.

bookingQuestions: [{
  "message": "For safety reasons you must enter the weight of <b>all</b> passengers",
  "required": true,
  "questionId": 23,
  "title": "Passenger Weights",
  "subTitle": "(e.g. 127 pounds, 145 kilos, etc)",
  "sortOrder": 1
}]

The questions should be displayed with the title, message, subtitle and whether it is mandatory (required) or not.

Validation – if the question is mandatory, the user must enter at least one character.

Special requirements

'Special requirements' should be presented as a text input field so that customers can record whether they require wheelchair assistance, for example. It is not mandatory for the customer to enter any text.

Pick-up information

The last thing that must be collected for each item being booked is the pick-up information. If the product includes pick-up, the hotelPickup flag will be set to true (in the product object).

If pick-up is included, you will need to make a request to /booking/hotels to determine if a hotel list exists. If it does, the list must be displayed so that the customer can make their selection. If not, a text input field should be displayed for hotel name collection.

Please note that the first three results in the list are not hotels; rather, these three are alternative selections, comprising:

  • 'Hotel not listed'
  • 'Live locally or staying with family/friends'
  • 'Hotel not yet booked'

If the customer selects 'hotel not listed', you must provide a hotel selection text input field. For the other two options, no hotel name is required. In all cases, the hotel ID must be updated with either a hotel ID or the IDs of the three items listed.

If no hotel list is available, you must provide a text input field for collecting the customer's hotel name. Please include instructions to enter 'live locally' or 'hotel not yet booked' if they cannot provide a hotel name.

Validation – if hotel list is available, the hotelId must be supplied. If the hotelId is notListed the, pickupPoint field must have at least one character.

If a hotel list is not available, then pickupPoint must contain a value.

Billing information

The 'billing' or 'booking information' step is where you will need to collect your customer's credit card details.

Validation

Field Validation requirements Mandatory
ccaddress1 at least 1 character
ccaddress2 none
ccaddressCity at least one character
ccaddressState at least one character from list in appendix if country is Canada, USA or Australia.
ccaddressZip at least one character
ccphone none
cctype one of Visa, Mastercard or Amex
ccname this must be at least two words (first and last name) and 2 characters long
ccnumber this must be valid. you must use a luhn check to validate
ccaddressCountryId must be a country code from the list in appendix
ccexpire expiry date for the credit card e.g. "12/2020"
ccadditionalDigits CVV – must be a three-digit number for Visa and Mastercard; four for American Express

Language services

If the response from the /product service contains information in the languageServices field, e.g.:

"langServices": {
  "en/SERVICE_AUDIO": "English - Audio"
}

...then you must specify which language option you wish to book for this tour in the languageOptionCode field (see request body schema of the /booking/book service).

Accept Viator terms and conditions

You must provide a checkbox that customers must check to confirm that they accept Viator's terms and conditions prior to submitting the booking request through the API. It's best to place this checkbox at the bottom of the form near the submit button.

Note that the value of this checkbox is not sent to Viator, but it will be assumed that by placing the booking, the customer agrees to the terms and conditions.

View voucher or confirmation status

The object returned by the /booking/book service contains booking details that can be used to display an order summary to the customer.

Confirmed bookings of freesale products will return a voucherKey and voucherURL. The voucherURL can be accessed by the customer to view their voucher.

Pending bookings of on-request products will return null in the voucherKey/voucherURL fields. These fields will only contain values once the booking is confirmed.

A bookingStatus object is included in the response that contains the status of the booking.

"bookingStatus": {
  "status": 1,
  "text": "Paid &amp; Confirmed",
  "type": "CONFIRMED",
  "level": "ITEM",
  "failed": false,
  "confirmed": true,
  "amended": false,
  "pending": false,
  "cancelled": false
}

The possible values of the status and type fields are described in bookingStatus field values and meanings.

Boolean flags that you can use to determine the booking status of the item:

  • failed
  • cancelled
  • confirmed
  • amended
  • pending

Pending bookings

A booking is considered pending if the booking process is 'in progress'. For example, an on-request booking would be pending until it is confirmed/rejected by the supplier.

If a customer has made an amendment to an on-request booking that is yet to be accepted by the supplier, the booking would then have a status of amended when the supplier or customer service accepts the amendment.

Example response object:

{
    "errorReference": null,
    "data": {
        "sortOrder": 0,
        "rulesApplied": [],
        "omniPreRuleList": null,
        "bookingStatus": {
            "status": 3,
            "text": "Confirmed",
            "type": "CONFIRMED",
            "level": "ITINERARY",
            "confirmed": true,
            "pending": false,
            "amended": false,
            "cancelled": false,
            "failed": false
        },
        "itemSummaries": [
            {
                "sortOrder": 0,
                "rulesApplied": [],
                "bookingStatus": {
                    "status": 1,
                    "text": "Paid &amp; Confirmed",
                    "type": "CONFIRMED",
                    "level": "ITEM",
                    "failed": false,
                    "confirmed": true,
                    "amended": false,
                    "pending": false,
                    "cancelled": false
                },
                "travellerAgeBands": [
                    {
                        "sortOrder": 0,
                        "count": 2,
                        "pluralDescription": "Adults",
                        "description": "Adult",
                        "ageBandId": 1
                    }
                ],
                "voucherKey": "1006291040:f73083cf41661dd626aa5280bcc5c0f5ffad3d6bc6da2c7f0016c5afdf35e082:581166836",
                "voucherURL": "https://partner.live.rc.viator.com/voucher.jspa?PUID=10970&setLocale=en&code=1006291040:f73083cf41661dd626aa5280bcc5c0f5ffad3d6bc6da2c7f0016c5afdf35e082:581166836&embedResources=false",
                "voucherRequirements": "You can present either a paper or an electronic voucher for this activity.",
                "appleWalletURL": null,
                "productPulledDown": false,
                "merchantCancellable": false,
                "productWidgetList": null,
                "savingAmount": 0.00,
                "applePassSupported": false,
                "supplierName": null,
                "supplierPhoneNumber": null,
                "vouchers": null,
                "passbooks": null,
                "termsAndConditions": "{\"NumberRange: 2 - null\":0,\"NumberRange: 0 - 1\":100}",
                "productCode": "5010SYDNEY",
                "travelDate": "2020-06-16",
                "tourGradeCode": "24HOUR",
                "distributorItemRef": null,
                "startingTime": null,
                "languageServicesLanguageCode": "en",
                "price": 69.44,
                "leadTravellerSurname": "Simpson Test",
                "itineraryId": 1006291040,
                "lastRetailPriceFormatted": "$69.44",
                "productTitle": "Big Bus Sydney and Bondi Hop-on Hop-off Tour",
                "merchantNetPrice": 0,
                "destId": 357,
                "voucherOption": "VOUCHER_E",
                "priceFormatted": "$69.44",
                "itemId": 581166836,
                "barcodeOption": "perperson",
                "barcodeType": "qrcode",
                "departurePoint": "You may start this tour at any of the stops listed.",
                "departurePointAddress": null,
                "departurePointDirections": null,
                "leadTravellerFirstname": "Homer",
                "rnplInfo": null,
                "obfsId": 140679,
                "leadTravellerTitle": "Mr",
                "lastRetailPrice": 69.44,
                "savingAmountFormated": "$0.00",
                "bookingEngineId": "UF",
                "merchantNetPriceFormatted": "",
                "departsFrom": "The Rocks, Australia",
                "tourGradeDescription": "24 Hour Classic Ticket  (24HOUR)",
                "pickupHotelId": null,
                "pickupHotelName": null,
                "hoursConfirmed": 0,
                "priceUSD": 69.44,
                "currencyCode": "USD"
            }
        ],
        "voucherURL": "https://partner.live.rc.viator.com/voucher.jspa?PUID=10970&setLocale=en&code=1006291040:f73083cf41661dd626aa5280bcc5c0f5ffad3d6bc6da2c7f0016c5afdf35e082&embedResources=false",
        "securityToken": "f73083cf41661dd626aa5280bcc5c0f5ffad3d6bc6da2c7f0016c5afdf35e082",
        "paypalRedirectURL": null,
        "exchangeRate": 1,
        "itineraryId": 1006291040,
        "bookingDate": "2020-05-10",
        "voucherKey": "1006291040:f73083cf41661dd626aa5280bcc5c0f5ffad3d6bc6da2c7f0016c5afdf35e082",
        "bookerEmail": "apitest@viator.com",
        "distributorRef": null,
        "totalPrice": 69.44,
        "totalPriceFormatted": "$69.44",
        "totalPriceUSD": 69.44,
        "hasVoucher": true,
        "userId": null,
        "currencyCode": "USD"
    },
    "dateStamp": "2020-05-10T19:13:25+0000",
    "errorType": null,
    "errorCodes": [],
    "errorMessage": null,
    "errorName": null,
    "extraInfo": {},
    "extraObject": null,
    "success": true,
    "totalCount": 1,
    "errorMessageText": null,
    "vmid": "331001"
}

Checking the status of bookings

Checking the status of a single booking:

  • /booking/mybookings can be used to check the status of a booking after it has been purchased. This is useful for checking the status of a pending booking, particularly if there are multiple items within the booking.

    It is recommended that you poll the service no more than once per hour.

Checking the status of multiple bookings:

  • /booking/status will return the status of all bookings, based on the following:
    • booking date range
    • travel date range
    • lead traveler date/first name

This is useful for checking the status of recently-made, but still pending bookings, or those that will commence soon.

Note: You can only poll this service (successful calls) once every 30 minutes.

Booking process flow

In this section, we show a sample booking process flow using Viator API services.

Product selection

  1. Determine the location using the /taxonomy/destinations service
  2. Search for products in the destination using the /search/products service

/search/products POST request body:

{
  "startDate": "2018-12-25",
  "endDate": "2018-12-28",
  "topX": "1-15", 
  "destId": 684, 
  "currencyCode": "USD",
  "sortOrder": "TOP_SELLERS"
}
  1. Select a product with /search/products

/search/products GET parameters:

code=5010SYDNEY&currencyCode=USD

Checkout process

  1. Check for available dates using the /booking/availability/dates service

/booking/availability/dates GET parameters:

productCode=5010SYDNEY
  1. Determine the number of passengers/travelers
  2. Check for available tour grades for the date chosen using the /booking/availability/tourgrades service; or, check for available tour grades by month using the /booking/availability/tourgrades/pricingmatrix service

/booking/availability/tourgrades POST request:

{
  "productCode": "5010SYDNEY",
  "bookingDate": "2018-12-05",
  "currencyCode": "USD",
  "ageBands": [
    {      
      "bandId": 1,
      "count": 2    
    }  
  ]
}

/booking/availability/tourgrades/pricingmatrix POST request:

{
  "productCode": "5010SYDNEY",
  "month": "12",
  "year": "2018",
  "currencyCode": "USD"
}
  1. Finalize pricing using the /booking/availability/tourgrades/pricingmatrix service.
  • Note: we strongly recommend using the /booking/calculateprice service prior to making the booking, as it reconfirms the product availability for the specified dates and passenger mix.
  1. Make the booking
  • Note that the /booking/book service supports multi-item bookings. The response from the /product service indicates mandatory information that must be sent when making the booking, such as required booking questions and hotel pick-up options.
  • For hotel pick-up:
    • Send a hotel ID to the /booking/book service if hotelPickup is true for the product.
    • /booking/hotels can be used to return a list of hotels available for the product.
    • The hotelId is the id field in the response from the /booking/hotels service. This can be:
      • a number (represented as a string) – e.g., '4119'
      • 'local' – if the customer resides near the location in which the product operates
      • 'notBooked' – if the customer's hotel is not yet booked
      • 'notListed' – if the customer's hotel is not listed in the response from /booking/hotels. If this is the case, capture the customer’s hotel details in a text box and pass this information in the pickupPoint field in the request body of the /booking/book service.

/booking/book POST request example:

{
  "demo": true,
  "currencyCode": "USD",
  "booker": {
      "firstname": "Homer Test",
      "surname": "Simpson Test",
      "title": "Mr",
      "email": "apitest@viator.com",
      "homePhone": "(02)66987564"
  },
  "ccPayDetail": {
      "ccaddress1": "742 Evergreen Terrace",
      "ccaddress2": "",
      "ccaddressCity": "Springfield",
      "ccaddressState": "WI",
      "ccaddressZip": "12345",
      "ccphone": "",
      "cctype": "Visa",
      "ccname": "Homer Simpson Test",
      "ccnumber": "4242424242424242",
      "ccaddressCountryId": "US",
      "ccexpire": "12/2020",
      "ccadditionalDigits": "747",
      "fiscalNumber": null
    },
  "items": [
    {
      "hotelId": null,
      "pickupPoint": null,
      "travelDate": "2019-03-19",
      "productCode": "5010SYDNEY",
      "tourGradeCode": "24HOUR",
      "languageOptionCode": "en/SERVICE_GUIDE",
      "bookingQuestionAnswers": [
        {
          "questionId": 100,
          "answer": "120 kgs"
        }
      ],
      "specialRequirements": "",
      "travellers": [
        {
          "bandId":1,
          "firstname": "Homer",
          "surname": "Simpson Test",
          "title": "Mr",
          "leadTraveller": true
        }, {
          "bandId": 1,
          "firstname": "Marge",
          "surname": "Viator Test",
          "title": "Mrs"
        }
      ]
    }
  ]
}

/booking/hotels GET example parameters:

productCode=5010SYDNEY

or

destId=684
  1. You will receive different booking statuses depending on the product's booking engine.
  • For products that are free-sale ('FreesaleBE'), unconditional free-sale ('UnconditionalBE') and free-sale / on-request ('FreesaleOnRequestBE') - i.e., during the free-sale period, confirmation should occur instantly.
  • The 'FreesaleOnRequestBE' status means that the product will only remain free-sale up until a certain number of days before the travel date, after which it becomes on-request.
  • Normally, if the product is on-request, its booking status will be 'Pending'.

Post-booking

Displaying vouchers

The voucherOption field in the response from the /booking/book service will contain one of the following values:

  • 'VOUCHER_PAPER_ONLY'
    • if so, direct the customer to the URL returned in the voucherURL field
  • 'VOUCHER_E' or 'VOUCHER_ID_ONLY'
    • if so, the customer's voucher information can be retrieved using the /booking/voucher service, which returns an HTML-formatted summary of the customer's booking details.

Note: the voucher will not be available until the booking is confirmed – the value of the hoursConfirmed field in the response from the /booking/book service can be shown to the customer to indicate the time frame within which they are likely to be notified as to their booking confirmation.

Viewing bookings

Viewing booking statuses

To view the booking statuses for multiple items based on various criteria, use the /booking/status service.

Note that this service can only be polled once every five minutes. Ideally, this service should be used by your software implementation to perform bulk updates of pending itineraries. The maximum number of itinerary results returned is 1,000.

Currency considerations for bookings

If the booking shows prices converted to and formatted according to a different currency to that in which it was made, it is because each API partner has a particular 'base currency', and all bookings will be made in that currency.

Making demo bookings

To make a demo booking, simply set the demo field to true in the /booking/book service.

While demo bookings are allowed on the live production environment, we recommend not doing so as it is possible that a notification could be sent to the supplier. Performing a cancellation of the demo booking is therefore recommended.

To cancel the booking, use the /booking/mybookings/message service. See: Contact customer service

Alternatively, send an email to dpsupport@viator.com including 'CANCEL' in the subject line along with the booking reference number to have the booking cancelled for you.

Cancellation API workflow

Note:

Getting cancellation reasons

When 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 endpoint.

As the acceptable reasons for cancellation may be extended at any point (existing reasons will not change or be removed), we recommend retrieving an up-to-date list from this endpoint at least weekly.

The output from the /bookings/cancel-reasons endpoint at the time of writing is as follows:

{
    "reasons": [
        {
            "cancellationReasonCode": "Customer_Service.I_canceled_my_entire_trip",
            "cancellationReasonText": "I canceled my entire trip"
        },
        {
            "cancellationReasonCode": "Customer_Service.Booked_wrong_tour_date",
            "cancellationReasonText": "Booked wrong tour/date"
        },
        {
            "cancellationReasonCode": "Customer_Service.Duplicate_Booking",
            "cancellationReasonText": "Duplicate Booking"
        },
        {
            "cancellationReasonCode": "Customer_Service.Chose_a_different_cheaper_tour",
            "cancellationReasonText": "Chose a different/cheaper tour"
        },
        {
            "cancellationReasonCode": "Customer_Service.Weather",
            "cancellationReasonText": "Weather"
        },
        {
            "cancellationReasonCode": "Customer_Service.Unexpected_medical_circumstances",
            "cancellationReasonText": "Unexpected/medical circumstances"
        },
        {
            "cancellationReasonCode": "Customer_Service.Tour operator asked me to cancel",
            "cancellationReasonText": "Tour operator asked me to cancel"
        }
    ]
}

Canceling a booking

Getting a cancellation quote

Before canceling the booking, call the /bookings/{booking-reference}/cancel-quote endpoint to get information about whether the booking can be canceled using this endpoint and what the refund will be, for example:

GET https://api.viator.com/partner/bookings/BR-580254558/cancel-quote

Note: For information about the {booking-reference} in URL parameter, see Key concepts: Booking references

You will receive a cancellation quote object, e.g.:

{
    "bookingId": "BR-580254558",
    "status": "CANCELLABLE",
    "refundDetails": {
        "itemPrice": 109.77,
        "refundAmount": 109.77,
        "currencyCode": "USD",
        "refundPercentage": 100.00
    }
}

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".

The data elements in this object have meanings as follows:

Element Meaning Example
bookingId the booking reference number prepended with BR- BR-580254556
status One of the following:
  • CANCELLABLE: the booking is eligible to be cancelled
  • CANCELLED: the booking has already been cancelled
  • NOT_CANCELLABLE: the booking is for a product that operated in the past, and therefore cannot be cancelled using this endpoint (you will need to send an email to dpsupport including both "CANCEL" and the booking reference number in the subject line in order to request a refund for such a booking)
CANCELLABLE
refundDetails object containing information about the refund
itemPrice the amount paid for this product at the time of booking in the currency specified by currencyCode 109.77
refundAmount the amount that will be reimbursed if the booking is cancelled now 109.77
currencyCode the currency code for the currency in which pricing information is displayed USD
refundPercentage the refund amount expressed as a percentage of the itemPrice 100.00

Canceling the booking

If the status field has a value of CANCELLABLE and you are happy with the refundAmount, call the /bookings/{booking-ref}/cancel endpoint to cancel the booking, e.g.:

POST https://api.viator.com/partner/bookings/BR-580254558/cancel

A reason code corresponding to the reason for cancellation must be included in the request body; e.g.:

{
  "reasonCode":"Customer_Service.Chose_a_different_cheaper_tour"
}

You should receive a response indicating that the cancellation was successful, e.g.:

{
    "bookingId": "BR-580254558",
    "status": "ACCEPTED"
}

A status of ACCEPTED indicates that the booking was successfully canceled.

Booking services

Making a booking on Viator's system can be somewhat complex due to the wide variety of tours and other products that we sell. There are a number of key concepts that must be understood in order to develop a booking workflow and application.

Booking data classes

Classes used for booking (expressed in PHP syntax):

class booking {
  var $booker; // see class definition below
  var $ccPayDetail; // see class definition below
  var $items = array(); // see class definition below
  var $sessionId;
  var $currencyCode;
  var $promoCode;
  var $partnerDetail; // for partner bookings – this can be null if not used 
  var $newsletterSignUp; 
  var $demo;
}
// Partner use only. For tracking commissions, etc. class partnerDetail

class partnerDetail {
  var $subPUID; // is some number which the partner should know
  var $agentNumber; // is the agent PCC (??) / ARC / IATA number
  var $agentEmailDelivery; // is one of these options (based off VAP and it seems 
  var $additionalEmail; // is some additional agent email
  var $partnerParam; // is some extra parameters they want to write to the
}

// Viator use only 
class partnerDetailEAP {
  var $eapChainCode; 
  var $eapPropertyCode; 
  var $eapAuid;
}

// Viator use only
class partnerDetailShareASale {
  var $shareSaleId; 
  var $shareSaleData;
}

class priceCheck {
  var $promoCode;
  var $currencyCode; 
  var $items = array();
}

class booker {
  var $email;
  var $workPhone; 
  var $postcode; 
  var $homePhone; 
  var $firstname; 
  var $surname; 
  var $title;
}

class ccPayDetail {
  var $ccaddress1;
  var $ccaddress2;
  var $ccaddressCity; 
  var $ccaddressState; 
  var $ccaddressZip; 
  var $ccphone;
  var $cctype;
  var $ccname;
  var $ccnumber;
  var $ccaddressCountryId; var $ccexpire;
  var $ccadditionalDigits;
}

class item {
  var $ccaddress1;
  var $ccaddress2;
  var $ccaddressCity; 
  var $ccaddressState; 
  var $ccaddressZip; 
  var $ccphone;
  var $cctype;
  var $ccname;
  var $ccnumber;
  var $ccaddressCountryId;
  var $ccexpire;
  var $ccadditionalDigits;
  var $travelDate;
  var $productCode;
  var $tourGradeCode;
  var $hotelId;
  var $pickupPoint;
  var $languageOptionCode;
  var $travellers = array();
  var $bookingQuestionAnswers = array(); // array of bookingQuestionAnswer 
  var $specialRequirements;
}

class bookingQuestionAnswer {
  var $questionId; 
  var $answer;
}

class traveller {
  var $bandId;
  var $firstname;
  var $surname;
  var $title;
  var $leadTraveller;
  var $cellPhoneCountryCode; 
  var $cellPhone;
}

Product availability services

Product availability information can be retrieved with the following services:

Example: multiple departures in a single day

Multiple departures in a single day (each represented by a tour grade) and the language options (langServices).

This request is for three adults on a helicopter tour:

  • Note: No prices are returned if the tour grade is unavailable.

Request object (/booking/availability/tourgrades):

{
  "productCode": "2280AAHT",
  "bookingDate": "2013-05-11",
  "currencyCode": "EUR",
  "ageBands": [{
    "bandId": 1,
    "count": 3
  }]
}

Response object (/booking/availability/tourgrades) :

{
  "data": [{
    "available": false,
    "ageBands": null,
    "langServices": null,
    "gradeCode": "EARLYM",
    "unavailableReason": "BOOKING_CUTOFF_EXPIRED",
    "gradeTitle": "Early Morning Departure",
    "gradeDepartureTime": "",
    "gradeDescription": "Flight departs Las Vegas between 7am & 8am",
    "defaultLanguageCode": "en",
    "ageBandsRequired": null,
    "currencyCode": "ERROR",
    "retailPrice": 0,
    "bookingDate": "2013-05-11",
    "retailPriceFormatted": "",
    "merchantNetPrice": 0,
    "merchantNetPriceFormatted": "",
    "sortOrder": 1
  },
  {
    "available": false,
    "ageBands": null,
    "langServices": null,
    "gradeCode": "LATEM",
    "unavailableReason": "BOOKING_CUTOFF_EXPIRED",
    "gradeTitle": "Late Morning Departure",
    "gradeDepartureTime": "",
    "gradeDescription": "Flight departs Las Vegas between 9:45am & 10:45am",
    "defaultLanguageCode": "en",
    "ageBandsRequired": null,
    "currencyCode": "ERROR",
    "retailPrice": 0,
    "bookingDate": "2013-05-11",
    "retailPriceFormatted": "",
    "merchantNetPrice": 0,
    "merchantNetPriceFormatted": "",
    "sortOrder": 2
  },
  {
    "available": false,
    "ageBands": null,
    "langServices": null,
    "gradeCode": "EARLYA",
    "unavailableReason": "BOOKING_CUTOFF_EXPIRED",
    "gradeTitle": "Early Afternoon Departure",
    "gradeDepartureTime": "2:50 PM",
    "gradeDescription": "Flight departs Las Vegas between 12:30pm & 1:30pm",
    "defaultLanguageCode": "en",
    "ageBandsRequired": null,
    "currencyCode": "ERROR",
    "retailPrice": 0,
    "bookingDate": "2013-05-11",
    "retailPriceFormatted": "",
    "merchantNetPrice": 0,
    "merchantNetPriceFormatted": "",
    "sortOrder": 3
  },
  {
    "available": false,
    "ageBands": null,
    "langServices": null,
    "gradeCode": "LATEA",
    "unavailableReason": "BOOKING_CUTOFF_EXPIRED",
    "gradeTitle": "Late Afternoon Departure",
    "gradeDepartureTime": "",
    "gradeDescription": "Flight departs Las Vegas between 3:15pm & 4:15pm; available Ap",
    "defaultLanguageCode": "en",
    "ageBandsRequired": null,
    "currencyCode": "ERROR",
    "retailPrice": 0,
    "bookingDate": "2013-05-11",
    "retailPriceFormatted": "",
    "merchantNetPrice": 0,
    "merchantNetPriceFormatted": "",
    "sortOrder": 4
  }],
  "vmid": "221001",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2013-06-04T17:01:34+0000",
  "totalCount": 1,
  "errorReference": null,
  "errorMessageText": null,
  "success": true,
  "errorName": null
}

Example: traveler mix mismatch

The request is for five adults, but this product only support up to four adults.

Example request object (/booking/availability/tourgrades):

{
  "productCode": "2280ULTWED",
  "bookingDate": "2013-12-11",
  "currencyCode": "EUR",
  "ageBands": [{
    "bandId": 1,
    "count": 5
  }]
}

Example response object The response contains "TRAVELLER_MISMATCH" and you can see the ageBandsRequired values for the adult (1) age band in the available tour grade.

{
  "data": [{
    "available": false,
    "ageBands": null,
    "langServices": null,
    "gradeCode": "DEFAULT",
    "unavailableReason":
    "TRAVELLER_MISMATCH",
    "gradeTitle": "DEFAULT",
    "gradeDepartureTime": "12:00 AM",
    "gradeDescription": "DEFAULT",
    "defaultLanguageCode": "en",
    "ageBandsRequired": [
    [{
      "bandId": 1,
      "minimumCountRequired": 2,
      "maximumCountRequired": 2
    }],
    [{
      "bandId": 1,
      "minimumCountRequired": 3,
      "maximumCountRequired": 3
    }],
    [{
      "bandId": 1,
      "minimumCountRequired": 4,
      "maximumCountRequired": 4
    }]],
    "currencyCode": "ERROR",
    "retailPrice": 0,
    "bookingDate": "2013-12-11",
    "retailPriceFormatted": "",
    "merchantNetPrice": 0,
    "merchantNetPriceFormatted": "",
    "sortOrder": 1
  }],
  "vmid": "221001",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2013-06-04T17:02:35+0000",
  "totalCount": 1,
  "errorReference": null,
  "errorMessageText": null,
  "success": true,
  "errorName": null
}

Calculating prices

The /booking/calculateprice service is used to calculate a total price, taking into account the specified traveler mix. It also reconfirms the availability of the products for the requested dates and traveler mix as well as pricing. It is strongly recommended that this service is called prior to making the booking to confirm that the booking will go through. This can be used to implement a shopping cart.

Example request body (JSON)

{
  "currencyCode": "USD",
  "items": [{
    "travelDate": "2015-03-01",
    "productCode": "2916ROME",
    "tourGradeCode":
    "24HR",
    "travellers": [
      {
        "bandId": 1
      },
      {
        "bandId": 1
      }
    ]
  }]
}

travellers is an associative array of bandId -> [quantity].

There can be several items in the cart. This allows for different traveler mixes per product booked.

The overall total of the booking is displayed in the itineraryNewPrice and itineraryNewPriceFormatted fields.

The result indicates if the booking is freesale or on-request. On-request bookings are not sold as "CONFIRMED", but are instead confirmed by the supplier at a later date. The approximate window for confirmation is provided in the hoursConfirmed (integer) field for presentation to the customer. An hoursConfirmed of 0 means that the booking is freesale. An hoursConfirmed greater than 0 indicates that it is on-request.

The partnerDetail object can also be added to the JSON. Please see /booking/book for more details on the partnerDetails object.

Finding hotel pick-up points

Hotel pickup example:

Example response body (/booking/hotels)

{
  "vmid":"221002",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2012-04-12T13:48:27+0000",
  "success": true,
  "errorReference": null,
  "errorMessageText": null,
  "totalCount": 1,
  "errorName": null
  "data": [
    {
      "address": null,
      "name": "I live locally / I'm staying with friends, relatives",
      "id": "local",
      "phone": null,
      "productCodes": null,
      "destinationId": 0,
      "city": null,
      "notes": null,
      "latitude": null,
      "longitude": null,
      "postcode": null,
      "brand": null,
      "hotelString": "I live locally / I'm staying with friends, relatives",
      "sortOrder": 1
    },
    {
      "address": null,
      "name": "My hotel is not yet booked",
      "id": "notBooked",
      "phone": null,
      "productCodes": null,
      "destinationId": 0,
      "city": null,
      "notes": null,
      "latitude": null,
      "longitude": null,
      "postcode": null,
      "brand": null,
      "hotelString": "My hotel is not yet booked",
      "sortOrder": 2
    },
    {
      "address": null,
      "name": "My hotel is not listed",
      "id": "notListed",
      "phone": null,
      "productCodes": null,
      "destinationId": 0,
      "city": null,
      "notes": null,
      "latitude": null,
      "longitude": null,
      "postcode": null,
      "brand": null,
      "hotelString": "My hotel is not listed",
      "sortOrder": 3
    },
    {
      "address": "375 East Harmon Avenue",
      "name": "Alexis Park Resort Hotel",
      "id": "684_2",
      "phone": "",
      "productCodes": null,
      "destinationId": 684,
      "city": "Las Vegas",
      "notes": null,
      "latitude": 36.106258,
      "longitude": -115.156146,
      "postcode": "89169",
      "brand": "",
      "hotelString": null,
      "sortOrder": 4
    },
    {
      "address": "167 East Tropicana Avenue",
      "name": "Americas Best Value Inn",
      "id": "684_3",
      "phone": "",
      "productCodes": null,
      "destinationId": 684,
      "city": "Las Vegas",
      "notes": null,
      "latitude": 36.100778,
      "longitude": -115.165522,
      "postcode": "89109",
      "brand": "",
      "hotelString": null,
      "sortOrder": 5
    },
    {
      "address": "3131 Las Vegas Boulevard South",
      "name": "Wynn Resort",
      "id": "684_126",
      "phone": "",
      "productCodes": null,
      "destinationId": 684,
      "city": "Las Vegas",
      "notes": null,
      "latitude": 36.127563,
      "longitude": -115.167704,
      "postcode": "89109",
      "brand": "",
      "hotelString": null,
      "sortOrder": 119
    }
  ]
}

Making a booking

To make a booking, use the /booking/book service.

To make a real booking, ensure demo is set to false in the booking request.

Demo bookings will enter our system as a test booking and will not charge the merchant. To enable demo bookings, set demo to true in the booking request and pass "test" as the traveler's first or last name.

Note: Avoid testing on Live, as the booking may be sent to the supplier (depending on the product). Any test bookings on live must be cancelled via the cancellation service; or, contact dpsupport@viator.com if you experience any other issues.

Example request

{
  "demo": true,
  "currencyCode": "USD",
  "booker": {
    "email": "apitest@viator.com",
    "firstname": "Homer Test",
    "surname": "Simpson Test",
    "title": "Mr"
    "cellPhoneCountryCode": "0055", 
    "cellPhone": "12345678",
    "homePhone": "(02)66987564"
  },
  "ccPayDetail": {
    "ccaddress1": "742 Evergreen Terrace", 
    "ccaddress2": "",
    "ccaddressCity": "Springfield", 
    "ccaddressState": "WI", 
    "ccaddressZip": "12345",
    "ccphone": "",
    "cctype": "Visa",
    "ccname": "Homer Simpson Test", 
    "ccnumber": "4242424242424242", 
    "ccaddressCountryId": "US", 
    "ccexpire": "12/2020", 
    "ccadditionalDigits": "747", 
    "fiscalNumber": null
  },
  "items": [{
    "hotelId": null,
    "pickupPoint": null,
    "travelDate": "2015-03-31",
    "productCode": "2916ROME",
    "tourGradeCode": "24HR",
    "languageOptionCode": "en/SERVICE_GUIDE",
    "bookingQuestionAnswers": [{
      "questionId": 100,
      "answer": "120 kgs"
    }],
    "travellers": [{
      "bandId": 1,
      "firstname": "Homer",
      "surname": "Simpson Test",
      "title": "Mr",
      "leadTraveller": true
      "cellPhoneCountryCode": "0055", 
      "cellPhone": "911"
    },
    {
      "bandId": 1, 
      "firstname": "Marge", 
      "surname": "Simpson", 
      "title": "Mrs"
    }]
  }]
}

Description of JSON request parameters

Object name Element name Type Comments Mandatory
sessionId string Viator API User Account session Id. Not applicable to partners.
ipAddresss string The client ip address which is doing the booking. Internal sites only.
aid string Ignore (Viator only)
newsletterSignUp boolean If this is set to true, the booker email will be added to the list of subscribers for any Viator marketing emails.
demo boolean If this is set to True, then it is a demo booking only. Full demos do not send any notifications, are automatically confirmed and OnRequest products become freesale products. Default value is true. Production must have demo set to false.
promoCode string Ignore (Viator only)
currencyCode string The currency the booking will be submitted in. You will be billed in this currency.
partnerDetail object Applicable only for extra partner detail for either partner, EAP or Share-A-Sale. Itinerary level. Can omit or pass null if not needed. See object details below.
agentEmailDelivery string Applicable only to ARC/AAA (agent partners). Use one of "Agent only", "Agent and Customer" or "Customer only"
subPUID string Used by agents to pass an additional identifier for their bookings. Alphanumeric characters only.
agentNumber string Agent ID
agencyName string Name of agency
agentName string Name of agent
agentEmail string Email of agent
additionalEmail string Additional email to send the booking confirmation to
partnerParam string Ignore (Viator only)
partnerItemDetail object Not applicable to affiliate partners
otherDetail object Other optional details to pass to the booking. At the moment, only call-center messages
callCenterSource string Ignore (Viator only)
callCenterAgent string Ignore (Viator only)
booker object The information of the primary contact. This contact does not have to be a traveler.
email string Email address of the primary contact
homePhone string Home phone number of the primary contact
firstname string First name of the primary contact
surname string Surname of the primary contact
title string Title of the primary contact
cellPhoneCountryCode string Country-code of the primary contact's cell phone
cellPhoneCountryCode string Cell phone number of the primary contact
ccPayDetail object API partners must pass this object. The billing details of the booking
ccaddress1 string Billing address
ccaddress2 string Billing address, second line
ccaddressCity string City in billing address
ccaddressState string See appendices for US, Canadian and Australian states
ccaddressZip string ZIP code / postcode of billing address
ccaddressCountryId string Country-code for the billing address. See appendices or use the /util/countrymap service
ccphone string Billing phone number
cctype string One of: "visa", "mastercard", "amex" or "discover"
ccname string Name on credit card
ccnumber string Credit card number
ccadditionalDigits string Equivalent to the CVV number
fiscalNumber string This field is mandatory for payments made with a Brazilian credit card, or a transaction conducted in Brazil. The transaction will be rejected by the payment gateway if the field is not provided. The customer name and fiscal number combination must be valid. Note that this number is also referred to as Cadastro de Pessoas Físicas (CPF) or individual fiscal registration number. This field accepts a max of 15 characters. ✅ – Brazilian transactions
❌ – otherwise
altContactDetails object Optional object for capturing additional contact details of the primary contact whilst travelling
contactType string Type of contact information passed. The types available are: "MOBILE" - mobile/cell phone number; "EMAIL" - email address; "ALTERNATE" - alternate phone number; "NON_CONTACTABLE" - additional details not available
phone string Alternative phone number or mobile/cell phone number. Must be supplied if contactType is "MOBILE" or "ALTERNATE"
phoneCountry string Country code of phone number or mobile/cell phone number. Must be supplied if contactType is "MOBILE" or "ALTERNATE"
email string Alternative email address. Must be supplied if contactType is "EMAIL"
items array Array of items in itinerary to be booked
productCode string product code of the itinerary to be booked
tourGradeCode string tourGradeCode of the item to be booked. If tour grades are supplied in /product, you must allow the customer to select a tour grade code. If no tour grades are available for the product, pass "DEFAULT".
languageOptionCode string The language service provided for this product that has been chosen for this booking. Usually in the format langcode/Service eg "en/SERVICE_GUIDE". If the product details service /product for the product returns a langService, this must be provided.
(if languageServices are provided in /product)
travelDate date date of travel for the item (format is YYYY-MM-DD; e.g. 2013-12-25)
hotelId string If /product returns hotelPickup: true and a list of hotels is available for this product in /booking/hotels, a hotelId must be captured. The hotel id as per the hotel service (id field) or use one of these alternative hotel ids:
local: customer lives locally
notBooked: Customer has not booked their hotel yet
notListed: Hotel not listed

(if /product returns hotelPickup: true for productCode and hotels available)
pickupPoint string Pickup point information related to hotel pickup. Details of the hotel or pickup point must be provided if the hotelId selected by the user is "notListed" or if no hotels are returned for the product in /booking/hotels where hotelPickup: true
(if hotelId = "notListed" or no hotels returned)
specialReservation string Not applicable to partners
specialRequirements string Capture any additional requirements for the booking, such as dietary requirements or if a wheelchair is required. Suggested workflow is if there are no bookingQuestionAnswers for the product, to collect specialRequirements.
travellers array Array of traveller names with a required lead traveller selected per item.
bandId integer Age band id. Available age band details for the product is listed in /product.
firstname string First name of the traveller.
surname string Surname of the traveller.
title string Title of the traveller. Suggested options: Mr, Mrs, Ms, Miss, Mstr, Dr
leadTraveller boolean Each item must have one traveller assigned as the lead traveller for the tour. The lead traveller will have a value of true, all other travellers will have a value of false. The lead traveller can have a mobile phone number added to the booking.
cellPhoneCountryCode string Ideally only collect the phone number country code for the lead traveller. Alternatively, collect the phone number of the booker instead.
cellPhone string Ideally only collect the phone number country code for the lead traveller. Alternatively, collect the phone number of the booker instead.
bookingQuestionAnswers object Answers to booking questions for the particular item. If a booking question is available in the bookingQuestions array in /product for the product, the matching bookingQuestionAnswers must be passed. If a product does not have any bookingQuestion items, you can omit the bookingQuestionAnswers field completely. Any invalid or unnecessary bookingQuestionAnswers that are passed to /booking/book will be ignored (no exceptions will be raised)
(if /product returns bookingQuestions)
questionId integer questionId (provided in /product)
answer string Answer to the question at the questionId listed. Recommended length for the answer is 500 characters.
marketing object Object to send marketing data associated with the booking to the Viator system. Currently only capturing the user's operating system.
os string The user's operating system. The API partner will need to capture the user's operating system or user agent to pass into this field.

partnerDetail object details

AAA should use this partnerDetail object when making a request to this service:

{
  "subPUID": "",
  "agentNumber": "",
  "agencyName": "",
  "agentName": "", 
  "agentEmail": "", 
  "agentEmailDelivery": "",
  "additionalEmail": "", 
  "partnerParam": ""
}

ARC should use this partnerDetail object when making a request to this service:

{
  "agentNumber": "",
  "agencyName": "",
  "agentName": "",
  "agentEmail": "", 
  "agentEmailDelivery": ""
}

Other partner parameters:

{ 
  ... 
  "subPUID": "",
  "partnerParam": "", 
  "additionalEmail": "", 
  ... 
}

Test bookings for API partners

A demo booking can be made by either setting the demo card variable to true, or passing a demo credit card number.

If demo is set to true, regardless of the credit card number used, the booking will be a full demo booking. It is advised that a demo card is used if demo is set to true as it is an extra check or confirmation that a demo booking has been made.

Setting demo to false and using the partial demo credit card will make a partial demo booking. A partial demo booking will honour the booking type (freesale or on request) and no notifications will be sent to the supplier.

If you use the full demo credit card (4242), the booking will be a full demo booking and the value of the demo flag will be ignored.

Demo card type Credit card number CVV Credit card type Expiry date demo flag
Full demo card 4242424242424242 747 VISA Any future date true
Partial demo card 4111111111111111 777 VISA Any future date false

In addition, ensure the ccname includes "test" (e.g. "John Test") and indicate in the special requirements it is a test booking.

If you make a test booking on the live site, you must put in a request to cancel the booking. This can be done via the /booking/mybookings/message service.

NOTE: If demo is set to false and a real credit card is used in the Live environment, the credit card will be charged. If you need to test a live credit card on Live and need the charge refunded, please email apitechsupport@viator.com, ideally within 24 hours.

Booking errors

A number of errors may be returned in the response to the /booking/book service. If any errors are reported, NO items will be booked, NO items/data will be returned in the response, and NO billing will occur.

There are two error types:

  • "VALIDATION" - occurs if a required field is missing or a field is not formatted properly
  • "EXCEPTION" - occurs when there are issues with the booking date, product / tourgrade code or the payment.

Example of an error message:

{
  "data": null,
  "vmid": "221001",
  "errorMessage": [ "Email is required" ],
  "errorType": "VALIDATION",
  "dateStamp": "2013-04-24T15:50:05+0000",
  "errorReference": "null",
  "errorMessageText": [ "Email is required" ],
  "success": false,
  "totalCount": 1,
  "errorName": "null"
}

Please see Standard JSON fields in the Appendix for an explanation of the fields.

Scenario errorType Example error message text
Missing required field from booking request, such as email address VALIDATION Email is required
Expiry date of credit card not in format mm/yyyy VALIDATION The expiration date for your credit card is not formatted properly. Please verify and re-enter the expiration date.
Lead traveller is not specified VALIDATION A traveler needs to be selected as lead traveler. Lead Traveler's name must match credit card name.
Traveller names are not provided VALIDATION First name of traveler 1 is required, Last name of traveler 1 is required
No travellers provided VALIDATION A traveler needs to be selected as lead traveler. Lead Traveler's name must match credit card name.
Product code does not exist EXCEPTION We're sorry, we cannot find the tour, activity or attraction you are looking for
Product code exists, but tour grade code does not exist EXCEPTION SICInvalidTourGrade
Booking date is in the past EXCEPTION We're sorry, the following tour you are trying to book is sold out and no longer available: Grand Canyon All American Helicopter Tour (2280AAHT)
Testing (where demo = true) with a test card not on the list EXCEPTION Demo bookings only allow demo cards to be used! Please check the CC number entered
languageOptionCode is in the wrong format EXCEPTION languageOptionCode should be LangCode/LangServices
Missing required answers for item EXCEPTION Additional questions missing
Unsupported currency EXCEPTION Could not lookup SGD:java.lang.RuntimeException: Could not lookup SGDf:au.com.fim.v3.etravel.PiusRecordNotFoundException: No currency found: select * from CurrencyFormat where currencyID = 'SGD'
Invalid credit card number, expiry date, and/or CVV EXCEPTION We're sorry, we cannot process the credit card you submitted. Either payment has been refused, or the card is invalid. Please verify and re-enter the credit card details, or use a different credit card.

Get the booking status for multiple items

The /booking/status service retrieves the booking status for multiple items based on different criteria.

This service can only be polled every 30 minutes. This would ideally be used in software for bulk updates of pending itineraries.

The maximum number of results returned is 1,000 itineraries. Narrow your search criteria if you receive this many itineraries in response from the service.

NOTE: This will return both live and test bookings.

Example request body

{
  "bookingDateFrom": "2020-08-01",
  "bookingDateTo": "2020-09-01",
  "itineraryIds": [
    581166836
  ],
  "itemIds": [
    1006291040
  ],
  "leadFirstName": "Homer test",
  "leadSurname": "Simpson test",
  "test": false
}

All fields are optional and can be omitted; however, at least one needs to be provided.

Field Meaning
bookingDateFrom The booking date is greater than or equal this date
bookingDateTo The booking date is less than or equal this date
itineraryIds Array of itinerary ids (AKA Viator Reference) to check for; e.g., [1234657,2345267,3245154]
itemIds Array of item ids (AKA Viator Item Reference) to check for; e.g., [1234657,2345267,3245154]
leadFirstName The lead traveller's first name
leadSurname The lead traveller's surname
test Note: Setting test to true will bypass the poll limit on the sandbox environment only. The default value for test is false.

Example response object (/booking/status)

{
  "data": [
  {
    "itineraryId": 3332064,
    "bookingStatus": {
      "type": "CONFIRMED",
      "level": "ITINERARY",
      "failed": false,
      "text": "Confirmed",
      "cancelled": false,
      "status": 3,
      "confirmed": true,
      "amended": false,
      "pending": false
    },
    "bookingDate": "2013-03-25",
    "distributorRef": null,
    "itemSummaries": [{
      "itineraryId": 3332064,
      "itemId": 600088886,
      "bookingStatus": {
        "type": "CONFIRMED",
        "level": "ITEM",
        "failed": false,
        "text": "Paid &amp; Confirmed",
        "cancelled": false,
        "status": 1,
        "confirmed": true,
        "amended": false,
        "pending": false
      },
      "travelDate": "2013-12-03",
      "distributorItemRef": null,
      "sortOrder": 0
    }],
    "sortOrder": 1
  },
  {
    "itineraryId": 3332076,
    "bookingStatus": {
      "type": "CONFIRMED",
      "level": "ITINERARY",
      "failed": false,
      "text": "Confirmed",
      "cancelled": false,
      "status": 3,
      "confirmed": true,
      "amended": false,
      "pending": false
    },
    "bookingDate": "2013-03-26",
    "distributorRef": null,
    "itemSummaries": [{
      "itineraryId": 3332076,
      "itemId": 600088907,
      "bookingStatus": {
        "type": "CONFIRMED",
        "level": "ITEM",
        "failed": false,
        "text": "Paid &amp; Confirmed",
        "cancelled": false,
        "status": 1,
        "confirmed": true,
        "amended": false,
        "pending": false
      },
      "travelDate": "2013-12-03",
      "distributorItemRef": null,
      "sortOrder": 0
    }],
    "sortOrder": 2
  }],
  "vmid": "221002",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2013-03-26T10:25:57+0000",
  "errorReference": null,
  "errorMessageText": null,
  "success": true,
  "totalCount": 2,
  "errorName": null
}

Exceeding the poll limit

You will receive the following error if you exceed the number of calls allowed to the service within the timeframe:

{
  "data": null,
  "vmid": "221002",
  "errorMessage": [
    "Access allowed every 30 minutes"
  ],
  "errorType": "EXCEPTION",
  "dateStamp": "2013-03-26T10:28:51+0000",
  "errorReference": "~55315512721712161381352771",
  "errorMessageText": [
    "Access allowed every 30 minutes"
  ],
  "success": false,
  "totalCount": 1,
  "errorName": "PollingDeniedException"
}

Get the tour grade pricing matrix

The /booking/pricingmatrix service retrieves the pricing matrix for tour grades, product age bands and pax (passenger) mixes.

Example request object (/booking/pricingmatrix)

  "productCode": "5261HTLAP",
  "tourGradeCode": "Zone 1",
  "bookingDate": "2013-12-01",
  "currencyCode": "USD",
  "specialReservation": false

bookingDate: The date to check for pricing data. This is an optional parameter for a normal product.

If the date is not provided then the nearest available date is determined (i.e. not blocked out or unavailable for any reason)

Example response object (/booking/pricingmatrix).

{
  "data": [{
    "pricingUnit": "per person",
    "bookingDate": "2013-12-01",
    "sortOrder": 1,
    "ageBandPrices": [{
      "bandId": 1,
      "prices": [{
        "sortOrder": 1,
        "currencyCode": "USD",
        "price": 81.94,
        "priceFormatted": "$81.94",
        "merchantNetPrice": 0,
        "merchantNetPriceFormatted": "",
        "minNoOfTravellersRequiredForPrice": 1
      }],
      "sortOrder": 1,
      "minimumCountRequired": 1,
      "maximumCountRequired": 1
    }]
  },
  {
    "pricingUnit": "per person",
    "bookingDate": "2013-12-01",
    "sortOrder": 2,
    "ageBandPrices": [{
      "bandId": 1,
      "prices": [{
        "sortOrder": 1,
        "currencyCode": "USD",
        "price": 40.97,
        "priceFormatted": "$40.97",
        "merchantNetPrice": 0,
        "merchantNetPriceFormatted": "",
        "minNoOfTravellersRequiredForPrice": 1
      }],
      "sortOrder": 1,
      "minimumCountRequired": 2,
      "maximumCountRequired": 2
    }]
  },
  {
    "pricingUnit": "per person",
    "bookingDate": "2013-12-01",
    "sortOrder": 3,
    "ageBandPrices": [{
      "bandId": 1,
      "prices": [{
        "sortOrder": 1,
        "currencyCode": "USD",
        "price": 27.32,
        "priceFormatted": "$27.32",
        "merchantNetPrice": 0,
        "merchantNetPriceFormatted": "",
        "minNoOfTravellersRequiredForPrice": 1
      }],
      "sortOrder": 1,
      "minimumCountRequired": 3,
      "maximumCountRequired": 3
    }]
  }],
  "errorReference": null,
  "dateStamp": "2017-11-24T21:30:47+0000",
  "errorType": null,
  "errorCodes": null,
  "errorMessage": null,
  "errorName": null,
  "success": true,
  "totalCount": 3,
  "errorMessageText": null,
  "vmid": "321050"
}

Description of elements in JSON response object

Object Element Type Comments To be viewed by customer Required field
data object main response object
sortOrder integer order in which to show the pricing
bookingDate date booking date criteria
pricingUnit string unit for pricing: currently, only "per person" is supported
ageBandPrices object available age bands and their pricing
sortOrder integer sort order for age band display
bandId integer Note: the numeric bandId is associated with an age band description (e.g., "Adult", "Infant" etc.) and a corresponding age range (e.g., from 12 to 99) - these details are available from the /product service. See Working with age bands
minimumCountRequired integer minimum number of pricing units that apply to these prices
maximumCountRequired integer maximum number of pricing units that apply to these prices
prices object pricing available for the age band (based on the min and max count requirements)
currencyCode string currency of the pricing
sortOrder integer order the pricing is to be shown within the bandId
price number price in decimal format
priceFormatted string suggested sell price formatted according to the currency selected (with two decimal places where applicable)
merchantNetPrice number Ignore (Viator only)
merchantNetPriceFormatted string Ignore (Viator only)
minNoOfTravellersRequiredForPrice integer number of units that the pricing applies to (e.g., a minNoOfTravellersRequiredForPrice of 3 means that the price is for three people)

Dealing with vouchers

The /booking/voucher service retrieves details for a complete itinerary or a single itinerary item. The data is returned as HTML that can be wrapped in a header/footer.

Sample URL parameters

itineraryId=3299307&leadLastName=DP&itemId=600033670

or

voucherKey=3299307:93c7f36a56b18ba1068787ba7fb7988da5c8ad08db77604110141ff21498603e:600033670

Key concepts

voucherKey

  • Use either the voucherKey or the three separate parameters.
  • If voucherKey is provided as well as other parameters, then the voucherKey overrides the other parameters.
  • The voucherKey is obtained from /booking/mybookings or in the /booking/book response object when a booking is made.

fullHTML

This is an optional parameter:

  • If true, the full HTML (including <!DOCTYPE>, <html> and <head> tags) will be returned.
  • If false, an HTML <div> element will be returned.
  • The default for this parameter is false

mobileVoucher

  • Optional parameter. Defaults to true. If true, the mobile (cut down) voucher HTML is returned; otherwise, the full voucher HTML is returned and fullHTML is ignored
  • This field should only be enabled for products that have a voucherOption of "VOUCHER_E" or "VOUCHER_ID_ONLY" (e-vouchers are available for both options). Do not enable mobileVouchers for paper vouchers (voucherOption of "VOUCHER_PAPER_ONLY") as no barcode is returned.
  • The voucher information is available in the responses for:
  • Voucher information is also displayed under the Redemption Info heading in the response from this service.

Example response object (/booking/voucher)

{
  "data": "<div style=\'line-height: 1.5;font-family:\'Arial\',\'Helvetica\',\'Verdana\',sans-serif; font-size: 12px; padding: 0 10px; border-bottom: 1pxsolid #CAE2EA;\'><h2 style=\'font-size:16px;font-weight:bold;margin:0.5em 0;padding:0;\'>San FranciscoBay Sunset Catamaran Cruise &reg;</h2><h2 style=\'font-size:16px;font-weight:bold;margin:0.5em0;padding:0;\'>SAMPLE ONLY</h2><ul style=\'margin:0 0 1em 1em; padding:0;\'> <li><strong>Date:</strong>Friday April 13, 2012 </li><li><strong>Time:</strong><strong>2011:</strong><br><ul><li><strong>Nov. 6 to Nov. 27</strong>: 4:00pm (Fri., Sat. &amp; Sun)</li></ul><p><strong>2012:</strong></p><ul><li><strong>March 2 to March 10:</strong>&nbsp; 5:00 pm (Fri., Sat. &amp; Sun)</li><li><strong>March 11 to April 15:</strong> 6:00pm Daily</li><li><strong>April 16 to May 20:</strong> 6:30 pm Daily</li><li><strong>May 21 to July 22:</strong> 7:00 pm Daily</li><li><strong>July 23 to Aug 26: </strong>6:30 pm Daily</li><li><strong>Aug 27 to Sept 23:</strong>6:00 pm Daily</li><li><strong>Sept. 24 to Nov. 3:</strong> 5:30 pm Daily</li><li><strong>Nov 4 to Dec 2:</strong> 4:00pm (Friday, Sat., &amp; Sun.)</li></ul><p>Please arrive 30 minutes prior to cruise departure.</li></ul> <ul style=\'margin:0 0 1em 1em; padding:0;\'> <li><strong>Lead Traveler: </strong> jos dp</li><li><strong>Number of Travelers: </strong> 1 Adult</li> <li><strong>Booking Reference: </strong>VIATOR600033672</li><li><strong>Product Code: </strong>2316SUN</li><li><strong>Confirmation Details:</strong>SUN </li> <li><strong>Location </strong><div><p>Pier 39</p></div><div></div><div>When you get to Pier 39, stand on the sidewalk &amp; look towards the water, do NOT go down the center wherethe shops are, but take the left OUTSIDE walkway. Go towards the sea lions &amp; look for a gate with the letter J on it</div></li></ul><h3 style=\'font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\'> Redemption Info</h3><ul style=\'margin:0 0 1em 1em; padding:0;\'> <li>You can present either a paper or an electronic voucherfor this activity. </li> </ul> <h3 style=\'font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\'>Important</h3> <ul><li>Your local contact is Adventure Cat Sailing Charters on +1 800 498 4228.</li><li>Please note: You mustreconfirm directly with Adventure Cat Sailing Charters at <ul> <li>Locally on 415 777 1630</li></ul> at least 24 Hour(s)prior to your tour/activity date. If you are not arriving within the specified timeframe, please contact Adventure CatSailing Charters prior to your travels, or immediately upon arrival at your destination.</li></ul><ul><li>Duringthe months of March, April and November, the weather in San Francisco can be unpredictable and sailings are subject tocancellation or rescheduling. Please ensure that you call the operator 1 day prior to sailing to confirm your tour</li></ul><h3 style=\'font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\'>Inclusions</h3><ul><li>1.5-hour Sunset Cruise</li><li>Light hors d\'oeuvres</li><li>Two complimentary drinks</li></ul><h3 style=\'font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\'>Terms and Conditions </h3> Read our completeTerms & Conditions for information on cancellations, date changes and other modifications to this confirmed reservation. </div><!-- end of voucher_item --></div>",
  "vmid": "221001",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2012-04-13T10:40:47+0000",
  "success": true,
  "errorReference": null,
  "errorMessageText": null,
  "totalCount": 1,
  "errorName": null
}

Emailing a voucher using the API

To email a voucher to a customer, you can use the /booking/voucher/email service.

You can provide an itineraryId and leadLastName; or, optionally, an itemId or voucherKey in the request object for this service.

Example request object

{
  "itineraryId": 3299307,
  "itemId": 600033670,
  "leadLastName": "DP",
  "voucherKey": null,
  "name": "David",
  "email": "DavidT@viator.com",
  "subject": "Tour vouchers from David",
  "message": "hello this is a very very very long message"
}
Parameter Meaning Mandatory
voucherKey If a value is provided, it will override itineraryId, itemId and leadLastName.
itemId If an itemId is passed (not null and not 0), then only the individual item voucher gets sent.

Example result object

{
  "data": "Done",
  "vmid": "221001",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2012-04-13T15:24:12+0000", 
  "success": true,
  "errorReference": null, 
  "errorMessageText": null, 
  "totalCount": 1, 
  "errorName": null
}

Faxing a voucher using the API

To have a voucher faxed to a customer, you can use the /booking/voucher/fax service.

You can provide an itineraryId and leadLastName; or, optionally, an itemId or voucherKey in the request object for this service.

Example request object

{
  "itineraryId": 3299307, 
  "itemId": 600033670, 
  "leadLastName": "DP", 
  "voucherKey": null, 
  "countryCode": "61", 
  "areaCode": "02",
  "faxNumber":"82195499",
  "to":"Mary",
  "subject":"Hi from David",
  "message": "Here are all your tour vouchers for your trip"
}
Parameter Meaning Mandatory
voucherKey If a value is provided, it will override itineraryId, itemId and leadLastName.
itemId If an itemId is passed (not null and not 0), then only the individual item voucher gets sent.

Example result object

{
  "data": "Done",
  "vmid": "221001",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2012-04-13T16:13:40+0000", 
  "success": true,
  "errorReference": null, 
  "errorMessageText": null,
  "totalCount": 1,
  "errorName": null
}

Reviewing bookings

The /booking/pastbooking service gets the details of a single specific past booking based on the voucherKey, itineraryId, or itemId passed into it.

Sample URL Parameters

"email=john.doe@viator.com&itineraryId=3299307"

or

"email=john.doe@viator.com&itemId=600033670"

or

"voucherKey=3299307:93c7f36a56b18ba1068787ba7fb7988da5c8ad08db77604110141ff21498603e:600033670"

Key concepts

Email

The email address passed must match the email address associated to the itinerary

Departure Details

Departure details, such as the departurePoint, departurePointAddress and departurePointDirections, will be included in the response. These fields may contain HTML escape characters, such as &amp; and special characters that are escaped by a backslash. Ensure that these fields are parsed after receiving the response, or it may cause your JSON to be invalid.

Example response object (/booking/pastbooking):

{
  "errorReference": null,
  "data": {
    "sortOrder": 0,
    "rulesApplied": null,
    "bookingStatus": {
      "status": 3,
      "text": "Confirmed",
      "type": "CONFIRMED",
      "level": "ITINERARY",
      "confirmed": true,
      "pending": false,
      "amended": false,
      "cancelled": false,
      "failed": false
    },
    "itemSummaries": [{
      "sortOrder": 0,
      "rulesApplied": null,
      "bookingStatus": {
        "status": 1,
        "text": "Paid &amp; Confirmed", "type": "CONFIRMED",
        "level": "ITEM",
        "failed": false,
        "confirmed": true,
        "amended": false,
        "pending": false,
        "cancelled": false
      },
      "travellerAgeBands": [{
        "sortOrder": 0,
        "count": 2,
        "pluralDescription": "Adults",
        "description": "Adult",
        "ageBandId": 1
      }],
      "voucherKey": "1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69:700179574",
      "voucherURL": "https://viatorapi.viator.com/service/merchant/voucher.jspa?code=1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69:700179574&embedResources=false",
      "voucherRequirements": "You must present a paper voucher for this tour. We will email a link to access and print your voucher at the Lead Travelers email address.",
      "productPulledDown": false,
      "merchantCancellable": true,
      "productWidgetList": null,
      "savingAmount": 0,
      "vouchers": null,
      "passbooks": null,
      "termsAndConditions": null,
      "itineraryId": 1000308214,
      "productCode": "2065CPT",
      "tourGradeCode": "1DAY",
      "distributorItemRef": null,
      "languageServicesLanguageCode": "en",
      "travelDate": "2015-09-03",
      "price": 26.28,
      "leadTravellerSurname": "Test",
      "barcodeOption": "tour",
      "barcodeType": "code128",
      "destId": 318,
      "voucherOption": "VOUCHER_PAPER_ONLY",
      "productTitle": "City Sightseeing Cape Town Hop-On Hop-Off Tour",
      "itemId": 700179574,
      "obfsId": 27643,
      "departurePoint": "Tour starts at V&amp;A Waterfront, outside the Two Oceans Aquarium, however you may board the bus at any one of the stops throughout the city (see the Itinerary section below for a list of stops)",
      "departurePointAddress": "",
      "departurePointDirections": "",
      "leadTravellerTitle": "Mr",
      "leadTravellerFirstname": "Homer",
      "lastRetailPrice": 26.28,
      "bookingEngineId": "UF",
      "priceFormatted": "$26.28",
      "savingAmountFormated": "$0.00",
      "merchantNetPrice": 0,
      "merchantNetPriceFormatted": "",
      "currencyCode": "USD",
      "lastRetailPriceFormatted": "$26.28",
      "departsFrom": "Cape Town, South Africa",
      "tourGradeDescription": "1-Day Bus Tour (1DAY)",
      "hoursConfirmed": 0,
      "priceUSD": 26.28
    }],
    "voucherURL": "https://viatorapi.viator.com/service/merchant/voucher.jspa?code=1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69&embedResources=false",
    "voucherKey": "1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69",
    "bookerEmail": "jocelyn@viator.com",
    "itineraryId": 1000308214,
    "exchangeRate": 1,
    "distributorRef": null,
    "totalPrice": 26.28,
    "bookingDate": "2015-06-10",
    "totalPriceFormatted": "$26.28",
    "totalPriceUSD": 26.28,
    "hasVoucher": true,
    "userId": null,
    "currencyCode": "USD"
  }
}

Checking bookings

The /booking/mybookings service gets a user's future bookings; i.e., those with travel dates in the future. This service can also be used to check the status of a booking.

Key concepts

Sample URL parameters

  • "sessionId=xxx", or
  • "voucherKey=xxx", or
  • "email=terry.smith@viator.com&lastCCFourDigits=4242", or
  • "email=terry.smith@viator.com&itineraryOrItemId=3299307"

Provide one of:

  • a sessionId for all bookings related to a user account, or
  • a voucherKey, or
  • an email address (email) and the last four digits of the credit card number (lastCCFourDigits) used to make the booking to get all associated bookings, or
  • an email address (email) with either an itemId or itineraryId

...in that order

For "Failed" items, display a message that communicates the following information to your customers:

"The booking has failed either because this tour or activity was not available or there was a technical issue. Please contact Customer Service if you need more information."

See also: bookingStatus field values and meanings

Departure details

Departure details, such as the departurePoint, departurePointAddress and departurePointDirections will be included in the response. These fields may contain HTML escape characters, such as &amp; and special characters that are escaped using a backslash. Ensure that these fields are parsed after receiving the response or it may cause your JSON to be invalid.

Example response object (/booking/mybookings):

{
  "errorReference": null,
  "data": {
    "sortOrder": 0,
    "rulesApplied": null,
    "bookingStatus": {
      "status": 3,
      "text": "Confirmed",
      "type": "CONFIRMED",
      "level": "ITINERARY",
      "confirmed": true,
      "pending": false,
      "amended": false,
      "cancelled": false,
      "failed": false
    },
    "itemSummaries": [{
      "sortOrder": 0,
      "rulesApplied": null,
      "bookingStatus": {
        "status": 1,
        "text": "Paid &amp; Confirmed",
        "type": "CONFIRMED",
        "level": "ITEM",
        "failed": false,
        "confirmed": true,
        "amended": false,
        "pending": false,
        "cancelled": false
      },
      "travellerAgeBands": [{
        "sortOrder": 0,
        "count": 2,
        "pluralDescription": "Adults",
        "description": "Adult",
        "ageBandId": 1
      }],
      "voucherKey": "1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69:700179574",
      "voucherURL": "https://viatorapi.viator.com/service/merchant/voucher.jspa?code=1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69:700179574&embedResources=false",
      "voucherRequirements": "You must present a paper voucher for this tour. We will email a link to access and print your voucher at the Lead Travelers email address.",
      "productPulledDown": false,
      "merchantCancellable": true,
      "productWidgetList": null,
      "savingAmount": 0,
      "vouchers": null,
      "passbooks": null,
      "termsAndConditions": null,
      "itineraryId": 1000308214,
      "productCode": "2065CPT",
      "tourGradeCode": "1DAY",
      "distributorItemRef": null,
      "languageServicesLanguageCode": "en",
      "travelDate": "2015-09-03",
      "price": 26.28,
      "leadTravellerSurname": "Test",
      "barcodeOption": "tour",
      "barcodeType": "code128",
      "destId": 318,
      "voucherOption": "VOUCHER_PAPER_ONLY",
      "productTitle": "City Sightseeing Cape Town Hop-On Hop-Off Tour",
      "itemId": 700179574,
      "obfsId": 27643,
      "departurePoint": "Tour starts at V&amp;A Waterfront, outside the Two Oceans Aquarium, however you may board the bus at any one of the stops throughout the city (see the Itinerary section below for a list of stops)",
      "departurePointAddress": "",
      "departurePointDirections": "",
      "leadTravellerTitle": "Mr",
      "leadTravellerFirstname": "Homer",
      "lastRetailPrice": 26.28,
      "bookingEngineId": "UF",
      "priceFormatted": "$26.28",
      "savingAmountFormatted": "$0.00",
      "merchantNetPrice": 0,
      "merchantNetPriceFormatted": "",
      "currencyCode": "USD",
      "lastRetailPriceFormatted": "$26.28",
      "departsFrom": "Cape Town, South Africa",
      "tourGradeDescription": "1-Day Bus Tour (1DAY)",
      "hoursConfirmed": 0,
      "priceUSD": 26.28
    }],
    "voucherURL": "https://viatorapi.viator.com/service/merchant/voucher.jspa?code=1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69&embedResources=false",
    "voucherKey": "1000308214:899757cf8b419ed11f39045636b0b30af986d19126d04547097f4b9c05fb4b69",
    "bookerEmail": "jocelyn@viator.com",
    "itineraryId": 1000308214,
    "exchangeRate": 1,
    "distributorRef": null,
    "totalPrice": 26.28,
    "bookingDate": "2015-06-10",
    "totalPriceFormatted": "$26.28",
    "totalPriceUSD": 26.28,
    "hasVoucher": true,
    "userId": null,
    "currencyCode": "USD"
  },
  "dateStamp": "2015-06-10T00:33:24+0000", "errorType": null,
  "errorMessage": null,
  "errorName": null,
  "success": true,
  "totalCount": 1,
  "vmid": "321004",
  "errorMessageText": null
}

Contact customer service

In order to have a confirmation email regarding the booking sent to the email address associated with the booking by Viator Customer Service, you can use the /booking/mybookings/message service.

Example request object

{
  "itineraryId": 3299307,
  "itemId": 600033670,
  "type": "OTHER",
  "message": "Voucher enquiry",
  "otherQuestion": "This question will be overwritten with the question set at otherQuestionId"
  "otherQuestionId":"VOUCHER_PROBLEM",
  "respondInFL": false
}
Parameter Meaning Mandatory
sessionId Partners can either omit the sessionId field altogether or simply leave the value blank.
type Valid message types are: "AMEND", "CANCEL", "OTHER", "REFUND" and partners must specify the type of "OTHER"
otherQuestion If otherQuestionId is not included, the text in this field will be the question asked
otherQuestionId If "OTHER" is specified in type, this field will override the otherQuestion with a pre-mapped question. Partners can specify: "ON_REQUEST", "GENERAL_INFO", "VOUCHER_PROBLEM", "TECH_PROBLEM", "INCORRECT_DETAILS", "FAX_MOBILE", "MOBILE_UPDATES", "GENERAL_OTHER"
respondInFL Only applicable for "PARTNER"/"VML" sites. If true then respond in Foreign Language (FL)

Cancellations with this service

Example request body to make a cancellation

{
  "itineraryId": 3299307,
  "itemId": 600033670,
  "type": "CANCEL",
  "message": "Holiday cancelled by the customer"
}

Your request will then be placed into a queue to be canceled manually by the Viator customer service team.

Example result object

{
  "data": "Successfully Submitted booking message", 
  "vmid": "221001",
  "errorMessage": null,
  "errorType": null,
  "dateStamp": "2012-04-16T13:03:54+0000", 
  "success": true,
  "errorReference": null, 
  "errorMessageText": null,
  "totalCount": 1, 
  "errorName": null
}

Sample code

PHP sample code

POST request

This is a sample PHP POST API request to get the detailed availability of a product for a month.

function getAvailability ($productCode, $month, $year, $currencyCode, $ageBandIdQtyArray) {
  
  // getServiceURL() should return the base URL; e.g., 'https://viatorapi.viator.com'
  $url = getServiceURL() . "/service/booking/availability" . "?apiKey=" . getapiKey();

  // set up an array for the agebands -> qty list
  $agebandQtyList = array();

  foreach ($ageBandIdQtyArray as $band => $qty) {
    $agebandQty = new agebandQty();
    $agebandQty->bandId = $band;
    $agebandQty->count = $qty;
    $agebandQtyList[] = $agebandQty;
  }

  // Sample JSON: { "productCode": "2280AAHT","month": "6", "year": "2011", "currencyCode": "EUR", "ageBands":[{ "bandId":1, "count":1 }]}

  // add the other parameters
  $data['productCode'] = $productCode;
  $data['month'] = $month;
  $data['year'] = $year;
  $data['currencyCode'] = $currencyCode;
  $data['ageBands'] = $agebandQtyList;

  // encode the $data, post to the service, decode the JSON and return the resulting objec
  return json_decode (do_post_request($url, json_encode($data),"Content-Type: application/json\n"));
}

// THIS IS A HELPER FUNCTION TO WRAP AN HTTP POST
// $data = array(); - this is a key value assoc array to emulate a form being posted...
// $response = do_post_request($url, http_build_query($data));

function do_post_request($url, $data, $optional_headers = null) {
  $params = array('https' => array('method' => 'POST', 'content' => $data));

  if ($optional_headers !== null) {
    $params['https']['header'] = $optional_headers;
  }

  $ctx = stream_context_create($params);
  $fp = @fopen($url, 'rb', false, $ctx);

  if (!$fp) {
    throw new Exception("Problem with $url, $php_errormsg");
  }

  $response = @stream_get_contents($fp);

  if ($response === false) {
    throw new Exception("Problem reading data from $url, $php_errormsg");
  }

  return $response;
}

GET request

Here's some sample code for getting the product details.

function getProduct ($productCode, $currencyCode) {
  global $prefix, $memcache, $cacheTime;

  // create key for memcache
  $key = $prefix."_".getapiKey()."_"."getProduct"."-".$productCode."-".$currencyCode;

  // get the result from memcache if it's available
  $ret = $memcache->get($key);

  // if not available, call the API
  if ($ret === false) {
    // form the URL
    $url = getServiceURL() . "/service/product" . "?apiKey=" . getapiKey() . "&code=" . $productCode . "&currencyCode=" . $currencyCode;

    // do the GET and decode the results
    $ret = json_decode (file_get_contents($url));

    // check the return object for a successful request
    if ($ret->success === true) {

      // set the object into memcache for next time
      $memcache->set($key, $ret, false, $cacheTime);
    }
  }

  // return the data object
  return $ret;
}

Java sample code

Java POST request

This is a sample Java POST API request to get the products in Las Vegas available on the 25th February, 2014

Note that this for Java code with Apache http-client 4.3.2:

HttpPost post = new HttpPost("http://viatorapi.viator.com/service/search/products?apiKey=xxxxxxxx");
post.setHeader("Content-Type", "application/json");

String json = "

{\"startDate\":\"2014-02-25\",\"endDate\":\"2014-02-25\", \"topX\":\"1-5\",\"destId\":\"684\"

";

post.setEntity(new StringEntity(json));
CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response = httpclient.execute(post);
InputStream content = response.getEntity().getContent();

Testing

API testing with Postman collection

To facilitate your testing of the API in the sandbox environment, please use the following file, which can be loaded into the Postman API development environment via its import function:

Setting up API-key authentication in Postman

Before you start using the linked Postman collection for testing, you will need to set up the authorization method you wish to use. This can be either the new method (the exp-api-key header parameter) or, the legacy method (the apiKey query parameter).

While both methods remain available, we strongly recommend that you use the new method, as it:

  1. Provides access to all languages available for your organization with a single API-key as opposed to one API-key per language
  2. Allows access to the new booking cancellation endpoints, as well as all newly-created endpoints in future

Please speak to your account manager if you are still using the legacy apiKey and would like to switch to our new authentication mechanism.

How to set up the new exp-api-key header parameter

  1. Select Edit from the collection menu:

postman-testing-1

  1. Set the following values:
  • Key: exp-api-key
  • Value: Your organization's single exp-api-key, which will have an identical format to that shown in the image below
  • Add to: Header

postman-testing-2

  1. Click Update

How to set up the legacy apiKey query parameter

  1. Select Edit from the collection menu:

postman-testing-1

  1. Set the following values:
  • Key: apiKey
  • Value: One of your organization's legacy apiKeys, which will have an identical format to that shown in the image below
  • Add to: Query Params

postman-testing-3

  1. Click Update

FAQs

We are getting rates 0 in 'merchantNetPriceFrom' field for all products, why?

  • The merchantNetPriceFrom is only available for our merchant partners; whereas, you currently have an affiliate apiKey. These are two completely separate partner programs that require different key configurations and agreements. Please contact the your account manager if you are interested in becoming a merchant partner.

What are some common issues that cause bookings to fail in the API?

  • homePhone or any phone field in the booking request contain spaces. The only non-numeric characters acceptable are: “-“, “+” , “(“, and “)”

  • No traveller or an incorrect traveller has been set as the lead traveller in the booking request;

    • leadTraveller:true must be set for one traveller
    • the leadTraveller must be from an ageBand that has treatAsAdult set to true. The data is available in the ageBands object in the product details service.
  • languageOptionCode is invalid

    • To find the valid language option codes for a particular product, have a look at the langServices object in the response from the /product service; e.g.,
"langServices": {
  "en/SERVICE_AUDIO": "English - Audio"
}
  • You must then ensure that the languageOptionCode is populated in the same way; i.e.,
"languageOptionCode": "en/SERVICE_AUDIO"

What does it mean if I receive a "503 Service Unavailable" response?

  • This means that there was a temporary service outage on our end at that time. We recommend that you re-try the operation until you no longer receive this error.

Why am I getting an empty response when checking booking details?

  • If you are attempting to check a booking using the /booking/status or /booking/status/items endpoints and receive an empty response, it may be that the booking was made with the demo parameter set to true, as the booking status endpoints will ignore demo bookings. Please try making the booking again, ensuring the demo parameter is set to false. If this also fails, please email dpsupport@viator.com and include a copy of the request and response JSON objects.

Must I always provide details for all travelers when booking a product where allTravellerNamesRequired=true?

  • Approximately 45% of the products in our catalog require all traveller details to be supplied at the time of booking, and this requirement is enforced by the API. While it is technically possible to bypass this requirement – for example, by setting the lead traveler's name, but using dummy values for the the remaining travelers' details ('traveler 2', etc.) – we strongly advise against this, as it can cause problems for suppliers for whom this is a strict requirement. Examples include: Alcatraz tickets, theme park tickets that require a QR code, bookings for flights needing to meet TSA requirements; or, vehicle, Segway or jet-ski rentals. If you are unable to implement the collection of all traveler details on your site, we recommend filtering-out products where this is a strict requirement. You may also request that we filter-out these products for you so that they do not appear in product search results.

Must I always provide answers to the required booking questions when making a booking?

  • Yes. You must provide answers to all necessary booking questions when making a booking. Approximately 40% of the products in our catalog have booking questions, some of which may be necessary to fulfil the suplier's legal requirements. In the case that the customer cannot provide specific details at the time of booking – e.g., a departure flight number – they may enter 'unknown' and the supplier will manually send a follow-up message to ask for this information.

Why is there such a big difference in price between that given in the product endpoints and the actual price at the time of booking?

  • The price returned in the product endpoints is the 'From Price', which is the lowest possible price for an adult passenger when taking into account all available tour grades, group bookings and so forth. The exact price can only be determined when you check the availability for a specific date and passenger/traveler mix. We recommend using the /booking/availability/tourgrades endpoint for this purpose.

Appendices

Accept-Language header

The Accept-Language header parameter controls which language the natural language fields in the response from each endpoint will be translated into.

Note that you can only specify languages that have been configured for your API-key. Therefore, if you wish to access additional languages, you will need to contact your business development account manager.

Language Accept-Language parameter value
English en, en-US
Danish da, da-DK
Dutch nl, nl-NL
Norwegian no, no-NO
Spanish es, es-ES
Swedish sv, sv-SE
French fr, fr-FR
Italian it, it-IT
German de, de-DE
Portuguese pt, pt-PT
Japanese ja, ja-JP

bookingStatus field values and meanings

Field: type Field: status Meaning
"WAITING" 0 This item has not been booked. Part of an unfinished itinerary.
"CONFIRMED" 1 This item has been successfully booked
"UNAVAILABLE" 2 This item has been had an availability check, that came back false.
"PENDING" 3 This item has begun booking, but has paused in a deferred booking engine
"FAILED" 4 A merchant partner with a freesale-only API-key has attempted to book an on-request product
"CANCELLED" 5 This item has successfully been cancelled.
"EXPIRED" 6 This item is now expired.
"AMENDED" 7 This item has been amended after booking.
"PENDING_AMEND" 8 This item has a pending amendment which can be cancelled.
"REJECTED" 12 Viator only
"ON_HOLD" 13 Viator only

Supported currency codes

Supported currency codes for affiliate partners:

Currency code Currency
USD US dollar
GBP British pound
EUR Euro
AUD Australian dollar
HKD Hong Kong Dollar
SGD Singapore Dollar
CHF Swiss Franc
JPY Japanese Yen
NOK Norwegian Krone
CAD Canadian Dollar
NZD New Zealand Dollar
INR Indian Rupee
BRL Brazillian Lire
ZAR South African Rand
DKK Danish Krone
SEK Swedish Krona

Note: Access to currencies other than the main currency configured your account is restricted by default. Please speak to your account manager if you require access to pricing in alternative currencies. Furthermore, partners will be paid commissions only in the main currency configured for their account.

Country codes

Country code Country
AF Afghanistan
AL Albania
DZ Algeria
AS American Samoa
AD Andorra
AO Angola
AI Anguilla
AQ Antarctica
AG Antigua and Barbuda
AR Argentina
AM Armenia
AW Aruba
AU Australia
AT Austria
AZ Azerbaijan
BS Bahamas
BH Bahrain
BD Bangladesh
BB Barbados
BY Belarus
BE Belgium
BZ Belize
BJ Benin
BM Bermuda
BT Bhutan
BO Bolivia
BA Bosnia Herzegovina
BW Botswana
BR Brazil
BN Brunei
BG Bulgaria
BF Burkina Faso
BI Burundi
KH Cambodia
CM Cameroon
CA Canada
CV Cape Verde
KY Cayman Islands
CF Central Africa
TD Chad
CL Chile
CN China
CX Christmas Island
CC Cocos (Keeling) Islands
CO Colombia
KM Comoros
CK Cook Islands
CR Costa Rica
CI Cote D'Ivoire
HR Croatia
CY Cyprus
CZ Czech Republic
DK Denmark
DJ Djibouti
DM Dominica
DO Dominican Republic
EC Ecuador
EG Egypt
SV El Salvador
GQ Equatorial Guinea
ER Eritrea
EE Estonia
ET Ethiopia
FK Falkland Island
FO Faroe Islands
FJ Fiji
FI Finland
FR France
GF French Guiana
PF French Polynesia
GA Gabon
GM Gambia
GE Georgia
DE Germany
GH Ghana
GI Gibraltar
GR Greece
GL Greenland
GD Grenada
GP Guadeloupe
GU Guam
GT Guatemala
GN Guinea
GW Guinea Bissau
GY Guyana
HT Haiti
HN Honduras
HK Hong Kong
HU Hungary
IS Iceland
IN India
ID Indonesia
IQ Iraq
IE Ireland
IL Israel
IT Italy
JM Jamaica
JP Japan
JO Jordan
KZ Kazakhstan
KE Kenya
KI Kiribati
KW Kuwait
KG Kyrgyzstan
LA Lao People's Democratic Republic
LV Latvia
LB Lebanon
LS Lesotho
LR Liberia
LY Libyan Arab Jamahiriya
LI Liechtenstein
LT Lithuania
LU Luxembourg
MO Macau
MK Macedonia
MG Madagascar
MW Malawi
MY Malaysia
MV Maldives
ML Mali
MT Malta
MQ Martinique
MR Mauritania
MU Mauritius
YT Mayotte
MX Mexico
FM Micronesia
MD Moldova
MC Monaco
MN Mongolia
MS Monserrat
MA Morocco
MZ Mozambique
NA Namibia
NR Nauru
NP Nepal
NL Netherlands
AN Netherlands Antilles
KN Nevis- St Kitts
NC New Caledonia
NZ New Zealand
NI Nicaragua
NE Niger
NG Nigeria
NU Niue
NF Norfolk Island
KP North Korea
MP Northern Mariana Islands
NO Norway
OM Oman
PK Pakistan
PW Palau
PS Palestinian Territory, Occupied
PA Panama
PG Papua New Guinea
PY Paraguay
PE Peru
PH Philippines
PN Pitcairn
PL Poland
PT Portugal
PR Puerto Rico
QA Qatar
RE Reunion
RO Romania
RU Russian Federation
RW Rwanda
SH Saint Helena
LC Saint Lucia
SM San Marino
ST Sao Tome and Principe
SA Saudi Arabia
SN Senegal
YU Serbia and Montenegro
SC Seychelles
SL Sierra Leone
SG Singapore
SK Slovakia
SI Slovenia
SB Solomon Islands
SO Somalia
ZA South Africa
KR South Korea
ES Spain
LK Sri Lanka
PM St Pierre Miquelon
VC St Vincent and Grenadines
SR Suriname
SZ Swaziland
SE Sweden
CH Switzerland
SY Syria
TW Taiwan
TJ Tajikistan
TZ Tanzania
TH Thailand
TL Timor-Leste
TG Togo
TK Tokelau
TO Tonga
TT Trinidad and Tobago
TN Tunisia
TR Turkey
TM Turkmenistan
TC Turks and Caicos Islands
TV Tuvalu
UG Uganda
UA Ukraine
AE United Arab Emirates
GB United Kingdom
UY Uruguay
UM US Minor Outlying Islands
US United States of America
UZ Uzbekistan
VU Vanuatu
VE Venezuela
VN Vietnam
VG Virgin Islands-British
VI Virgin Islands-US
WF Wallis and Futuna Islands
WS Western Samoa
YE Yemen Republic
ZM Zambia
ZW Zimbabwe

US state codes

State code State
AL Alabama
AK Alaska
AZ Arizona
AR Arkansas
CA California
CO Colorado
CT Connecticut
DE Delaware
DC District of Columbia
FL Florida
GA Georgia
HI Hawaii
ID Idaho
IL Illinois
IN Indiana
IA Iowa
KS Kansas
KY Kentucky
LA Louisiana
ME Maine
MD Maryland
MA Massachusetts
MI Michigan
MN Minnesota
MS Mississippi
MO Missouri
MT Montana
NE Nebraska
NV Nevada
NH New Hampshire
NJ New Jersey
NM New Mexico
NY New York
NC North Carolina
ND North Dakota
OH Ohio
OK Oklahoma
OR Oregon
PA Pennsylvania
RI Rhode Island
SC South Carolina
SD South Dakota
TN Tennessee
TX Texas
UT Utah
VT Vermont
VA Virginia
WA Washington
WV West Virginia
WI Wisconsin
WY Wyoming

Canadian provinces

Code Province
Alberta Alberta
British Columbia British Columbia
Manitoba Manitoba
New Brunswick New Brunswick
Newfoundland and Labrador Newfoundland
Northwest Territories Northwest Territories
Nova Scotia Nova Scotia
Nunavut Nunavut
Ontario Ontario
Prince Edward Island Prince Edward Island
Quebec Quebec
Saskatchewan Saskatchewan
Yukon Yukon Territory

Australian states

Code State
ACT Australian Capital Territory
NSW New South Wales
NT Northern Territory
QLD Queensland
SA South Australia
TAS Tasmania
VIC Victoria
WA Western Australia

Viator API error codes

Error code Services Error message Description
ADDRESS_REQUIRED /booking/book "You have not entered an address. Please enter your address information." ccAddress1 was empty
ADDRESS_SIZE_EXCEEDED /booking/book "Billing address is restricted to 50 characters long." address field was longer than 51 characters
ATTRIBUTE_NOT_FOUND /product
AGE_BAND_INVALID /booking/book a bandId has been submitted that does not correspond to any bandId available for the tour grade in question
BOOKING_QUESTIONS_MISSING /booking/book "Additional questions missing" one or more required booking questions are missing in the booking request
CARD_EXPIRED /booking/book submitted credit card details corresponding to an expired card
CITY_REQUIRED /booking/book "You have not entered a city in the address section. Please enter your city." address is required in the credit card section
CITY_SIZE_EXCEEDED /booking/book "City is restricted to 40 characters long." city name submitted was more than 40 characters long
COUNTRY_REQUIRED /booking/book "You have not entered a country. Please enter your country." no country was submitted in the booking request
CREDIT_CARD_DECLINED /booking/book credit card used for booking was declined by the payment processor
CREDIT_CARD_EXPIRY_DATE_INVALID /booking/book "The expiration date for your credit card is not formatted properly. Please verify and re-enter the expiration date." incorrectly-formatted credit card expiration date was submitted
CREDIT_CARD_HOLDER_NAME_INVALID /booking/book credit card holder's name was invalid, perhaps due to the inclusion of invalid characters
CREDIT_CARD_NUMBER_INVALID /booking/book "Please verify and re-enter the credit card details, or use a different credit card" invalid characters in credit card number
CREDIT_CARD_NUMBER_REQUIRED /booking/book "Credit card number is required" credit card number was omitted
CREDIT_CARD_SECURITY_NUMBER_INVALID /booking/book "The card security number you entered for your credit card is invalid. It must contain 3 digits (or 4 with American Express cards). Please re-enter the card security number." incorrect CCV code submitted
CREDIT_CARD_SECURITY_NUMBER_REQUIRED /booking/book "Credit card security number is required" CCV was not provided
DEMO_BOOKING_WITH_REAL_CARD /booking/pricingmatrix demo is true, but credit card details are real
DISTRIBUTOR_REFERENCE_MISMATCH /booking/pastbooking; /booking/mybookings Not applicable to booking affiliates
EMAIL_ADDRESS_INVALID /booking/book "Your email address format is invalid" email address is formatted incorrectly
EMAIL_REQUIRED /booking/book "Email is required" email address is missing in the booking request
FIRST_NAME_INVALID /booking/book "You have entered a name for the credit-card holder that is not valid. Please verify and re-enter the name of the credit card holder." first name is formatted incorrectly or contains invalid characters in the booking request – string length must be > 1 and must not contain the following characters: <>%;"(),
FIRST_NAME_REQUIRED /booking/book "First name of credit card details is required" no first name specified
FIRST_NAME_SIZE_EXCEEDED /booking/book "First name of credit card details is restricted to 30 characters long" first name exceeds 30 characters
INTERNAL_ERROR any any the API itself has experienced an unexpected error
LAST_NAME_INVALID /booking/book "You have entered a name for the credit-card holder that is not valid. Please verify and re-enter the name of the credit card holder." last name is formatted incorrectly in the booking request – string length must be > 1 and must not contain the following characters: <>%;"(),
LAST_NAME_REQUIRED /booking/book "Last name of credit card details is required" no last name supplied in the ccname field of the ccPayDetail object
LAST_NAME_SIZE_EXCEEDED /booking/book "Last name of credit card details is restricted to 35 characters long" the surname in the ccname field of the ccPayDetail object must not exceed 35 characters in length
LEAD_TRAVELLER_REQUIRED /booking/book "A traveler needs to be selected as lead traveler." one traveller object within the travellers array in the booking request needs to have leadTraveller set to true
PAYMENT_AMOUNTS_CHANGED /booking/book [e.g. "PAYMENT_AMOUNTS_CHANGED: HKD 2213.20 (was HKD 2210.26)" This error indicates that the exchange rate was updated while the booking was being made. Refresh the product's pricing information and retry the booking.
PAYMENT_CURRENCY_MISMATCH /booking/book
PAYMENT_ENCRYPTION_ERROR /booking/book Viator-only internal error - retry booking request
PAYMENT_INTERNAL_ERROR /booking/book Viator-only internal error - retry booking request
PAYMENT_LIMIT_REACHED /booking/book Viator-only internal error - retry booking request
PAYMENT_REJECTED /booking/book triggered when expiry: "01/2018" and card number: "4539791001730106" were submitted
POSTCODE_REQUIRED /booking/book "You have not entered a zip code / post code. Please enter your zip code / post code.", ccaddressZip was empty
POSTCODE_SIZE_EXCEEDED /booking/book "Zip code / post code is restricted to 10 characters long." ccaddressZip was more than 10 characters in length
PRICING_DATA_MISSING Viator-only internal error - retry booking request
PRODUCT_TOUR_GRADE_UNKNOWN /booking/pricingmatrix Unknown tour grade: for product an invalid tour grade code was submitted
PRODUCT_UNAVAILABLE /booking/book Viator-only internal error - retry booking request
REFUND_REJECTED Viator-only internal error - retry booking request
STATE_REQUIRED /booking/book ccaddressState is required for this billing request
STATE_SIZE_EXCEEDED /booking/book ccaddressState must be fewer than 35 characters long
TOUR_NOT_AVAILABLE /booking/book "We're sorry, the following tour you are trying to book is sold out and no longer available" the tour is not available on the requested date
TOUR_GONE /product "We're sorry, we cannot find the tour, activity or attraction you are looking for" no product corresponding to the supplied details was found
TOUR_NOT_AVAILABLE_BETWEEN_DATES
TOUR_NOT_FOUND /product "We're sorry, we cannot find the tour, activity or attraction you are looking for" no product corresponding to the supplied details was found
TRAVELLER_COUNT_EXCEEDED_MAX_LIMIT number of travellers in the booking request was greater than the limit for the product being booked
TRAVELLER_FIRST_NAME_INVALID /booking/book "First name of traveler 1 must only contain alphabetical characters" non-alphabetical characters were used in the traveller's first name
TRAVELLER_FIRST_NAME_REQUIRED /booking/book "First name of traveler 1 is required" firstname in the booker object was omitted
TRAVELLER_LAST_NAME_INVALID /booking/book "Last name of traveler 1 should contain alphabet only and at least two letters long" surname in the booker object contained non-alphabetical characters
TRAVELLER_LAST_NAME_REQUIRED /booking/book "Last name of traveler 1 is required" surname in the booker object was omitted
TRAVELLER_MISMATCH the bandId is not available for the selected tour grade
UNKNOWN_ERROR any any the API reports this error when the exception from the underlying system (e.g. booking server) is not recognized
UNKNOWN_PAYMENT_METHOD
UNSUPPORTED_CARD cctype is not one of "Visa", "Mastercard" or "Amex"

Booking questions

Example product codes were valid at the time of writing. If you find that any of these product codes are invalid or do not include the relevant booking question, please inform us about it via email.

Id stringQuestionId title subtitle message example product
1 dateOfBirth_dob Date of Birth (e.g. 20 October 1970) Enter your date of birth. 100009P2
2 heights_passengerHeights Passenger Heights (eg. 5'2, 158cm etc) For safety reasons you must enter the height of all passengers. Please indicate inches or centimetres. 100009P1
3 passport_expiry Passport Expiry Date (e.g. 15 September 2015. If multiple passengers, separate each entry e.g. 01 July 2012, 31 May 2014) Enter passport expiry date for all passengers 100014P10
4 passport_nationality Passport Nationality (e.g. United States of America. If multiple passengers, separate each entry e.g. Australia, China) Enter country of issue of passport for all passengers 100014P10
5 passport_passportNo Passport Number (e.g. 0123456789. If multiple passengers, separate each entry e.g. 0123456789, 9876543210) Enter passport number for all passengers 100014P10
6 N/A N/A N/A N/A N/A
7 transfer_air_arrival_airline Arrival Airline (e.g. United, British Airways, Qantas, etc) Enter the name of your airline. 100006P15
8 transfer_air_arrival_flightNo Arrival Flight No (e.g. UA 864, BA 923, QA 233, etc) Enter your flight number. 100006P15
9 transfer_air_departure_airline Departure Airline (e.g. United, British Airways, Qantas, etc) Enter the name of your airline. 100006P17
10 transfer_air_departure_flightNo Departure Flight No (e.g. UA 864, BA 923, QA 233, etc) Enter your flight number. 100006P17
11 transfer_arrival_dropOff Drop Off Location (e.g. 1234 Cedar Way, Brooklyn, NY 00123) Enter the address for drop off. 100006P15
12 transfer_arrival_time Arrival Time (eg. 8pm, 20:30 etc) Enter your arrival time. Please indicate AM/PM or use the 24-hour clock. 100006P15
13 transfer_departure_date Departure date (e.g. 15 September 2015) Enter your departure date. 100006P15
14 transfer_departure_pickUp Pick up Location (e.g. 1234 Cedar Way, Brooklyn, NY 00123) Enter the address for pick up. 100006P17
15 transfer_departure_time Departure Time (eg. 8pm, 20:30 etc) Enter your departure time. Please indicate AM/PM or use the 24-hour clock. 100006P17
16 transfer_port_arrival_time Disembarkation Time (eg. 8pm, 20:30 etc) Enter your disembarkation time. Please indicate AM/PM or use the 24-hour clock. 100014P14
17 transfer_port_cruiseShip Cruise Ship (e.g. Brilliance of the Seas, etc) Enter your cruise ship. 100014P14
18 transfer_port_departure_time Boarding Time (eg. 8pm, 20:30 etc) Enter your boarding time. Please indicate AM/PM or use the 24-hour clock. 100014P4
19 transfer_rail_arrival_line Arrival Rail Line (e.g. Amtrak, etc) Enter the name of the rail provider. 100006P15
20 transfer_rail_arrival_station Arrival Rail Station (e.g. Central Station, etc) Enter name of arrival and/or departure station. 100006P15
21 transfer_rail_departure_line Departure Rail Line (e.g. Amtrak, etc) Enter the name of the rail provider. 100014P10
22 transfer_rail_departure_station Departure Rail Station (e.g. Central Station, etc) Enter name of arrival and/or departure station. 100014P10
23 weights_passengerWeights Passenger Weights (e.g. 127 pounds, 145 kilos, etc) For safety reasons you must enter the weight of all passengers. Please indicate pounds or kilos. 100111P12

bookingStatus field values and meanings

Field: type Field: status Meaning
"WAITING" 0 This item has not been booked. Part of an unfinished itinerary.
"CONFIRMED" 1 This item has been successfully booked
"UNAVAILABLE" 2 This item has been had an availability check, that came back false.
"PENDING" 3 This item has begun booking, but has paused in a deferred booking engine
"FAILED" 4 A merchant partner with a freesale-only API-key has attempted to book an on-request product
"CANCELLED" 5 This item has successfully been cancelled.
"EXPIRED" 6 This item is now expired.
"AMENDED" 7 This item has been amended after booking.
"PENDING_AMEND" 8 This item has a pending amendment which can be cancelled.
"REJECTED" 12 Viator only
"ON_HOLD" 13 Viator only

Booking services

Booking services

/booking/availability

Get the cheapest tour grade

This service:

  • returns the tour grade with the lowest price that is available for each day
  • useful when displaying a calendar of available tours
  • retailPrice represents the 'from' price for this product
  • Note: /booking/availability/dates provides all availability in one call and is more suitable for calendars, etc.
  • Service dir: Booking availability dates (one month from now)
Authorizations:
API-keyLegacy-API-key
Request Body schema: application/json
productCode
string

unique alphanumeric identifier of the product for which you wish to retrieve tour grade availability information

currencyCode
string (currencyCode)

currency code for the currency to use for pricing fields

month
string

month component (text format) of the start of the date range for which to retrieve tour grade availability information (must be in the future)

year
string

year component (text format) of the start of the date range for which to retrieve tour grade availability information (must be in the future)

Array of objects

array of objects specifying the age bands by which to to filter search results

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

object detailing available tourgrades for the specified age bands and date range for this product

Request samples

Content type
application/json
{
  • "productCode": "5010SYDNEY",
  • "currencyCode": "USD",
  • "month": "12",
  • "year": "2020",
  • "ageBands": [
    ]
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": {
    },
  • "dateStamp": "2020-04-21T23:22:52+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331002"
}

/booking/availability/dates

Get available dates

This service:

  • retrieves all available dates for a product, excluding days it does not operate and blocked-out dates
  • returns a multi-dimensional array of year-month -> days that have any availabile tour grade or traveler mix
  • useful to present the user with a list of dates for selection on which this product is available for booking
  • note: the user's desired traveler mix may not be eligible for booking; these details can be displayed when you retrieve its list of tour grades
Authorizations:
API-keyLegacy-API-key
query Parameters
productCode
string
Example: productCode=2280AAHT

unique alphanumeric identifier of the product

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

dictionary of month identifiers (e.g., '2018-12') to an array of days-of-the-month (text) specifying which days of the specified month this product is available to be booked"

  • example: 2018-12: ["15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"]
  • note: at present, the structure of the response data is not rendering correctly here; see response sample for details

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": {
    },
  • "dateStamp": "2020-04-22T17:28:30+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331001"
}

/booking/availability/tourgrades

Get available tour grades

This service reports:

  • all tour grades for the specified product, on the specified day, that are available for the specified age bands
  • the pricing breakdown and the total price, depending on the travel date and traveler mix
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
productCode
string
currencyCode
string (currencyCode)

currency code for the currency to use for pricing fields

bookingDate
string

date to enquire about available tour grades for this product

Array of objects

array of ageBand objects

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

Request samples

Content type
application/json
{
  • "productCode": "5010SYDNEY",
  • "currencyCode": "USD",
  • "bookingDate": "2018-12-12",
  • "ageBands": [
    ]
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-22T17:38:59+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": {
    },
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331002"
}

/booking/availability/tourgrades/pricingmatrix

Get availability, tour grades and pricing matrix

When queried with a given month, this service returns:

  • days with available tour grades only (i.e., days which have at least one tourgrade available)
  • the pricing matrix for that tour grade for that day
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
productCode
string

alphanumeric identifier of product about which to retrieve tour grade and pricing information

currencyCode
string (currencyCode)

currency code for the currency to use for pricing fields

month
string

month of year (as text) by which to filter results (must be in the future)

year
string

year (as text) by which to filter results (must be in the future)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

Request samples

Content type
application/json
{
  • "productCode": "5010SYDNEY",
  • "month": "12",
  • "year": "2020",
  • "currencyCode": "EUR"
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": {
    },
  • "dateStamp": "2020-04-22T23:17:31+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331002"
}

/booking/calculateprice

Calculate price

This service:

  • is used to calculate the total price for the booking, taking the traveler mix into account
  • reconfirms the availability of the products for the dates and traveler mix provided, as well as pricing
  • is usefule when implementing 'shopping cart' functionality

Importantly:

  • It is strongly recommended that this service is called prior to making a booking to confirm that the booking will succeed
  • The travelers are an associative array: age band identifier -> quantity
  • There can be several items in the cart. This allows for different traveler mixes per product booked.
  • The overall total of the booking is displayed in the itineraryNewPrice and itineraryNewPriceFormatted fields.
  • The result indicates if the booking is 'freesale' or 'on request'. On-request bookings are not sold as 'confirmed' but are confirmed by the supplier at a later date. The approximate window for confirmation is provided in the hoursConfirmed (integer) field for presentation to the customer. An hoursConfirmed of 0 means that the booking is 'freesale'. An hoursConfirmed greater than 0 indicates that it is 'on request'.
  • The partnerDetail object can also be added to the request object (see /booking/book for more details on the partnerDetails object)
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
currencyCode
string (currencyCode)

currency code for the currency to use for pricing fields

Array of objects

array of travel detail objects

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

Request samples

Content type
application/json
{
  • "currencyCode": "USD",
  • "items": [
    ]
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": {
    },
  • "dateStamp": "2020-04-22T17:56:17+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331001"
}

/booking/hotels

Get hotel pick-ups

This service:

  • Lists the hotel pickups available for either a product or a destination
Authorizations:
API-keyLegacy-API-key
query Parameters
productCode
string
Example: productCode=2280AAHT

unique alphanumeric identifier of the product

destId
integer
Example: destId=684

unique numeric identifier of the destination

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array of hotel pick-up objects

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-22T18:09:15+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331001"
}

/booking/book

Book a product

This service allows you to:

  • Make a Booking (HTTPS ONLY)
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
demo
boolean

specifier: true if this is a demo booking only (demos do not send any notifications, are automatically confirmed and OnRequest products become freesale products. Default value is true. Production must have demo set to false.

currencyCode
string (currencyCode)

currency code for the currency to use for pricing fields

object

object containing details about the primary contact (note: this contact needn't be a traveller)

object

API partners must pass this object. The billing details of the booking.

object

Optional object for capturing additional contact details of the primary contact whilst travelling. If you specify a contactType of MOBILE or ALTERNATE, pass phone and phoneCountry. If you specify EMAIL, specify the email address.

Array of objects

array of items in itinerary to be booked

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

Request samples

Content type
application/json
{
  • "partnerDetail": {
    },
  • "demo": true,
  • "currencyCode": "USD",
  • "altContactDetails": {
    },
  • "booker": {
    },
  • "ccPayDetail": {
    },
  • "items": [
    ]
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": {
    },
  • "dateStamp": "2020-04-22T19:12:27+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331002"
}

/booking/status

Get booking status

This service:

  • retrieves the booking status for multiple items based on different criteria
  • can only be polled every 30 minutes
  • is ideally be used in software for bulk updates of pending itineraries
  • returns a maximum of 1000 itineraries (narrow your search if you expect a greater number of results)
  • will return both live and test bookings

Exceeding the poll limit

  • You will receive the following error if you exceed the number of calls allowed to the service within the timeframe:
    {
      "data": null
      "vmid": 221002
      "errorMessage": ["Access allowed every 30 minutes"]
      "errorType": "EXCEPTION"
      "dateStamp": "2013-03-26T10:28:51+0000"
      "errorReference": 55315512721712161381352771
      "errorMessageText": ["Access allowed every 30 minutes"]
      "success": false
      "totalCount": 1
      "errorName": "PollingDeniedException"  
    }
    
Authorizations:
API-keyLegacy-API-key
Request Body schema: application/json
bookingDateFrom
string

earliest date for this booking

bookingDateTo
string

latest date for this booking

itineraryIds
Array of integers

array of itinerary identifiers to check

itemIds
Array of integers

array of item identifiers to check

distributorRefs
Array of strings

array of partner-defined distributor reference identifiers

distributorItemRefs
Array of strings

array of partner-defined distributor item reference identifiers e.g. ['refItem1','refItem2','refItem3']

leadFirstName
string

first name of the lead traveler

leadSurname
string

surname of the lead traveler

test
boolean

ignore (Viator only)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

object containing booking status, date and itinerary details

Request samples

Content type
application/json
{
  • "bookingDateFrom": "2020-12-01",
  • "bookingDateTo": "2020-12-31",
  • "itineraryIds": [
    ],
  • "itemIds": [
    ],
  • "distributorRefs": [
    ],
  • "distributorItemRefs": [
    ],
  • "leadFirstName": "Homer test",
  • "leadSurname": "Simpson test",
  • "test": false
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "dateStamp": "2020-04-22T19:12:27+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "321050",
  • "data": {
    }
}

/booking/status/items

Get brief booking statuses

This service is similar to /booking/status in that it:

  • retrieves the booking status for multiple items based on different criteria
  • has the same request parameters as /booking/status

However, it differs in that it returns a multi-item array of booking items with less detail than what would be received from /booking/status.

Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
bookingDateFrom
string

earliest date for this booking

bookingDateTo
string

latest date for this booking

itineraryIds
Array of integers

array of itinerary identifiers to check

itemIds
Array of integers

array of item identifiers to check

distributorRefs
Array of strings

array of partner-defined distributor reference identifiers

distributorItemRefs
Array of strings

array of partner-defined distributor item reference identifiers e.g. ['refItem1','refItem2','refItem3']

leadFirstName
string

first name of the lead traveler

leadSurname
string

surname of the lead traveler

test
boolean

ignore (Viator only)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array containing item ids and their associated booking status object

Request samples

Content type
application/json
{
  • "bookingDateFrom": "2013-12-22",
  • "bookingDateTo": "2013-12-25",
  • "itineraryIds": [
    ],
  • "itemIds": [
    ],
  • "distributorRefs": [
    ],
  • "distributorItemRefs": [
    ],
  • "leadFirstName": null,
  • "leadSurname": null,
  • "test": false
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "dateStamp": "2017-11-24T21:30:47+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "321050",
  • "data": [
    ]
}

/booking/pricingmatrix

Get pricing matrix

This service:

  • retrieves the pricing matrix for tourgrades, product age bands and pax mixes
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
productCode
string

unique alphanumeric identifier of the product for which to retrieve the pricing matrix

tourGradeCode
string

alphanumeric identifier of the product tour grade for which to retrieve the pricing matrix

bookingDate
string

date for which to retrieve pricing data (note: this is an optional parameter for normal products; if the date is not provided then the nearest available date is determined)

currencyCode
string (currencyCode)

currency code for the currency to use for pricing fields

specialReservation
boolean

ignore (Viator only)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

Request samples

Content type
application/json
{
  • "productCode": "5010SYDNEY",
  • "tourGradeCode": "24HOUR",
  • "bookingDate": "2020-12-21",
  • "currencyCode": "USD",
  • "specialReservation": false
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-22T18:28:01+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331004"
}

/booking/voucher

Get voucher details

This service:

  • Retrieves the voucher details of either a complete itinerary or an item (the data returned is in HTML and can be wrapped in a header and/or footer)

Sample query parameters

  • itineraryId=3299307&leadLastName=DP&itemId=600033670

or

  • voucherKey=3299307:93c7f36a56b18ba1068787ba7fb7988da5c8ad08db77604110141ff21498603e:600033670
Authorizations:
API-keyLegacy-API-key
query Parameters
itineraryId
string
Example: itineraryId=3299307

identifier of this itinerary

leadLastName
string
Example: leadLastName=Simpson

surname of this lead traveler

itemId
integer
Example: itemId=600033670

numeric identifier of this item

embeddedResources
boolean
Example: embeddedResources=false

ignore (Viator only)

voucherKey
string
Example: voucherKey=3299307:93c7f36a56b18ba1068787ba7fb7988da5c8ad08db77604110141ff21498603e:600033670

identifier for the voucher

  • note: use either voucherKey or the three separate parameters
  • if voucherKey is provided as well as the other parameters, then voucherKey overrides the other paramaters
  • voucherKey is obtained from /booking/mybookings or in the response from /booking/book when you make a booking
fullHTML
boolean
Example: fullHTML=true

specifier:

  • set to true if you wish to retrieve the full HTML-formatted voucher
  • set to false if you want the div fragment (optional)
mobileVoucher
boolean
Example: mobileVoucher=true

specifier:

  • if set to true, the service returns the mobile (cut down) HTML-formatted voucher
  • if false the full voucher HTML is returned (ignoring fullHTML)
  • default: true
  • this field should only be enabled for products that have a voucherOption of 'VOUCHER_E' or 'VOUCHER_ID_ONLY' (e-vouchers available for both options)
  • do not enable mobileVouchers for paper vouchers (voucherOption of 'VOUCHER_PAPER_ONLY') as no barcode is returned
  • the voucher information is available in the response from /product, /booking/book, /booking/pastbooking, /booking/mybookings (it is also displayed under the 'Redemption Info' heading in this service)
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

data
string

HTML-formatted voucher content

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": "\n <div id=\"content\" class=\"voucher_box\">\n <div id=\"voucher_1\">\n\n <div class=\"section\">\n <div class=\"voucher_title\">\n Voucher 1\n of 1: Homer Simpson test\n </div>\n </div>\n\n <div class=\"section bline\">\n <div class=\"btn_box\">\n </div>\n </div>\n\n <div style=\"line-height: 1.5;font-family:'Arial','Helvetica','Verdana',sans-serif; font-size: 12px; padding: 0 10px; border-bottom: 1px solid #CAE2EA;\">\n\n <h2 style=\"font-size:16px;font-weight:bold;margin:0.5em 0;padding:0;\">\n Grand Canyon All-American Helicopter Tour\n <span style=\"display: block;font-size:12px;\">\n Special: Earlybird A-Star 06:45\n </span>\n </h2>\n\n <div class=\"barcode\">\n <img src=\"/voucher/resource?type=barcode&itineraryItemId=581108716&voucherToken=371ddaac6b5c6d66eabb4aa4ffa1d4080b153d37cf4794261b74986098c4b618\" alt=\"\"/>\n </div>\n\n <h2 style=\"font-size:16px;font-weight:bold;margin:0.5em 0;padding:0;\">SAMPLE ONLY</h2>\n\n <ul style=\"margin:0 0 1em 1em; padding:0;\">\n <li>\n <strong>Date:</strong>\n Thursday August 06, 2020\n </li>\n </ul>\n\n <ul style=\"margin:0 0 1em 1em; padding:0;\">\n <li>\n <strong>Lead traveler\n :\n </strong>Homer Simpson test\n </li>\n <li>\n <strong>Number of Travelers\n :\n </strong>1 Adult</li>\n\n <li>\n <strong>Booking Reference:\n </strong>BR-581108716</li>\n\n <li>\n <strong>Product Code:\n </strong>2280AAHT</li>\n\n <li>\n <strong>Option Code:\n </strong>EB_ASTAR_SP~06:45</li>\n\n <li>\n <strong>Supplier\n : </strong>Sundance Helicopters</li>\n\n\n\n\n\n <li>\n <strong>Location\n :</strong>\n <p>Traveler pickup is offered<br><br></p>\n </li>\n\n <li>\n <strong>Tour Option Description\n :</strong>\n Special Offer: Receive a discounted seat for the Grand Canyon All American Helicopter Tour departing between 6:45am and 7am on an A-Star helicopter&lt;br/&gt;Pickup included\n \n </li>\n </ul>\n\n <h3 style=\"font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\">\n Voucher Information\n </h3>\n\n <ul style=\"margin:0 0 1em 1em; padding:0;\">\n You can present either a paper or an electronic voucher for this activity.\n <span style=\"color:#888888;\"> / You can present either a paper or an electronic voucher for this activity.</span>\n </ul>\n\n <h3 style=\"font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\">\n Important Information\n </h3>\n <ul><li>Your local contact is Sundance Helicopters on +17027360606.</li></ul>• Important: due to comfort, weight and balance of the aircraft, the maximum weight per passenger to ride in an A-Star helicopter is 275lbs (125kg / 19.6st). If passengers weigh in between 275lbs and 300lbs (136kg/21.4st), you will be required to upgrade to the EC-130.<br> • Any passenger over 300lbs will be required to purchase an additional seat. This is payable directly to the tour operator on the day of the tour.<br> • Due to the nature of this tour and the safety of all guests, the tour operator reserves the right to refuse service to passengers who are intoxicated or show signs of intoxication. If, as a result, your tour is canceled, you will not be entitled to a refund.<br> • Infant children must be under the age of two and have proof of age, such as a passport and are considered lap children.<br> • Per FAA regulations, all passenger must present photo ID at check in.<br> • If you would like a vegetarian meal as your lunch option, please contact the local operator as soon as possible.<br> • Please Note: Please look for your Limo driver who will get out and will be looking for the lead traveler’s last name of whom the reservation is under. There is also a sign in the front windshield of the Limo that will say Sundance Helicopters.<br><br>Hotel pickups commence prior to this time, you must contact the local service provider to verify your exact pickup time.<br><br>All flight times are approximate and subject to change due to weather conditions and weight restrictions.<br><br>This operator requires you to contact them directly prior to this tour/activity.<br><br>This operator requires you to contact them directly prior to this tour/activity.\n\n <h3 style=\"font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\">\n Inclusions\n </h3>\n <ul><li>45-minute (approx.) flight each way (helicopter based on option selected)</li><li>Hotel pickup and drop-off by limousine</li><li>Snacks</li><li>Glass of Champagne</li><li>All taxes and fees</li></ul>\n\n <h3 style=\"font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\">\n Exclusions\n </h3>\n <ul><li>Gratuities</li></ul>\n\n\n <h3 style=\"font-size:14px;font-weight:bold;margin:0.5em 0;padding:0;\">\n Terms and Conditions\n </h3>\n For a full refund, cancel at least 24 hours in advance of the start date of the experience.\n </div>\n\n </div>\n <br/>\n\n </div>\n\n",
  • "dateStamp": "2020-04-22T23:44:26+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331004"
}

/booking/voucher/email

Email a voucher

This service:

  • emails a voucher to a customer
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
itineraryId
integer

numeric identifier of the itinerary

itemId
integer

numeric identifier of the item

leadLastName
string

surname of the lead traveler

voucherKey
string

unique identification code for the voucher

name
string

name of the person to whom the voucher is to be sent

email
string

email address of the person to whom the voucher is to be sent

subject
string

subject line for the email that is to be sent to the recipient of the voucher

message
string

message content for the email to be sent to the recipient of the voucher

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

data
string

natural-language status of the email operation

Request samples

Content type
application/json
{
  • "itineraryId": 3299307,
  • "itemId": 600033670,
  • "leadLastName": "DP",
  • "voucherKey": null,
  • "name": "David",
  • "email": "DavidT@viator.com",
  • "subject": "Tour vouchers from David",
  • "message": "hello this is a very very very long message"
}

Response samples

Content type
application/json
"./examples/booking-voucher-email-example.yaml"

/booking/voucher/fax

Fax a voucher

This service:

  • faxes a voucher to a customer
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
itineraryId
integer

numeric identifier of the itinerary

itemId
integer

numeric identifier of the item

leadLastName
string

surname of the lead traveler

voucherKey
string

unique identification code for the voucher

countryCode
string

country-code for the telephone number to which the voucher will be sent via fax

faxNumber
any

telephone number to which the voucher will be sent via fax

to
string

short name of the person to whom the fax will be addressed

subject
string

subject line for the fax that is to be sent to the recipient of the voucher

message
string

message content for the email to be sent to the recipient of the voucher

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

data
string

natural-language status of the fax operation

Request samples

Content type
application/json
{
  • "itineraryId": 3299307,
  • "itemId": 600033670,
  • "leadLastName": "DP",
  • "voucherKey": null,
  • "countryCode": "string",
  • "faxNumber": "82195499",
  • "to": "string",
  • "subject": "Tour vouchers from David",
  • "message": "hello this is a very very very long message"
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "dateStamp": "2017-11-24T21:30:47+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "321050",
  • "data": "Done"
}

/booking/pastbooking

Get past booking

This service:

  • Gets the details of a single specific past booking based on the voucherKey, itineraryId or itemId sent in the request

Note: This service will only return past bookings that were made with the same apiKey that was used to make the booking

Sample query parameters:

  • email=john.doe@viator.com&itineraryId=3299307

or

  • email=john.doe@viator.com&itemId=600033670

or

  • voucherKey=3299307:93c7f36a56b18ba1068787ba7fb7988da5c8ad08db77604110141ff21498603e:600033670

email

  • The email address passed must match the email address associated to the itinerary

Departure details

  • Departure details, such as the departurePoint, departurePointAddress and departurePointDirections, are included in the response.
  • These fields may contain HTML escape characters such as & and special characters that are escaped by a backslash. Ensure that these fields are parsed after receiving the response as it will cause your JSON to be invalid.
Authorizations:
API-keyLegacy-API-key
query Parameters
voucherKey
string
Example: voucherKey=3299307:93c7f36a56b18ba1068787ba7fb7988da5c8ad08db77604110141ff21498603e:600033670

specifier of past booking type (use one of: 'voucherKey' or 'email' and one of itineraryId or itemId)

email
string
Example: email=apitest@viator.com

email address by which to search for past bookings

itineraryId
string
Example: itineraryId=1000308214

itinerary identifier by which to search for past bookings

itemId
string
Example: itemId=600033670

unique booking reference number by which to search for past bookings

header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

object containing pricing matrix information

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": {
    },
  • "dateStamp": "2020-04-22T23:40:47+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331003"
}

/booking/mybookings

Get user bookings

This service:

  • gets a user's bookings that have travel dates in the future
  • checks the status of a booking

Provide either:

  • a session identifier (sessionId) for all bookings related to a user account, or...
  • a voucherKey

or, provide:

  • an email address (email) and
  • the last four digits of the cc number (lastCCFourDigits)

...to get all associated bookings

or...

  • an email address with either

    • an itemId or

    • itineraryId

For failed items, show this text:

  • The booking has failed either because this tour or activity was not available or there was a technical issue. Please contact Customer Service if you need more information.
  • See also: bookingStatus field values and meanings

Departure Details

  • Departure details such as the departurePoint, departurePointAddress and departurePointDirections is included in the response
  • These fields may contain HTML escape characters such as &amp; and special characters escaped with a backslash. Ensure that these fields are parsed after receiving the response as it will cause your JSON to be invalid.
Authorizations:
API-keyLegacy-API-key
query Parameters
sessionId
integer

numeric session identifier for the booking

voucherKey
string
Example: voucherKey=3299307:93c7f36a56b18ba1068787ba7fb7988da5c8ad08db77604110141ff21498603e:600033670

voucher key for the booking

email
string
Example: email=apitest@viator.com

email address of the booker for the booking

lastCCFourDigits
integer
Example: lastCCFourDigits=4242

last four digits of the credit card that made the booking

itineraryOrItemId
string
Example: itineraryOrItemId=700179574

numeric identifier of the itinerary or item

header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-23T17:19:24+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331002"
}

/booking/mybookings/message

Send a message to a customer

This service requests that a confirmation email be sent to the customer (email address associated with the booking) from Viator Customer Service (see Contact customer service for more information)

Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
sessionId
string

unique numeric Id for the session. Partners can either omit the sessionId field altogether or leave its value blank

itineraryId
integer

numeric identifier of the itinerary

itemId
integer

numeric identifier of the item

type
string
Enum: "AMEND" "CANCEL" "OTHER" "REFUND"

Specifier of the question type - if 'OTHER', partners must specify the kind of 'other' in either the otherQuestion field or by providing an otherQuesitionId

message
string

message content for the email to be sent to the recipient of the voucher

otherQuestion
string

natural-language iteration of the question to ask if type is 'OTHER' and otherQuestionId is not provided.

otherQuestionId
string
Enum: "ON_REQUEST" "GENERAL_INFO" "VOUCHER_PROBLEM" "TECH_PROBLEM" "INCORRECT_DETAILS" "FAX_MOBILE" "MOBILE_UPDATES" "GENERAL_OTHER"

specifier of the premapped question when type is 'OTHER'. Partners must include this parameter.

respondInFL
boolean

Only applicable for "PARTNER"/"VML" sites. If true, then respond in Foreign Language (FL).

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

data
string

natural-language status of the customer-service contact operation

Request samples

Content type
application/json
{
  • "sessionId": "",
  • "itineraryId": 3299307,
  • "itemId": 600033670,
  • "type": "CANCEL",
  • "message": "Voucher enquiry",
  • "otherQuestion": "This question will be overwritten with the question set at `otherQuestionId`",
  • "otherQuestionId": "ON_REQUEST",
  • "respondInFL": false
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "dateStamp": "2017-11-24T21:30:47+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "321050",
  • "data": "Successfully submitted booking message"
}

/bookings/cancel-reasons

Retrieves a dictionary of unique identification codes (cancellationReasonCode) and their associated natural-language descriptions (cancellationReasonText).

For information on how to use this service, see: Cancellation API workflow

Note:

  • This service requires exp-api-key to be included as a header parameter. Please speak to your account manager if you have not yet been issued an exp-api-key.
  • The base URL for the server for this endpoint is different from the older endpoints described in this document. Use https://api.sandbox.viator.com/partner/bookings/cancel-reasons (sandbox) or https://api.sandbox.viator.com/partner/bookings/cancel-reasons (live)
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
Array
Array of objects (CancellationReason)

Array of cancellation reason codes and their asssociated texts for display to the user

Response samples

Content type
application/json
{
  • "reasons": [
    ]
}

/bookings/{booking-reference}/cancel-quote

Retrieves a quote for the cancellation of a booking

For information on how to use this service, see: Cancellation API workflow

Note:

  • This service requires exp-api-key to be included as a header parameter. Please speak to your account manager if you have not yet been issued an exp-api-key.
  • The base URL for the server for this endpoint is different from the older endpoints described in this document. Use https://api.sandbox.viator.com/partner/bookings/{booking-reference}/cancel-quote (sandbox) or https://api.viator.com/partner/bookings/{booking-reference}/cancel-quote (live)
Authorizations:
API-keyLegacy-API-key
path Parameters
booking-reference
required
string

Unique numeric identifier of the booking for which to retrieve a cancellation quote

Responses

Response Schema: application/json
object (RefundDetails)

Details of the refund

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 has been accepted by the supplier and its status is "CONFIRMED".

bookingId
string

The booking reference number, prepended with BR-

status
string
Enum: "CANCELLABLE" "CANCELLED" "NOT_CANCELLABLE"

String indicating the cancellation status of this itinerary item:

  • CANCELLABLE - this booking is available to be cancelled
  • CANCELLED - this booking has already been cancelled
  • NOT_CANCELLABLE - this booking cannot be cancelled (because the product's operation date is now in the past)

Response samples

Content type
application/json
{
  • "bookingId": "BR-580669678",
  • "refundDetails": {
    },
  • "status": "CANCELLABLE"
}

/bookings/{booking-reference}/cancel

Submits a cancellation request for the specified booking

For information on how to use this service, see: Cancellation API workflow

Note:

  • This service requires exp-api-key to be included as a header parameter. Please speak to your account manager if you have not yet been issued an exp-api-key.
  • The base URL for the server for this endpoint is different from the older endpoints described in this document. Use https://api.sandbox.viator.com/partner/bookings/{booking-reference}/cancel (sandbox) or https://api.viator.com/partner/bookings/{booking-reference}/cancel (live)
Authorizations:
API-keyLegacy-API-key
path Parameters
booking-reference
required
string

The ID of the booking

header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
reasonCode
string

Machine-interpretable identification code for this cancellation reason, retrieved from cancellationReasons

Responses

Response Schema: application/json
bookingId
string

Booking reference number for this booking, prepended with BR-

status
string
Enum: "ACCEPTED" "DECLINED"

String indicating the outcome of the booking cancellation request.

  • ACCEPTED: The cancellation was successful
  • DECLINED: The cancellation failed
reason
string
Enum: "ALREADY_CANCELLED" "NOT_CANCELLABLE"

Request samples

Content type
application/json
{
  • "reasonCode": "Customer_Service.I_canceled_my_entire_trip"
}

Response samples

Content type
application/json
Example
{
  • "bookingId": "BR-580669678",
  • "status": "ACCEPTED"
}

Product services

Product services

/search/products

Note: This service is included in this manual in order to draw attention to the fields that are exclusively relevant to partners with booking capabilities. i.e., transactional affiliates and not content affiliates. All other field descriptions have been removed for clarity. See the Affiliate partner technical manual for information about how to use this service.

This service is used to search for products based on various criteria; such as:

  • the destination (locale) in which it operates
  • its association with a tourist attraction
  • its category and/or subcategory
  • the time period during which it operates
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
destId
integer

n/a

seoId
string

n/a

catId
integer

n/a

subCatId
integer

n/a

startDate
string

n/a

endDate
string

n/a

currencyCode
string

n/a

topX
string (topX)

start and end rows to return in the format {start}-{end}

  • e.g. '1-10', '11-20'
  • maximum number of rows per request is 100
  • therefore, '100-400' will return the same as '100-200'
  • if topX is not specified, the default is '1-100'
sortOrder
string

n/a

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array of product objects

Request samples

Content type
application/json
Example
{
  • "destId": 684,
  • "subCatId": 26052,
  • "sortOrder": "REVIEW_AVG_RATING_A",
  • "topX": "1-3"
}

Response samples

Content type
application/json
Example
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-20T19:24:12+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 3,
  • "errorMessageText": null,
  • "vmid": "331001"
}

/search/products/codes

Note: This service is included in this manual in order to draw attention to the fields that are exclusively relevant to affiliate partners with booking capabilities. i.e., 'transactional affiliates' and not 'content affiliates'. All other field descriptions have been removed for clarity. See the Affiliate partner technical manual for information about how to use this service.

This service returns an array of products given an array of product identifiers that is useful for wishlist / shopping cart / user account display

Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
currencyCode
string (currencyCode)

currency code for the currency to use for pricing fields

productCodes
Array of strings

n/a

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array of product objects

Request samples

Content type
application/json
{
  • "currencyCode": "USD",
  • "productCodes": [
    ]
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-20T21:02:27+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331001"
}

/search/freetext

Note: This service is included in this manual in order to draw attention to the fields that are exclusively relevant to affiliate partners with booking capabilities. i.e., 'transactional affiliates' and not 'content affiliates'. All other field descriptions have been removed for clarity. See the Affiliate partner technical manual for information about how to use this service.

This service provides a free text search across all products destinations, attractions and recommendations

Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
destId
integer

n/a

topX
string

n/a

currencyCode
string

n/a

text
string

n/a

searchTypes
Array of strings
Items Enum: "PRODUCT" "DESTINATION" "ATTRACTION" "RECOMMENDATION"

n/a

sortOrder
string

n/a

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array of product objects

Request samples

Content type
application/json
{
  • "destId": 684,
  • "topX": "1-3",
  • "currencyCode": "USD",
  • "text": "helicopter",
  • "searchTypes": [
    ],
  • "sortOrder": "TOP_SELLERS"
}

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-20T21:07:44+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 124,
  • "errorMessageText": null,
  • "vmid": "331001"
}

/product

Note: This service is included in this manual in order to draw attention to the fields that are exclusively relevant to affiliate partners with booking capabilities. i.e., 'transactional affiliates' and not 'content affiliates'. All other field descriptions have been removed for clarity. See the Affiliate partner technical manual for information about how to use this service.

This service (/product) provides all product details required for a product display page, as well as information required for price checks and booking, such as:

  • age bands
  • tour grades (product options)
  • language options
  • booking questions
  • hotel pickup flags
Authorizations:
API-keyLegacy-API-key
query Parameters
currencyCode
string

n/a

voucherOption
string
Enum: "VOUCHER_PAPER_ONLY" "VOUCHER_E" "VOUCHER_ID_ONLY"

n/a

code
string

n/a

showUnavailable
string

n/a

sortOrder
string

n/a

excludeTourGradeAvailability
boolean

n/a

header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

object

object containing product details

Response samples

Content type
application/json
{}

Taxonomy services

Taxonomy services

/taxonomy/attractions

  • Retrieves a list of attractions (things like the Eiffel Tower or Empire State Building) and their associated unique numeric identifiers
  • The attraction's identifier (seoId) can be used as a means of searching for available products; for example, in the /search/products service.
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Request Body schema: application/json
destId
integer

unique numeric identifier of the destination in which to search for attractions

topX
string (topX)

start and end rows to return in the format {start}-{end}

  • e.g. '1-10', '11-20'
  • maximum number of rows per request is 100
  • therefore, '100-400' will return the same as '100-200'
  • if topX is not specified, the default is '1-100'
sortOrder
string

Sort order for the results; one of:

  • 'RECOMMENDED' – sorted in order of recommendation (Note: What Viator gets paid impacts this sort order)
  • 'SEO_ALPHABETICAL' – Alphabetical (A->Z)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

Request samples

Content type
application/json
{
  • "destId": 684,
  • "topX": "1-3",
  • "sortOrder": "RECOMMENDED"
}

Response samples

Content type
application/json
{}

/taxonomy/destinations

  • Retrieves all the country taxonomy/city nodes as a flat list
  • Returns a complete list of Viator destinations, including destination names and parent identifiers
  • Used to provide navigation through drill down lists or combo boxes
Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array of destination objects

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-20T23:56:25+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331001"
}

/taxonomy/categories

  • Retrieves a list of product categories for a destination that can be used as a means of filtering when searching for products using the /search/products service
  • This service can be used to get a list of all categories and subcategories for a destination by including its destId, or you can omit the destId to get a list of all categories and subcategories
  • Note: If no destId is passed, productCount and thumbnailURL will be null as they are destination-specific fields
Authorizations:
API-keyLegacy-API-key
query Parameters
destId
integer
Example: destId=684

unique numeric identifier of the destination to enquire about (optional)

header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array of category data objects

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-20T23:59:14+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331004"
}

Utility services

Utility services

/util/countrymap

Retrieves all the country codes that can be used for the billing country ccaddressCountryId in the /booking/book service

Authorizations:
API-keyLegacy-API-key
header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

array of countrymap objects

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": {
    },
  • "dateStamp": "2022-06-14T23:28:29+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331001"
}

Attraction services

/attraction/products

Note: This service is included in this manual in order to draw attention to the fields that are exclusively relevant to affiliate partners with booking capabilities. i.e., 'transactional affiliates' and not 'content affiliates'. All other field descriptions have been removed for clarity. See the Affiliate partner technical manual for information about how to use this service.

This service gets attraction-related products (for cross-selling purposes)

Aliases:

Authorizations:
API-keyLegacy-API-key
query Parameters
seoId
integer
Example: seoId=14235

n/a

topX
string
Example: topX=1-3

start and end rows to return in the format {start}-{end}

  • e.g. '1-10', '11-20'

Note:

  • the maximum number of rows per request is 100; therefore, '100-400' will return the same as '100-200'
  • if topX is not specified, the default is '1-100'
sortOrder
string
Example: sortOrder=SEO_PRODUCT_TOP_SELLERS

n/a

currencyCode
string
Example: currencyCode=EUR

n/a

header Parameters
Accept-Language
required
string

Specifies the language into which the natural-language fields in the response from this service will be translated (see Accept-Language header for available langage codes)

Responses

Response Schema: application/json
errorReference
string

reference number of this error

dateStamp
string

timestamp of this response

errorType
string

code specifying the type of error

errorCodes
Array of strings

array of error codes pertaining to this error

errorMessage
Array of arrays

array of error message strings

errorName
string

name of this type of error

success
boolean

boolean indicator of this request's outcome

  • true: the request was successful with no errors
  • false: an error was encountered
totalCount
integer

number of results available for this service

errorMessageText
string

array of error message strings in plain text

vmid
string

unique numeric id of the server that processed this request

Array of objects

Response samples

Content type
application/json
{
  • "errorReference": null,
  • "data": [
    ],
  • "dateStamp": "2020-04-20T22:33:42+0000",
  • "errorType": null,
  • "errorCodes": [ ],
  • "errorMessage": null,
  • "errorName": null,
  • "extraInfo": { },
  • "extraObject": null,
  • "success": true,
  • "totalCount": 1,
  • "errorMessageText": null,
  • "vmid": "331002"
}