Best practices
When implementing the product management capability, be aware of the following best practices.
DO:
- Use Expedia Group IDs for units, rate plans, cancellation policies, and fee sets and rate plan IDs to identify the resources to be updated. Ensure that the correct Expedia Group IDs are accurately mapped in your implementation of the product management capability to make sure the right units, rate plans, cancellation policies, and fee sets are updated when the API sends updates.
- Use caution when sequencing messages to Expedia Group. Sending an older message after a newer message can overwrite current information with outdated data.
- Ensure monitoring is in place in the capability's implementation to validate the success rate of updates, including visibility into error details/messaging.
- Ensure error reports are reviewed and actioned by the appropriate team.
DON’T:
- Send create or update messages with the partner code in the URL.
- Create duplicates (units or rates with the codes that are already in use).
- Convert the pricing model of the active rates.
- Map the same value add inclusion on the unit and/or rate plan level.
- Attempt to modify property level amenities with this capability.
- When performing updates, do not send concurrent messages for the same entity (unit or rate plan). For example, do not send messages within milliseconds of the previous update.
- Ignore errors. These may signal connection issues or problems with your request.
Error monitoring
Ensure that monitoring is in place for the API implementation to capture detailed information on any errors that may occur. You may want to create alarms to notify you when the rate of errors returned by Expedia Group exceeds an acceptable threshold. Review errors frequently to ensure that units and rate plans are correct and that all updates are processed accurately. Failure to do so may result in Expedia Group travelers booking incorrect units or rate plans.
Retrieving property details
The property
query allows for the retrieval of several important settings related to a property's configuration in our system. Some of these settings will help you better understand how to manage unit and rate plan resources.
It also enables you to determine the properties that are assigned to your accounts. Refer to the property
query reference for a detailed example.
Maintaining units
Be aware that units can have multiple rate plans, but each rate plan ID can only belong to one unit. Also, note that for properties using the Expedia Traveler Preference (ETP) business model, standalone rates have two IDs - one for Expedia Collect and one for Hotel Collect. Hotel Collect rate plans always have an "A" at the end of the rate plan ID.
The mapping between a property's unit and rate plan IDs must be developed and maintained. This mapping is critical for sending updates because the Expedia ID must be specified, not the property’s codes. For example, if room code STD maps to a rate plan code BPK in your system, and unit ID 123 and unique rate plan 1093294 are mapped in our system, the link between unit STD/123 and rate plan BPK/1093294 should be preserved in your system.
When properties change their room or rate codes, or if new products to be created, the mapping of the property’s codes must be updated in your system to include our IDs to maintain successful communication of availability updates and booking notifications between you and Expedia Group.
Coding to the correct pricing model
When implementing this capability, make sure to develop the correct pricing models for your customers. Currently, Expedia Group offers several pricing models: occupancy-based pricing, per-day pricing, day-of-arrival pricing, and per-day length-of-stay pricing. For more details, see Pricing models.
Determining rate types
Expedia Group accepts receiving sell rate, net rate, or lowest available rate (LAR or Sell LAR) for rate updates. Rate acquisition type settings are confirmed at the property level and cannot be modified with this capability. Refer to Rate acquisition to learn more about the type of rate to send to Expedia Group. The rates sent must be in sync with the configuration in our system. Verify which type of rate is being used using the property
query.
Units and rate plans available for properties using the Expedia Traveler Preference business model are available to travelers with both the "pay now" at the time of booking (Expedia Collect) and "pay later" at the hotel (Hotel Collect) options.
Identifying a property's business model
To identify whether a property has Expedia Traveler Preference enabled, retrieve inventoryConfig : businessModels
using the property
query.
Identifying Expedia Traveler Preference rate plans
When properties opt into the program, at least one of their standalone rate plans must be enabled for the Expedia Traveler Preference program. This translates into having two different business models configured for each rate plan. For example, when retrieving a rate plan enabled for the program, something like this should be returned:
1-need example-
Creating Expedia Traveler Preference rate plans
When a property opts into the program, all its standalone rate plans must be enabled for Expedia Traveler Preference (ETP). The minimum information needed to create an Expedia Traveler Preference-enabled rate plan is 2 distribution rules, along with a partner code for each. The partner code doesn't have to be different between the Expedia Collect and Hotel Collect rules, but it has to be unique across all the rate plans under the unit it belongs to.
Example:
1{2 "distributionRules": [3 {4 "partnerCode": "A123",5 "distributionModel": "ExpediaCollect"6 },7 {8 "partnerCode": "D123",9 "distributionModel": "HotelCollect"10 }11 ]12}
This will create a rate plan with these 2 codes, and will default everything else.
If two distinct rate plans are used to support the Expedia Traveler Preference program, these will need to be combined into one rate plan creation request to Expedia Group. The codes for their Expedia Collect and Hotel Collect versions should be provided under the appropriate distribution rules. Then Expedia Group’s response is consumed and the returned Expedia rate plan IDs are mapped and returned (i.e. resource ID) as part of each distribution rule. These IDs will also be used to interpret booking messages or push availability/rate messages to Expedia Group.
Naming units
Because Expedia Group has points of sale in more than 45 languages and wants to offer the best experience to travelers around the world, and names must be received in a structured way to enable instant availability in all languages. Therefore, the API builds a unit's name from structured attributes. There are up to nine different attributes that can be used to build a name, which are specified by the CreateUnitNameAttributesInput
or UpdateUnitNameAttributesInput
input type of the createUnit
or updateUnit
mutations. However, because Expedia Group also has a constraint on room name length, not all attributes can be used all at once.
Expedia Group recommends that all the attributes that a property would like to be part of the name be provided. Expedia Group will then only use the ones deemed most relevant if too many attributes are received.
1nameConfig {2 attributes {3 accessibility {4 includeAccessibility5 accessibilityTypeOverride6 }7 bedroomDetails8 customLabel9 featuredAmenity10 includeBedType11 includeSmokingPolicy12 location13 unitClass14 unitType15 view16 }17}
If more control over unit names and which attributes get used is desired, refer to the table below indicating Expedia Group’s sets and the maximum number of attributes Expedia Group will use from each group.
Attribute name | Group | Optional | Explanation |
---|---|---|---|
unitType | - | No | Required and always used. |
unitClass | - | Yes | Always used in name if provided. |
includeBedType | Bedding | Yes | Part of a grouping of 2 elements. Only one of the two will be used if both are specified in this group. If the unit includes a vast array of bedding options (e.g. King, Queen, Twin and Sofa), Expedia Group defaults to "Multiple Beds" instead of listing each bed type in the room name, as it would exceed 100 character limitation. |
bedroomDetails | Bedding | Yes | Part of a grouping of 2 elements. Only one of the two will be used if both are specified in this group. |
includeSmokingPolicy | Key Features | Yes | Part of a grouping of 5 elements. Expedia Group will use a maximum of 2 attributes from this group. |
includeAccessibility | Key Features | Yes | Part of a grouping of 5 elements. Expedia Group will use a maximum of 2 attributes from this group. Indicates accessibility features for the room. |
view | Key Features | Yes | Part of a grouping of 5 elements. Expedia Group will use a maximum of 2 attributes from this group. |
featuredAmenity | Key Features | Yes | Part of a grouping of 5 elements. Expedia Group will use a maximum of 2 attributes from this group. |
location | Key Features | Yes | Part of a grouping of 5 elements. Expedia Group will use a maximum of 2 attributes from this group. |
customLabel | - | Yes | Always used in name if provided. Data type: string, 1-37 characters |
Cancellation policy
A cancellation policy is applicable when a guest wants to cancel a reservation or change a reservation that would cause the total amount of the initial reservation to be different from the total amount for the modified reservation. Changes impacting the reservation rate include: a change of unit, rate plan, occupancy or dates. See the CancelPolicy table for more detailed information.
Cancellation policy logic takes into account:
- Cancellation window or cancellation policy level, determined by the
cancellationWindow
attributes - Cancellation window penalties (cancellation policy level) starting with the window where the "deadline" is set to 0, up to three windows.
- Cancellation time (property level)
The logic is:
- Cancellation time at the property level determines at what time the cancellation window ends in hours.
- Cancellation window is counted from the date of the arrival backwards
- Depending on when the cancellation was performed, the applicable window applies.
Cancellation policy is defined at a property level and then can later be attached to any rate plan. When creating a new rate plan, it is mandatory to attach a cancellation policy. If provided, it is required to provide at least one default policy with one cancellation window in hours and a penalty.
When creating a cancellation policy, one to three default policies can be provided.
- At least one default policy must be provided, with a cutoff greater than 0. This will determine the number of hours before the check-in date to which this policy applies.
- In addition to the default policy, up to two additional default policies can be provided (for a total of three).
- If a second and third penalty is provided, its deadline must be greater than 0, and less than 1000. This determines the window penalties.
- It is currently not possible to provide more than three default policies. Expedia can only manage three different penalties per cancellation policy.
Optionally, exceptions (override policies) can be added. If used:
- Start and end dates are required.
- Overrides with end dates in the past in a create or update message will not be accepted. Overrides with end dates in the past will not be returned in query responses.
- Override date ranges cannot overlap. If more than one override is provided, Expedia Group will make sure that there are no date overlaps between them.
- The rules and validations around the policies included in an override policy are the same as with the default policies.
When exceptions are defined, Expedia Group will apply a cancellation policy to a booking based on the booking start/arrival date. See example 1 below for a concrete example of what this means.
Example 1 - Assume a cancellation policy with only one exception defined:
- By default, if a guest cancels 72 hours or less before a property's cancellation time, the customer pays the full amount of the reservation. If the guest cancels more than 72 hours before the property's cancellation time, the customer pays no penalty.
- For dates from June 2nd to July 15th inclusively, the rate plan is not refundable.
To reflect such terms, the following should be sent:
1{2 "cancelPolicy": {3 "defaultPenalties": [4 {5 "deadline": 0,6 "perStayFee": "FullCostOfStay",7 "amount": 08 },9 {10 "deadline": 72,11 "perStayFee": "None",12 "amount": 013 }14 ],15 "exceptions": [16 {17 "startDate": "2016-06-02",18 "endDate": "2016-07-15",19 "penalties": [20 {21 "deadline": 0,22 "perStayFee": "FullCostOfStay",23 "amount": 024 }25 ]26 }27 ]28 }29}
How will Expedia Group decide which penalty to apply to a booking based on example 1's policy?
Expedia Group picks a cancellation policy to apply based on arrival date.
Example:
- Assume a booking is made for arrival on June 1st, for 3 nights: because the arrival date is outside of the range of dates covered by the exception, the default policy applies.
- Assume a booking is made for arrival on July 15th, for 3 nights: because the arrival date falls on the last date of the exception, the exception policy applies.
Example 2 - Consider the following policy:
- If a customer cancels between 24 hours or less before the property's cancellation time, the customer pays twenty percent cost of stay.
- If a customer cancels between 24 and 72 hours before the property's cancellation time, the customer pays ten percent cost of stay.
- If a customer cancels more than 72 hours before the property's cancellation time, the customer pays no penalty.
To reflect such terms, the following should be sent:
1{2 "cancelPolicy": {3 "defaultPenalties": [4 {5 "deadline": 0,6 "perStayFee": "20PercentCostOfStay",7 "amount": 0.08 },9 {10 "deadline": 24,11 "perStayFee": "10PercentCostOfStay",12 "amount": 0.013 },14 {15 "deadline": 72,16 "perStayFee": "None",17 "amount": 0.018 }19 ]20 }21}
Example 3:
- Cancellations within 24 hours of the property’s cancellation time deadline should be charged 1 night room and tax
- Cancellations further out should incur a 5 units of currency penalty (for example 5 GBP for a London, UK property, assuming property rate acquisition type is Sell lowest available rate (LAR))
To reflect such terms, the following should be sent:
1"cancelPolicy": {2 "defaultPenalties": [3 {4 "deadline": 0,5 "perStayFee": "1stNightRoomAndTax",6 "amount": 0.07 },8 {9 "deadline": 24,10 "perStayFee": "None",11 "amount": 5.012 }13 ]14}
Example 4 - if a policy is non-refundable, the following should be sent:
1"cancelPolicy": {2 "defaultPenalties": [3 {4 "deadline": 0,5 "perStayFee": "FullCostOfStay",6 "amount": 0.07 }8 ]9}
Occupancy and age category settings
Age categories are used for two different things in Expedia Group’s system: to confirm if the room supports both adults and children, and to define additional guest amounts per age category. Extra person fees are always defined at the rate plan level.
Occupancy settings define the maximum occupancy of the room by number of adults, children, and total. Unlike the age categories, there's no granularity in the configuration for children. There is however a relationship between the age categories and the occupancy settings. If a room accepts children in its occupancy, and you want to define a maximum number of children under the occupancy element, Expedia Group will expect that the age categories include at least one ChildAge category, or Infant. If it is not the case, Expedia Group will reject the message.
Note: At properties with occupancy-based pricing, children can be charged as either regular occupants or as "Always Extra." In this case, even when children are within the maximum occupancy, pricing for each child occupant is based on the "additionalGuestAmounts" array set for each Child Age group.
The maximum number of Child Age categories supported by the property is set at the property level and cannot be overridden by Product API. Perform a GET call for the property-level information to learn which age categories are allowed (array in the attribute "allowedAgeCategories"). If this limit needs to be increased, please contact Expedia Group.
When a room supports children and infants, assuming a room can accommodate up to 4 people, Expedia Group would expect to receive a configuration similar to this:
1{2 "ageCategories": [3 {4 "category": "Adult",5 "minAge": 186 },7 {8 "category": "ChildAgeA",9 "minAge": 010 }11 ],12 "maxOccupancy": {13 "total": 4,14 "adults": 4,15 "children": 316 }17}
If a room doesn't support children, Expedia Group would expect to receive something like this:
1{2 "ageCategories": [3 {4 "category": "Adult",5 "minAge": 186 }7 ],8 "maxOccupancy": {9 "total": 4,10 "adults": 411 }12}
If a room supports children, but only older children (for example 16+), Expedia Group would expect to receive something like this:
1{2 "ageCategories": [3 {4 "category": "Adult",5 "minAge": 186 },7 {8 "category": "ChildAgeA",9 "minAge": 1610 }11 ],12 "maxOccupancy": {13 "total": 4,14 "adults": 4,15 "children": 316 }17}
If intending to charge children as adults and only accept older children of 16+, you could consider doing something like this as well:
1{2 "ageCategories": [3 {4 "category": "Adult",5 "minAge": 166 }7 ],8 "maxOccupancy": {9 "total": 4,10 "adults": 411 }12}
Infant category definitions should never be sent to Expedia Group if the room doesn't support infants. Due to the way occupancy is calculated, there is only one count for any non-adult age category: the children count. It is not possible to send a count of 0 infants. For that reason, it is critical that properties that cannot take infants in their rooms do not define the infant age category at all.
As a best practice, only define the guest age categories supported. The examples defined in the Occupancy and age category section were designed with this principle in mind.
Expedia Group does not support defining room configurations where infants are allowed, but other children are not accepted.
It is also important to know that there is no "maximum age" explicitly defined for an age category. The maximum age of a given category is equivalent to the (minimum age-1) of the next defined category.
If something like this was sent:
1{2 "ageCategories": [3 {4 "category": "Adult",5 "minAge": 186 },7 {8 "category": "Infant",9 "minAge": 010 }11 ],12 "maxOccupancy": {13 "total": 3,14 "adults": 2,15 "children": 116 }17}
The outcome of this request would be that any guest aged from 0 to 17 would be considered an Infant, and anyone 18 or above would be considered an adult.
Yes, if a property has occupancy-based pricing and the child pricing logic is set to consider children always as extra occupants. The unit will have to be mapped to include at least ChildAgeA. Then the rate plan must be mapped with no additional charge for the children.
For instance, in the room:
1"ageCategories": [2 {3 "category": "Adult",4 "minAge": 185 },6 {7 "category": "ChildAgeA",8 "minAge": 59 },10 {11 "category": "ChildAgeB",12 "minAge": 013 }14]
The rate carries:
1"additionalGuestAmounts": [2 {3 "ageCategory": "Adult",4 "amount": 505 },6 {7 "ageCategory": "ChildAgeA",8 "amount": 509 }10]
Therefore, children ages 0 to 5 will not be charged.
Updating rate plans to require deposits
With the introduction of the Deposit API, some might be interested in managing only the depositRequired flag of rate plans, in order to indicate which rate plans should make use of a deposit policy. If you know which rate plans (and corresponding unit IDs) should make use of the policy, they can be PATCHed with the following operation:
PATCH https://services.expediapartnercentral.com/properties/{Expedia Property ID}/roomTypes/{unit ID of the rate plan to be patched}/ratePlans/{rate plan ID to be update}
Content-Type: application/vnd.expedia.eps.product-v3+json
1{2 "depositRequired": true3}
The same operation needs to be repeated for all rate plans requiring a deposit.
If you don't know the unit or rate plan IDs, they can be discovered by using GET roomTypes and GET ratePlans calls.
Example - to list all units of a property:
GET https://services.expediapartnercentral.com/properties/{Expedia Property ID}/roomTypes
This will give back a list of active roomTypes. A query parameter (?status=all) could be added to return all units, both active and inactive. This shouldn't be needed since inactive units wouldn't be available to guests, therefore updating the depositRequired flag would have no visible effect for them.
Then, to get the rate plans, you can iterate on each unit, and request all rate plans for each unit, using:
GET https://services.expediapartnercentral.com/properties/{Expedia Property ID}/roomTypes/{Expedia unit ID}/ratePlans
This will give back a list of active rate plans. A query parameter (?status=all) could be added to return both active and inactive rate plans.
Once all units and rate plans have been identified, and the deposit policy has been created with Deposit API, those rate plans requiring a deposit can be updated with the same PATCH call as above.
Note: It is important to know that only Hotel Collect or Expedia Traveler Preference (Hotel Collect/Expedia Collect) rate plans can be updated to require a deposit.