Travelers can purchase ancillaries (or add-ons) along with their hotel booking. Common ancillaries include early check-in, late checkout, Wi-Fi access, breakfast, and parking. Spotnana APIs allow you to fetch the available ancillaries for an available rate, include them when creating a new booking, or modify them as part of an existing reservation.
Paid ancillaries are currently only supported for Travelodge bookings. To use this feature, it must first be enabled for your company profile. Contact your Spotnana representative to enable it.
Each ancillary returned by the API belongs to an ancillary category (listed below). The category field indicates the type of service offered and is useful when deciding how to group or display them in your user interface.
| Category | Description |
|---|---|
EARLY_CHECKIN | Allows the traveler to check in before the hotel's standard check-in time. |
LATE_CHECKOUT | Allows the traveler to check out after the hotel's standard checkout time. |
WIFI | Provides Wi-Fi access for the duration of the stay. It's usually sold as a package (e.g., 24-hour Wi-Fi add-on) or as a per-night item. |
BREAKFAST | Breakfast for the entire stay. The service is priced per night. However, the traveler can only purchase this ancillary for their entire stay (i.e., if a traveler is staying for 3 nights they cannot purchase breakfast for just one night). |
Use the get hotel ancillaries API to retrieve the list of paid ancillaries available for a selected hotel rate. The request takes the priceValidateKey returned from step 2 of the creating a hotel booking workflow.
Here's a sample request body of the get hotel ancillaries API:
{
"priceValidateKey": "Cg5TUE9UTkFOQTozMDc3NhIgCgIIARIMCgoyMDI0LTA="
}The response contains an ancillaries array, where each item describes an ancillary available to purchase for the selected room. The totalRate object holds the price information for each ancillary. The key fields are:
| Field | Description |
|---|---|
ancillaryKey | A unique identifier for the ancillary. This is the value that needs to be passed when creating or modifying a booking. |
category | The type of ancillary (see paid ancillary categories for the list of supported categories). |
displayName | The name of the ancillary which will be displayed to the traveler in the UI (e.g., "Early check-in from 12pm."). |
description | A detailed description that provides additional context about the ancillary. |
refundability | Indicates whether the ancillary purchase can be refunded if the booking is canceled. Possible values are FULLY_REFUNDABLE, PARTIALLY_REFUNDABLE, and NON_REFUNDABLE. |
purchaseStatus | Indicates whether the ancillary is available for purchase. Possible values are:
|
paymentType | Indicates whether the ancillary is PREPAID (charged at the time of booking) or POSTPAID (charged at the property). |
totalRate | The full rate breakdown of the ancillary, including base, tax, and other fees. |
prepaidRate | The prepaid price structure of the ancillary. This object is populated when the paymentType is PREPAID. |
postpaidRate | The postpaid price structure of the ancillary. This object is populated when the paymentType is POSTPAID. |
status | The current status of the ancillary associated with the booking. It can contain one of the following values:
|
Here's a sample response from the get hotel ancillaries API containing two available ancillaries:
{
"ancillaries": [
{
"ancillaryKey": "EICHK001",
"category": "EARLY_CHECKIN",
"displayName": "Early check-in from 12pm",
"description": "Check in from 12 noon to 2:30pm instead of the standard 3pm. Subject to availability.",
"totalRate": {
"base": { "amount": 15.00, "currencyCode": "GBP" },
"tax": { "amount": 0.00, "currencyCode": "GBP" },
"total": { "amount": 15.00, "currencyCode": "GBP" }
},
"prepaidRate": {
"base": { "amount": 15.00, "currencyCode": "GBP" },
"tax": { "amount": 0.00, "currencyCode": "GBP" },
"total": { "amount": 15.00, "currencyCode": "GBP" }
},
"refundability": "FULLY_REFUNDABLE",
"purchaseStatus": "AVAILABLE",
"paymentType": "PREPAID"
},
{
"ancillaryKey": "BFAST002",
"category": "BREAKFAST",
"displayName": "Full English Breakfast",
"description": "Cooked-to-order breakfast included for every night of the stay.",
"totalRate": {
"base": { "amount": 19.00, "currencyCode": "GBP" },
"tax": { "amount": 0.00, "currencyCode": "GBP" },
"total": { "amount": 19.00, "currencyCode": "GBP" }
},
"prepaidRate": {
"base": { "amount": 19.00, "currencyCode": "GBP" },
"tax": { "amount": 0.00, "currencyCode": "GBP" },
"total": { "amount": 19.00, "currencyCode": "GBP" }
},
"refundability": "FULLY_REFUNDABLE",
"purchaseStatus": "AVAILABLE",
"paymentType": "PREPAID"
}
]
}Each ancillary returned by the get hotel ancillaries API carries two distinct state fields: purchaseStatus and status. These two fields work together. Collectively, they can be used to understand the overall status of the ancillary before and after purchase.
The following are some possible combinations you can expect:
| Status | Context |
|---|---|
If purchaseStatus = AVAILABLE and status = NOT_PURCHASED | The hotel offers this ancillary but it has not been purchased and included in the booking. |
If purchaseStatus = ALREADY_PURCHASED and status = ACTIVE | The ancillary has been purchased and is currently active on the hotel booking. |
If purchaseStatus = ALREADY_PURCHASED and status = CANCELLED | The ancillary was purchased earlier but it has been canceled during a hotel booking modification. This ancillary is no longer included with the hotel booking. Refunds may be applicable as per the hotel policies. |
If purchaseStatus = ALREADY_PURCHASED and status = MODIFIED | The ancillary was purchased and it has been modified after the purchase. |
If purchaseStatus = INCLUDED_IN_RATE and status = ACTIVE | The ancillary is already bundled with the room's total rate and is currently active with the hotel booking. No separate purchase is required. |
To include ancillaries in a new hotel booking, pass the ancillaryKeys array in the request when creating a new hotel PNR.
{
"bookingKey": "example_booking_key",
"travelers": [
// ... traveler details
],
"tripData": {
"tripId": { "id": "2783425534" }
},
"ancillaryKeys": [
"EICHK001",
"BFAST002"
]
}Once a new booking is created, you can use the get PNR API to review the rate of the purchased ancillary in the following places:
- The
hotelPnr>ancillaries>totalRatefield. Each ancillary uses a dedicatedhotelPnr>ancillaries>totalRate>roomFees>feeTypefield. This makes it easy to distinguish ancillary charges from other charges (e.g., taxes) when displaying the price breakdown (e.g.,feeTypecan containHOTEL_ANCILLARY_EARLY_CHECK_IN_FEEwhich indicates the price of the early check-in fee). - The
hotelPnr>room>rateInfo>totalRate>extras>amountfield. Use theextras>typefield to find the ancillary category (e.g.,type=HOTEL_ANCILLARY_EARLY_CHECK_IN_FEE). - The
hotelPnr>room>rateInfo>prepaidRate>extras>amountfield if the purchase is prepaid. - The
hotelPnr>room>rateInfo>postpaidRate>extras>amountfield if the purchase is postpaid and will be charged when checking into the property.
Ancillaries can be added, removed, or modified as part of an existing hotel booking. For the full step-by-step API sequence to do this, see the modifying ancillaries in a hotel booking workflow.
The key behavior to understand is that the modify hotel booking endpoint reconciles ancillaries using a delete-and-add pattern. The ancillaryKeys array in the request body represents the complete state of the booking's ancillaries after the modification is applied, not a list of changes to make.
A traveler has an existing booking with early check-in (ancillaryKey = EICHK001) and breakfast (ancillaryKey = BFAST002) already purchased. They want to cancel the early check-in, keep the breakfast, and add a Wi-Fi package (ancillaryKey = WIFI007). The intended final state of the ancillaryKeys array will be breakfast and Wi-Fi as shown below in the sample API request:
{
"bookingKey": "example_booking_key",
"travelers": [
// ... traveler details
],
"tripData": {
"tripId": { "id": "2783425534" }
},
"ancillaryKeys": [
"BFAST002",
"WIFI007"
]
}This API call will cancel the early check-in ancillary (issuing a refund if applicable) and will add the new Wi-Fi package service to the booking. The booking also retains the breakfast service which was originally purchased. The final cost the traveler has to pay for this modification will be reflected in the totalRate > roomFees.
Some ancillaries may behave differently based on the updated stay duration. For example, a per-night ancillary like breakfast automatically adjusts to cover all nights of the new stay. The totalRate returned in the modified ancillary list reflects the updated cost.
Ancillaries can be canceled using the modifying ancillaries workflow. Also, the purchased ancillaries will be canceled automatically if the hotel booking is canceled. The refund process for each ancillary is treated according to its refundability value:
- Applicable refunds are processed for ancillaries if
refundabilityis set toFULLY_REFUNDABLEorPARTIALLY_REFUNDABLE. - Ancillaries with
refundabilityset toNON_REFUNDABLEare not refunded.