Managing promotions
Booking.com has sunset Business booker rates since December 7, 2022 and is therefore no longer usable.
The Promotions API enables you to create and manage promotions for a property.
Use the promotions
endpoint to:
- Create a promotion by choosing from six different promotion types.
- Update a promotion to make changes to an existing promotion.
- Activate a promotion that was deactivated by the provider. Any newly created or updated promotion is, by default, marked as active.
- Deactivate an active promotion if you no longer want guests to use the promotion.
Promotions with stay dates in the past are active, but no longer bookable. However, you can update the promotion with future dates to make it bookable again.
What are promotion types?
Promotion types help you create promotions for certain scenarios. Booking.com provides six promotion types, namely:
- Basic: Create a fully customisable promotion.
- Last minute: Promote maximum occupancy by leveraging unbooked rooms.
- Early booker: Attract early bookers.
- Geo rate: Offer special prices for guests from a specific location. Booking.com supports a list of predefined geolocations.
- Mobile rate: Offer special prices to mobile app users.
Promotion details
Depending on the promotion type selected, you can specify (among other parameters) the following:
- Bookable date range or time period when the promotion is available.
- The last minute stay date range within which the guests should book a stay to get a discount.
- The number of days in advance the guests must book to get a discount.
- A geolocation to offer discounts to guests booking from a specific location.
- A discount value as a percentage of the roomrate.
For promotion types other than geo_rate
and mobile_rate
, you can also choose whether a promotion is available to [all guests, or only certain guests][#target-promotions-to-specific-audience].
Creating promotions
POST
https://supply-xml.booking.com/hotels/xml/promotions
When creating a promotion, the mandatory list of request parameters varies based on the promotion type. The following subsections help you create promotions using the various promotion types.
- Creating a basic promotion.
- Creating a last minute promotion.
- Creating an early booker promotion.
- Creating a geo rate promotion.
- Creating a mobile rate promotion
A promotion is marked active whenever it is created or updated irrespective of whether the bookable/stay dates are current or in the past.
Creating a basic promotion
Booking.com has sunset the China channel for promotions on December 7, 2022. It is therefore no longer available or usable.
Use this promotion type to create a fully customisable promotion and specify a discount on selected rooms and price/rate attached to a roomrate.
Sample request
The following request creates a basic promotion:
<request> <hotel_id>12312</hotel_id> <promotion name="Summer Promotion" type="basic" target_channel="public" min_stay_through="3" non_refundable="0"> <book_date start="2024-05-14" end="2024-07-31" /> <book_time start="11" end="13" /> <stay_date start="2024-06-06" end="2024-06-29"> <active_weekdays> <active_weekday>Thu</active_weekday> </active_weekdays> <excluded_dates> <excluded_date>2024-06-15</excluded_date> <excluded_date>2024-06-16</excluded_date> </excluded_dates> </stay_date> <additional_dates> <additional_date>2024-07-18</additional_date> <additional_date>2024-07-20</additional_date> </additional_dates> <rooms> <room id="1423432"/> <room id="325436"/> </rooms> <parent_rates> <parent_rate id="756878"/> <parent_rate id="543754"/> </parent_rates> <discount value="10" /> </promotion> </request>
Request body
Element | Attribute | Description | Type | Occurrences | Notes |
---|---|---|---|---|---|
request | Root element | object | 1..1 | - | |
hotel_id | The ID of the property to which the promotion applies. | integer | 1..1 | You must have permission to edit the property. | |
promotion | - | object | 1..1 | - | |
promotion | name | The name of the promotion. This name is only for you: it does not appear on Booking.com. | string | 1..1 | Must be 20 characters or less. This includes spaces. |
promotion | type | The type of promotion. | string | 1..1 | Accepts: basic , last_minute , early_booker . |
promotion | target_channel | Determines who can see the promotion. | string | 0..1 | Accepts: public , subscribers . Default: public |
promotion | min_stay_through | The minimum number of nights a guest must stay to be eligible for the promotion. | integer | 0..1 | Possible values are 0-7 . Be aware that 0 means that the promotion follows the minimum length of stay (MLOS) of the chosen parent rate plan. 1 means that there is no MLOS required for this promotion. 2-7 refers to the actual minimum number of days for MLOS. |
promotion | non_refundable | Specifies if the promotion is non-refundable. | boolean | 0..1 | Accepts: 1 (non-refundable), 0 (refundable). Default: 0 |
book_date | Specifies the date range during which the promotion appears on Booking.com. | - | 0..1 | If you specify neither book_date[@start] nor book_date[@end] , then the promotion has no date restrictions. | |
book_date | start | Specifies the date from which the promotion is available. | date (YYYY-MM-DD) | 0..1 | Default: empty. book_date[@start] must be before book_date[@end] . You should provide also book_date[@end] |
book_date | end | Specifies the date up to which the promotion is available. | date (YYYY-MM-DD) | 0..1 | book_date[@end] must be after book_date[@start] . book_date[@end] must be on or before stay_date[@end] . You should provide also book_date[@start] |
book_time | Specifies the time window during which the promotion appears on Booking.com. | object | 0..1 | If you specify neither book_time[@start] nor book_time[@end] , then the promotion has no time restrictions. | |
book_time | start | Specifies the hour from which the promotion appears on Booking.com, in 24-hour time, in the property's timezone. | integer | 0..1 | Accepts: 0 –24 . |
book_time | end | Defines the hour after which the promotion no longer appears on Booking.com, in 24-hour time, in the property's timezone. | integer | 0..1 | Accepts: 0 –24 . |
stay_date | Specifies the date range in which the stay must take place in order for the promotion to apply. | object | 1..1 | - | |
stay_date | start | Defines the start of the stay days which the promotion will be applied on | date (YYYY-MM-DD) | 1..1 | Must be less than or equal to stay_date[@end] . |
stay_date | end | Defines the end of the stay days which the promotion will be applied until | date (YYYY-MM-DD) | 1..1 | Must be greater than or equal to stay_date[@start] . |
active_weekdays | Specifies the days of the week on which the promotion applies. | object | 0..1 | If you provide no active_weekday children, then the promotion applies to all days. | |
active_weekday | Specifies a day of the week on which the promotion applies. | string | 0..7 | Accepts: Sat , Sun , Mon , Tue , Wed , Thu , Fri . | |
excluded_dates | Specifies the date range (within the stay_date range) to which the promotion does not apply. | object | 0..1 | Number of days in the date range should not exceed 30 days. | |
excluded_dates | start | Specifies the first date of the date range (within the stay_date range) to which the promotion does not apply. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include excluded_dates[@end] . |
excluded_dates | end | Specifies the last date of the date range (within the stay_date range) to which the promotion does not apply. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include excluded_dates[@start] . |
excluded_date | Specifies an individual date (within the stay_date range) on which the promotion does not apply. | date (YYYY-MM-DD) | 0..* | - | |
additional_dates | Specifies the date range (outside the stay_date range) to which the promotion applies. | object | 0..1 | Number of days in the date range should not exceed 30 days. | |
additional_dates | start | Specifies the first date of the date range (outside the stay_date range) on which the promotion applies. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include additional_dates[@end] . |
additional_dates | end | Specifies the last date of the date range (outside the stay_date range) on which the promotion applies. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include additional_dates[@start] . |
additional_date | Specifies an individual date outside the stay_date range on which the promotion applies. | date (YYYY-MM-DD) | 0..* | - | |
rooms | - | object | 1..1 | - | |
room | - | object | 1..* | - | |
room | id | Specifies a room to which the promotion applies. | integer | 1..1 | The rooms must belong to the property you specified in hotel_id . |
parent_rates | - | array of parent_rate | 1..1 | Important: See the note about parent_rates. | |
parent_rate | - | object | 1..* | - | |
parent_rate | id | Specifies the rate to which the promotion must be applied. | integer | 1..1 | The rate must be active, and must belong to the property in hotel_id . Important: See the note about parent_rates. |
discount | - | object | 1..1 | - | |
discount | value | The percentage that will be deducted from the room price. | integer | 1..1 | Accepts: 1 –99 . |
Target promotions to specific audience
Booking.com has sunset the China channel for promotions on December 7, 2022. It is therefore no longer available or usable.
Use the target_channel
attribute to specify who can see the promotion. For promotion types other than geo_rate
and mobile_rate
, Booking.com supports the following values:
Type | Value | Description |
---|---|---|
One of the following: basic , last_minute , early_booker | public | All guests can see the promotion. |
One of the following: basic , last_minute , early_booker | subscribers | Only guests who subscribed to the Booking.com newsletter can see the promotion. |
Important note about parent_rates
The API will only apply a promotion to all rooms and rates in your request that are connected through existing roomrates. It will not create a new roomrate if a room isn't connected to every rate, or vice versa.
Take the following example. Earlier, you sent two OTA_HotelProductNotif requests to create products with these room/rate combinations:
Product A | Product B | |
---|---|---|
Room IDs | 0 | 0 1 |
Rate IDs | 10 | 11 12 |
Then, you sent a promotions requests containing these lines:
<rooms> <room id="0"/> <room id="1"/> </rooms> <parent_rates> <parent_rate id="10"/> <parent_rate id="11"/> <parent_rate id="12"/> </parent_rates>
The request will be successful, but the API will ignore the combination of room 1
and rate 10
, because there is no product connecting them.
Sample response
<promotions> <id>TB449324213596220037</id> </promotions> <!-- RUID: [...] -->
If your request is successful, the API returns the ID of the newly created promotion. You must specify this ID when editing the promotion.
Response body parameters
Element | Attribute | Description | Type | Notes |
---|---|---|---|---|
id | The updated promotion ID. | string | During subsequent updates the id remains the same. |
Creating a last minute promotion
Use this promotion type to attract last-minute bookers. This promotion type may help sell leftover rooms, max out your occupancy, and increase your visibility on mobile devices.
Sample request
The following request creates a last minute promotion:
<request> <hotel_id>12312</hotel_id> <promotion name="Winter Promotion" type="last_minute" target_channel="public" min_stay_through="3" non_refundable="0" no_cc_promotion="1"> <last_minute unit="hour" value="5"/> <book_time start="11" end="13" /> <stay_date start="2024-06-06" end="2024-06-29"> <active_weekdays> <active_weekday>Thu</active_weekday> </active_weekdays> <excluded_dates> <excluded_date>2024-06-15</excluded_date> <excluded_date>2024-06-16</excluded_date> </excluded_dates> </stay_date> <additional_dates> <additional_date>2024-07-18</additional_date> <additional_date>2024-07-20</additional_date> </additional_dates> <rooms> <room id="1423432"/> <room id="325436"/> </rooms> <parent_rates> <parent_rate id="756878"/> <parent_rate id="543754"/> </parent_rates> <discount value="10" /> </promotion> </request>
Request body parameters
The parameters for creating a last minute promotion are similar to creating a basic promotion type, except for the following:
Element | Attribute | Description | Type | Occurrences | Notes |
---|---|---|---|---|---|
promotion | type | The type of promotion. | string | 1..1 | Should be last_minute . |
last_minute | Specifies the unit and value of time before guests check-in during which the promotion applies. | object | 1..1 | See the example below. | |
last_minute | unit | The unit of time specified in days or hours. | string | 1..1 | Accepts: hour , day . To create promotions that are available only at the very last hour, use the hour value. |
last_minute | value | The amount of time (in days or hours) before guests check-in during which the promotion applies. | integer | 1..1 | Specify: 1 and higher. If the value is set to 0 , irrespective of the value set in unit , the API creates a last minimum promotion effective 3 days and fewer. |
book_date | - | object | 0..0 | This field is not relevant to this promotion type. |
Last minute promotion type example
To create a last minute promotion for guests booking a stay within 2 days or fewer before their intended check-in, use these values:
<last_minute unit="day" value="2"/>
This promotion is applied only when a guest books a stay two days or fewer before their intended check-in. This promotion is even applicable if a guest books a stay as close as 1 minute prior to their check-in.
Sample response
See sample response for basic promotion.
Response body parameters
Element | Attribute | Description | Type | Notes |
---|---|---|---|---|
id | The promotion ID. | string | When you create a promotion for the first time, the API generates a promotion id . During subsequent updates the id remains the same. |
Creating an early booker promotion
Use this promotion type to attract early bookers. This promotion may help fill the property's low-season rooms early.
Sample request
The following request creates an early booker promotion:
<request> <hotel_id>12312</hotel_id> <promotion name="Off-season Promotion" type="early_booker" target_channel="public" min_stay_through="3" non_refundable="0" no_cc_promotion="1"> <early_booker value="15" /> <book_time start="11" end="13" /> <stay_date start="2024-06-06" end="2024-06-29"> <active_weekdays> <active_weekday>Thu</active_weekday> </active_weekdays> <excluded_dates> <excluded_date>2024-06-15</excluded_date> <excluded_date>2024-06-16</excluded_date> </excluded_dates> </stay_date> <additional_dates> <additional_date>2024-07-18</additional_date> <additional_date>2024-07-20</additional_date> </additional_dates> <rooms> <room id="1423432"/> <room id="325436"/> </rooms> <parent_rates> <parent_rate id="756878"/> <parent_rate id="543754"/> </parent_rates> <discount value="10" /> </promotion> </request>
Request body
The fields for an Early booker promotion are the same as for a basic promotion, except for the following:
Element | Attribute | Description | Type | Occurrences | Notes |
---|---|---|---|---|---|
promotion | type | Type of the promotion. | string | 1..1 | Should be early_booker . |
early_booker | - | object | 1..1 | - | |
early_booker | value | The number of days guests must book in advance to get the discount from this promotion. | integer | 1..1 | - |
book_date | - | object | 0..0 | This field is not relevant to this promotion type. |
The early_booker[@value]
number counts backwards, in days, from the stay_date start
. Ensure the number you specify is not larger than the difference between stay_date start
and the day you created the promotion.
For example, creating an early booker promotion for stay_date start="2021-06-01"
on 2021-05-17 with early_booker value="20"
returns an error, because counting backwards from stay_date start
with that number of days passes the creation date.
Creating a geo rate promotion
A geo rate promotion is a special, discounted rate that is only offered to customers from a specific region. Geo rate promotions are available to all customers from certain markets, and apply to all room types, rates and dates except those that were specifically excluded. The lower price and special tag on search results might help increase the property's visibility and ultimately earn more bookings.
Sample request
The following request creates a geo rate promotion:
<request> <hotel_id>12312</hotel_id> <promotion type="geo_rate" target_channel="india_pos"> <stay_date> <excluded_dates> <excluded_date>2024-06-15</excluded_date> <excluded_date>2024-06-16</excluded_date> </excluded_dates> </stay_date> <discount value="15" /> </promotion> </request>
Request body
Element | Attribute | Description | Type | Occurrences | Notes |
---|---|---|---|---|---|
promotion | type | Type of the promotion. | string | 1..1 | Should be geo_rate . |
promotion | target_channel | Determines who can see the promotion. | string | 0..1 | To get a list of target_channel values, use the /xml/getpromotionchannels endpoint. Not all properties are eligible to use all target channels. |
discount | - | object | 1..1 | - | |
discount | value | The percentage that will be deducted from the room price. | integer | 1..1 | Accepts: 5 –30 . |
excluded_dates | Specifies the date range to which the promotion does not apply. | object | 0..1 | Number of days in the date range should not exceed 30 days. | |
excluded_dates | start | Specifies the first date of the date range to which the promotion does not apply. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include excluded_dates[@end] . |
excluded_dates | end | Specifies the last date of the date range to which the promotion does not apply. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include excluded_dates[@start] . |
excluded_date | Specifies an individual date on which the promotion does not apply. | date (YYYY-MM-DD) | 0..* | - |
Creating a mobile rate promotion
Use the mobile rate promotion to offer a discounted rate to guests who book through the mobile app, and/or through mobile or tablet browsers.
Properties can choose to provide a discount for guests who book through:
- An app. For example, guests booking (only) through the Booking.com mobile app can get this discount.
- A mobile or tablet browser. For example, guests booking through the Booking.com website using their mobile browser can get this discount.
If you create mobile rate promotions without specifying a target_channel
, by default, the API selects the app
only option.
Sample request
This request creates a mobile rate promotion:
<request> <hotel_id>12312</hotel_id> <promotion type="mobile_rate" target_channel="app"> <stay_date> <excluded_dates> <excluded_date>2024-06-15</excluded_date> <excluded_date>2024-06-16</excluded_date> </excluded_dates> </stay_date> <discount value="15" /> </promotion> </request>
Request body
Element | Attribute | Description | Type | Occurrences | Notes |
---|---|---|---|---|---|
promotion | type | Type of the promotion. | string | 1..1 | You must specify mobile_rate here. |
promotion | target_channel | Determines the platform from which the user can see the promotion. | string | 0..1 | Accepts: app , all . 'all' means app + mobile + tablet browser. For example, all includes guests who book through the Booking.com website using their mobile browser. |
discount | - | object | 1..1 | - | |
discount | value | The percentage that will be deducted from the room price. | integer | 1..1 | Accepts: 10 –80 . This means that you cannot send discounts less than 10% and more than 80%. |
excluded_dates | Specifies the date range to which the promotion does not apply. | object | 0..1 | Number of days in the date range should not exceed 30 days. | |
excluded_dates | start | Specifies the first date of the date range to which the promotion does not apply. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include excluded_dates[@end] . |
excluded_dates | end | Specifies the last date of the date range to which the promotion does not apply. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include excluded_dates[@start] . |
excluded_date | Specifies an individual date on which the promotion does not apply. | date (YYYY-MM-DD) | 0..* | - |
Sample response
See sample response for basic promotion.
Updating a promotion
POST
https://supply-xml.booking.com/hotels/xml/promotions
You can update a promotion by including the promotion id
in the request body and specifying only the fields that need to be updated.
On successful update, the promotion is marked as active irrespective of the previous status.
💡 Remember that promotions with stay dates in the past are not bookable, even though they are still active. However, you can update the promotion with future dates to make it bookable again.
Every successful promotion update returns the same promotion ID. You can use the same id
in the subsequent calls.
Sample request 1
The following example shows how to update the min_stay_through
field for an existing promotion.
<request> <hotel_id>12312</hotel_id> <promotion id="TB210380259622003780" min_stay_through="3"> </promotion> </request>
Sample response 1
<promotions> <id>TB210454585596220037</id> </promotions> <!-- RUID: [...] -->
Sample request 2
The following example shows how to remove optional fields like (book_date
, book_time
, active_weekdays
, excluded_dates
, ....)
<request> ... <promotion ... target_channel="public" min_stay_through="0" non_refundable="0" no_cc_promotion="0"> <book_date/> <book_time/> <active_weekdays/> <excluded_dates/> <additional_dates/> ... </promotion> </request>
Activating a promotion
POST
https://supply-xml.booking.com/hotels/xml/promotions
Use this section to activate a deactivated promotion.
Whenever you create or update a promotion, by default, the API marks the promotion as active irrespective of whether the bookable/stay dates are current or in the past. To make a promotion unavailable for guest's use, make sure to deactivate the promotion.
Sample request
The following request uses the promotion's id
to activate the promotion.
<request> <hotel_id>12312</hotel_id> <promotion id="TB210454585"> </promotion> </request>
Sample response
<promotions> <id>TB210454585</id> </promotions> <!-- RUID: [...] -->
Deactivating a promotion
DELETE https://supply-xml.booking.com/hotels/xml/promotions?id={promotionID}&hotel_id={hotelID}
To deactivate a promotion, send a DELETE
request including the promotion ID and property ID.
Irrespective of the promotion's active status, after a successful update, the API marks the promotion as active by default.
Query parameters
Element | Description | Type | Required/Optional | Notes |
---|---|---|---|---|
id | Specify the promotion ID to deactivate. | string | required | To get a list of promotions along with their ID s, see Retrieve details about existing promotions. |
hotel_id | Specify the ID of the property to which the promotion applies. | string | required | You must have permission to edit the property. |
Sample response
<promotions> <id>TB210454585</id> </promotions> <!-- RUID: [...] -->
Troubleshooting errors and warnings in response
This section covers the most commonly encountered error and warning responses when calling the Promotions API.
Schema validation errors
HTTP/1.1 400 Bad Request
<promotions> <fault code="400"> <string>code= 1824 level= 2 message= Element 'stay_date', attribute 'start': '2024-06-0' is not a valid value of the atomic type 'xs:date'. </string> <string>code= 1824 level= 2 message= Element 'promotion', attribute 'id': '2wef' is not a valid value of the atomic type 'xs:integer'. </string> </fault> </promotions> <!-- RUID: [...] -->
Invalid ID
HTTP/1.1 403 Forbidden
<promotions> <fault code="1009"> <string>Access denied for hotel '23543'</string> </fault> </promotions> <!-- RUID: [...] -->
HTTP/1.1 400 Bad Request
<promotions> <fault code="400"> <string>Invalid Room id= 124324</string> <string>Invalid Room id= 34645</string> </fault> </promotions> <!-- RUID: [...] -->
Warnings
Sometimes a promotion is created even when there is invalid data in the input. The invalid data is filtered and sent back as a warning in the response.
<promotions> <id>TB222200159622003729</id> <warnings> <warning>The promotion could not be applied to these dates: 2024-05-03, 2024-05-04. The reason is that these dates are earlier than book_date[@start] (2024-05-05).</warning> </warnings> </promotions> <!-- RUID: [...] -->