Skip to content
Last updated

Paid ancillaries for hotel booking

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_CHECKINAllows the traveler to check in before the hotel's standard check-in time.
LATE_CHECKOUTAllows the traveler to check out after the hotel's standard checkout time.
WIFIProvides 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.
BREAKFASTBreakfast 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).

Fetching available ancillaries

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:

/v2/hotel/ancillaries
{
  "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
ancillaryKeyA unique identifier for the ancillary. This is the value that needs to be passed when creating or modifying a booking.
categoryThe type of ancillary (see paid ancillary categories for the list of supported categories).
displayNameThe name of the ancillary which will be displayed to the traveler in the UI (e.g., "Early check-in from 12pm.").
descriptionA detailed description that provides additional context about the ancillary.
refundabilityIndicates whether the ancillary purchase can be refunded if the booking is canceled. Possible values are FULLY_REFUNDABLE, PARTIALLY_REFUNDABLE, and NON_REFUNDABLE.
purchaseStatusIndicates whether the ancillary is available for purchase. Possible values are:
  • AVAILABLE: Can be purchased.
  • ALREADY_PURCHASED: Already purchased as part of this booking. This value is applicable when you're modifying a hotel booking that already has the same purchased ancillary.
  • INCLUDED_IN_RATE: Already part of the totalRate and doesn't need to be purchased separately.
paymentTypeIndicates whether the ancillary is PREPAID (charged at the time of booking) or POSTPAID (charged at the property).
totalRateThe full rate breakdown of the ancillary, including base, tax, and other fees.
prepaidRateThe prepaid price structure of the ancillary. This object is populated when the paymentType is PREPAID.
postpaidRateThe postpaid price structure of the ancillary. This object is populated when the paymentType is POSTPAID.
statusThe current status of the ancillary associated with the booking. It can contain one of the following values:
  • ACTIVE: The ancillary has been purchased and is active along with the hotel reservation.
  • CANCELLED: The ancillary purchase has been canceled and is no longer associated with the booking. The hotel booking reservation may still be active.
  • MODIFIED: The ancillary purchase has been modified (e.g., Wi-Fi purchased for 2 additional days).
  • NOT_PURCHASED: The ancillary hasn't been purchased yet.

Here's a sample response from the get hotel ancillaries API containing two available ancillaries:

/v2/hotel/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"
    }
  ]
}

The totalPrice and dailyPrice fields (in the hotel APIs and the get PNR API) have been deprecated. Use the totalRate instead to identify the price of the ancillaries, room, and other fees.

Understanding purchaseStatus and status

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_PURCHASEDThe hotel offers this ancillary but it has not been purchased and included in the booking.
If purchaseStatus = ALREADY_PURCHASED and status = ACTIVEThe ancillary has been purchased and is currently active on the hotel booking.
If purchaseStatus = ALREADY_PURCHASED and status = CANCELLEDThe 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 = MODIFIEDThe ancillary was purchased and it has been modified after the purchase.
If purchaseStatus = INCLUDED_IN_RATE and status = ACTIVEThe ancillary is already bundled with the room's total rate and is currently active with the hotel booking. No separate purchase is required.

Booking a hotel with ancillaries

To include ancillaries in a new hotel booking, pass the ancillaryKeys array in the request when creating a new hotel PNR.

/v2/hotel/create-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:

  1. The hotelPnr > ancillaries > totalRate field. Each ancillary uses a dedicated hotelPnr > ancillaries > totalRate > roomFees > feeType field. This makes it easy to distinguish ancillary charges from other charges (e.g., taxes) when displaying the price breakdown (e.g., feeType can contain HOTEL_ANCILLARY_EARLY_CHECK_IN_FEE which indicates the price of the early check-in fee).
  2. The hotelPnr > room > rateInfo > totalRate > extras > amount field. Use the extras > type field to find the ancillary category (e.g., type = HOTEL_ANCILLARY_EARLY_CHECK_IN_FEE).
  3. The hotelPnr > room > rateInfo > prepaidRate > extras > amount field if the purchase is prepaid.
  4. The hotelPnr > room > rateInfo > postpaidRate > extras > amount field if the purchase is postpaid and will be charged when checking into the property.

Modifying ancillaries on an existing booking - Overview

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.

Sample use case

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:

/v2/hotel/pnrs/{pnrId}/modify-book
{
  "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.

Cancellation and refunds

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 refundability is set to FULLY_REFUNDABLE or PARTIALLY_REFUNDABLE.
  • Ancillaries with refundability set to NON_REFUNDABLE are not refunded.