In this guide, we cover:
Pricing structure in the API
Verify the pricing of all Viator products and calculate the pricing for a specific date, product option, start time and passenger mix
Ingesting & updating data
Easily ingest availability and pricing schedules
Per person and unit pricing
Identify the lowest per-person price for a product, as well as the exact price based on the total passenger count, calculated either per person or per group
Special pricing
Promote special offers
Currency conversion
Convert pricing between multiple currencies
Low margin products
Ensure that your pricing aligns with current industry standards for pricing and calculate the exact amount that will be invoiced by Viator
Real time pricing checks
Verify real-time pricing
Pricing hold
Make an availability and pricing hold (for a limited period of time)
Invoicing
Check the exact amount you will be invoiced and the refund amount in case of a booking cancellation
As a merchant partner, you are free to decide on the pricing that will apply to Viator products sold to your customers. However, it is essential to verify the exact cost to you in order to keep the industry standards and make sure that you can make a profit from your bookings.
Do you know if you are a commission merchant or a markup merchant?
There are sections in this guide that apply only to markup merchants or are specific to commission merchants. To avoid confusion, make sure you confirm commerical details with your team. This will be specified in your contract.
Pricing structure in the API
Structured pricing information is provided by the API via the availability schedules endpoints. It consists of the following elements:
pricingPackageType – pricing type for this product; one of:
- “PER_PERSON” – pricing is calculated per-person,
- “UNIT” – pricing is calculated per-group/unit with the following options available for “unitType”: “GROUP”, “ROOM”, “PACKAGE”, “VEHICLE”, “BIKE”, “BOAT”, “AIRCRAFT” (other unit types might be added in the future).
maxTravelers – maximum number of travelers allowed to book for this price to apply
- “ADULT”
- “SENIOR”
- “YOUTH”
- “CHILD”
- “INFANT”
- “TRAVELER”
commission – the amount that you will keep for this sale in case you have a commission merchant agreement (please note: commission doesn’t apply to markup merchants who are invoiced the merchant net rate + the booking fee)
partnerTotalPrice – the total amount that Viator will invoice you for this sale, including the transaction fee (if you are a markup merchants)
offerStartDate and offerEndDate fields are returned to indicate the period during which the offer applies. For example, a special offer applies when you make the booking between 1 and 15 March, for any travel date
travelStartDate and travelEndDate fields are used to indicate the period during which the tour must be completed. For example, if you book for travel date between 1 and 15 March you get a discounted rate but the special pricing wouldn’t apply if you book after 15 March
Example response for product 100912P8 (markup merchants)
{
“productCode”: “100912P8”,
“bookableItems”: [
{
“productOptionCode”: “TG1”,
“seasons”: [
{
“startDate”: “2019-08-08”,
“pricingRecords”: [
{
“daysOfWeek”: [
“MONDAY”,
“TUESDAY”,
“WEDNESDAY”,
“THURSDAY”,
“FRIDAY”,
“SATURDAY”,
“SUNDAY”
],
“timedEntries”: [
{
“startTime”: “09:00”,
“unavailableDates”: [
{
“date”: “2022-05-02”,
“reason”: “SOLD_OUT”
},
{
“date”: “2022-04-13”,
“reason”: “SOLD_OUT”
},
{
“date”: “2022-05-01”,
“reason”: “SOLD_OUT”
}
]
}
],
“pricingDetails”: [
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “INFANT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 100.00,
“partnerNetPrice”: 79.88,
“bookingFee”: 5.19,
“partnerTotalPrice”: 85.07
},
“special”: {
“recommendedRetailPrice”: 95.00,
“partnerNetPrice”: 75.89,
“bookingFee”: 4.93,
“partnerTotalPrice”: 80.82,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “CHILD”,
“price”: {
“original”: {
“recommendedRetailPrice”: 100.00,
“partnerNetPrice”: 79.88,
“bookingFee”: 5.19,
“partnerTotalPrice”: 85.07
},
“special”: {
“recommendedRetailPrice”: 90.00,
“partnerNetPrice”: 71.89,
“bookingFee”: 4.67,
“partnerTotalPrice”: 76.56,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “YOUTH”,
“price”: {
“original”: {
“recommendedRetailPrice”: 200.00,
“partnerNetPrice”: 159.75,
“bookingFee”: 10.38,
“partnerTotalPrice”: 170.13
},
“special”: {
“recommendedRetailPrice”: 180.00,
“partnerNetPrice”: 143.78,
“bookingFee”: 9.34,
“partnerTotalPrice”: 153.12,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 200.00,
“partnerNetPrice”: 159.75,
“bookingFee”: 10.38,
“partnerTotalPrice”: 170.13
},
“special”: {
“recommendedRetailPrice”: 180.00,
“partnerNetPrice”: 143.78,
“bookingFee”: 9.34,
“partnerTotalPrice”: 153.12,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “SENIOR”,
“price”: {
“original”: {
“recommendedRetailPrice”: 200.00,
“partnerNetPrice”: 159.75,
“bookingFee”: 10.38,
“partnerTotalPrice”: 170.13
},
“special”: {
“recommendedRetailPrice”: 180.00,
“partnerNetPrice”: 143.78,
“bookingFee”: 9.34,
“partnerTotalPrice”: 153.12,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
}
]
}
]
}
]
}
],
“currency”: “EUR”,
“summary”: {
“fromPrice”: 180.00
}
}
Example response for product 100912P8 (commission merchants)
{
“productCode”: “100912P8”,
“bookableItems”: [
{
“productOptionCode”: “TG1”,
“seasons”: [
{
“startDate”: “2019-08-08”,
“pricingRecords”: [
{
“daysOfWeek”: [
“MONDAY”,
“TUESDAY”,
“WEDNESDAY”,
“THURSDAY”,
“FRIDAY”,
“SATURDAY”,
“SUNDAY”
],
“timedEntries”: [
{
“startTime”: “09:00”,
“unavailableDates”: [
{
“date”: “2022-05-02”,
“reason”: “SOLD_OUT”
},
{
“date”: “2022-04-13”,
“reason”: “SOLD_OUT”
},
{
“date”: “2022-05-01”,
“reason”: “SOLD_OUT”
}
]
}
],
“pricingDetails”: [
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “INFANT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 100.00,
“partnerNetPrice”: 90.00,
“bookingFee”: 0,
“commission”: 10.00,
“partnerTotalPrice”: 90.00
},
“special”: {
“recommendedRetailPrice”: 95.00,
“partnerNetPrice”: 85.50,
“bookingFee”: 0,
“commission”: 9.50,
“partnerTotalPrice”: 85.50,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “CHILD”,
“price”: {
“original”: {
“recommendedRetailPrice”: 100.00,
“partnerNetPrice”: 90.00,
“bookingFee”: 0,
“comission “: 10.00,
“partnerTotalPrice”: 90.00
},
“special”: {
“recommendedRetailPrice”: 90.00,
“partnerNetPrice”: 81.00,
“bookingFee”: 0,
“commission”: 9.00,
“partnerTotalPrice”: 81.00,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “YOUTH”,
“price”: {
“original”: {
“recommendedRetailPrice”: 200.00,
“partnerNetPrice”: 180.00,
“bookingFee”: 0,
“commission”: 20.00,
“partnerTotalPrice”: 180.00
},
“special”: {
“recommendedRetailPrice”: 180.00,
“partnerNetPrice”: 162.00,
“bookingFee”: 0,
“commission”: 18.00,
“partnerTotalPrice”: 162.00,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 200.00,
“partnerNetPrice”: 180.00,
“bookingFee”: 0,
“commission”: 20.00,
“partnerTotalPrice”: 180.00
},
“special”: {
“recommendedRetailPrice”: 180.00,
“partnerNetPrice”: 162.00,
“bookingFee”: 0,
“commission”: 18.00,
“partnerTotalPrice”: 162.00,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “SENIOR”,
“price”: {
“original”: {
“recommendedRetailPrice”: 200.00,
“partnerNetPrice”: 180.00,
“bookingFee”: 0,
“commission”: 20.00,
“partnerTotalPrice”: 180.00
},
“special”: {
“recommendedRetailPrice”: 180.00,
“partnerNetPrice”: 162.00,
“bookingFee”: 0,
“commission”: 18.00,
“partnerTotalPrice”: 162.00,
“offerStartDate”: “2022-03-19”,
“offerEndDate”: “2022-05-17”,
“travelStartDate”: “2022-03-20”,
“travelEndDate”: “2022-08-20”
}
}
}
]
}
]
}
]
}
],
“currency”: “EUR”,
“summary”: {
“fromPrice”: 180.00
}
}
Based on the example above, the same product might offer different pricing depending on the productOptionCode, seasons, startTime, or ageBand.
Ingesting and updating pricing data
The /availability/schedules/modified-since endpoint allows you to ingest all availability and pricing data and keep it updated on your end.
Availability and pricing schedules should be ingested for all products only once and it must be done using the /availability/schedules/modified-since endpoint unless you don’t wish to ingest the full product catalog but only selected products. In that case you would need to use the /availability/schedules/bulk endpoint.
The more frequently this data is updated on your end the better – we recommend updating availability and pricing schedules at least hourly to ensure that the data is not stale.
The rates returned from the /availability/schedules/* endpoints are provided in the supplier’s currency. In order to convert the rates between currencies and check the rates in the currency in which you will charge your customers, you need to use the /exchange-rates endpoint. For additional information about currency conversion check the currency conversion section.
The data returned from the /availability/schedule endpoints should be ingested and used to display the initial pricing, for example in the calendar view before users select a specific date:
Please note:
- The /availability/check endpoint must not be used for ingesting availability and pricing data in bulk. It is for real-time checks only.
- You shouldn’t expect to be invoiced based on the pricing returned with /availability/schedules endpoints as this is cached data. That’s why real-time availability and pricing checks with the /availability/check endpoint must be conducted prior to booking in order to get fully accurate pricing.
Per person and unit pricing
Viator pricing can be grouped into two categories: per person pricing and unit pricing – indicated in the pricingPackageType field of the product content response with the value either “PER_PERSON” or “UNIT”.
Per-person pricing
Per-person pricing is calculated based on the number of participants from each age band (to read more about the Viator age bands, check this article). The pricing is returned separately for each age band, as shown in the response example.
Example response (markup merchants)
{
“pricingPackageType”: “PER_PERSON”, “minTravelers”: 1, “maxTravelers”: 15, “ageBand”: “INFANT”, “price”: {
“original”: {
“recommendedRetailPrice”: 0.00, “partnerNetPrice”: 0.00, “bookingFee”: 0.00, “partnerTotalPrice”: 0.00
}
}
}, {
“pricingPackageType”: “PER_PERSON”, “minTravelers”: 1, “maxTravelers”: 15, “ageBand”: “CHILD”, “price”: {
“original”: {
“recommendedRetailPrice”: 80.11, “partnerNetPrice”: 66.46, “bookingFee”: 4.32, “partnerTotalPrice”: 70.78
}
}
}, {
“pricingPackageType”: “PER_PERSON”, “minTravelers”: 4, “maxTravelers”: 4, “ageBand”: “ADULT”, “price”: {
“original”: {
“recommendedRetailPrice”: 80.11, “partnerNetPrice”: 66.46, “bookingFee”: 4.32, “partnerTotalPrice”: 70.78
}
}
}, {
“pricingPackageType”: “PER_PERSON”, “minTravelers”: 2, “maxTravelers”: 2, “ageBand”: “ADULT”, “price”: {
“original”: {
“recommendedRetailPrice”: 92.43, “partnerNetPrice”: 76.68, “bookingFee”: 4.98, “partnerTotalPrice”: 81.66
}
}
}, {
“pricingPackageType”: “PER_PERSON”, “minTravelers”: 1, “maxTravelers”: 1, “ageBand”: “ADULT”, “price”: {
“original”: {
“recommendedRetailPrice”: 154.05, “partnerNetPrice“: 127.80, “bookingFee”: 8.31, “partnerTotalPrice”: 136.11
}
}
}, {
“pricingPackageType”: “PER_PERSON”, “minTravelers”: 3, “maxTravelers”: 3, “ageBand”: “ADULT”, “price”: {
“original”: {
“recommendedRetailPrice”: 87.30, “partnerNetPrice”: 72.42, “bookingFee”: 4.71, “partnerTotalPrice”: 77.13
}
}
}
]Example response (commission merchants)
“pricingDetails”: [
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“maxTravelers”: 15,
“ageBand”: “INFANT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 0.00,
“partnerNetPrice”: 0.00,
“bookingFee”: 0.00,
“commission”: 0.00,
“partnerTotalPrice”: 0.00
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“maxTravelers”: 15,
“ageBand”: “CHILD”,
“price”: {
“original”: {
“recommendedRetailPrice”: 80.11,
“partnerNetPrice”: 72.10,
“bookingFee”: 0,
“commission”: 8.01,
“partnerTotalPrice”: 72.10
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 4,
“maxTravelers”: 4,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 80.11,
“partnerNetPrice”: 72.10,
“bookingFee”: 0,
“commission”: 8.01,
“partnerTotalPrice”: 72.10
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 2,
“maxTravelers”: 2,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 92.43,
“partnerNetPrice”: 83.19,
“bookingFee”: 0,
“commission”: 9.24,
“partnerTotalPrice”: 83.19
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“maxTravelers”: 1,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 154.05,
“partnerNetPrice“: 138.65,
“bookingFee”: 0,
“commission”: 15.40,
“partnerTotalPrice”: 138.65
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 3,
“maxTravelers”: 3,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 87.30,
“partnerNetPrice”: 78.57,
“bookingFee”: 0,
“commission”: 8.73,
“partnerTotalPrice”: 78.57
}
}
}
]
The same age band might have different pricing depending on the number of participants from that age band.
As illustrated in the example above for product 40856P10, the per-person pricing for an ADULT age band is much higher when only one adult is booked than in the scenario where multiple adults are booked.
The lowest per-person retail price for the product is returned as fromPrice in the response from the /availability/schedules/* endpoints (in the currency provided by the supplier). It’s calculated according to the price for a group of at least two standard participants (or, the smallest bookable group if more than two participants are required) for a period not exceeding 384 days into the future. This value can be used to advertise a ‘from’-price.
Example response
{
“currency”: “THB”,
“summary”: {
“fromPrice”: 2900.00
}
}
Unit pricing
Unit pricing is based on the number of groups (units) and types of groups (units) that could be either: “GROUP”, “ROOM”, “PACKAGE”, “VEHICLE”, “BIKE”, “BOAT”, or “AIRCRAFT” – all defined in the API documentation:
Example response
“pricingInfo”: {
“type”: “UNIT”,
“ageBands”: [
{
“ageBand”: “TRAVELER”,
“startAge”: 0,
“endAge”: 99,
“minTravelersPerBooking”: 1,
“maxTravelersPerBooking”: 15
}
],
“unitType”: “VEHICLE”
},
The pricing information can be retrieved from the /availability/schedules/* endpoints:
Example response (markup merchants)
“pricingDetails”: [
{
“pricingPackageType”: “UNIT”,
“minTravelers”: 1,
“maxTravelers”: 15,
“ageBand”: “TRAVELER”,
“price”: {
“original”: {
“recommendedRetailPrice”: 500.00,
“partnerNetPrice”: 392.99,
“bookingFee”: 25.54,
“partnerTotalPrice”: 418.53
}
}
}
]
Example response (commission merchants)
“pricingDetails”: [
{
“pricingPackageType”: “UNIT”,
“minTravelers”: 1,
“maxTravelers”: 15,
“ageBand”: “TRAVELER”,
“price”: {
“original”: {
“recommendedRetailPrice”: 500.00,
“partnerNetPrice”: 450.00,
“bookingFee”: 0,
“commission”: 50.00,
“partnerTotalPrice”: 450.00
}
}
}
]
The price for two travelers would be exactly the same as the price for four travelers, because the price is based on the number of units and not the number of travelers.
In order to book this product for more than four travelers, a new booking request would need to be made (the API doesn’t support multiple bookings at the same time).
Please note: unit pricing is linked to only one age band – TRAVELER (this age band will not appear for products that have per-person pricing).
You can read more about per-person vs unit pricing in this section of the API documentation.
Special pricing
Some Viator suppliers offer discounted pricing for their products – this information is returned in the API under “special” pricing. Special pricing is valid only for a time period specified,, and sometimes it applies to specific travel dates.
Special offers and discounts draw customer attention and increase sales – it’s highly recommended to use them.
For example, the pricing schedule below for the product 195878P21 indicates that the special offer applies to the CHILD age band for bookings made between 2 April and 31 May 2022, for any travel date between 2 April and 31 October 2022.
Example response (markup merchants)
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “CHILD”,
“price”: {
“original”: {
“recommendedRetailPrice”: 45.00,
“partnerNetPrice”: 38.34,
“bookingFee”: 2.49,
“partnerTotalPrice”: 40.83
},
“special”: {
“recommendedRetailPrice”: 36.00,
“partnerNetPrice”: 30.67,
“bookingFee”: 1.99,
“partnerTotalPrice”: 32.66,
“offerStartDate”: “2022-04-02”,
“offerEndDate”: “2022-05-31”,
“travelStartDate”: “2022-04-02”,
“travelEndDate”: “2022-10-31”
}
}
}
Example response (commission merchants)
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “CHILD”,
“price”: {
“original”: {
“recommendedRetailPrice”: 45.00,
“partnerNetPrice”: 40.50,
“bookingFee”: 0,
“commission”: 4.5,
“partnerTotalPrice”: 40.50
},
“special”: {
“recommendedRetailPrice”: 36.00,
“partnerNetPrice”: 32.40,
“bookingFee”: 0,
“commission”: 3.60,
“partnerTotalPrice”: 32.40,
“offerStartDate”: “2022-04-02”,
“offerEndDate”: “2022-05-31”,
“travelStartDate”: “2022-04-02”,
“travelEndDate”: “2022-10-31”
}
}
}
Please note:
- You will always see the offerStartDate and offerEndDate returned for special pricing and depending on the supplier’s set up you may or may not see the travelStartDate and travelEndDate returned – this depends if the supplier wants to apply the offer to all future dates or only specific dates.
- Special pricing is defined on a per-age-band basis. It’s possible to get special pricing for the same product only for selected age bands (i.e. special pricing is returned for an adult age band but not for a child age bnd).
You can also identify products with permanently discounted rates using the Viator tags. For example:
“tagId”: 12493 – “Discounted Pricing for Select Groups”
“tagId”: 12461 – “Discounted Pricing for Children”
“tagId”: 12462 – “Discounted Pricing for Seniors”
“tagId”: 12463 – “Discounted Pricing for Students”
“tagId”: 12464 – “Discounted Pricing for Veterans”
Feel free to read more about the Viator tags and how to use them to merchandise products in this article.
Pricing could be modified by the supplier at any time therefore it’s recommended to always verify if the product offers special pricing based on the pricing schedules returned in the API.
Low margin products (markup merchants)
You can easily check the price of the activity on Viator – it’s returned in the API as the recommendedRetailPrice.
However, in some rare cases the recommendedRetailPrice might be lower than the partnerTotalPrice (the total amount that you will be invoiced if you are a markup merchant). This means that selling a product at the recommended retail price without first confirming that the margin is acceptable could result in a net loss for that transaction. This would apply to low margin products on Viator and only to markup merchants (the value of partnerTotalPrice and partnerNetPrice will always be equal for commission merchants).
Therefore if you are a markup merchant, it’s important for you to have logic in place to compare the recommendedRetailPrice and the partnerTotalPrice and adjust the pricing if necessary to make sure that selling at the recommendedRetailPrice wouldn’t result in a loss.
For example, product 3328DISNEY returns the recommendedRetailPrice higher than the partnerTotalPrice for both ADULT and CHILD age bands:
Example response (markup merchants)
“pricingDetails”: [
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “CHILD”,
“price”: {
“original”: {
“recommendedRetailPrice”: 520.00,
“partnerNetPrice”: 492.88,
“bookingFee”: 32.04,
“partnerTotalPrice”: 524.92
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 540.00,
“partnerNetPrice”: 511.84,
“bookingFee”: 33.27,
“partnerTotalPrice”: 545.11
}
}
}
]
}
]
Example response (commission merchants)
“pricingDetails”: [
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “CHILD”,
“price”: {
“original”: {
“recommendedRetailPrice”: 520.00,
“partnerNetPrice”: 468.00,
“bookingFee”: 0,
“commission”: 52.00,
“partnerTotalPrice”: 468.00
}
}
},
{
“pricingPackageType”: “PER_PERSON”,
“minTravelers”: 1,
“ageBand”: “ADULT”,
“price”: {
“original”: {
“recommendedRetailPrice”: 540.00,
“partnerNetPrice”: 486.00,
“bookingFee”: 0,
“commission”: 54.00,
“partnerTotalPrice”: 486.00
}
}
}
]
}
]
To make sure that you make a profit on that product, you will need to adjust the pricing on your end so that it’s not lower than the partnerTotalPrice.
Currency conversion
The availability schedules endpoints return rates in the currency provided by the supplier. The following supplier currencies are supported: AED, AUD, BRL, CAD, CHF, CNY, DKK, EUR, FJD, GBP, HHL, HKD, IDR, INR, ISK, JPY, KRW, MXN, MYR, NOK, NZD, PLN, RUB, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR.
It’s necessary to use the /exchange-rates endpoint in order to convert the pricing into the currency in which you wish to be invoiced (either AUD, EUR, GBP or USD). There is no need to call this endpoint every time a new booking is made. Instead you should bulk load all exchange rates and refresh them periodically (we recommend daily).
For example, in order to check the conversion rate from THB to USD, you need to make the following request:
Example request
curl –location -g –request POST ‘{{papi_host}}/exchange-rates’ \
–header ‘Accept: application/json;version={{version}}’ \
–header ‘Content-Type: application/json’ \
–header ‘exp-api-key: xxxx’ \
–data-raw ‘{
“sourceCurrencies”: [
“THB”
],
“targetCurrencies”: [
“USD”
]
}’
In the response, you will receive:
Example response
{
“rates”: [
{
“sourceCurrency”: “THB”,
“targetCurrency”: “USD”,
“rate”: 0.03190690376500000000,
“lastUpdated”: “2022-02-18T07:00:09Z”,
“expiry”: “2022-02-20T07:05:09Z”
}
]
}
The expiry field returns a timestamp (UTC) that indicates until when the conversion rate is valid. We highly recommend storing the conversion rates data and refreshing it daily based on the expiry timestamp (the same conversion rate applies to all products, so there is no need to verify it for each booking separately).
It’s also important to do the real-time availability check with the /availability/check endpoint in the correct currency (for example “currency”: “USD” must be sent in the request body). This way you will be able to verify the exact amount that Viator will invoice you based on Viator exchange rates.
Real time pricing checks
Before the user makes a booking, it’s necessary to verify the pricing in real-time with the /availability/check endpoint. This could be done either when the user is moving to the checkout page, or as soon as they select a specific date and passenger mix (read more about the Viator age bands here).
Please note:
- This endpoint may only be used to check live availability on a per-product basis once a passenger mix and travel date have been selected.
- You should never use the availability real-time request (/availability/check) for bulk ingestion purposes.
- The request to the /availability/check endpoint should specify the currency in which you wish to be invoiced by Viator.The pricing and availability hold (/bookings/hold) endpoint must never be used to check availability. Holds should only be placed after availability and pricing have been verified in real-time with the /availability/check endpoint.
(See our certification requirements)
Example request
{
“productCode”: “5096LASNIGHT”,
“travelDate”: “2022-08-26”,
“currency”: “USD”,
“paxMix”: [
{
“ageBand”: “ADULT”,
“numberOfTravelers”: 1
},
{
“ageBand”: “CHILD”,
“numberOfTravelers”: 1
}
]
}
The response returns all product options for the requested date and passenger mix:
Example response (markup merchants)
“currency”: “USD”, “productCode”: “5096LASNIGHT”, “travelDate”: “2022-08-26”, “bookableItems”: [
{
“productOptionCode”: “TG3”, “startTime”: “22:15”, “available”: false, “unavailableReason”: “TRAVELER_MISMATCH”
}, {
“productOptionCode”: “TG2”, “startTime”: “19:15”, “available”: false, “unavailableReason”: “TRAVELER_MISMATCH”
}, {
“productOptionCode”: “TG1”, “startTime”: “19:00”, “available”: true, “lineItems”: [
{
“ageBand”: “CHILD”, “numberOfTravelers”: 1, “subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 44.99, “partnerNetPrice”: 31.14
}
}, {
“ageBand”: “ADULT”, “numberOfTravelers”: 1, “subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 49.99, “partnerNetPrice”: 34.60
}
}
}
], “totalPrice”: {
“price”: {
“recommendedRetailPrice”: 94.98, “partnerNetPrice”: 65.74, “bookingFee”: 4.27, “partnerTotalPrice”: 70.01
}
}
}
]
}
Example response (commission merchants)
{
“currency”: “USD”,
“productCode”: “5096LASNIGHT”,
“travelDate”: “2022-08-26”,
“bookableItems”: [
{
“productOptionCode”: “TG3”,
“startTime”: “22:15”,
“available”: false,
“unavailableReason”: “TRAVELER_MISMATCH”
},
{
“productOptionCode”: “TG2”,
“startTime”: “19:15”,
“available”: false,
“unavailableReason”: “TRAVELER_MISMATCH”
},
{
“productOptionCode”: “TG1”,
“startTime”: “19:00”,
“available”: true,
“lineItems”: [
{
“ageBand”: “CHILD”,
“numberOfTravelers”: 1,
“subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 44.99,
“partnerNetPrice”: 40.49
}
},
{
“ageBand”: “ADULT”,
“numberOfTravelers”: 1,
“subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 49.99,
“partnerNetPrice”: 44.99
}
}
}
],
“totalPrice”: {
“price”: {
“recommendedRetailPrice”: 94.98,
“partnerNetPrice”: 85.48,
“bookingFee”: 0.00,
“commission”: 9.50,
“partnerTotalPrice”: 85.48
}
}
}
]
}
Availability and pricing hold
We highly recommend using the /bookings/hold endpoint during the booking process in order to place a temporary hold on availability and price. This way customers will be given enough time to fill in all required information and book before the product gets sold out or the price changes.
Please note:
- It’s essential to verify the timestamps returned in the API response for availability and pricing holds. A new hold can be placed only once the previous hold expires.
- A request to /bookings/hold should not be made until the user has indicated a strong intention to book. Typically, this means that it should not be called until immediately prior to the user entering their payment details.
- The /bookings/hold endpoint must never be used to check product availability.
- All data included in a booking request (passenger mix, travel date, booking questions, etc.) must be validated for the product in question before an availability or pricing hold (/bookings/hold) or booking request (/bookings/book) is made.
(See our certification requirements)
Example request
{
“productCode”: “85890P5”,
“startTime”: “06:00”,
“travelDate”: “2022-06-10”,
“currency”: “EUR”,
“paxMix”: [
{
“ageBand”: “ADULT”,
“numberOfTravelers”: 1
},
{
“ageBand”: “CHILD”,
“numberOfTravelers”: 1
}
]
}
TThe response includes the booking reference that should be used in the /bookings/book request, the status of availability and pricing holds as well as timestamps for each one (validUntil) and the pricing information:
Example response (markup merchants)
{
“bookingRef”: “BR-872448818”,
“bookingHoldInfo”: {
“availability”: {
“status”: “HOLDING”,
“validUntil”: “2022-04-13T13:05:55Z”
},
“pricing”: {
“status”: “HOLDING”,
“validUntil”: “2022-04-13T13:05:55.422456Z”
}
},
“currency”: “EUR”,
“lineItems”: [
{
“ageBand”: “CHILD”,
“numberOfTravelers”: 1,
“subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 73.13,
“partnerNetPrice”: 59.97
}
}
},
{
“ageBand”: “ADULT”,
“numberOfTravelers”: 1,
“subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 129.38,
“partnerNetPrice“: 106.10
}
}
}
],
“totalPrice”: {
“price”: {
“recommendedRetailPrice”: 202.51,
“partnerNetPrice”: 166.07,
“bookingFee”: 10.79,
“partnerTotalPrice”: 176.86
}
}
}
Example response (commission merchants)
{
“bookingRef”: “BR-872448818”,
“bookingHoldInfo”: {
“availability”: {
“status”: “HOLDING”,
“validUntil”: “2022-04-13T13:07:34Z”
},
“pricing”: {
“status”: “HOLDING”,
“validUntil”: “2022-04-13T13:07:33.620645Z”
}
},
“currency”: “EUR”,
“lineItems”: [
{
“ageBand”: “CHILD”,
“numberOfTravelers”: 1,
“subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 73.13,
“partnerNetPrice”: 59.97
}
}
},
{
“ageBand”: “ADULT”,
“numberOfTravelers”: 1,
“subtotalPrice”: {
“price”: {
“recommendedRetailPrice”: 129.38,
“partnerNetPrice“: 106.10
}
}
}
],
“totalPrice”: {
“price”: {
“recommendedRetailPrice”: 202.51,
“partnerNetPrice”: 166.07,
“bookingFee”: 0,
“commission”: 20.25,
“partnerTotalPrice”: 174.37
}
}
}
Invoicing
Viator will invoice you the amount returned under the partnerTotalPrice in the /bookings/book response in the currency sent in the booking request. It’s possible to make a booking in one of the following currencies: AUD, EUR, GBP, USD.
If you make multiple bookings using different currencies, you will receive separate invoices from Viator for each currency. If you would prefer to receive only one invoice, please make sure to specify the same currency in all your booking requests (this is recommended).
If you attempt to use a non-supported currency, you will receive this error message:
Example error message
{
“code”: “BAD_REQUEST”,
“message”: “Incorrect currency code provided”,
“timestamp”: “2021-08-06T14:57:44.478266Z”,
“trackingId”: “5C28A86F:2ECE_0A5D03D4:01BB_610D4DE8_6A78A4:1A92”
}
In case the booking needs to be amended and the change would result in a different price, the original booking needs to be canceled using the API and a new booking needs to be made. Viator will not invoice you for any canceled bookings as long as they have been canceled within the free cancellation window. This can be verified with the /bookings/{booking-reference}/cancel-quote endpoint (read more about the Viator cancellation policies and processes in this article).
For example, if you received the following response from the /bookings/{booking-reference}/cancel-quote endpoint, Viator would invoice you 50% of the booking amount if you were to cancel:
Example response
{
“bookingId”: “BR-585389372”,
“refundDetails”: {
“itemPrice”: 12148.54,
“refundAmount”: 6074.27,
“refundPercentage”: 50.00,
“currencyCode”: “GBP”
},
“status”: “CANCELLABLE”
}
It’s recommended to store the logs with responses to the /bookings/{booking-reference}/cancel-quote and /bookings/{booking-reference}/cancel endpoints for canceled bookings for at least a month so that they can be used to dispute any invoicing discrepancies. If you’d like to open a dispute regarding your Viator invoice, please fill in this form.
Please note:
- You shouldn’t rely on the pricing returned in the response from any of the availability schedules endpoints for invoicing purposes, as this is cahed data. That’s why it’s important to perform a real-time pricing check with the /availability/check endpoint prior to confirming the booking. If you use the /bookings/hold endpoint to make a pricing hold before the customer confirms the booking, make sure that you verify the timestamp returned in the response from this endpoint, as it indicates how long the price will be held for. In case the booking request isn’t submitted within the time frame specified, the price might have changed. These steps are essential to verify that the pricing is correct and to avoid situations where the amount on the invoice is different from what you were expecting to see.