# Managing promotions

Use the Promotions API to create and manage promotions for an individual property.

Use the `promotions` endpoint to:

- [Create a promotion](#creating-promotions) by choosing from different [promotion types](#what-are-promotion-types)
- [Update a promotion](#updating-a-promotion) to make changes to an existing promotion
- [Activate](#activating-a-promotion) a promotion that was previously deactivated. Newly created and updated promotions are active by default
- [Deactivate](#deactivating-a-promotion) a promotion if you no longer want it to be bookable


Active promotions with book/stay dates in the past
If all of a promotion's active stay dates have passed and there are no upcoming stay dates, the promotion is marked as 'Active' but it is not bookable. Update the promotion and add upcoming stay dates to make it bookable again.

This topic also provides a [UI/UX recommendations](#uiux-recommendations) for creating promotions.

## What are promotion types?

Each promotion type has a distinct way to attract customers and drive occupancy and revenue, by allowing you to be more price competitive on Booking.com for specific audiences and periods.

- Basic deal: Fully customisable to suit your specific needs
- Last-minute deal: A discount only available when booked closer to check-in – to help fill any empty rooms you have left
- Early booker deal: A discount only available when booking long before check-in – to be better prepared with more bookings made earlier
- Campaign deal: A seasonal sales event, with fixed bookable dates and stay dates. Properties offer a minimum discount (or more) and in exchange receive extra visibility from emails, push notifications, affiliate sites, graphics and landing pages on Booking.com and more, for the duration of the promotion
- Country rate: A discount only available to customers booking from a specific country or region. Booking.com supports a list of [predefined geolocations](#supported-geolocations)
- Mobile rate: A device-specific discount only available to customers booking from a mobile device (mobile web or the Booking.com app)
- New property deal: A 20% discount for new properties to help secure the first few bookings. The deal automatically ends after three bookings or 90 days, whichever comes first


## Promotion details

Depending on the promotion type, you can select (among other things):

- Dates the promotion can be booked
- Specific time of day the promotion can be booked
- Stay dates
- Room types
- Rate plans the promotion will base its discount on
- How many days (or hours) before check-in a guest can receive a last-minute discount
- How many days in advance a guest must book to receive an early booker discount
- Specific regions and countries you offer the discount to
- Mobile device-specific discounts


For promotion types other than `geo_rate` and `mobile_rate`, you can also choose whether the promotion is available to [all guests, or only certain guests](#creating-a-country-rate).

## Creating promotions


```http
POST
https://supply-xml.booking.com/hotels/xml/promotions
```

When creating a promotion, the mandatory list of request parameters varies depending on the promotion type. The following subsections help you create promotions using the various promotion types:

- [Creating a basic deal.](#creating-a-basic-deal)
- [Creating a last-minute deal.](#creating-a-last-minute-deal)
- [Creating an early booker deal.](#creating-an-early-booker-deal)
- [Creating a campaign deal.](#creating-a-campaign-deal)
- [Creating a country rate.](#creating-a-country-rate)
- [Creating a mobile rate](#creating-a-mobile-rate)
- [Creating a new property deal](#creating-a-new-property-deal)


All newly created or updated promotions are marked as active
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 deal

Use this promotion type to create a fully customisable promotion and specify a discount on selected rooms and the original rate plan.

### Sample request

The following request creates a basic deal:


```xml
<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 255 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`. Selecting `0` means that the promotion will have the same minimum length of stay (MLOS) as its chosen rate plan(s). Selecting `1` means there is no MLOS for this promotion. Selecting `2-7` means the guest needs to stay at least that number of nights to get the promotion. |
| `promotion` | `non_refundable` | The guest won't receive any refund if they cancel. | boolean | 0..1 | Accepts: `1` (non-refundable), `0` (refundable). Default: `0` |
| `book_date` |  | The date range the promotion will appear on Booking.com. | - | 0..1 | If you don't specify `book_date[@start]` and `book_date[@end]`, the promotion has no date restrictions. |
| `book_date` | `start` | The first date the promotion is available. | date (YYYY-MM-DD) | 0..1 | Default: empty. `book_date[@start]` must be before `book_date[@end]`. You should also specify book_date[@end]. |
| `book_date` | `end` | The last date 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 also specify book_date[@start]. |
| `book_time` |  | The times of day (on dates specified in `book_date`) the promotion appears on Booking.com, in 24-hour format, in the property's timezone. | object | 0..1 | If you don't specify `book_time[@start]` and/or `book_time[@end]`, the promotion won't have any time of day restrictions. |
| `book_time` | `start` | The time of day (on dates specified in `book_date`) the promotion will appear on Booking.com, in 24-hour format, in the property's timezone. | integer | 0..1 | Accepts: `0`–`24`. |
| `book_time` | `end` | The time of day (on dates specified in `book_date`) the promotion will no longer appear on Booking.com, in 24-hour format, in the property's timezone. | integer | 0..1 | Accepts: `0`–`24`. |
| `stay_date` |  | The range of dates during which guests must stay at the property to receive the promotion. | object | 1..1 | - |
| `stay_date` | `start` | The first date of the range during which guests must stay at the property to receive the promotion. | date (YYYY-MM-DD) | 1..1 | Must be less than or equal to `stay_date[@end]`. |
| `stay_date` | `end` | The last date of the range during which guests must stay at the property to receive the promotion. | date (YYYY-MM-DD) | 1..1 | Must be greater than or equal to `stay_date[@start]`. |
| `active_weekdays` |  | The days of the week (within the `stay_date` range) the guest must be staying at the property to receive the promotion. | object | 0..1 | If you provide no `active_weekday`, the promotion applies to all days of the week. |
| `active_weekday` |  | A specific day of the week (within the `stay_date` range) the guest must be staying at the property to receive the promotion. | string | 0..7 | Accepts: `Sat`, `Sun`, `Mon`, `Tue`, `Wed`, `Thu`, `Fri`. |
| `excluded_dates` |  | A range of dates (within the `stay_date` range) during which guests staying at the property will **not** receive the promotion. | object | 0..1 |  |
| `excluded_dates` | `start` | The first date of the range (within the `stay_date` range) during which guests staying at the property will **not** receive the promotion. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include `excluded_dates[@end]`. |
| `excluded_dates` | `end` | The last date of the range (within the `stay_date` range) during which guests staying at the property will **not** receive the promotion. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include `excluded_dates[@start]`. |
| `excluded_date` |  | A specific date (within the `stay_date` range) during which guests staying at the property will **not** receive the promotion. | date (YYYY-MM-DD) | 0..* | - |
| `additional_dates` |  | A date range (outside the `stay_date` range) when guests staying at the property would receive the promotion. | object | 0..1 |  |
| `additional_dates` | `start` | The first date of a range (outside the `stay_date` range) when guests staying at the property would receive the promotion. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include `additional_dates[@end]`. |
| `additional_dates` | `end` | The last date of a range (outside the `stay_date` range) when guests staying at the property would receive the promotion. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include `additional_dates[@start]`. |
| `additional_date` |  | An individual date (outside the `stay_date` range) when guests staying at the property would receive the promotion. | date (YYYY-MM-DD) | 0..* | - |
| `rooms` |  | - | object | 1..1 | - |
| `room` |  | - | object | 1..* | - |
| `room` | `id` | A room type the promotion applies to. | 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](#important-note-about-parent_rates). |
| `parent_rate` |  | - | object | 1..* | - |
| `parent_rate` | `id` | The original rate the promotion is discounted from. | integer | 1..1 | The rate must be active, and must belong to the property in `hotel_id`. **Important:** See the [note about parent_rates](#important-note-about-parent_rates). |
| `discount` |  | - | object | 1..1 | - |
| `discount` | `value` | The percentage discounted from the parent_rate. | integer | 1..1 | Accepts: `1`–`99`. **Note:** If you use `target_channel="subscribers"` then the acceptable range is `10`-`99`. |


####  Target promotions to specific audience

Use the `target_channel` attribute to specify who can see the promotion. For promotion types `basic`, `last_minute` and `early_booker`, 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 Promotions API will apply a promotion to all rooms and rates specified in your request only if all rooms in the request are connected to all rates in the request. It will not create new roomrates.

Take the following example. Earlier, you sent two [OTA_HotelProductNotif](/connectivity/docs/room-type-and-rate-plan-management/managing-roomrates) 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:


```xml
<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


```xml
<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 deal

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 deal:


```xml
<request>
   <hotel_id>12312</hotel_id>
    <promotion
        name="Winter Promotion"
        type="last_minute"
        target_channel="public"
        non_refundable="0"
        min_stay_through="3">
        <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 deal are similar to creating a [basic deal](/connectivity/docs/b_xml-promotions#basic_deal), 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` |  | A promotion that can only be booked a specific number of days or hours before check-in. | object | 1..1 | See the [example](/connectivity/docs/b_xml-promotions#last-minute-promotion-type-example) below. |
| `last_minute` | `unit` | The unit of measurement (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 maximum amount of time (in days or hours) before check-in the promotion can be booked. | 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 deal with a bookable period of 3 days and less. |
| `book_date` |  | - | object | 0..0 | This field is not relevant to this promotion type. |


####  Last-minute deal type example

To create a last-minute deal for guests booking a stay within 2 days or fewer before their intended check-in, use these values:


```xml
<last_minute unit="day" value="2"/>
```

This promotion is only applied when a guest books two days or fewer before their intended check-in. The promotion is active from 2 days before check-in until 1 minute before check-in.

### Sample response

See [sample response for basic deal](/connectivity/docs/b_xml-promotions#sample-response).

### 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 deal

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 deal:


```xml
<request>
   <hotel_id>12312</hotel_id>
    <promotion
        name="Off-season Deal"
        type="early_booker"
        target_channel="public"
        non_refundable="0"
        min_stay_through="3">
        <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 deal are the same as for a [basic deal](/connectivity/docs/b_xml-promotions#basic_deal), 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 minimum number of days in advance guests must book to receive the promotion. | integer | 1..1 | - |
| `book_date` |  | - | object | 0..0 | This field is not relevant to this promotion type. |


Promotion cannot start in the past.
The `early_booker[@value]` number counts backwards, in days, from `stay_date start`. Make sure the number you specify isn't larger than the difference between `stay_date start` and the day you created the promotion.  For example, creating an early booker deal for `stay_date start="2025-06-01"` on 2025-05-17 with `early_booker value="20"` returns an error, because counting backwards from `stay_date start` by that number of days passes the creation date.

### Creating a campaign deal

Get extra visibility from emails, push notifications, affiliate websites, visuals on Booking.com and more, for the duration of any campaign you join.

Unlike other types of promotions, Marketing Campaigns must respect certain restrictions to be created (otherwise the creation requests will fail) and those restrictions are pertinent to each individual campaign. They are:

- Black Friday Deal
- Early Year Deal
- Getaway Deal
- Late Escape Deal


One more particularity about the Marketing Campaigns in relation to the other products is that you can only create promotions of those types during the respective campaign sourcing period. It's also not possible to edit restrictions on a marketing campaign promotion once it's created (but you can always deactivate undesired promotions and create new ones).

### Sample request

The following request creates a campaign deal for a specific campaign — in this example, a Black Friday Deal:


```xml
<request>
   <hotel_id>12312</hotel_id>
    <promotion
        name="Black Friday Deal"
        type="campaign_black_friday">
        <stay_date start="2025-08-16" end="2026-08-16">
            <active_weekdays>
               <active_weekday>Mon</active_weekday>
               <active_weekday>Tue</active_weekday>
               <active_weekday>Wed</active_weekday>
               <active_weekday>Thu</active_weekday>
           </active_weekdays>
            <excluded_dates>
                <excluded_date>2025-08-20</excluded_date>
                <excluded_date>2025-08-21</excluded_date>
            </excluded_dates>
        </stay_date>
        <additional_dates>
            <additional_date>2026-08-20</additional_date>
            <additional_date>2026-08-21</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="30" />
    </promotion>
</request>
```

### Request body parameters

The parameters for creating a campaign deal are similar to creating a [basic deal](/connectivity/docs/b_xml-promotions#basic_deal), except for the following:

| Element | Attribute | Description | Type | Occurrences | Notes |
|  --- | --- | --- | --- | --- | --- |
| `promotion` | `type` | The type of promotion. | string | 1..1 | Should be one of the following: `campaign_black_friday`, `campaign_early_year`, `campaign_getaway` or `campaign_late_escape`. |
| `promotion` | `target_channel` | - | string | 0..0 | This field is not relevant to this promotion type. |
| `promotion` | `min_stay_through` | - | integer | 0..0 | This field is not relevant to this promotion type. |
| `promotion` | `non_refundable` | - | boolean | 0..0 | This field is not relevant to this promotion type. |
| `book_date` |  | - | object | 0..0 | For campaign deals, bookable dates are pre-defined and cannot be changed, so this field is not relevant. |
| `book_times` |  | - | object | 0..0 | This field is not relevant to this promotion type. |


Minimum discount required:
Different campaigns have different minimum discount requirements to be accepted. At the moment, the minimum discount needed for the promotions are:

- Getaway Deal: 15% or more
- Late Escape Deal: 15% or more
- Early Year Deal: 15% or more
- Black Friday Deal: 30% or more


 Stay dates must be between the campaign's first and last stay date
**Stay dates restrictions:** Any stay dates included in a marketing campaign promotion have to be inside the campaign's “stay window”.

**Book dates restrictions:** For marketing campaign promotions, book dates are pre-defined and cannot be overwritten or changed. They will be automatically filled based on the promotion type and don't need to be included in the promotion creation requests.

### Sample response

See [sample response for basic deal](/connectivity/docs/b_xml-promotions#sample-response).

### 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 a country rate

A country rate is a special, discounted rate that is only offered to customers from a specific region.

They are available to all customers from included regions, and apply to all room types, rates and dates except any which are specifically excluded. The discounted price can help to reach customers and increase revenue and bookings from a specific location.

### Sample request

The following request creates a country rate promotion:


```xml
<request>
    <hotel_id>12312</hotel_id>
    <promotion
        type="geo_rate"
        target_channel="india_pos"
        min_stay_through="3">
        <stay_date>
            <excluded_dates>
                <excluded_date>2024-06-15</excluded_date>
                <excluded_date>2024-06-16</excluded_date>
            </excluded_dates>
        </stay_date>
        <parent_rates>
            <parent_rate id="756878"/>
            <parent_rate id="543754"/>
        </parent_rates>
        <early_booker value="15" />
        <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](/connectivity/docs/b_xml-getpromotionchannels/#retrieving-promotion-channels) endpoint. Not all properties are eligible to use all target channels. |
| `promotion` | `min_stay_through` | The minimum number of nights a guest must stay to be eligible for the promotion. | integer | 0..1 | Accepts: 1–30. |
| `discount` |  | - | object | 1..1 | - |
| `discount` | `value` | The percentage that will be deducted from the parent_rate. | integer | 1..1 | Accepts: `5`–`30`. |
| `excluded_dates` |  | A range of dates during which guests staying at the property will **not** receive the promotion. | object | 0..1 |  |
| `excluded_dates` | `start` | The first date of the range during which guests staying at the property will **not** receive the promotion. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include `excluded_dates[@end]`. |
| `excluded_dates` | `end` | The final date of the range during which guests staying at the property will **not** receive the promotion. | date (YYYY-MM-DD) | 0..1 | If you include this attribute, you must also include `excluded_dates[@start]`. |
| `excluded_date` |  | An individual date on which the promotion does **not** apply. | date (YYYY-MM-DD) | 0..* | - |
| `parent_rates` |  | - | array of `parent_rate` | 1..1 | - |
| `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 specified in `hotel_id`. |
| `early_booker` |  | - | object | 1..1 | Can not be used together with `last_minute` |
| `early_booker` | `value` | The number of days guests must book in advance to get the discount from this promotion. | integer | 1..1 | Accepts: 1–365. |
| `last_minute` |  | Specifies the unit and value of time before guests check-in during which the promotion applies. | object | 1..1 | Can not be used together with `early_booker` |
| `last_minute` | `unit` | The unit of time specified in days or hours. | string | 1..1 | Accepts: `day`. |
| `last_minute` | `value` | The amount of time (in days) before guests check-in during which the promotion applies. | integer | 1..1 | Accepts: 1–365. |


###  Creating a mobile rate:

Use a mobile rate to offer a discounted price to guests who book through the Booking.com Android or iOS mobile app, or from a mobile phone or tablet browser.

Using the `target_channel` `app` means guests booking (only) through the Booking.com mobile app can get this discount.

Using the `target_channel` `all` means guests booking through the Booking.com mobile app as well as guests booking through the Booking.com website using a mobile device can get this discount.

If you create mobile rates without specifying `target_channel`, by default, the API selects the `app` option.

### Sample request

This request creates an app-only mobile rate:


```xml
<request>
    <hotel_id>12312</hotel_id>
    <promotion
        type="mobile_rate"
        target_channel="app"
        min_stay_through="3">
        <stay_date>
            <excluded_dates>
                <excluded_date>2024-06-15</excluded_date>
                <excluded_date>2024-06-16</excluded_date>
            </excluded_dates>
        </stay_date>
        <parent_rates>
            <parent_rate id="756878"/>
            <parent_rate id="543754"/>
        </parent_rates>
        <last_minute unit="day" value="5"/>
        <discount value="15" />
    </promotion>
</request>
```

### Request body

| Element | Attribute | Description | Type | Occurrences | Notes |
|  --- | --- | --- | --- | --- | --- |
| `promotion` | `type` | Type of promotion. | string | 1..1 | You must specify `mobile_rate` here. |
| `promotion` | `target_channel` | The platform(s) where the customer can book the promotion. | string | 0..1 | Accepts: `app`, `all`. 'all' means app + mobile browser + tablet browser. For example, `all` includes guests who book through the Booking.com website using their mobile browser. |
| `promotion` | `min_stay_through` | The minimum number of nights a guest must stay to be eligible for the promotion. | integer | 0..1 | Accepts: 1–30. |
| `discount` |  | - | object | 1..1 | - |
| `discount` | `value` | The percentage that will be deducted from the original price. | integer | 1..1 | Accepts: `10`–`80`. You can't discount less than 10% or more than 80%. |
| `excluded_dates` |  | The date range the promotion does **not** apply. | object | 0..1 |  |
| `excluded_dates` | `start` | The first date of a range 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` | The last date of a range 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` |  | A specific date the promotion does **not** apply. | date (YYYY-MM-DD) | 0..* | - |
| `parent_rates` |  | - | array of `parent_rate` | 1..1 | - |
| `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 specified in `hotel_id`. |
| `early_booker` |  | - | object | 1..1 | Can not be used together with `last_minute` |
| `early_booker` | `value` | The number of days guests must book in advance to get the discount from this promotion. | integer | 1..1 | Accepts: 1–365. |
| `last_minute` |  | Specifies the unit and value of time before guests check-in during which the promotion applies. | object | 1..1 | Can not be used together with `early_booker` |
| `last_minute` | `unit` | The unit of time specified in days or hours. | string | 1..1 | Accepts: `day`. |
| `last_minute` | `value` | The amount of time (in days) before guests check-in during which the promotion applies. | integer | 1..1 | Accepts: 1–365. |


### Sample response

See [sample response for basic deal](/connectivity/docs/b_xml-promotions#sample-response).

### Creating a new property deal

By offering a new property deal, you incentivise guests to book with a 20% discount. The property incurs the cost of this discount. The sooner the property opts in, the faster it can increase bookings, gain guest reviews, and get review scores that attract potential guests.

Unlike other promotion types, this deal requires no setup for specific room types, rate plans, or date ranges. Once created, the discount applies to all rooms and rates automatically.

Automatic deactivation
The new property deal automatically ends after **three bookings** or **90 days**, whichever occurs first. The price then reverts to the original rate. The deal can also be turned off at any time. See [deactivating a promotion.](/connectivity/docs/b_xml-promotions#deactivating-a-promotion)

### Sample request

The following request creates a New Property Deal:


```xml
<request>
   <hotel_id>12312</hotel_id>
    <promotion
        type="new_property_deal">
    </promotion>
</request>
```

### Request body parameters

| 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` | `type` | The type of promotion. | string | 1..1 | Must be `new_property_deal`. |


Eligibility
New property deals are available for properties that meet the following conditions:

- The property has been open and bookable on Booking.com for less than 12 months
- The property has no reservations yet


### Sample response

See [sample response for basic deal](/connectivity/docs/b_xml-promotions#sample-response).

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


## Updating a promotion


```http
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. However, when updating the `additional_dates` parameter, you must also provide the `stay_date` field in the request. Make sure to specify `additional_dates` outside the `stay_date` range. For example, the dates must fall:

- prior to the stay date, or
- after the stay date


If the dates provided in `additional_dates` are within the `stay_date` range, the API returns the following `HTTP 400` error: `<promotions><faults><error code="STAY_DATE_INVALID">Invalid value for stay_date</error>`

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 if they are still active. Update the promotion and add stay dates in the future to make it bookable.

Every update returns the same promotion ID
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.


```xml
<request>
  <hotel_id>12312</hotel_id>
  <promotion
    id="TB210380259622003780"
    min_stay_through="3">
  </promotion>
</request>
```

### Sample response 1


```xml
<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`, ....) but add additional_dates


```xml
<request>
  ...
  <promotion
    ...
    target_channel="public"
    non_refundable="0"
    min_stay_through="0">
    <book_date/>
    <book_time/>
    <active_weekdays/>
    <excluded_dates/>
    <stay_date start="2026-06-13" end="2028-10-30">
        </stay_date>
    <additional_dates>
            <additional_date>2028-11-15</additional_date>
            <additional_date>2028-11-16</additional_date>
    </additional_dates>
    ...
  </promotion>
</request>
```

## Activating a promotion


```http
POST
https://supply-xml.booking.com/hotels/xml/promotions
```

Use this section to activate a deactivated promotion.

All newly created or updated promotions are marked as active
Whenever you create or update a promotion, by default, the API marks the promotion as active, whether its book/stay dates are current or in the past. To make a promotion unbookable, make sure to [deactivate the promotion](#deactivating-a-promotion).

### Sample request

The following request uses the promotion's `id` to activate the promotion.


```xml
<request>
    <hotel_id>12312</hotel_id>
     <promotion 
         id="TB210454585">
     </promotion>
 </request>
```

### Sample response


```xml
<promotions>
    <id>TB210454585</id>
</promotions>
<!-- RUID: [...] -->
```

## Deactivating a promotion


```https
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.

After a successful promotion update, the promotion is marked as active
Whether or not it's active, after a successful update the API will mark the promotion as active.

### Query parameters

| Element | Description | Type | Required/Optional | Notes |
|  --- | --- | --- | --- | --- |
| `id` | Enter the promotion ID to deactivate. | string | required | To get a list of promotions along with their `ID`s, see [Retrieve details about existing promotions.](/connectivity/docs/b_xml-getpromotions) |
| `hotel_id` | Enter the ID of the property the promotion applies to. | string | required | You must have permission to edit the property. |


### Sample response


```xml
<promotions>
    <id>TB210454585</id>
</promotions>
<!-- RUID: [...] -->
```

## UI/UX recommendations

When implementing forms for creating promotions we recommend keeping a consistent design across different input types, only changing what’s needed to support different data or to make the field easier to understand and complete.

Here is an example of a simple design using a card for each input type:

![Managing promotions form example 1](/assets/managing_promotions_1.e5d76a20594e196376489fba2a5e1034d6fb395563c2ac749ab34083bf969d15.5cba86b9.png)

Keep things as simple as possible. Showing too much information or too many fields at one time can quickly become overwhelming. For more complex fields, only show additional inputs as they are needed. This allows the form to remain as short and simple as possible.

In the next example the cards have both a “read-only” and an “edit” state. This allows us to display all relevant information without cluttering the form with additional inputs after they’ve been completed.

![Managing promotions form example 2](/assets/managing_promotions_2.ea5e45896593359caa4d3c5ffdfedb5a1e366a310a920794967b59c92f2f1537.5cba86b9.png)

Additional inputs can be shown as needed. For instance, in the above example the `<parent_rates>` option “select parent rates” has been selected, revealing the additional checklist of all rate plans below. However, for the `<rooms>` option there is no secondary checklist as the “all rooms” option has been selected.

### Date inputs

Date range / specific date selection fields are some of the more complicated inputs for these forms. These inputs need to be able to support date ranges (`<book_date>` & `<stay_date>`) and specific dates (`<excluded_dates>` & `<additional dates>`), as well as allow selection of `<active_weekdays>`.

![Managing promotions form example 3](/assets/managing_promotions_3.97be574bdc3a60c233e3fbbceb0f5799965c3cbca8c08e2f6deff9d572d92a41.5cba86b9.png)

This example is one possible implementation of the `<stay_date>` and `<additional_dates>` inputs. Here, stay dates is defined as a range with <active_weekdays> selected alongside it, while `<additional_dates>` are selected as individual dates in a calendar view.
The same date selection functionality can be used for selecting specific `<excluded_dates>` or for `<book_dates>` as a date range.

## Errors

For a complete list of error codes and possible solutions, see [Troubleshooting and list of error codes](/connectivity/docs/promotions-troubleshooting).