Skip to content

4. Data exchange actions

These actions allow the actual exchange of data between client and server.

For data exchange actions, both parameters (action and request) are mandatory.

The value of the request parameter (sent by the client) and the server response are XML documents following OTA2015A and using the XML root elements specified in the following table:

known as (since) usage parameter action (string) parameter request and server response (XML documents)

FreeRooms (since 2011-11)

a client sends room availability notifications to a server

OTA_HotelInvCountNotif:FreeRooms

OTA_HotelInvCountNotifRQ OTA_HotelInvCountNotifRS

GuestRequests (since 2012-05)

a client sends a request to receive requests for a quote or booking requests from the server

OTA_Read:GuestRequests

OTA_ReadRQ OTA_ResRetrieveRS

GuestRequests (Push) (since 2018-10)

a client sends requests for a quote or booking requests to the server

OTA_HotelResNotif:GuestRequests

OTA_HotelResNotifRQ OTA_HotelResNotifRS

GuestRequests Status Update (Push) (since 2022-10)

a client sends status updates for a quote or booking requests to the server

OTA_HotelResNotif:GuestRequests_StatusUpdate

OTA_HotelResNotifRQ OTA_HotelResNotifRS

GuestRequests/Acknowledgments (since 2014-04)

a client acknowledges the requests it has received

OTA_NotifReport:GuestRequests

OTA_NotifReportRQ OTA_NotifReportRS

SimplePackages (2012-05 until 2015-07b)

this action has been removed in version 2017-10

Inventory/Basic (Push) (since 2015-07)

a client sends room category information and room lists

OTA_HotelDescriptiveContentNotif:Inventory

OTA_HotelDescriptiveContentNotifRQ OTA_HotelDescriptiveContentNotifRS

Inventory/Basic (Pull) (since 2017-10)

a client requests room category information and room lists

OTA_HotelDescriptiveInfo:Inventory

OTA_HotelDescriptiveInfoRQ OTA_HotelDescriptiveInfoRS

Inventory/HotelInfo (Push) (since 2015-07)

a client sends additional descriptive content regarding properties

OTA_HotelDescriptiveContentNotif:Info

OTA_HotelDescriptiveContentNotifRQ OTA_HotelDescriptiveContentNotifRS

Inventory/HotelInfo (Pull) (since 2017-10)

a client requests additional descriptive content regarding properties

OTA_HotelDescriptiveInfo:Info

OTA_HotelDescriptiveInfoRQ OTA_HotelDescriptiveInfoRS

RatePlans (since 2014-04)

a client sends information about rate plans with prices and booking rules

OTA_HotelRatePlanNotif:RatePlans

OTA_HotelRatePlanNotifRQ OTA_HotelRatePlanNotifRS

BaseRates (since 2017-10)

a client requests information about rate plans

OTA_HotelRatePlan:BaseRates

OTA_HotelRatePlanRQ OTA_HotelRatePlanRS

Activities (since 2020-10)

a client requests information about hotel activities

OTA_HotelPostEventNotif:EventReports

OTA_HotelPostEventNotifRQ OTA_HotelPostEventNotifRS

AlpineBits® requires all XML documents to be encoded in UTF-8.

Caution must be taken when dealing with special and unusual characters (e.g. emojis, kanjis,…​). Their use is increasing and where the user is allowed to enter arbitrary text (mostly from mobile devices) they could be inserted and sent through APIs. AlpineBits® and XML format can handle any character without issue but if unexpected, they might lead to unpredictable results, particularly on unprepared applications. Usually, supporting Unicode or UTF-8 encoding prevents most potential serious issues, but some unpleasant situations can still occur; for example:

  • Incorrect visualization of certain characters might create confusion in text comprehension or in text formatting.

  • Unicode characters bigger than 16 bits might not be supported yet by every system and can also cause alterations in stored data.

  • Ambiguity between characters and their composite version (e.g. characters with diacritical marks) might create issues with some algorithms (e.g. searches, comparisons).

Therefore, it is a good practice to parse the data received with AlpineBits® for special characters prior to storing it. In worst cases this will lead only to a validation error rather than more unpleasant situations. More in general, it is advised to ensure the necessary checks in order to prepare its own application to receive special characters.

The business logic of an AlpineBits® server, i.e. how the server processes and stores the information it receives is implementation-specific.

The format of the requests and responses is, however, exactly specified.

First of all the requests and responses must validate against the OTA2015A schema.

Since OTA is very flexible regarding mandatory / optional elements, AlpineBits® adds extra requirements about exactly which elements and attributes are required in a request.

If these are not present, a server’s business logic is bound to fail and will return a response indicating an error even though the request is valid OTA2015A.

OTA2015A, for instance allows OTA_HotelInvCountNotifRQ requests that do not indicate the hotel, this might make perfect sense in some context, but an AlpineBits® server will return an error if that information is missing from the request.

To aid developers, two AlpineBits® schema files (one XML schema file and one Relax NG schema file) are provided as an integral part of the specification in the AlpineBits® documentation kit.

The Relax NG file is somewhat stricter than the XML schema file, as RelaxNG is intrinsically more powerful in expressing constraints that express how elements and attributes depend on each other.

Both AlpineBits® schema files are stricter than OTA2015A in the sense that all documents that validate against AlpineBits® will also validate against OTA2015A, but not vice versa.

The AlpineBits® documentation kit also provides a sample file for each of the request and response documents.

The latest AlpineBits® documentation kit for each protocol version is available from the official AlpineBits® website.

Even though the XML snippets and sample files express prices in EUR, in AlpineBits® all currency codes from the ISO 4217 are allowed. It is important that clients and servers that exchange data with each other use the same currency code. In the event that a server receives unsupported currencies in a message, it must reply to the client with a warning outcome. Likewise, a client that receives unsupported currencies should discard the whole message and notify the server in some way.

Many AlpineBits messages allow to transmit URLs to multimedia objects (mostly images), and whenever possible suggest the explicit identification of the copyright holder. However, in order to know its rights, the receiving end must also be aware of the licensing terms attached to these multimedia resource. Unfortunately there is no place for this information inside the XML messages, hence some other means of conveying it is suggested below as a best practice.

  • The publisher of the multimedia object could add some metadata (e.g. EXIF in case of pictures) that contains the licensing information. To this end, AlpineBits recommends the utilization of a standard like the IPTC specification. The receiving end should not ignore nor remove this metadata and should also include them in a derived work (e.g. thumbnails or resized representations).

  • The publisher of the multimedia object could add some metadata to the HTTP response that serves the multimedia content, to this end AlpineBits recommends the usage of X-AlpineBits-License and X-AlpineBits-CopyrightHolder headers. The receiving end should not ignore these headers and should consider also any derived work to be under the same constraints.

Please note that these approaches are not mutually exclusive. Furthermore it is recommended to provide as much information as possible within each data exchange.

4.1. FreeRooms: room availability notifications

When the value of the action parameter is OTA_HotelInvCountNotif:FreeRooms the client intends to send room availability notifications to the server.

A server that supports this action must support at least one of two capabilities: OTA_HotelInvCountNotif_accept_rooms or OTA_HotelInvCountNotif_accept_categories. This way the server indicates whether it can handle the availability of rooms at the level of distinct rooms, at the level of categories of rooms or both (a better explanation will follow).

4.1.1. Client request

The parameter request must contain an OTA_HotelInvCountNotifRQ document.

Consider the outer part of the example document:

---- <?xml version="1.0" encoding="UTF-8"?> <OTA_HotelInvCountNotifRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" Version="4" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelInvCountNotifRQ.xsd"> <UniqueID Type="16" ID="1" Instance="CompleteSet"/> <Inventories HotelCode="123" HotelName="Frangart Inn"> </Inventories> </OTA_HotelInvCountNotifRQ> ----

An OTA_HotelInvCountNotifRQ may contain just one Inventories (note the plural) element, hence at most one hotel can be dealt with in a single request.

AlpineBits® requires the attributes HotelCode or HotelName to be present (and match information in the server’s database). The fictitious hotel in the example is the "Frangart Inn" with code "123". When specifying both — code and name — only the code is required to be consistent.

AlpineBits® requires a match of HotelCode or HotelName to be case sensitive.

Second, consider the inner part of the example that contains Inventory elements (note the singular) for three different time periods.

---- <Inventory> <StatusApplicationControl Start="2022-08-01" End="2022-08-10" InvTypeCode="DOUBLE" /> <InvCounts> <InvCount CountType="2" Count="3" /> </InvCounts> </Inventory> <Inventory> <StatusApplicationControl Start="2022-08-11" End="2022-08-20" InvTypeCode="DOUBLE" /> </Inventory> <Inventory> <StatusApplicationControl Start="2022-08-21" End="2022-08-30" InvTypeCode="DOUBLE" /> <InvCounts> <InvCount CountType="2" Count="1" /> </InvCounts> </Inventory> ----

The absence of the InvCode attribute tells us we’re dealing with a room category (DOUBLE) given by the InvTypeCode.

Alternatively, using a InvCode together with a InvTypeCode attribute would indicate that the availability refers to a specific room, not a room category.

AlpineBits® requires a match of InvCode or InvTypeCode to be case sensitive.

An AlpineBits® server must be able to treat at least one out of two cases (specific rooms or categories). A client should perform the OTA_Ping:Handshaking action to find out whether the server treats the room case (token OTA_HotelInvCountNotif_accept_rooms), the category case (token OTA_HotelInvCountNotif_accept_categories) or both.

Mixing rooms and categories in a single request is not allowed. An AlpineBits® server must return an error if it receives such a mixed request.

The Inventory element for a given room/room category can contain an InvCounts (plural) element. Based on the supported capabilities, the InvCounts element contains from 1 to 3 InvCount (singular) elements, one for each of the allowed CountType attributes:

  • CountType = 2 indicates rooms that are bookable (this CountType must be supported).

  • CountType = 6 indicates rooms that are out of order (i.e. rooms that are not booked nor bookable, maybe due to renovations), requires the OTA_HotelInvCountNotif_accept_out_of_order capability.

  • CountType = 9 indicates rooms that are available but not bookable (see section GuestRequests for the description of bookings), requires the OTA_HotelInvCountNotif_accept_out_of_market capability.

If the server does not have the corresponding capability set, a client must not send the CountType = 6 or the CountType = 9 elements, and all the rooms not specified in the CountType = 2 element are to be considered as already booked.

The integer value of the attribute Count indicates the room count for the given CountType and must be a non negative number (≥ 0).

If an InvCount element for a specific CountType is missing it must be considered as if its Count attribute is 0. Likewise, if the whole InvCounts container is missing it is considered as if the whole room/room category is fully booked in the given time period (same as CountType = 2 with Count = 0).

Count numbers are always interpreted to be absolute numbers. Differential updates are not allowed.

Since in the example we’re dealing with a room category (InvCode is missing), the value of Count can be > 1. In the case of a specific room (InvCode is specified), the only meaningful value would be 1 (the same room can not be "counted" more than once).

Since overbooking is not allowed and the number of counted rooms (bookable or not) cannot exceed the total number of rooms, the inequality 0 ≤ 'sum of Count values' ≤ 'total number of rooms' holds.

Considering the example, the attributes Start and End and the corresponding InvCount element indicate that room cateogry DOUBLE has 3 rooms available from 2020-08-01 to 2020-08-10 and 1 room available from 2020-08-21 to 2020-08-30; from 2020-08-11 to 2020-08-20 there are no DOUBLE rooms available.

Regarding the first interval, this means the earliest possible check-in is 2020-08-01 afternoon and latest possible check-out is 2020-08-11 morning (maximum stay is 10 nights).

Check-ins after 2020-08-01 and stays of less than 10 nights are allowed as well, provided the check-out is not later than the morning of 2020-08-11.

Same applies for the third block of 10 nights from 2020-08-21 to 2020-08-30 (latest check-out is 2020-08-31 morning).

During the second time period, from 2020-08-11 to 2020-08-20, no check-in is possible.

Note that AlpineBits® does not allow Inventory elements with overlapping periods regarding the same room or room category. This implies that the order of the Inventory elements doesn’t matter. It is a client’s responsibility to avoid overlapping. An AlpineBits® server’s business logic may identify overlapping and return an error or may proceed in an implementation-specific way.

CompleteSet

Clients and servers typically wish to exchange only delta information about room availabilities in order to keep the total amount of data to be processed in check.

However, AlpineBits® considered several use-cases in which it is important to transmit the complete availability information, as might be the case for a first synchronization or for aligning two systems after a communication issue. For this reason it defines a request that has the purpose of resetting the server information with that contained in the message. Such request is called a CompleteSet.

If a server provides the capability OTA_HotelInvCountNotif_accept_complete_set, then a client may send a CompleteSet message as explained below.

In the example, the UniqueID element with attribute Instance = CompleteSet and Type = 16 indicates that this message contains the complete information (as entered by the user). When receiving such a request, a server must remove all information about any availability it might have on record regarding the given hotel.

The attribute ID is needed for compatibility with OTA, the value is ignored by AlpineBits®.

In a CompleteSet message all the rooms/room categories managed by the client must be specified for any time period for which the client has data on records. This means that also in cases where a room/room category is fully booked (with no availability), it must have a corresponding Inventory element with its own StatusApplicationControl sub element and a coherent set of InvCount elements contained in it (or no InvCounts container at all, as stated above). This states unambiguously that the room/room category has no availability for the specified period.

A client must not include in a CompleteSet message a period for which it has no data on record (for instance a client that is forwarding data received from a source, must not forward any information besides what was originally received from the source).

Normally the FreeRooms message requires exactly one StatusApplicationControl element with attributes Start, End, InvTypeCode (and optional InvCode) for each Inventory element. The server must return an error if any of these are missing. There is however one exception: to completely reset all room availability information for a given hotel a client might send a CompleteSet request with just one empty Inventory element without any attributes. The presence of the empty Inventory element is required for OTA validation.

In addition, a client might want to let a server know its availability data, should be purged based on internal business rules. An example might be availability data that is considered stale, because it hasn’t been updated by the user for some time. The client should then send a request using an UniqueID element with attribute Instance = CompleteSet and Type = 35. A server must accept this value (without returning an error or warning) and could make use of this hint and keep the availability data it has on record flagging it as purged. Otherwise such a message should be considered equivalent to the one with Type = 16.

Deltas

If the UniqueID element is missing, the message contains delta information. In that case the server updates only the information that is contained in the message without touching the other information that it has on record.

A server that supports delta requests must indicate so via the OTA_HotelInvCountNotif_accept_deltas capability. As always, it is the client’s responsibility to check whether the server supports deltas before trying to send them.

AlpineBits® recommends that implementers that use delta requests should send the full set of information periodically if both client and server support it.

If the entire period is explicitly transmitted and processsed in a delta message, this leads to the complete overwriting of the previous situation.

If a server does not support CompleteSet messages, it might lead to cases where the hotel would have to intervene and delete obsolete data from the server manually in its backend.

A server should provide at least one of OTA_HotelInvCountNotif_accept_deltas and OTA_HotelInvCountNotif_accept_complete_set capabilities in order to accept FreeRooms messages.

Closing seasons

A special Inventory element can be used to send information about closing seasons, i.e. time periods in which the hotel is completely closed. It is in fact important to distinguish the cases in which a hotel is fully booked (where one could still hope for a last minute cancellation) from those in which a hotel is closed (where it could not even answer the phone).

Closing seasons elements require both parties to expose the OTA_HotelInvCountNotif_accept_closing_seasons capability during handshaking and can only be sent as first Inventory elements in a CompleteSet message. The content of the closing seasons Inventory element is defined as follows:

  • One StatusApplicationControl sub element indicating a time period with the mandatory Start and End attributes and with the mandatory attribute AllInvCode set to true.

  • No InvCounts sub elements are allowed.

Multiple Inventory elements can be specified this way to indicate multiple closing periods.

Each of the closing time periods must not overlap with other closed periods nor with any time period that states a room/room category is available (it is therefore possible for a closed period to overlap with a period where all the rooms/room categories are unavailable). A server must return an error if it detects such inconsistencies.

Delta messages are still to be considered as the most up to date, so in case a delta message would set a room/room category as available in a period previously set as closed, it must be considered as if the hotel revoked the closed period for the overlapping days.

As a best practice, the client should avoid such overwriting or at least send a complete set afterwards in order to explicitly set the correct closed periods. If the server deems it appropriate to force a full synchronization, it might request a CompleteSet in one of its next responses (see Appendix A).

4.1.2. Server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelInvCountNotifRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed.

See Appendix A for details.

4.1.3. Implementation tips and best practice

  • Note that in the 2011-11 version of AlpineBits® the support of this action was mandatory for the server. This is no longer the case.

  • Note that sending partial information (deltas) was added with AlpineBits® 2013-04.

  • Note that this action has been completely re-written in the 2020-10 version of AlpineBits®.

  • It is important that applications that forward data received from other sources (e.g. channel managers and alike) do not forward any information not present in the original data. For example, if such an application manages on its system a wider time frame than the one received from the source, it should not forward any information beyond the most future date it has received. This is necessary to keep the information clean through the forwarding without complementary (and arbitrary) data to be added by third party applications.

  • For CompleteSet requests, since no time frame is explicitly transmitted by the client, a server is encouraged to delete and insert all information stored in its backend, rather than updating it.

  • Please note that the End date of an interval identifies the last day and night of the stay. Departure is the morning of the day after the End date.

  • Please note that previous versions of AlpineBits® allowed some booking restrictions to be used in FreeRooms (length of stay and day of arrival). This possibility has been removed with version 2014-04 as these restrictions are better handled by RatePlans.

4.2. GuestRequests: quote requests, booking reservations and cancellations

The typical use case for GuestRequests is a portal that collects quote requests, booking reservations or booking cancellations from potential customers and stores them until a client (typically the software used by a hotel) retrieves them.

In this case, the client sends a first request to obtain the information from the server about any requests, reservations or cancellations with the parameter action set to the value OTA_Read:GuestRequests.

The server then responds with the requested information.

Successively, the client sends a follow-up request to acknowledge having received the information, with the parameter action set to the value OTA_NotifReport:GuestRequests.

Please note that a server that has announced support for OTA_Read:GuestRequests MUST also support the action OTA_NotifReport:GuestRequests so that the client can execute follow-up acknowledgement requests. See section 4.2.3 and section 4.2.4 for more details.

Push Support

Starting with AlpineBits version 2018-10 it is possible to push the GuestRequest instead of polling them. Please note that this functionality relies on a few arrangements between the two parties that are not negotiated through AlpineBits, namely the endpoint (URL) where the client can receive the pushed GuestRequests, its credentials, etc. This behavior is described in section 4.2.6 and 4.2.7, but the XML structure of the HotelReservation is the same as in the rest of this chapter.

4.2.1. First client request

The action paramater is set to the value OTA_Read:GuestRequests and the request parameter must contain a OTA_ReadRQ document.

For the attributes HotelCode and HotelName the rules are the same as for room availability notifications (section 4.1.1).

The element SelectionCriteria with the Start attribute is optional.

When given, the server will send only inquiries generated after the Start timestamp, regardless whether the client has retrieved them before or not.

When omitted, the server will send all inquiries it has on record and that the client has not yet retrieved.

---- <?xml version="1.0" encoding="UTF-8"?> <OTA_ReadRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_ReadRQ.xsd" Version="1.001"> <ReadRequests> <HotelReadRequest HotelCode="123" HotelName="Frangart Inn"> <SelectionCriteria Start="2012-03-21T15:00:00+01:00"></SelectionCriteria> </HotelReadRequest> </ReadRequests> </OTA_ReadRQ> ----

4.2.2 Server response

The server will send a response indicating the outcome of the request. The response is a OTA_ResRetrieveRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed.

See Appendix A for details.

In case of success, the OTA_ResRetrieveRS response will contain a single, empty Success element followed by a ReservationsList element with zero or more HotelReservation elements containing the requested information (zero elements indicate the server has no information for the client at this point).

Each HotelReservation must have the attributes CreateDateTime (the timestamp the information was collected by the portal). Furthermore the ResStatus attribute must be set. AlpineBits® expects it to be one of the following four:

  • Requested - this is a request for a quote, newsletter or catalog.

  • Reserved - this is a booking reservation.

  • Modify - this is a booking modification.

  • Cancelled - this is a booking cancellation.

For a newsletter- or catalog request the optional attribute RoomStayReservation must be explicitly set to false.

The following example is a reservation (thus, ResStatus is Reserved). The documentation kit also has an example of a quote request. A cancellation is discussed later.

First, consider the outer part of the OTA_ResRetrieveRS document:

---- <?xml version="1.0" encoding="UTF-8"?> <OTA_ResRetrieveRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_ResRetrieveRS.xsd" Version="7.000"> <Success/> <ReservationsList> <HotelReservation CreateDateTime="2022-03-21T15:00:00+01:00" ResStatus="Reserved"> <UniqueID Type="14" ID="6b34fe24ac2ff810"/> <RoomStays> </RoomStays> <ResGuests> </ResGuests> <ResGlobalInfo> </ResGlobalInfo> </HotelReservation> </ReservationsList> </OTA_ResRetrieveRS> ----

Each HotelReservation contains a mandatory UniqueID element that the client can use to recognize information it has already processed.

The UniqueID element must have the Type attribute set according the OTA Unique Id Type list (UIT). The value must be consistent with the ResStatus attribute of the surrounding HotelReservation element:

  • For ResStatus = Requested, the Type must be 14 (Reservation).

  • For ResStatus = Reserved, the Type must be 14 (Reservation).

  • For ResStatus = Modify, the Type must be 14 (Reservation).

  • For ResStatus = Cancelled, the Type must be 15 (Cancellation).

The attribute ID is a free text field suitable for uniquely identifying the HotelReservation.

The actual data is then split into three parts: each HotelReservation contains the elements: RoomStays, ResGuests and ResGlobalInfo discussed in the following paragraphs.

Part I: RoomStays (mandatory for reservations, optional for quote requests, disallowed for newsletter- or catalog requests).

The RoomStays element contains one or more RoomStay elements, each indicating a desired stay.

---- <RoomStays> <RoomStay> <RoomTypes> <RoomType RoomTypeCode="bigsuite" RoomClassificationCode="42"/> </RoomTypes> <RatePlans> <RatePlan RatePlanCode="123456-xyz"> <Commission Percent="15"/> <MealsIncluded MealPlanIndicator="true" MealPlanCodes="1"/> </RatePlan> </RatePlans> <GuestCounts> <GuestCount Count="2"/> <GuestCount Count="1" Age="9"/> <GuestCount Count="1" Age="3"/> </GuestCounts> <TimeSpan Start="2022-01-01" End="2022-01-12"/> <Guarantee> <GuaranteesAccepted> <GuaranteeAccepted> <PaymentCard CardCode="VI" ExpireDate="1226"> <CardHolderName>Otto Mustermann</CardHolderName> <CardNumber> <PlainText>4444333322221111</PlainText> </CardNumber> </PaymentCard> </GuaranteeAccepted> </GuaranteesAccepted> </Guarantee> <Total AmountAfterTax="299" CurrencyCode="EUR"/> </RoomStay> </RoomStays> ----

Each RoomStay element contains:

  • One RoomType element (mandatory for reservations, optional for quote requests): see below for an explanation;

  • One RatePlan element with:

    • A RatePlanCode attribute (mandatory for reservations, optional for quote requests).

    • Zero or one Commission elements with either a Percent attribute (the commission in percent) or a CommissionPayableAmount sub-element with attributes Amount and CurrencyCode; the Amount must follow the currency decimal format.

    • One MealsIncluded element (mandatory for reservations, optional for quote requests): the MealsIncluded element must contain the MealPlanCodes attribute (values see below) and must have the MealPlanIndicator attribute set to true;

  • One GuestCounts element (mandatory) indicating the number of all adults (identified by zero or one GuestCount element with no Age attribute given) and the number of all children (identified by zero or more GuestCount element with Age attribute given); of course all guests must be listed and their total (adults + children) must not be zero.

  • One TimeSpan element (mandatory): see below for an explanation.

  • One PaymentCard element (only for reservations, optional) with:

    • The mandatory attributes CardCode (the card issuer, two uppercase letters, such as "VI" for Visa) and ExpireDate (four digits).

    • The optional sub-element CardHolderName.

    • The mandatory sub-element CardNumber (see below).

  • One Total element (mandatory for reservations, optional for quote requests) containing the cost after taxes the portal has displayed to the customer, both attributes AmountAfterTax and CurrencyCode are required; the AmountAfterTax must follow the currency decimal format.

The CardNumber element is used to send a credit card number. The number can be sent either as plain text (but note the message transport is encrypted using HTTPS) or encrypted.

For the plain text case, the CardNumber element has no attributes and must contain a PlainText sub-element holding the complete credit card number or its last four digits as in the example above.

For the encrypted case, the CardNumber element must not have any sub-elements and must have attributes EncryptedValue (a string representation of the encrypted card number) and EncryptionMethod (a string identifying the encryption method, e.g. "RSA-PKCSV2.2").

For reservations, the RoomType element is mandatory. Reservations must refer to a specific room category (specified by RoomTypeCode). Quote requests should refer a specific room category whenever possible (specified by the optional attribute RoomTypeCode) but may refer to a generic GRI (specified by the optional attribute RoomClassificationCode) or may be completely open if the RoomType element is present without attributes.

The RoomTypeCode must be identical to the InvTypeCode attribute used for room categories (see section 4.1.1).

The RoomClassificationCode follows the OTA list "Guest Room Info" (GRI). It is used to loosely classify the kind of guest room (42 means just "Room", 13 means "Apartments", 5 means "Pitches", etc.) wished by the guest.

The optional RoomType attribute may be specified, see the definition of the RoomType attribute used for the Inventory (see section 4.4.1) for the list of values defined by AlpineBits®. If the RoomType attribute is specified, then also RoomClassificationCode must be present.

Regarding the MealPlanCodes attribute, AlpineBits® does not use the single Breakfast/Lunch/Dinner booleans, but relies on the MealPlanCodes attribute only. The following codes (a subset of the full OTA list) are allowed:

  • 1 - All inclusive

  • 3 - Bed and breakfast

  • 10 - Full board

  • 12 - Half board

  • 14 - Room only

The TimeSpan element deserves a more detailed explanation.

For reservations (ResStatus is Reserved or Modify), the arrival and departure date must be given with the Start and End attributes of the TimeSpan element. No other attributes and no sub elements must be present in TimeSpan.

For quote requests (ResStatus is Requested) the timespan can be given in the same way (i.e. using the Start and End attributes) or it may be given as a window. In this case the TimeSpan element must have the Duration attribute (encoded in ISO 8601) and the StartDateWindow sub element with attributes EarliestDate and LatestDate which must be greater than EarliestDate indicating a range of possible start dates.

Duration are given in nights, the form is thus always PxN where x is a number.

A reservation can contain multiple RoomStay elements. Thus, different rooms with different RatePlans can be managed in one reservation. In addition, it is possible to book a stay of, for example, 10 days with a weekly flat rate and a standard offer for the remaining days.

The optional RoomStayGroupID attribute comes into play when alternative room stays or periods need to be transmitted. Note that this is valid for quote requests only (ResStatus is Requested) and they cannot be used together. Each room type with the same RoomStayGroupID indicates a group of room types which must be requested together, meaning that RoomStayGroupID set to "1" is the first alternative, RoomStayGroupID set to "2" the second alternative and so on. One or more alternatives can be specified by using a different identifier.

Part II: ResGuests (mandatory).

Nested inside the ResGuests element is exactly one Customer element, providing the data of the primary guest.

The Gender attribute can be Male, Female or Unknown. The BirthDate attribute follows ISO 8601. The Language follows ISO 639-1 (two-letter lowercase language abbreviation). It identifies the language to be used when contacting the customer.

These three attributes are all optional. However, it is recommended that at least gender and language be specified (so the customer can be addressed properly).

---- <ResGuests> <ResGuest> <Profiles> <ProfileInfo> <Profile> <Customer Gender="Male" BirthDate="1980-01-01" Language="de"> <PersonName> <NamePrefix>Herr</NamePrefix> <GivenName>Otto</GivenName> <Surname>Mustermann</Surname> <NameTitle>Dr</NameTitle> </PersonName> <Telephone PhoneTechType="1" PhoneNumber="+4934567891"/> <Telephone PhoneTechType="3" PhoneNumber="+4934567892"/> <Telephone PhoneTechType="5" PhoneNumber="+4934567893"/> <Email Remark="newsletter:yes">otto.mustermann@example.com</Email> <Address Remark="catalog:yes"> <AddressLine>Musterstraße 1</AddressLine> <CityName>Musterstadt</CityName> <PostalCode>1234</PostalCode> <CountryName Code="DE"/> </Address> </Customer> </Profile> </ProfileInfo> </Profiles> </ResGuest> </ResGuests> ----

The Customer element contains:

  • One PersonName element with NamePrefix, GivenName (mandatory), Surname (mandatory) and NameTitle.

  • Zero or more Telephone elements with the optional PhoneTechType attribute: it indicates the phone technology (1 → voice, 3 → fax, 5 → mobile per OTA).

  • One optional Email element.

  • One optional Address element with the (all optional) elements AddressLine , CityName , PostalCode and CountryName with Code attribute; the Code attribute follows ISO 3166-1 alpha-2 (two-letter uppercase country codes)

Note that most elements and attributes under the ResGuests element are optional in the AlpineBits® schema. It is, however, expected that as much contact information as possible is given.

The Email element may contain the attribute Remark having either values newsletter:yes or newsletter:no indicating whether the customer does or does not wish to receive an email newsletter. A missing Remark indicates the information is not known - for new customers this should be treated the same way as if a newsletter:no was given (do not send a newsletter), while existing customer records should not be updated.

Analogously, the Address element may contain the attribute Remark having either values catalog:yes or catalog:no indicating whether the customer does or does not wish to receive print ads by mail. A missing Remark indicates the information is not known - for new customers this should be treated the same way as if a catalog:no was given (do not send a mail), while existing customer records should not be updated.

Part III: ResGlobalInfo (mandatory).

---- <ResGlobalInfo> <Comments> <Comment Name="included services"> <ListItem ListItem="1" Language="de">Parkplatz</ListItem> <ListItem ListItem="2" Language="de">Schwimmbad</ListItem> <ListItem ListItem="3" Language="de">Skipass</ListItem> </Comment> <Comment Name="customer comment"> <Text> Sind Hunde erlaubt? Mfg. Otto Mustermann. </Text> </Comment> </Comments> <SpecialRequests> <SpecialRequest CodeContext="ALPINEBITS" RequestCode="PETS"> <Text TextFormat="PlainText">Zwei Hunde</Text> </SpecialRequest> <SpecialRequest CodeContext="HOTEL" RequestCode="VEGETARIAN_GUEST"> <Text TextFormat="PlainText"></Text> </SpecialRequest> </SpecialRequests> <CancelPenalties> <CancelPenalty> <PenaltyDescription> <Text> Cancellation is handled by hotel. Penalty is 50%, if canceled within 3 days before show, 100% otherwise. </Text> </PenaltyDescription> </CancelPenalty> </CancelPenalties> <HotelReservationIDs> <HotelReservationID ResID_Type="13" ResID_Value="Slogan" ResID_Source="www.example.com" ResID_SourceContext="top banner" /> </HotelReservationIDs> <Profiles> <ProfileInfo> <Profile ProfileType="4"> <CompanyInfo> <CompanyName Code="123" CodeContext="ABC"> ACME Travel Agency </CompanyName> <AddressInfo> <AddressLine>Musterstraße 1</AddressLine> <CityName>Flaneid</CityName> <PostalCode>12345</PostalCode> <CountryName Code="IT"/> </AddressInfo> <TelephoneInfo PhoneTechType="1" PhoneNumber="+391234567890"/> <Email>info@example.com</Email> </CompanyInfo> </Profile> </ProfileInfo> </Profiles> <BasicPropertyInfo HotelCode="123" HotelName="Frangart Inn"/> </ResGlobalInfo> ----

The ResGlobalInfo element contains:

  • One Comment element (optional) with attribute Name set to included services containing the included services given as free text fields using ListItem elements (see below). In most cases the AlpineBits® client software will just display this to a human hotel employee with no further processing.

  • One Comment element (optional) with attribute Name set to customer comment containing a single Text element freely filled out by the customer and fed through unchecked by the portal.

  • One or more SpecialRequest elements (optional) with the following mandatory attributes:

    • CodeContext set to ALPINEBITS or HOTEL.

    • RequestCode set to a distinct value inside of the provided CodeContext.

SpecialRequests within CodeContext ALPINEBITS must contain a predefined RequestCode value from the following list:

  • PETS providing details regarding pets

SpecialRequests within CodeContext HOTEL contain hotel-specific requests, in which the RequestCode value can be freely defined.

An SpecialRequest element can contain a single Text element (optional) with attribute TextFormat set to PlainText, stating details regarding the specific request. To express that a SpecialRequest element is explictly not wanted by the customer, the Text element must be omitted. On the other hand it is not allowed to express absence inside of the Text element (e.g. “no pets“ or “none” should not be used). An empty Text element means that the request is wanted but provides no further details.

The absence of the whole SpecialRequest element means that the information about a potential presence of a SpecialRequest is not available (i.e. can not be guaranteed their presence nor absence).

Example A: the customer will surely bring pets described as “two dogs”.

---- <SpecialRequests> <SpecialRequest CodeContext="ALPINEBITS" RequestCode="PETS"> <Text TextFormat="PlainText">two dogs</Text> </SpecialRequest> </SpecialRequests> ----

Example B: the customer will surely bring pets but no further information is given.

---- <SpecialRequests> <SpecialRequest CodeContext="ALPINEBITS" RequestCode="PETS"> <Text TextFormat="PlainText"></Text> </SpecialRequest> </SpecialRequests> ----

Example C: the customer will surely not have any pet with him.

---- <SpecialRequests> <SpecialRequest CodeContext="ALPINEBITS" RequestCode="PETS"></SpecialRequest> </SpecialRequests> ----

  • Only allowed for reservations, one PenaltyDescription element (optional) containing a single Text element with no attributes that clearly states the cancellation policy the portal and the hotel have previously agreed upon and the portal has communicated to the customer - the language or languages of this text is chosen by the portal.

  • One or more HotelReservationID elements (optional) that can be used to transmit miscellaneous IDs associated with the reservation the trading partners have agreed upon; ResID_Type must be specified with a value from the OTA "Unique Id Type" list (UIT); the other attributes, ResID_Value, ResID_Source and ResID_SourceContext are all optional; historically, AlpineBits® has used these fields to handle internet campaign management: in this case the agreement is to use a ResID_Type value of "13" (internet broker) and the three attributes ResID_Value, ResID_Source and ResID_SourceContext identify, respectively, the campaign name (Slogan in our example), the campaign source (www.example.com) and the campaign marketing medium (top banner) following the scheme used by Google Analytics.

  • One optional Profile element with attribute ProfileType set to "4" with information about the booking channel; nested under Profile, a CompanyName element with attributes Code and CodeContext must be present, while the AddressInfo, TelephoneInfo and Email elements are optional: these contain the same data as the equivalent fields in the customer part (note the element names: AddressInfo and TelephoneInfo vs Address and Telephone in the customer part - also different ordering - dictated by OTA)

  • One mandatory BasicPropertyInfo element with the HotelCode and HotelName attributes following the same rules of that used in the corresponding attributes in the request (see section 4.2.1).

Each ListItem element must have Language and ListItem attributes. At most one ListItem element is allowed for each combination of Language and ListItem.

Modifications and Cancellations.

A booking modification (ResStatus is Modify) is identical to a booking reservation (ResStatus is Reserved). However, for a booking modification the client will recognize the UniqueId attribute and act accordingly, updating the reservation instead of adding a new one.

Besides quote requests and booking reservations, also cancellations can be handled. For cancellations the ResStatus is Cancelled as shown in the following example:

---- <?xml version="1.0" encoding="UTF-8"?> <OTA_ResRetrieveRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_ResRetrieveRS.xsd" Version="7.000"> <Success/> <ReservationsList> <HotelReservation CreateDateTime="2022-03-21T15:00:00+01:00" ResStatus="Cancelled"> <UniqueID Type="15" ID="c24e8b15ca469388"/> <!-- <RoomStays> …​ </RoomStays> <ResGuests> …​ </ResGuests> <ResGlobalInfo> …​ </ResGlobalInfo> -→ </HotelReservation> </ReservationsList> </OTA_ResRetrieveRS> ----

Each HotelReservation must of course have the attributes CreateDateTime and ResStatus set to Cancelled.

Of course, the element UniqueID is mandatory, again with mandatory attribute Type 15 and attribute ID referring to the reservation that is being cancelled! Other reservation elements may be also sent.

4.2.3. Follow-up client request (acknowledgement)

A client, upon receiving a non-empty response to its first request (OTA_Read:GuestRequests), should initiate another request, acknowledging or refusing the UniqueID values it got (referring to quotes, reservations or cancellations).

For this follow-up request, the action paramter is set to the value OTA_NotifReport:GuestRequests and the parameter request must contain a OTA_NotifReportRQ document.

For the refusal, a standard Warning element is used. The value of the attribute Type can be set to any value of the OTA list "Error Warning Type" (EWT). The value 3 stands for "Biz rule". The attribute Code can be set to any value present in the OTA list "Error Codes" (ERR). The value 450 stands for "Unable to process". For the acknowledgments, the client again uses the HotelReservation element, one for each ID it wishes to acknowledge.

Here is an example where a client refuses one reservation request and acknowledges three other requests.

---- <?xml version="1.0" encoding="UTF-8"?> <OTA_NotifReportRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_NotifReportRQ.xsd" Version="1.000"> <Success/> <Warnings> <Warning Type="3" Code="450" RecordID="f054bbd2f5ebab9"> Unable to process reservation </Warning> </Warnings> <NotifDetails> <HotelNotifReport> <HotelReservations> <HotelReservation> <UniqueID Type="14" ID="6b34fe24ac2ff810"/> </HotelReservation> <HotelReservation> <UniqueID Type="15" ID="c24e8b15ca469388"/> </HotelReservation> <HotelReservation> <UniqueID Type="14" ID="1000000000000001"/> </HotelReservation> </HotelReservations> </HotelNotifReport> </NotifDetails> </OTA_NotifReportRQ> ----

The following rules apply to acknowledgements:

  • For every UniqueID, the server must remember whether or not the client has acknowledged it yet.

  • It is a client’s responsibility to send the acknowledgments - if it doesn’t, it must be prepared to deal with duplicates the next time it queries the server.

Here is a sample sequence of messages exchanged between a client and a server:

time client request server response comment [small]

08:00 [small]

action = OTA_Read:GuestRequests;
request = OTA_Read with SelectionCriteria Start today 00:00 [small]

OTA_ResRetrieveRS with UniqueID=1 (Reservation) and UniqueID=2 (Request) [small]

the server answers with today’s two requests (1 and 2)

[small]

08:01 [small]

action = OTA_NotifReport:GuestRequests;
request = OTA_NotifReportRQ with UniqueID=1 [small]

OTA_NotifReportRS Success [small]

server knows the client got 1, it will not be sent again

[small]

09:00 [small]

action = OTA_Read:GuestRequests;
request = OTA_Read [small]

OTA_ResRetrieveRS with UniqueIDs 2 and 3 (Request) [small]

the client wishes to read all new requests, 1 is not sent (since it was ack’ed), 2 is sent again and 3 is sent because it’s new

[small]

10:00 [small]

action = OTA_Read:GuestRequests;
request = OTA_Read [small]

OTA_ResRetrieveRS with UniqueIDs 2 and 3 (Request) [small]

same server response as at 09:00 because 2 and 3 were not ack’ed

[small]

10:01 [small]

action = OTA_NotifReport:GuestRequests;
request = OTA_NotifReportRQ with UniqueID=2, 3 [small]

OTA_NotifReportRS Success [small]

server now knows the client got all three

[small]

11:00 [small]

action = OTA_Read:GuestRequests;
request = OTA_Read with SelectionCriteria Start today 00:00 [small]

OTA_ResRetrieveRS with UniqueIDs 1, 2 and 3 (Request) [small]

the SelectionCriteria Start overrides the fact that all three guest requests had already been ack’ed, so the server sends all three again

4.2.4. Follow-up server response

The server will send a response indicating the outcome of the request. The response is a OTA_NotifReportRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed.

See Appendix A for details.

4.2.5. Implementation tips and best practice

The attribute RatePlanCode is mandatory for reservations and is meant to refer a reservation to the originating RatePlan. If reservations are not originated from an AlpineBits® Rateplan this information may be unavailable. In this case it is recommended to set the value of the RatePlanCode attribute to the string "Unknown" (with a capital "U", please note that OTA schemas do not allow an empty value for this attribute).

Every CurrencyCode attribute must be consistent with the originating RatePlan. In case of "Unknown" RatePlan, the currency must be one supported by the hotel or previously agreed upon for communication.

If a non-standard MealsIncluded has to be transmitted, consider using the closest standard MealsIncluded combination. This needs prior agreement among the parts, which is not covered by AlpineBits®. For example in South-Tyrol some hotels offer ¾ board (half board plus afternoon snack, hence a non-standard MealsIncluded combination) to their guests. This may be transmitted as half board, since ¾ board replaces half board for these hotels.

The value of the PhoneNumber attribute (element Telephone) should contain the standard international format (as in +<country code><phone number>) whenever possible.

Some guidelines on how to fill the fields in the HotelReservationID and Profile / CompanyInfo elements are provided here in order to allow easier grouping of the data coming from different servers.

The attributes of the HotelReservationID attributes can be mapped to the attributes used for internet marketing like in the following table:

utm_source

ResID_Source

utm_medium

ResID_SourceContext

utm_content

not present in AlpineBits®

utm_campaign

ResID_Value

We can then distinguish different use cases - here are some examples:

1. Request or reservation via homepage

  1. Direct (user types domain into browser address bar)
    ResID_Source (utm_source) = direct
    ResID_SourceContext (utm_medium) =
    ResID_Value (utm_campaign) =
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  2. Referral link to hotel site from other website
    ResID_Source (utm_source) = otherwebsite.com
    ResID_SourceContext (utm_medium) = referral
    ResID_Value (utm_campaign) =
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  3. Referral link to hotel site from portal website with campaign infos
    ResID_Source (utm_source) = portalwebsite.com
    ResID_SourceContext (utm_medium) = referral (or exact medium type of portal, e.g. "banner", "membership", "toplinks")
    ResID_Value (utm_campaign) = [campaign-name]
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  4. Search engine organic
    ResID_Source (utm_source) = google.com
    ResID_SourceContext (utm_medium) = organic_search
    ResID_Value (utm_campaign) =
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  5. Search engine paid (e.g. Google Adwords)
    ResID_Source (utm_source) = google.com
    ResID_SourceContext (utm_medium) = cpc
    ResID_Value (utm_campaign) = [campaign-name]
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  6. Social media content link (e.g. Facebook)
    ResID_Source (utm_source) = facebook.com
    ResID_SourceContext (utm_medium) = social_media
    ResID_Value (utm_campaign) = [facebook-post]
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  7. Social media paid (e.g. Facebook Ads)
    ResID_Source (utm_source) = facebook.com
    ResID_SourceContext (utm_medium) = cpc
    ResID_Value (utm_campaign) = [campaign-name]
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  8. Newsletter
    ResID_Source (utm_source) = newsletter-[company-name]
    ResID_SourceContext (utm_medium) = email
    ResID_Value (utm_campaign) = [newsletter-name] (e.g. NL 09/2017)
    Profile / CompanyInfo (travel agent / booking channel) = homepage

  9. QR code in printed magazine
    ResID_Source (utm_source) = [magazine-name] (e.g. Bergwelten)
    ResID_SourceContext (utm_medium) = qr_code
    ResID_Value (utm_campaign) = [magazine-name-and-issue] (e.g. Bergwelten 08/2017)
    Profile / CompanyInfo (travel agent / booking channel) = homepage

2. Request or reservation via landing page

  1. Bookings/enquiries on landing pages from Google Adwords
    ResID_Source (utm_source) = google.com
    ResID_SourceContext (utm_medium) = cpc
    ResID_Value (utm_campaign) = [campaign-name]
    Profile / CompanyInfo (travel agent / booking channel) = landingpage

  2. Bookings/enquiries on landing pages from portal links
    ResID_Source (utm_source) = portalwebsite.com
    ResID_SourceContext (utm_medium) = referral (or exact medium type of portal, e.g. "banner", "membership", "toplinks")
    ResID_Value (utm_campaign) = [campaign-name]
    Profile / CompanyInfo (travel agent / booking channel) = landingpage

3. Reservation on a booking platform

  1. Bookings on booking portal (e.g. Booking.com)
    ResID_Source (utm_source) = booking.com
    ResID_SourceContext (utm_medium) =
    ResID_Value (utm_campaign) =
    Profile / CompanyInfo (travel agent / booking channel) = [booking portal name] (e.g. booking.com)

  2. Bookings/enquiries on portals (e.g. suedtirolerland.it)
    ResID_Source (utm_source) = [portal name] (e.g. suedtirolerland.it)
    ResID_SourceContext (utm_medium) =
    ResID_Value (utm_campaign) =
    Profile / CompanyInfo (travel agent / booking channel) = [portal operator] (e.g. Peer.travel)

4.2.6. Requests Push client request

Starting with AlpineBits version 2018-10, a new capability was added (action_OTA_HotelResNotif_GuestRequests) to allow a push mechanism for the GuestRequest. If the capability is exposed, the Client is capable of acting as an AlpineBits Server, and the Server is capable of acting as an AlpineBits Client. This means that a few arrangements between the two parties have to be made, and those are not negotiated through AlpineBits, namely the endpoint (URL) where the client can receive the pushed GuestRequests, its credentials, etc.

The action parameter is set to the value OTA_HotelResNotif:GuestRequests and the parameter request must contain a OTA_HotelResNotifRQ document.

Please note that this message does not allow to specify a HotelCode or HotelName in the root element, this information is however provided in the corresponding attributes within each Request’s BasicPropertyInfo element. All the Request exchanged with a single message must refer to the same Hotel.

The request must contain a single HotelReservations element with zero or more HotelReservation elements containing the requested information (zero elements indicate the client has no information for the server, but the Client should not initiate a transfer in this case). As for the content of the HotelReservation element, refer to section 4.2.2.

All the GuestRequests described above (e.g. Booking Requests, Quote Requests, Cancellations) can be pushed by using this mechanism.

4.2.7 Requests Push server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelResNotifRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed.

See Appendix A for details.

In case of success, the OTA_HotelResNotifRS response will contain a single, empty Success element followed by a HotelReservations element with zero or more HotelReservation elements. Each HotelReservation element must contain only a single UniqueID element with the Type and [xml_attribute_name]#ID" attributes referring to one of the GuestRequests the Client sent (quotes, reservations or cancellations).

Each request that could not be processed must be listed in a Warning element, where the RecordID attribute refers to the request ID and Type and Code refer to the reason of the refusal.

---- <?xml version="1.0" encoding="UTF-8"?> <OTA_HotelResNotifRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelResNotifRS.xsd" Version="1.000"> <Success/> <Warnings> <Warning Type="3" Code="450" RecordID="f054bbd2f5ebab9">Unable to process reservation</Warning> </Warnings> <HotelReservations> <HotelReservation> <UniqueID Type="14" ID="6b34fe24ac2ff810"/> </HotelReservation> <HotelReservation> <UniqueID Type="15" ID="c24e8b15ca469388"/> </HotelReservation> <HotelReservation> <UniqueID Type="14" ID="1000000000000001"/> </HotelReservation> </HotelReservations> </OTA_HotelResNotifRS> ----

4.2.8 Guest Requests status update

Starting with AlpineBits® version 2022-10, clients can send status updates of a given guest request to the server.

The action parameter is set to the value OTA_HotelResNotif:GuestRequests_StatusUpdate and the request parameter must contain a OTA_HotelResNotifRQ document.

The request must contain a single HotelReservations element with one or more HotelReservation elements containing the guest request status update.

Each HotelReservation element must contain the mandatory attributes ResStatus and CreateDateTime (the first timestamp recorded by the client for the guest request). The possible values for the ResStatus attribute expected by AlpineBits® are:

  • Reserved - this is a booking reservation.

  • Cancelled - this is a booking cancellation.

A HotelReservation element may contain the LastModifyDateTime attribute which identifies the timestamp of modification. If the LastModifyDateTime attribute is not specified, the timestamp of the request may be used instead.

Each HotelReservation element contains a mandatory UniqueID element which itself contains the mandatory ID and Type attributes. The ID attribute must match the unique HotelReservation identifier previously sent by the server. The Type attribute is set according to the OTA Unique Id Type (UIT) list.

The Type attribute value must be consistent with the ResStatus attribute of the surrounding HotelReservation element:

  • For ResStatus = Reserved, the Type must be 14 (Reservation).

  • For ResStatus = Cancelled, the Type must be 15 (Cancellation).

Below is an example of a status update sent from a client for some guest requests.

---- <HotelReservations> <HotelReservation ResStatus="Reserved" CreateDateTime="2023-03-21T11:00:00+01:00"> <UniqueID Type="14" ID="6b34fe24ac999999"/> </HotelReservation> <HotelReservation ResStatus="Cancelled" CreateDateTime="2023-05-12T19:00:00+01:00"> <UniqueID Type="15" ID="6b34fe24ac244444"/> </HotelReservation> </HotelReservations> ----

The server’s response is the same as that described in Chapter 4.2.7.

4.3. SimplePackages: package availability notifications (removed)

This feature has been removed with version 2017-10.

SimplePackages can be still used by servers and clients supporting previous versions of the standard (from 2012-05 to 2015-07b).

4.4. Inventory: room category information

The Inventory request allows up to four values for the action parameter (depending on the server exposed capabilities):

  • OTA_HotelDescriptiveContentNotif:Inventory indicates the client wishes to define a room category, send its basic description and optionally provide a list of specific rooms for each category (see section Inventory/Basic (push)).

  • OTA_HotelDescriptiveInfo:Inventory indicates the client wishes to retrieve the information about room category, basic description and the list of specific rooms (see section Inventory/Basic (pull)).

  • OTA_HotelDescriptiveContentNotif:Info indicates the client wishes to send additional descriptive content (see section Inventory/HotelInfo (push)).

  • OTA_HotelDescriptiveInfo:Info indicates the client wishes to retrieve the additional descriptive content (see section Inventory/HotelInfo (pull)).

4.4.1. Inventory/Basic (push) client request

The parameter request contains an OTA_HotelDescriptiveContentNotifRQ document.

Each document contains one HotelDescriptiveContent element. For the attributes HotelCode and HotelName the rules are the same as for room availability notifications (section 4.1.1). Note that information about only one hotel per message can be transmitted.

Nested inside HotelDescriptiveContent, an FacilityInfo element contains a list of zero or more GuestRoom elements. There are two distinct kinds of GuestRoom elements:

  • The heading one is used to define a room category and its basic description (the category is identified by the attribute Code).

  • The following ones list specific rooms for each category (identified by the attribute Code).

More than one category can be transmitted. That means a category defining sequence of one-heading- GuestRoom-element plus zero or more following- GuestRoom-elements can be repeated for each category.

Sending zero GuestRoom elements (meaning an empty GuestRooms element) will remove all room categories for the given hotel.

Below is an example of the global structure of such a document:

<OTA_HotelDescriptiveContentNotifRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelDescriptiveContentNotifRQ.xsd" Version="8.000"> <HotelDescriptiveContents> <HotelDescriptiveContent HotelCode="123" HotelName="Frangart Inn"> <FacilityInfo> <GuestRooms> <!-- the heading GuestRoom element is used to define a category and its basic description -→ <GuestRoom Code="DZ" MaxOccupancy="2" MinOccupancy="1" MaxChildOccupancy="1"> </GuestRoom> <!-- the follow-up GuestRoom elements list the specific rooms in the category -→ <GuestRoom Code="DZ"> <TypeRoom RoomID="101"/> </GuestRoom> <GuestRoom Code="DZ"> <TypeRoom RoomID="102"/> </GuestRoom> </GuestRooms> </FacilityInfo> </HotelDescriptiveContent> </HotelDescriptiveContents> </OTA_HotelDescriptiveContentNotifRQ>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-basic.xml - outer part

The heading GuestRoom element, used to define a room category and its basic description, contains the following attributes:

  • Code: mandatory, identifies the category.

  • MinOccupancy: mandatory, sets the minimum number of guests allowed for this room category.

  • MaxOccupancy: mandatory, sets the maximum number of guests allowed for this room category.

  • MaxChildOccupancy: optional, must be 0 ≤ MaxChildOccupancyMaxOccupancy. This attribute can be used to influence the computation of the total cost of the stay in the presence of children (see section 4.5 under "Computing the cost of a stay" for details). Note that this attribute cannot be used to disallow children in a stay. This attribute may only be used if the capability OTA_HotelDescriptiveContentNotif_Inventory_occupancy_children is announced by the server.

  • ID: optional, used for updating room category codes (see remarks at the end of this section)

The heading GuestRoom element also contains the following sub-elements:

  • TypeRoom: mandatory element with the attributes:

    • StandardOccupancy (mandatory)

    • RoomClassificationCode (mandatory) to classify the kind of guest room following the OTA list "Guest Room Info" (GRI) - 42 means just "Room", 13 means "Apartments", "5" means "Pitches", etc…​

    • RoomType (optional) to allow a more exact classification of the guest accommodation (see below)

    • Size (optional)

  • Amenities: optional element containing a list of Amenity elements, each indentified by the mandatory attribute RoomAmenityCode following the OTA list "Room Amenity Type" (RMA).

  • MultimediaDescription: one or more elements with an InfoCode attribute with certain values (a subset of the OTA list "Information type" (INF)):

    • Exactly one MultimediaDescription element with attribute InfoCode = 25 (Long name) indicating a title must be present.

    • At most one MultimediaDescription element with attribute InfoCode = 1 (Description) may be present.

    • At most one MultimediaDescription element with attribute InfoCode = 23 (Pictures) may be present.

Regarding the optional attribute RoomType, the allowed values are defined by AlpineBits® as follows:

  • For rooms: RoomType value 1 (should only be used when RoomClassificationCode is 42).

  • For apartments: RoomType value 2 (should only be used when RoomClassificationCode is 13).

  • For mobile homes: RoomType value 3 (should only be used when RoomClassificationCode is 13).

  • For bungalows: RoomType value 4 (should only be used when RoomClassificationCode is 13).

  • For holiday homes: RoomType value 5 (should only be used when RoomClassificationCode is 13).

  • For camping grounds (place for vehicles in a camping): RoomType value 6 (should only be used when RoomClassificationCode is 5).

  • For pitches (place for tents in a camping): RoomType value 7 (should only be used when RoomClassificationCode is 5).

  • For camping grounds/pitches (place for either tents or vehicles in a camping): RoomType value 8 (should only be used when RoomClassificationCode is 5).

  • For resting places (beds in shared rooms, like hostels or mountain huts): RoomType value 9 (should only be used when RoomClassificationCode is 42).

Here is an example of such a heading GuestRoom element:

<GuestRoom Code="DZ" MaxOccupancy="2" MinOccupancy="1" MaxChildOccupancy="1"> <TypeRoom StandardOccupancy="2" RoomClassificationCode="42"/> <Amenities> <Amenity RoomAmenityCode="26"/> </Amenities> <MultimediaDescriptions> <MultimediaDescription InfoCode="25"> </MultimediaDescription> <MultimediaDescription InfoCode="1"> </MultimediaDescription> <MultimediaDescription InfoCode="23"> </MultimediaDescription> </MultimediaDescriptions> </GuestRoom>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-basic.xml - a heading GuestRoom element

The MultimediaDescription elements follow these rules:

  • A MultimediaDescription element with attribute InfoCode = 25 or 1 must contain only a single TextItem element.

  • A MultimediaDescription element with attribute InfoCode = 23 contains only ImageItem elements (one or more).

Here is an example:

<MultimediaDescriptions> <MultimediaDescription InfoCode="25"> <TextItems> <TextItem> <Description TextFormat="PlainText" Language="en"> Double room</Description> <Description TextFormat="PlainText" Language="de"> Doppelzimmer</Description> <Description TextFormat="PlainText" Language="it"> Camera doppia</Description> </TextItem> </TextItems> </MultimediaDescription> <MultimediaDescription InfoCode="1"> <TextItems> <TextItem> <Description TextFormat="PlainText" Language="en"> Description of the double room.</Description> <Description TextFormat="PlainText" Language="de"> Doppelzimmer Beschreibung.</Description> <Description TextFormat="PlainText" Language="it"> Descrizione della camera doppia.</Description> </TextItem> </TextItems> </MultimediaDescription> <MultimediaDescription InfoCode="23"> <ImageItems> <ImageItem Category="6"> <ImageFormat CopyrightNotice="Copyright notice 2015"> <URL>http://www.example.com/image.jpg</URL> </ImageFormat> <Description TextFormat="PlainText" Language="en"> Picture of the room</Description> <Description TextFormat="PlainText" Language="de"> Zimmerbild</Description> <Description TextFormat="PlainText" Language="it"> Immagine della stanza</Description> </ImageItem> </ImageItems> </MultimediaDescription> <MultimediaDescriptions>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-basic.xml - MultimediaDescription elements

TextItems contains a TextItem element, which must contain one or more Description elements, each with the mandatory attributes TextFormat and Language.

The following rules hold:

  • The attribute TextFormat is set to PlainText or HTML and the attribute Language is set to a two-letter lowercase language abbreviation according to ISO 639-1. At most one Text element is allowed for each combination of Language and TextFormat.

  • The presence of a TextItem element with TextFormat set to HTML is intended as a rich text alternative of a TextItem element with TextFormat set to PlainText of the same Language and makes the latter mandatory.

  • Please note that an AlpineBits® server is explicitly allowed to filter, shorten or even skip the HTML content, therefore the usage of TextItem elements with TextFormat set to HTML is not recommended but left as an option for implementers that absolutely need it.

ImageItems contains a list of one or more ImageItem elements with mandatory Category attribute following the OTA list "Picture Category Code" (PIC). Typical values are 6 (Guest Room) and 17 (Map) but the whole table is allowed. The ImageItem element contains a single, mandatory ImageFormat element with the optional attribute CopyrightNotice. Inside, a single mandatory element URL, holds the URL where the picture can be retrieved as its value. Zero or more Description elements follow, under the same rules outlined above for descriptions contained in the element TextItem. Images should be processed by the server in the order they are submitted (i.e. the order used to show the pictures the to end users should be consistent with the one sent by the client).

The following GuestRoom element lists all the rooms belonging to a category, as we’ve seen in the first code sample, repeated here:

<!-- the follow-up GuestRoom elements list the specific rooms in the category -→ <GuestRoom Code="DZ"> <TypeRoom RoomID="101"/> </GuestRoom> <GuestRoom Code="DZ"> <TypeRoom RoomID="102"/> </GuestRoom>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-basic.xml - part showing follow-up GuestRoom elements

Following GuestRoom elements have a mandatory Code attribute that identifies the category the specific room belongs to. No further attributes are allowed.

They also have a mandatory sub-element TypeRoom with a mandatory attribute RoomID that identifies the specific room. No further elements or attributes are allowed, included (but not limited to) the MultimediaDescription element.

If a server sets the capability OTA_HotelDescriptiveContentNotif_Inventory_use_rooms, a client must send the full list of rooms and the server must store it.

Otherwise, if a server does not set that capability, a client might or might not send the room list. A server that has no use for the room list is then free to discard it upon receiving them, but must do so silently (i.e. without returning errors or warnings).

Some remarks.

Note that AlpineBits® does not support deltas for Inventory/Basic (push) requests. After successfully processing a request, any previous data sent via an Inventory/Basic (push) request (and only the data sent via an Inventory/Basic (push) request) must be removed.

Moreover, all Inventory/HotelInfo, FreeRooms or RatePlans data that refer to any now missing room categories must be considered outdated.

Also note that categories in inventories should refer to physical inventories. They must not be used as logical inventories. For example it is not allowed to introduce an inventory with code suite-x and one withcode suite-x-special-offer for the purpose of modeling two different products from the same inventory (RatePlans will take care of that).

It happens that hotels change room category codes (for whatever reason). It is therefore important that these changes are communicated to the server in order to avoid losing any data linked to the renamed categories. The old code of the room category can be transferred via the attribute ID of the heading GuestRoom elements.

Here is an example:

<HotelDescriptiveContent HotelCode="123" HotelName="Frangart Inn"> <FacilityInfo> <GuestRooms> <GuestRoom Code="single" MaxOccupancy="2" MinOccupancy="1" ID="EZ"> <TypeRoom StandardOccupancy="2" RoomClassificationCode="42"/> </GuestRoom> <GuestRoom Code="double" MaxOccupancy="2" MinOccupancy="1" ID="DZ"> <TypeRoom StandardOccupancy="2" RoomClassificationCode="42"/> </GuestRoom> </GuestRooms> </FacilityInfo> </HotelDescriptiveContent>

The server will first look for a category "single". If that’s found, the server will silently ignore the ID attribute and replace the data it had on record for "single".

If "single" is not found, the server will look for a category "EZ". If that’s found, the server must rename it to "single". If "EZ" is not found either, the server will just store the new category "single".

This makes sure that "EZ" is renamed to "single", without causing problems if "EZ" wasn’t known in the first place or in case the renaming has already happened.

The same procedure is to be applied for "DZ" renamed to "double".

4.4.2. Inventory/Basic (push) server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelDescriptiveContentNotifRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed.

See Appendix A for details.

4.4.3. Inventory/Basic (pull) client request

The parameter request contains an OTA_HotelDescriptiveInfoRQ document.

Analogous to the Inventory/Basic (push) request, a client can send a pull request to query the basic data the server has stored about a hotel.

Here is such a client request:

<OTA_HotelDescriptiveInfoRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" Version="3.000"> <HotelDescriptiveInfos> <HotelDescriptiveInfo HotelCode="123" HotelName="Frangart Inn"/> </HotelDescriptiveInfos> </OTA_HotelDescriptiveInfoRQ>

samples/Inventory/Inventory-Pull-OTA_HotelDescriptiveInfoRQ-basic.xml

As expected, the document must contain one HotelDescriptiveInfo element with attributes HotelCode and HotelName that follow the same rules as for room availability notifications (section 4.1.1). Again, information about only one hotel per message can be queried.

Please note that the content of the XML message is identical, both for Inventory/Basic (pull) and Inventory/HotelInfo (pull), but the action is used by the server to distinguish the two requests.

4.4.4. Inventory/Basic (pull) server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelDescriptiveInfoRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed. See Appendix A for details.

In case of a successful outcome, the Success element is followed by a HotelDescriptiveContent element with the information about the hotel.

Here is such a server response. The complete file is in the developer kit.

<OTA_HotelDescriptiveInfoRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" Version="3.000"> <Success/> <HotelDescriptiveContents> <HotelDescriptiveContent HotelCode="123" HotelName="Frangart Inn"> </HotelDescriptiveContents> </HotelDescriptiveContents> </OTA_HotelDescriptiveInfoRS>

samples/InventoryInventory-Pull-OTA_HotelDescriptiveInfoRS-basic.xml - outer part

4.4.5. Inventory/HotelInfo (push) client request

The Inventory/HotelInfo message is used to exchange detailed descriptive information about a property such as:

  • Property name / type / category

  • Short/long descriptions

  • Logos, seasonal pictures, gallery pictures, videos

  • City id, latitude, longitude and elevation

  • Property amenities

  • Review ranking

  • Address info and contact info: telephone, email, urls

and descriptive policies info:

  • Cancellation

  • Extra charges

  • Pets

  • City tax

  • Guarantee and accepted payment methods

  • Check-in and check-out range

All policies information is intended for descriptive purposes only and do not alter room availability and price calculation.

Every transmission must be considered as a CompleteSet and will overwrite all previous Inventory/HotelInfo data (although the server will of course not replace any Inventory/Basic (push) data it has on record).

The client sends everything it wants to share with the server.

The server decides what to save and what to ignore of the Inventory/HotelInfo message, depending on the permissions dictated by the server business logic associated with the client account.

Consider the outer part of the OTA_HotelDescriptiveContentNotifRQ document:

<OTA_HotelDescriptiveContentNotifRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelDescriptiveContentNotifRQ.xsd" Version="8.000"> <HotelDescriptiveContents> <HotelDescriptiveContent HotelCode="123" HotelName="Frangart Inn" AreaID="3181913"> <HotelInfo> <CategoryCodes> …​ </CategoryCodes> <Descriptions> …​ </Descriptions> <Position/> <Services> …​ </Services> </HotelInfo> <Policies> …​ </Policies> <AffiliationInfo> …​ </AffiliationInfo> <ContactInfos> …​ </ContactInfos> </HotelDescriptiveContent> </HotelDescriptiveContents> </OTA_HotelDescriptiveContentNotifRQ>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-hotelInfo.xml - outer part

Structure of HotelDescriptiveContent.

HotelDescriptiveContent element must have an HotelCode attribute with a unique property ID and an HotelName attribute with the property name. AlpineBits® allows the following child-element right below HotelDescriptiveContent:

Part I: HotelInfo element

At most one HotelInfo element which contain property classifications and multimedia information. If present, HotelInfo holds at least one of these elements:

CategoryCodes at most one element, if present hold one HotelCategory element. CategoryCodes element contain information about the property type and category. HotelCategory has one CodeDetail attribute used to identify the property type and class value.

CodeDetail attribute is a string composed by two elements separated by colon: <CustomPropertyTypeTable_Value>:<ClassValue>.

  • CustomPropertyTypeTable_Value substring is a composition of 'CustomPropertyTypeTable' intended as the name of a custom property type table, the _ char used as separator and the value of the table that identify the property type. Partners are free to adopt their own custom tables.

  • ClassValue substring is intended as the property class value. Es. 4 for 4 stars or 4s for 4 stars superior properties.

Two examples of CodeDetail attribute content may be:

  • PCT2017_20:4s where PCT2017_20 is the reference to OTA (PCT) Property Class Type Codes (Version 2017) and its relative value, in this case 20 means Hotel. The string 4s after the colon character is the class value of the property.

  • ASTAT2020_11:4s where ASTAT2020_11 is the custom reference property type table name and its relative value. The string 4s after the colon character is the class value of the property. (In this example, ASTAT2020 is intended as the property type table defined by the Provincial Statistical Institute of the Autonomous Province of Bolzano for the year 2020).

At most one Descriptions element which contains descriptive information like long/short property description, photos and videos. If Descriptions element is present, hold one MultimediaDescriptions element, which contain one or more MultimediaDescription element. MultimediaDescription element must have an InfoCode attribute with a subset value of Information Type Code (INF):

  • 1 for a long description

  • 17 for a short description

  • 23 for pictures

  • 24 for videos

If InfoCode attribute is set to 1 or 17, the inner element must be one TextItems.

TextItems must have one or more TextItem with SourceID and CopyrightNotice attributes which are optionals.

CopyrightNotice attributes is optional and is used to transmit Copyright information.

TextItem element must contain one or more Description elements, each with the mandatory attributes TextFormat and Language.

The following rules hold:

  • The attribute TextFormat is set to PlainText or HTML and the attribute Language is set to a two-letter lowercase language abbreviation according to ISO 639-1. At most one Text element is allowed for each combination of Language and TextFormat.

  • The presence of a TextItem element with TextFormat set to HTML is intended as rich text alternative of a TextItem element with TextFormat set to PlainText of the same Language and makes the latter mandatory.

  • Please note that an AlpineBits® server is explicitly allowed to filter, shorten or even skip the HTML content, therefore the usage of TextItem elements with TextFormat set to HTML is not recommended but left as an option for implementers that absolutely need it.

If InfoCode attribute is set to 23, the inner element must be one ImageItems which contains one or more ImageItem elements. ImageItem elements have a mandatory Category attribute that explain the nature of the image. The value of this attribute is a subset of Picture Category Code (PIC).

  • 1 for an exterior view

  • 2 for a lobby view

  • 4 for a restaurant

  • 12 for a spa

  • 15 for a logo

  • 22 for a property amenity

Inside of ImageItem element must be present one ImageFormat element and zero or more Description elements. ImageFormat element could have four optional attributes:

  • CopyrightNotice attribute describe the copyright informations about the image.

  • SourceID attribute is an unique identifier that may be used by reciever to verify with the sender if there is the need to download the image.

  • ApplicableStart and ApplicableEnd attributes are used to suggest the seasonality of images. The format is --MM-DD, where MM is the month (01-12) and DD is the day (01-31).

Inside of ImageFormat one URL element is present with the reference to the image to download. The Description element follows the same rules of Description elements described in the long/short description case (InfoCode = 1 or 17).

If InfoCode attribute is set to 24, the inner element must be one VideoItems which contains one or more VideoItem elements. VideoItem elements have a mandatory Category attribute that explain the nature of the video. The value of this attribute is a subset of Picture Category Code (PIC).

  • 1 for exterior view

  • 2 for lobby view

  • 4 for restaurant

  • 12 for spa

  • 20 for Miscellaneous

  • 22 for property amenity

Inside of VideoItem element there must be one VideoFormat element present and zero or more Description elements. The VideoFormat element follows the same rules as the ImageFormat elements.

At most one Position element which contains geographic coordinates and elevation information of the property. If Position element is present it’s mandatory to have at least one of these couple of attributes:

  • Latitude and Longitude coordinates expressed in decimal degrees. The decimal separator is the point symbol.

  • Altitude and AltitudeUnitOfMeasureCode. Where AltitudeUnitOfMeasureCode attribute describe the unit of measure. See Unit of Measure Code (UOM) for reference. For Meters use code 3.

At most one Services element which contain a list of property amenities. If the Services element is present, must contain one or more Service elements. Each Service element has two mandatory attributes:

  • Code attribute identifies the facility code. See Hotel Amenity Codes (HAC) for reference.

  • ProximityCode attribute identifies where the service is located. See Proximity code (PRX) for reference.

Inside of Service with Code attribute set to 47, may be present at most one Features element that may contain zero or more Feature elements. Each Feature elements must have an AccessibleCode attribute which contain a Disability Feature Code (PHY) value.

There is another special case where half board needs to be seen as ¾ board when defining Service element with Code attribute set to 342 (Snack bar) in combination with MealPlanCode attribute set to 12 and Included attribute set to true.

Example of HotelInfo element:

<HotelInfo> <CategoryCodes> <HotelCategory CodeDetail="ASTAT2020_11:4s"/> </CategoryCodes> <Descriptions> <MultimediaDescriptions> <MultimediaDescription InfoCode="1"> <TextItems> <TextItem CopyrightNotice="Other copyright"> <Description Language="en" TextFormat="PlainText">A long description</Description> </TextItem> <TextItem CopyrightNotice="Other copyright"> <Description Language="de" TextFormat="PlainText">erweiterte Beschreibung</Description> </TextItem> <TextItem CopyrightNotice="Other copyright"> <Description Language="it" TextFormat="PlainText">Descrizione lunga</Description> </TextItem> </TextItems> </MultimediaDescription> <MultimediaDescription InfoCode="23"> <ImageItems> <ImageItem Category="1"> <ImageFormat CopyrightNotice="Image copyright" SourceID="56757e0211440d37910f407fb6f657fb" ApplicableStart="--09-30" ApplicableEnd="--03-30"> <URL>https://…​./HotelExteriorWinterView.jpg</URL> </ImageFormat> <Description TextFormat="PlainText" Language="en">Image description</Description> </ImageItem> </ImageItems> </MultimediaDescription> </MultimediaDescriptions> </Descriptions> <Position Altitude="200" AltitudeUnitOfMeasureCode="3" Latitude="46.1372647" Longitude="12.2011353"/> <Services> <Service Code="68" ProximityCode="2"/> <Service Code="47" ProximityCode="3"> <Features> <Feature AccessibleCode="8"/> </Features> </Service> </Services> </HotelInfo>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-hotelInfo.xml - outer part

Part II: Policies element

At most one Policies element which contain all the property policies. If present, Policies hold one or more Policy child-elements which in turn contain exactly one of these elements:

At most one CancelPolicy element which contain descriptive information about cancellation policies. If present, CancelPolicy element must contain one CancelPenalty element. CancelPenalty element contain one PenaltyDescription element which contain one or more Text elements. Each Text element contain a cancellation description for a specific language. Text elements must have TextFormat and Language attributes.

The following rules hold:

  • The attribute TextFormat is set to PlainText or HTML and the attribute Language is set to a two-letter lowercase language abbreviation according to ISO 639-1. At most one Text element is allowed for each combination of Language and TextFormat.

  • The presence of a Text element with TextFormat set to HTML is intended as a rich text alternative of a Text element with TextFormat set to PlainText of the same Language and makes the latter mandatory.

  • Please note that an AlpineBits® server is explicitly allowed to filter, shorten or even skip the HTML content, therefore the usage of Text elements with TextFormat set to HTML is not recommended but left as an option for implementers that absolutely need it.

At most one CheckoutCharges element containing descriptive information about check-out charge policies. If present, the CheckoutCharges element must contain one CheckoutCharge element. CheckoutCharge element may have an optional Amount attribute. If the Amount attribute is present, then the CurrencyCode must be present too. The CheckoutCharge element contains one Description element which contains one or more Text elements. Every Text element contains check-out descriptive information for a specific language. Text elements follow the same rules of Text elements described in CancelPolicy case.

At most one PetsPolicies element which contain descriptive information about pet policies. If present, PetsPolicies element must contain one PetsPolicy element. PetsPolicy element may have an optional MaxPetQuantity attribute and NonRefundableFee. If NonRefundableFee attribute is present, then the CurrencyCode must be present too. The PetsPolicy element contains one Description element which contains one or more Text elements. Every Text element contains pets policies descriptive information for a specific language. The Text elements follow the same rules of Text elements described in CancelPolicy case.

At most one TaxPolicies element which contains descriptive information about tax policies. If present, the TaxPolicies element must contain one TaxPolicy element. The TaxPolicy element has the following attributes:

  • Must have a Code attribute with value 3 = City Tax. (See Fee Tax Type FTT CodeList).

  • May have an optional Amount attribute. If the Amount attribute is present,the ChargeFrequency attribute with value 1 = Daily (See CHG Charge Type Codes) and the ChargeUnit attribute with value 21 = Per Person/night (See CHG Charge Type Codes) as well as the CurrencyCode must be present too.

For example, in case of a 2€ daily city tax per person, TaxPolicy attributes are: Code = 3, Amount = 200, ChargeFrequency = 1, ChargeUnit = 21.

The TaxPolicy element contains one TaxDescription element which contains one or more Text elements. Every Text element contains tax descriptive information for a specific language. Text elements follow the same rules of Text elements described in CancelPolicy case.

At most one GuaranteePaymentPolicy element which contains descriptive information about payment methods and guarantee policies. If present, GuaranteePaymentPolicy element must contain one GuaranteePayment element. GuaranteePayment element contain at most one AcceptedPayments element which contain one or more AcceptedPayment elements.

Each AcceptedPayment element contain one of these elements:

  • BankAcct which must contain BankAcctName for the name of the bank, BankAcctNumber with sub element PlainText where insert IBAN number and finally the BankID element with sub element PlainText for the SWIFT field.

  • Cash element with a mandatory CashIndicator attribute with value true or false.

  • PaymentCard element with a mandatory CardCode attribute with an OTA Payment Card Code Type.

    • At most one AmountPercent element. If present, AmountPercent element must have a Percent attribute set.

    • At most one Deadline element which defines the timeout for confirming the booking via deposit. If Deadline element is present, OffsetDropTime, OffsetTimeUnit and OffsetUnitMultiplier attributes are mandatory.

At most one StayRequirements element which contains descriptive information about check-in and check-out policies. If present, StayRequirements element must contain one or two StayRequirement elements. StayRequirement must have three attributes:

  • StayContext must be Checkin for check-in information or Checkout for check-out info.

  • Start must be a time e.g. 15:00:00.

  • End must be a time e.g. 20:00:00.

Example of Policies element:

<Policies> <Policy> <StayRequirements> <StayRequirement StayContext="Checkin" Start="15:00:00" End="20:00:00"/> <StayRequirement StayContext="Checkout" Start="06:00:00" End="10:00:00"/> </StayRequirements> </Policy> </Policies>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-hotelInfo.xml - outer part

Part III: The AffiliationInfo element

At most one AffiliationInfo element which contains aggregate review information. If present, AffiliationInfo holds one Awards element which contains one or more Award elements. Each Award elements must have the following attributes:

  • Rating is mandatory and provide the rating value of the aggregate review.

  • Provider is mandatory and provide the review provider.

  • OfficialAppointmentInd is optional and when it’s true indicate that the receiver has received official permission from the review provider to publish review info. If this attribute is not present it must be considered false.

Please note:

  • The review scale for Rating depends by the service provider specified by Provider attribute.

  • The transmitter must send the Rating as it is sent by the service provider.

  • The receiver must read the documentation of the service provider to know the scale value.

  • The Provider attribute value must be all uppercase. e.g. TRUSTYOU, TRIPADVISOR, TRUSTPILOT

Example of AffiliationInfo element:

<AffiliationInfo> <Awards> <Award Rating="95" Provider="TRUSTYOU" OfficialAppointmentInd="false"/> </Awards> </AffiliationInfo>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-hotelInfo.xml - outer part

Part IV: ContactInfos element

At most one ContactInfos element which contains contact information of the property. e.g. address, email, phone numbers, urls. If present, the ContactInfos holds one ContactInfo element with the attribute Location that must have value 6 ("Hotel direct contact" according to CON codelist) which contain at least one of these child elements:

At most one Addresses element which contains one or more Address elements. Each Address element must have a different Language attribute. If present, Address must contain at least following attributes: AddressLine, CityName, PostalCode and CountryName fields.

At most one Phones element which contains one or more Phone elements. Each Phone element has a mandatory PhoneTechType attribute and a mandatory PhoneNumber attribute.

At most one Emails element which contains one or more Email elements. Each Email element has a mandatory EmailType attribute.

At most one URLs element which contain one or more URL elements. Each URL element, if the ID attribute is specified it must follow rules described below. The content of the URL element must be a valid URI * despite its name, the content of URL may be any URI, so besides http(s) urls, also other schemes might be specified. URNs are allowed as well and in this case the schema must be id.

AlpineBits® defines some values for the ID attribute that should be recognized by servers and clients:

  • WEBSITE: for the lodging structure’s official website

  • TRUSTYOU: for the lodging structure’s presence on trustyou.com

  • TRIPADVISOR: for the lodging structure’s presence on tripadvisor.com

  • TWITTER: for the lodging structure’s presence on twitter.com

  • FACEBOOK: for the lodging structure’s presence on facebook.com

  • INSTAGRAM: for the lodging structure’s presence on instagram.com

  • YOUTUBE: for the lodging structure’s presence on youtube.com

Partners are allowed to define further values but the value of the attribute must be all uppercase. Lodging’s official website url must be free of referral parameters. The server can delete any parameters not allowed.

At most one CompanyName element which contains the name of the company.

Example of ContactInfos element:

<ContactInfos> <ContactInfo Location="6"> <Addresses> <Address Language="it"> <AddressLine>Via Bolzano 63/A</AddressLine> <CityName>Bolzano</CityName> <PostalCode>39057</PostalCode> <StateProv StateCode="BZ"/> <CountryName Code="IT"/> </Address> </Addresses> <Phones> <Phone PhoneTechType="1" PhoneNumber="+3903720000000"/> </Phones> <Emails> <Email EmailType="5">info@alpinebits.org</Email> </Emails> <URLs> <URL ID="WEBSITE">https://www.alpinebits.org/</URL> <URL ID="FACEBOOK">https://www.facebook.com/alpinebits/</URL> </URLs> </ContactInfo> </ContactInfos>

samples/Inventory/Inventory-Push-OTA_HotelDescriptiveContentNotifRQ-hotelInfo.xml - outer part

4.4.6. Inventory/HotelInfo (push) server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelDescriptiveContentNotifRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed.

See Appendix A for details.

4.4.7. Inventory/HotelInfo (pull) client request

The request parameter contains an OTA_HotelDescriptiveInfoRQ document.

Analogous to the Inventory/HotelInfo (push) request, a client can send a pull request to query the additional data the server has stored about a hotel.

Here is such a client request:

<OTA_HotelDescriptiveInfoRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" Version="3.000"> <HotelDescriptiveInfos> <HotelDescriptiveInfo HotelCode="123" HotelName="Frangart Inn"/> </HotelDescriptiveInfos> </OTA_HotelDescriptiveInfoRQ>

samples/Inventory/Inventory-Pull-OTA_HotelDescriptiveInfoRQ-hotelinfo.xml

As expected, the document must contain one HotelDescriptiveInfo element with attributes HotelCode and HotelName that follow the same rules as for room availability notifications (section 4.1.1). Again, information about only one hotel per message can be queried.

Please note that the content of the XML message is identical both for Inventory/Basic (pull) and Inventory/HotelInfo (pull), but the action is different and is used to distinguish the two requests.

4.4.8. Inventory/HotelInfo (pull) server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelDescriptiveInfoRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed. See Appendix A for details.

In case of a successful outcome, the Success element is followed by a HotelDescriptiveContent element with the information about the hotel.

<OTA_HotelDescriptiveInfoRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" Version="3.000"> <Success/> <HotelDescriptiveContents> <HotelDescriptiveContent HotelCode="123" HotelName="Frangart Inn"> </HotelDescriptiveContents> </HotelDescriptiveContents> </OTA_HotelDescriptiveInfoRS>

samples/Inventory/Inventory-Pull-OTA_HotelDescriptiveInfoRS-hotelinfo.xml - outer part

4.4.9. Implementation tips and best practice

Please note that section 4.4 has been changed multiple times since its creation. See appendix C for compatibility information.

4.5. RatePlans

If the action parameter is OTA_HotelRatePlanNotif:RatePlans the client sends information about rates and related rules.

4.5.1. Client request

The request parameter contains an OTA_HotelRatePlanNotifRQ document.

Each document contains one RatePlans element. For the attributes HotelCode and HotelName the rules are the same as for room availability notifications (section 4.1). Note that requests are limited to one hotel per message.

Nested inside RatePlans are RatePlan elements, one for each rate plan. The RatePlan element has the following mandatory attributes (but see the next section for exceptions):

  • RatePlanNotifType is either New, Overlay or Remove (see section "Synchronization" below).

  • CurrencyCode is the currency in which all amounts are expressed, it must be one of the ISO 4217 currency codes.

  • RatePlanCode is the rate plan ID.

The optional RatePlan attributes RatePlanType and RatePlanCategory are used to transmit special offers and are defined as follows: A special offer or package presented by the hotel must set RatePlanType to 12 (means "Promotional") and must not set the RatePlanCategory attribute. An offer or package campaigned by a third party (such as a consortium or a tourist organization) in which the hotel participates must set RatePlanType to 12 and also the RatePlanCategory attribute with a value defined by the third party.

The two optional attributes RatePlanID and RatePlanQualifier may be used by the client to identify a "master" rateplan and its alternative versions if the server supports them (see section about joining rate plans).

Each RatePlan element contains, in order:

  • Zero or more BookingRule elements: used to restrict the applicability of the rate plan to a given stay - zero means no restrictions.

  • Zero or more Rate elements: indicate the cost of stay.

  • Zero or more Supplement elements: to specify supplements such as final cleaning fees or similar extras.

  • One Offer element with one OfferRule element: it defines the cut-off age above which guests are considered adults, the allowed age range for children (or whether children are allowed at all), and optionally introduces more restrictions to the applicability of the rate plan.

  • Zero, one or two additional Offer elements: indicates potential discounts such as free nights or kids that go free.

  • Zero to five Description elements.

Here is the global structure of the document:

<?xml version="1.0" encoding="UTF-8"?> <OTA_HotelRatePlanNotifRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelRatePlanNotifRQ.xsd" Version="1.000"> <RatePlans HotelCode="123" HotelName="Frangart Inn"> <RatePlan RatePlanNotifType="New" CurrencyCode="EUR" RatePlanCode="Rate1-4-HB"> <BookingRules> <BookingRule Start="2014-03-03" End="2014-04-17"> …​ </BookingRule> </BookingRules> <Rates> <Rate> …​ </Rate> </Rates> <Supplements> <Supplement> …​ </Supplement> </Supplements> <Offers> <Offer> …​ </Offer> </Offers> <Description Name="title"> </Description> </RatePlan> </RatePlans> </OTA_HotelRatePlanNotifRQ>

samples/RatePlans/RatePlans-OTA_HotelRatePlanNotifRQ.xml - outer part

The elements BookingRule, Rate, Supplement and Offer are explained in the following sections.

Each Description element must have a Name attribute. Within a rate plan, the Name attribute values must be distinct. Allowed values are:

  • title

  • intro

  • description

  • gallery

  • codelist

For the optional Description elements with names title, intro or description, the following rules hold:

  • Each Description element contains one or more Text elements with the attribute TextFormat set to PlainText or HTML and the attribute Language set to a two-letter lowercase language abbreviation according to ISO 639-1. At most one Text element is allowed for each combination of Language and TextFormat.

  • The presence of a Text element with TextFormat set to HTML is intended as rich text alternative of a Text element with TextFormat set to PlainText of the same Language and makes the latter mandatory.

  • Please note that an AlpineBits® server is explicitly allowed to filter, shorten or even skip the HTML content, therefore the usage of Text elements with TextFormat set to HTML is not recommended but left as an option for implementers that absolutely need it.

Here is an example:

<Description Name="title"> <Text TextFormat="PlainText" Language="en">Wellness Offer</Text> <Text TextFormat="PlainText" Language="de">Wellness Angebot</Text> <Text TextFormat="PlainText" Language="it">Offerta Wellness</Text> </Description> <Description Name="intro"> <Text TextFormat="PlainText" Language="en">Lorem ipsum EN</Text> <Text TextFormat="PlainText" Language="de">Lorem ipsum DE</Text> <Text TextFormat="PlainText" Language="it">Lorem ipsum IT</Text> </Description> <Description Name="description"> <Text TextFormat="PlainText" Language="en">Lorem ipsum sit amet EN</Text> <Text TextFormat="PlainText" Language="de">Lorem ipsum sit amet DE</Text> <Text TextFormat="PlainText" Language="it">Lorem ipsum sit amet IT</Text> <Text TextFormat="HTML" Language="en">Lorem ipsum <br> sit amet EN</Text> <Text TextFormat="HTML" Language="de">Lorem ipsum <br> sit amet DE</Text> <Text TextFormat="HTML" Language="it">Lorem ipsum <br> sit amet IT</Text> </Description>

The optional Description element with name gallery is used to store a sequence of images. Each sequence describes one (independent) image and is made of:

  • One Image element containing the image URL.

  • Zero or more Text elements with attributes TextFormat (set to PlainText) and Language (at most one Text element per language) that describe the image above.

  • Zero or one Text elements with just the attribute TextFormat (set to PlainText) containing copyright information for the image above.

  • Zero or one URL elements containing a link to the attribution of image above.

Here is an example:

<Description Name="gallery"> <Image>http://www.example.com/my-beautiful-room.jpg</Image> <Text TextFormat="PlainText" Language="en">Description EN</Text> <Text TextFormat="PlainText" Language="it">Description IT</Text> <Text TextFormat="PlainText" Language="de">Description DE</Text> <Text TextFormat="PlainText">© 2012 Example Inc.</Text> <URL>http://www.example.com/attribution/</URL> <Image>http://www.example.com/my-even-more-beautiful-room.jpg</Image> <Text TextFormat="PlainText" Language="en">Description EN</Text> <Text TextFormat="PlainText" Language="it">Description IT</Text> <Text TextFormat="PlainText" Language="de">Description DE</Text> <Text TextFormat="PlainText">© 2012 Example Inc.</Text> <URL>http://www.example.com/attribution/</URL> </Description>

The optional Description element with name codelist is used to exchange "theme" information about the rate plan that is not meant to be read by humans.

Such a Description element contains nothing but one or more ListItem elements with no attributes, each containing a code (the quoted part) from the following list:

  • "ALPINEBITS:1001" meaning Bicycle touring

  • "ALPINEBITS:1002" meaning Car-free Holiday

  • "ALPINEBITS:1003" meaning Cars & Motorcycle

  • "ALPINEBITS:1004" meaning Christmas Markets

  • "ALPINEBITS:1005" meaning Culture

  • "ALPINEBITS:1006" meaning Ecologic Holiday

  • "ALPINEBITS:1007" meaning Events

  • "ALPINEBITS:1008" meaning Family

  • "ALPINEBITS:1009" meaning Food

  • "ALPINEBITS:1010" meaning Golf

  • "ALPINEBITS:1011" meaning Hiking

  • "ALPINEBITS:1012" meaning Horseback Riding

  • "ALPINEBITS:1013" meaning Luxury Holiday

  • "ALPINEBITS:1014" meaning Mountain Bike

  • "ALPINEBITS:1015" meaning Other Summer Activities

  • "ALPINEBITS:1016" meaning Other Winter Activities

  • "ALPINEBITS:1017" meaning Pets-friendly Holiday

  • "ALPINEBITS:1018" meaning Road Bike

  • "ALPINEBITS:1019" meaning Romantic Holiday

  • "ALPINEBITS:1020" meaning Ski & Snowboard

  • "ALPINEBITS:1021" meaning Spa & Health

  • "ALPINEBITS:1022" meaning Wine

  • "ALPINEBITS:1023" meaning eBike

The "ALPINEBITS" and "OTA" namespaces are reserved, but partners are free to define custom namespaces. A server can safely ignore codes it doesn’t recognize and must not return a warning or error if it encounters one.

Here is an example:

<Description Name="codelist"> <ListItem>ALPINEBITS:1001</ListItem> <ListItem>ALPINEBITS:1006</ListItem> </Description>

Booking rules

BookingRule elements can be linked to room categories (see section 4.4) via their Code attribute. If the Code attribute is given, also the CodeContext attribute must be set and its value must be ROOMTYPE (OTA lacks a InvTypeCode attribute in this context). A BookingRule without a Code attribute applies to all room categories.

A BookingRule element must have attributes Start and End (both must be valid dates in the form YYYY-MM-DD) and satisfy the condition StartEnd. Unless otherwise specified, Start and End must be considered inclusive.

Within the same rate plan, BookingRule elements must not overlap (concerning their Start and End attributes) if they belong to the same class. Classes are:

  • BookingRule elements with no Code attribute.

  • BookingRule elements with the same value for the Code attribute.

The server must consider overlaps as an error.

BookingRule elements are used to define a number of restriction criteria:

  • The minimum or maximum length of stay (LOS) using the LengthOfStay element.

  • The arrival day of week (arrival DOW) using the ArrivalDaysOfWeek element.

  • The departure day of week (departure DOW) using the DepartureDaysOfWeek element.

  • A master restriction status (values Open/ Close) using the RestrictionStatus element.

Any missing criteria is to be interpreted as unrestricted.

LengthOfStay elements indicate a minimum length of stay (by setting the attribute MinMaxMessageType to SetMinLOS or SetForwardMinStay) or a maximum length to stay (by setting the attribute MinMaxMessageType to SetMaxLOS or SetForwardMaxStay). Each value of MinMaxMessageType must not appear more than once in the same LengthsOfStay container element. It is the responsibility of the client to check that - if the attribute MinMaxMessageType sets a value for SetMinLOS, it must be ≤ than SetMaxLOS, similarly SetForwardMinStay must be ≤ SetForwardMaxStay.

When matching a BookingRule, a server must consider the following rules:

  • The criteria of the booking rule (if any) that applies to the arrival day (Start ≤ arrival day ≤ End): SetMinLOS, SetMaxLOS, arrival DOW, master status Open.

  • The criteria of the booking rule (if any) that applies to the departure day (Start ≤ departure day ≤ End): departure DOW.

  • The criteria of the booking rule (if any) that applies and need to be checked for each day of the stay (excluding the departure day): the day must not be denied by a master status Close rule. The whole length of the stay must be consistent with SetForwardMinStay and SetForwardMaxStay attributes.

A stay must be allowed by all applicable booking rules. In particular, there might be a BookingRule element with a Code attribute and a BookingRule element without a Code attribute, both applicable to a given stay. In such a case, both rules must allow the stay.

Three booking rule examples are shown here.

In example A, length of stay (LOS) restrictions are given. The Time attribute must be an integer > 0 and the TimeUnit must be Day. This rule would restrict any stay having 2016-03-03 ≤ arrival day ≤ 2016-04-17 to a duration between 5 and 7 nights.

<BookingRule Start="2016-03-03" End="2016-04-17"> <LengthsOfStay> <LengthOfStay Time="5" TimeUnit="Day" MinMaxMessageType="SetMinLOS"/> <LengthOfStay Time="7" TimeUnit="Day" MinMaxMessageType="SetMaxLOS"/> </LengthsOfStay> </BookingRule>

Booking rule (example A)

In example B, arrival day of week (arrival DOW) and departure day of week (departure DOW) restrictions are given. At most one ArrivalDayOfWeek element and at most one DepartureDayOfWeek element must be given. The DOW attributes that are 0 or false indicate restricted DOWs. A missing DOW attribute or a value of 1 or true indicate there is no restriction. This example would restrict any stay requesting a "double" room (note the Code attribute) to arrive and depart on a Thursday or Saturday.

<BookingRule Start="2016-01-01" End="2017-12-31" Code="double" CodeContext="ROOMTYPE"> <DOW_Restrictions> <ArrivalDaysOfWeek Mon="0" Tue="0" Weds="0" Thur="1" Fri="0" Sat="1" Sun="0"/> <DepartureDaysOfWeek Mon="0" Tue="0" Weds="0" Thur="1" Fri="0" Sat="1" Sun="0"/> </DOW_Restrictions> </BookingRule>

Booking rule (example B)

Alternatively, example B could also be written as:

<BookingRule Start="2016-01-01" End="2017-12-31" Code="double" CodeContext="ROOMTYPE"> <DOW_Restrictions> <ArrivalDaysOfWeek Mon="0" Tue="0" Weds="0" Fri="0" Sun="0"/> <DepartureDaysOfWeek Mon="0" Tue="0" Weds="0" Fri="0" Sun="0"/> </DOW_Restrictions> </BookingRule>

Booking rule (example B - alternative)

The following example (C) forbids any stay in the suite in August (departure on the 1st of August is possible).

<BookingRule Start="2016-08-01" End="2016-08-31" Code="suite" CodeContext="ROOMTYPE"> <RestrictionStatus Restriction="Master" Status="Close"/> </BookingRule>

Booking rule (example C)

Both attributes, Restriction and Status are mandatory. The value Close is necessary for the restriction to occur. An Open value would be equivalent to no restriction.

Another specific CodeContext for BookingRule is ALPINEBITSEXTRA-PETS which denotes a special BookingRule that restricts the applicability of the rate plan to the presence of pets in the group. It applies to the whole rate plan and to every category specified in it. Code must have the fixed value ANY (to express that it refers to any kind of animal). It must not overlap with other ALPINEBITSEXTRA-PETS BookingRule elements and must only contain a RestrictionStatus element with Restriction set to Master and a Status attribute set either to Close to disallow pets for the given time period or Open to allow them (which is equivalent to no restriction).

<BookingRule Start="2021-09-09" End="2021-11-30" CodeContext="ALPINEBITSEXTRA-PETS" Code="ANY"> <RestrictionStatus Restriction="Master" Status="Open" /> </BookingRule>

Pets' Booking rule

Check the Supplements' section later in this chapter for further details about pricing of pets.

Rates

AlpineBits® classifies Rate elements into two kinds: static Rate elements and date dependant Rate elements.

Static rates.

Static Rate elements are used to avoid sending the same information repeatedly for each rate of the same rate plan. They:

  • Contain static information that is valid for the whole Rateplan and is not date dependant.

  • Can only be transmitted in messages with RatePlanNotifType set to New.

  • Can only be used at position 1 in a list of Rate elements.

Here is an example of such a static rate:

<Rate RateTimeUnit="Day" UnitMultiplier="1"> <BaseByGuestAmts> <BaseByGuestAmt Type="7"/> </BaseByGuestAmts> <MealsIncluded MealPlanIndicator="true" MealPlanCodes="12"/> </Rate>

samples/RatePlans/RatePlans-OTA_HotelRatePlanNotifRQ.xml - static rate

By default, all rates are per night. It is, however, possible to specify rates per an arbitrary amount of nights. This is done by adding both of the optional attributes RateTimeUnit (Day is the only allowed value) and UnitMultiplier (number of nights) to the static Rate element. This will implicitly set the time unit for all the rates in the rate plan.

The mandatory BaseByGuestAmt element with the only and mandatory Type attribute determines if the amounts given in the rates of the containing rate plan are to be considered per person (Type 7) or per room (Type 25).

Finally, a static rate also sets the board type for the rate plan. This is done with the mandatory MealsIncluded element. The mandatory MealPlanIndicator attribute must be true and the mandatory MealPlanCodes attribute assumes one of the following values (a subset of the full OTA list):

  • 1 - All inclusive

  • 3 - Bed and breakfast

  • 10 - Full board

  • 12 - Half board

  • 14 - Room only

Note that AlpineBits® does not use the single Breakfast/Lunch/Dinner booleans.

Date dependant rates.

The date dependant rates (just "called" rates from here on) must have an InvTypeCode attribute that links them to room categories (see section 4.4).

A Rate element must have attributes Start and End (both must be valid dates in the form YYYY-MM-DD) and satisfy the condition StartEnd.

A stay matches the Start and End attributes if the the arrival day is ≥ Start and the departure day ≤ End + 1. When the server computes the total cost of the stay it must find a matching rate for each night of the stay. Otherwise it cannot compute the total cost, and the stay is not possible.

Within the same rate plan, two Rate elements must not overlap (concerning their Start and End attributes) if they have the same InvTypeCode attribute.

The server must consider overlaps as an error.

Rate elements specify costs after taxes; all amounts must be expressed in the currency specified by the RatePlan CurrencyCode attribute and must follow its currency convention of decimal digit amount after the decimal sign. Rate sub-elements are: BaseByGuestAmt and AdditionalGuestAmount.

Here is an example of such a rate (the prices are considered "per person" because of the static rate described above):

<Rate InvTypeCode="double" Start="2014-03-03" End="2014-03-08"> <BaseByGuestAmts> <BaseByGuestAmt NumberOfGuests="1" AgeQualifyingCode="10" AmountAfterTax="106"/> <BaseByGuestAmt NumberOfGuests="2" AgeQualifyingCode="10" AmountAfterTax="96"/> </BaseByGuestAmts> <AdditionalGuestAmounts> <AdditionalGuestAmount AgeQualifyingCode="10" Amount="76.8"/> <AdditionalGuestAmount AgeQualifyingCode="8" MaxAge="3" Amount="0" /> <AdditionalGuestAmount AgeQualifyingCode="8" MinAge="3" MaxAge="6" Amount="38.4"/> <AdditionalGuestAmount AgeQualifyingCode="8" MinAge="6" MaxAge="10" Amount="48" /> <AdditionalGuestAmount AgeQualifyingCode="8" MinAge="10" MaxAge="16" Amount="67.2"/> </AdditionalGuestAmounts> </Rate>

samples/RatePlans/RatePlans-OTA_HotelRatePlanNotifRQ.xml - rate

The BaseByGuestAmt elements (at least one must be present) have the following attributes:

  • NumberOfGuests (mandatory) is an integer value > 0,

  • AmountAfterTax (mandatory) is a positive non zero decimal value (zero is not allowed) which must follow the currency convention of decimal digit amount after the decimal sign for the specified currency,

  • AgeQualifyingCode (mandatory) is set to 10 ("adult").

For a given Rate, all BaseByGuestAmt elements must have distinct NumberOfGuests values.

One or more BaseByGuestAmt elements are needed to cover all possible guest occupancies compatible with the room category occupancy limits. In particular, one BaseByGuestAmt element with attributes NumberOfGuests equal to the standard occupancy must be present. Additional BaseByGuestAmt elements with values between the minimum and the standard occupancy may be present. See the section "Computing the cost of a stay" below for details.

The AdditionalGuestAmount elements (zero or more can be present) are used to transmit the prices for guests that are in a room beyond the minimum number of guests that ought to pay the full rate (see below for the definition). Specific prices for children may also be sent with these elements. They have the following attributes:

  • AgeQualifyingCode (mandatory) is set to 8 ("child) or 10 ("adult").

  • MinAge and MaxAge are both integer values > 0 (a value of 0 is forbidden by OTA, even for MinAge); when both are given together, the inequation MaxAge > MinAge must hold.

  • Amount (mandatory) is a positive decimal value (zero is allowed) which must follow the currency convention of decimal digit amount after the decimal sign for the specified currency.

AdditionalGuestAmount elements must also comply with these rules that help resolve ambiguities when computed the total cost of a stay:

  1. If AdditionalGuestAmount are defined at all, at most one AdditionalGuestAmount element with a AgeQualifyingCode set to 10 ("adult") may be present.

  2. AdditionalGuestAmount elements having AgeQualifyingCode set to 8 ("child") must have at least one of the attributes MinAge or MaxAge. Contrary, those with AgeQualifyingCode set to 10 ("adult") must have neither.

  3. The attributes MinAge and MaxAge are used to identify age brackets. An age matches the bracket if and only if the following two conditions hold:

    • MinAge is not given or MinAge ≤ age

    • MaxAge is not given or MaxAge > age

All the Rate elements in a Rateplan must be consistent with the "brackets" defined in the first OfferRule element, it is a client responsibility to ensure this.

A server must return a warning outcome or error outcome if this is not the case.

Supplements

Supplements are supported through Supplement elements.

Each Supplement element has the following mandatory attributes:

  • InvType is set to EXTRA.

  • InvCode can be set freely (1 - 16 characters according to OTA) and is used as a key to identify a supplement.

The InvType value ALPINEBITSEXTRA is not currently used, but is reserved for a future shared list of common InvCode values. The InvType value ALPINEBITSEXTRA-PETS is used for transmitting pets’ supplements. See end of section for further details.

Supplements, analogously to Rates are split into static and date dependant Supplement elements.

The static supplements contain the information used to identify and describe the supplement to guests. For each distinct InvCode that is specified, there must be exactly one static Supplement element and there may be several date depending Supplement elements.

The following attributes and sub-elements are used in static supplements:

  • The mandatory attribute AddToBasicRateIndicator must be set to true (to indicate the supplement amount must be added to the amount coming from the rate).

  • The mandatory attribute MandatoryIndicator (a boolean value) indicates that the customer must book the supplement (true) or can choose to book the supplement (false).

  • The mandatory attribute ChargeTypeCode must have one of the following values:

    • 1 - Daily

    • 18 - Per room per stay

    • 19 - Per room per night

    • 20 - Per person per stay

    • 21 - Per person per night

    • 24 - Item (per stay, see below).

    Note that when ChargeTypeCode is 1 or 24, if MandatoryIndicator is true, their amount should be considered as "1 per day" and "1 per stay" respectively; otherwise, for an optional Supplement, the total cost of stay should be computed by asking the user for the number of items.

  • An optional PrerequisiteInventory sub-element with the mandatory InvType attribute set to ALPINEBITSDOW can be used to make supplements available only on certain days of the week. The mandatory InvCode attribute can be used to identify those days of the week: it is a string made of seven binary digits. Each position in the string refers to a day of the week, starting with Monday. A 1 at a given position means that the supplement is available on the corresponding day, a 0 means it’s not. A value of 1100000 for instance, would indicate a supplement available only on Monday and Tuesday.

  • Zero to five Description elements - the format of the descriptions follow what has been explained for rate plan level descriptions (with the same name values).

All the Supplement attributes mentioned are mandatory.

No other attributes or sub-elements are allowed for static data supplements (in particular attributes Start and End are not allowed).

The following attributes and sub-elements define the price of the supplement for specific periods of time. They are thus used in date depending supplements:

  • The attribute Amount indicates the cost of the supplement after taxes; amounts must be expressed in the currency specified by the RatePlan CurrencyCode attribute and must follow its currency convention of decimal digit amount after the decimal sign; a value of 0 indicates the supplement is free of charge. If the attribute is missing, the Supplement is not available.

  • The attributes Start and End (with the usual meaning) define the period where the Amount surcharge is applied.

  • An optional PrerequisiteInventory sub-element with the mandatory InvType attribute set to ROOMTYPE can be used to make supplements available only for certain room categories or price them differently for different room categories. The mandatory InvCode attribute can be used to identify the room category the supplement applies to.

The attributes Start and End are mandatory for supplements that contain date depending data, the attribute Amount and the sub element PrerequisiteInventory are optional. No further Element or Attribute is allowed.

Multiple date depending Supplement elements referring to the same InvCode and PrerequisiteInventory might be used to specify different prices for different date ranges. Overlaps are not allowed: it is the responsibility of the client to check that different amounts are never set for the same date and the same Supplement; a server must return an error if it detects such an inconsistency in the data.

When defining supplements, static and date dependant data must be transmitted in separate Supplement elements.

Here is a complete example of a supplement:

<Supplements> <Supplement InvType="EXTRA" InvCode="0x539" AddToBasicRateIndicator="true" MandatoryIndicator="true" ChargeTypeCode="18"> <Description Name="title"> <Text TextFormat="PlainText" Language="de">Endreinigung</Text> <Text TextFormat="PlainText" Language="it">Pulizia finale</Text> </Description> <Description Name="intro"> <Text TextFormat="PlainText" Language="de"> Die Endreinigung lorem ipsum dolor sit amet. </Text> <Text TextFormat="PlainText" Language="it"> La pulizia finale lorem ipsum dolor sit amet. </Text> </Description> </Supplement> <Supplement InvType="EXTRA" InvCode="0x539" Amount="20" Start="2014-10-01" End="2014-10-11"> </Supplement> </Supplements>

samples/RatePlans/RatePlans-OTA_HotelRatePlanNotifRQ.xml - supplement

Static data may only be transmitted in messages with RatePlanNotifType set to New. Moreover, all the static data must be defined within a single Supplement element.

Date dependant data may be also transmitted in messages with RatePlanNotifType set to Overlay.

See the section "Synchronization" below for more details.

Supplements contribute to the total cost of a stay. The general rule is that this contribution must always be added to the amount calculated from the applied rates on a day by day basis. The departure day supplements must not be applied, as the guest is leaving.

In case of ChargeTypeCode with value 18, 20 and 24 (see above, all supplements that are per stay) the cost of a supplement may vary in the period of the stay. In this case, the total cost of the supplement must be calculated using the following algorithm (assuming a 3-night stay with a cost of € 80 for the first two days and € 85 for last two (including the departure day)):

  • Calculate the number of days where the supplement applies (the supplement must not be applied to the departure day, hence the result is 3).

  • Sum the applicable price for each day (80 + 80 + 85 = 245 €).

  • Divide the result for the number of days obtained at step 1 and round the result at the second decimal place (245 / 3 = 81.67 €).

Note that the rate plan is available also in dates for which a Supplement declared as mandatory is not specified. Of course in these dates the supplement will not be available to guests. Similarly when a supplement is not applicable to a potential stay due to an unmatched PrerequisiteInventory, the rate plan - without the supplement - is still available.

A specific kind of supplements can be sent with InvType value ALPINEBITSEXTRA-PETS in order to transmit supplements regarding pets’ pricing (called “Pets’ Supplements” in the following paragraphs). These special supplements, if present, follow the same rules just mentioned for the regular Supplement elements with the addition that they should be defined only for Open time periods of BookingRule elements with CodeContext value ALPINEBITSEXTRA-PETS (called “Pets’ BookingRules” in the following paragraphs).

A best practice is to dedicate a separate RatePlan for managing categories that host pets: in fact if a “Pets’ BookingRule” defines a period for which pets are allowed, every category without an associated “Pets’ Supplement” will not charge any extra for the pets since no Supplement can be added to the total cost, as stated above in the Supplements definition.

Defining at least one of “Pets’ BookingRules” or “Pets’ Supplements” implies that the information about pets’ acceptance and prices is managed. If both are undefined it means the information is unknown.

<Supplements> …​ <Supplement InvType="ALPINEBITSEXTRA-PETS" InvCode="…​supplementID…​" AddToBasicRateIndicator="true" MandatoryIndicator="false" ChargeTypeCode="14"> <Description Name="title"> <Text TextFormat="PlainText" Language="it">Supplemento animali al seguito</Text> <Text TextFormat="PlainText" Language="de">…​</Text> </Description> </Supplement> <Supplement InvType="ALPINEBITSEXTRA-PETS" InvCode="…​supplementID…​" Amount="15" Start="2021-09-09" End="2021-11-15"> </Supplement> <Supplement InvType="ALPINEBITSEXTRA-PETS" InvCode="…​supplementID…​" Amount="20" Start="2021-11-16" End="2021-11-30"> <PrerequisiteInventory InvType="ROOMTYPE" InvCode="DOUBLE" /> </Supplement> …​ </Supplements>

Pets' Supplements - supplement

Offers

Offers are considered static data and can only be transmitted in messages with RatePlanNotifType set to New.

The mandatory first Offer element must contain one OfferRule element, no Discount element and no Guest element.

The first OfferRule element contains:

  • Zero or one LengthOfStay elements with MinMaxMessageType set to SetMinLOS.

  • Zero or one LengthOfStay elements with MinMaxMessageType set to SetMaxLOS.

  • Zero or one ArrivalDaysOfWeek elements.

  • Zero or one DepartureDaysOfWeek elements.

The use of these elements inside an OfferRule is analogous to their use inside a BookingRule as explained above.

The first OfferRule element further contains:

  • One Occupancy element with the AgeQualifying attribute set to 10 ("adult") and an optional MinAge attribute (integer value > 0)

  • Zero or one Occupancy element with the AgeQualifying code set to 8 ("child") and optional attributes MinAge and MaxAge (integer value > 0)

Rules regarding these Occupancy elements:

  • If the only Occupancy element present is the one with AgeQualifying attribute 10 ("adult") and no MinAge attribute, all guests are to be considered "adults"; if the MinAge attribute is present, MinAge must be ≤ 18 – all guests ≥ MinAge are considered "adults" and all guests < MinAge are considered "children".

  • If and only if the MinAge attribute is specified for the "adult" guests, then in order to allow the presence of children, the Occupancy element with AgeQualifying attribute 8 ("child") must be present. If that element has a MinAge and/or a MaxAge attribute, the age of "children" is restricted to the interval MinAge ≤ age < MaxAge.

  • Any of the Occupancy elements may contain also the attributes MinOccupancy with integer values between 0 and 99 and MaxOccupancy with integer values between 1 and 99 having the purpose to restrict the total number of adults or children allowed in a stay with this rate plan.

The first OfferRule element might also have any of the following arguments with values that are durations given in days encoded in ISO 8601 (thus always in the form PxD where x is the integer number of days):

  • MinAdvancedBookingOffset - the rate plan is only bookable before the given number of days before the arrival date.

  • MaxAdvancedBookingOffset - the rate plan is only bookable if booked after the given number of days before the arrival date.

The first OfferRule element contains all the static booking rules of the rate plan. All the restrictions that are defined in this element must be fulfilled by a stay in order to make the rate plan bookable.

Here is a quite minimal first OfferRule element without any restrictions: guests are considered adults if they are of age 16 or older and children (of any age) are allowed:

<Offer> <OfferRules> <OfferRule> <Occupancy AgeQualifyingCode="10" MinAge="16"/> <Occupancy AgeQualifyingCode="8"/> </OfferRule> </OfferRules> </Offer>

samples/RatePlans/RatePlans-OTA_HotelRatePlanNotifRQ.xml - offer

The first offer element is followed by zero, one or two additional Offer elements describing discounts.

AlpineBits® only supports offers having a Discount element with the Percent attribute set to 100. There are two use cases:

  • free nights offers, such as "7+1" formulas and the like.

  • family offers, such as "first kid goes free".

Rate plans may only contain at most one of each kind. Note that discounts (if given at all) do not necessarily need to apply to a stay in order to make the rate plan bookable.

A free nights offer has a Discount element with the following attributes:

  • Percent (mandatory) - value is always 100.

  • NightsRequired (mandatory) - how many nights at least must be booked for the discount to apply.

  • NightsDiscounted (mandatory) - how many nights are discounted.

  • DiscountPattern (optional) - the pattern is required to be in the form (nights required - nights discounted) times the 0 followed by (nights discounted) times the 1. No other pattern is allowed.

If the DiscountPattern is present, the discount pattern can be applied repeatedly from the beginning of the stay. If, for instance, NightsRequired is 7 and the stay is 14 nights, the pattern applies exactly twice, thus two times the NightsDiscounted nights are free (corresponding to the nights having a 1 in the pattern).

If the DiscountPattern is absent, the discount is not repeatable and the free nights are simply the last NightsDiscounted nights of the stay.

Free night offers apply to every amount referring to the discounted night (rates as well as per-day or per-night supplements, including mandatory ones).

Free night offers may be only used in conjunction with rates that have a UnitMultiplier of 1.

A family offer has a Discount element with just the Percent attribute set to 100 followed by at most one Guest element defining who goes free. Guest attributes (all mandatory) are:

  • AgeQualifyingCode is set to 8.

  • MaxAge is an integer value > 0: the discount only applies to guests having age < MaxAge.

  • MinCount is an integer value ≥ 0: it identifies the minimum number of guests having age < MaxAge that are required for the offer to be applicable.

  • FirstQualifyingPosition - always set to 1.

  • LastQualifyingPosition - number of persons the discount applies to.

Family offers apply to every amount referring to the discounted guest (rates as well as per-person supplements, including mandatory ones).

In case the number of age-matching guests exceeds the number of discounted guests, AlpineBits® requires to discount the guests starting from the youngest.

Following are a few complete examples of the Offers element.

Example A (early booking offer): must be booked at least 30 days in advance, guests ≥ 16 are considered adults, guest < 10 are not allowed.

<Offers> <Offer> <OfferRules> <OfferRule MinAdvancedBookingOffset="P30D"> <Occupancy AgeQualifyingCode="10" MinAge="16" /> <Occupancy AgeQualifyingCode="8" MinAge="10" MaxAge="16" /> </OfferRule> </OfferRules> </Offer> </Offers>

Offers - example A

Example B (last minute offer): cannot be booked more than 7 days in advance, guests ≥ 16 are considered adults, children of any age allowed.

<Offers> <Offer> <OfferRules> <OfferRule MaxAdvancedBookingOffset="P7D"> <Occupancy AgeQualifyingCode="10" MinAge="16" /> <Occupancy AgeQualifyingCode="8" /> </OfferRule> </OfferRules> </Offer> </Offers>

Offers - example B

Example C (four nights for the price of three): only applicable to a stay of exactly 4 nights with arrival on Sunday and departure on Thursday, last night is free, guests ≥ 16 are considered adults, children of any age allowed.

<Offers> <Offer> <OfferRules> <OfferRule> <LengthsOfStay> <LengthOfStay Time="4" TimeUnit="Day" MinMaxMessageType="SetMinLOS" /> <LengthOfStay Time="4" TimeUnit="Day" MinMaxMessageType="SetMaxLOS" /> </LengthsOfStay> <DOW_Restrictions> <ArrivalDaysOfWeek Sun="1" Mon="0" Tue="0" Weds="0" Thur="0" Fri="0" Sat="0" /> <DepartureDaysOfWeek Sun="0" Mon="0" Tue="0" Weds="0" Thur="1" Fri="0" Sat="0" /> </DOW_Restrictions> <Occupancy AgeQualifyingCode="10" MinAge="16" /> <Occupancy AgeQualifyingCode="8" /> </OfferRule> </OfferRules> </Offer> <Offer> <Discount Percent="100" NightsRequired="4" NightsDiscounted="1" /> </Offer> </Offers>

Offers - example C

Example D (another free nights example): the last night is free if the stay is ≥ 4 nights. Since there is no DiscountPattern, you still get just one (the last) night free, even if the stay is ≥ 8 nights. Guests ≥ 16 are considered adults, children of any age allowed. Note the rate plan is still bookable for stays of less than 4 nights (but then there’s no discount).

<Offers> <Offer> <OfferRules> <OfferRule> <Occupancy AgeQualifyingCode="10" MinAge="16" /> <Occupancy AgeQualifyingCode="8" /> </OfferRule> </OfferRules> </Offer> <Offer> <Discount Percent="100" NightsRequired="4" NightsDiscounted="1" /> </Offer> </Offers>

Offers - example D

Example E (one child goes free): if there are at least two children < 5, one of them (the younger one) goes free. Guests ≥ 16 are considered adults, children of any age allowed. Note the rate plan is still bookable if the family offer isn’t applicable.

<Offers> <Offer> <OfferRules> <OfferRule> <Occupancy AgeQualifyingCode="10" MinAge="16" /> <Occupancy AgeQualifyingCode="8" /> </OfferRule> </OfferRules> </Offer> <Offer> <Discount Percent="100" /> <Guests> <Guest AgeQualifyingCode="8" MaxAge="5" MinCount="2" FirstQualifyingPosition="1" LastQualifyingPosition="1" /> </Guests> </Offer> </Offers>

Offers - example E

Example F has the same family discount as example E, but here there is also a restriction, stating the rate plan is only bookable if there are at least two children < 5.

<Offers> <Offer> <OfferRules> <OfferRule> <Occupancy AgeQualifyingCode="10" MinAge="16" /> <Occupancy AgeQualifyingCode="8" MaxAge="5" MinOccupancy="2"/> </OfferRule> </OfferRules> </Offer> <Offer> <Discount Percent="100" /> <Guests> <Guest AgeQualifyingCode="8" MaxAge="5" MinCount="2" FirstQualifyingPosition="1" LastQualifyingPosition="1" /> </Guests> </Offer> </Offers>

Offers - example F

Example G combines some restriction with a family offer and a free nights offer! N nights are free according to the pattern, if the stay is at least N times 4 nights. Additionally one child < 5 goes free. The stay must be > 4 nights due to LOS restriction, but the rate plan is bookable also without the presence of a child < 5 (the family offer just doesn’t apply).

<Offers> <Offer> <OfferRules> <OfferRule> <LengthsOfStay> <LengthOfStay Time="4" TimeUnit="Day" MinMaxMessageType="SetMinLOS" /> </LengthsOfStay> <Occupancy AgeQualifyingCode="10" MinAge="16" /> <Occupancy AgeQualifyingCode="8" /> </OfferRule> </OfferRules> </Offer> <Offer> <Discount Percent="100" NightsRequired="4" NightsDiscounted="1" DiscountPattern="0001" /> </Offer> <Offer> <Discount Percent="100" /> <Guests> <Guest AgeQualifyingCode="8" MaxAge="5" MinCount="1" FirstQualifyingPosition="1" LastQualifyingPosition="1" /> </Guests> </Offer> </Offers>

Offers - example G

Joining rate plans

The use case of having alternative prices for alternative meal plans is fairly common. To this end, AlpineBits® provides the functionality of joining rate plans. In this case, the two optional attributes RatePlanID and RatePlanQualifier may be used by the client to identify a "master" rateplan and its alternative versions. They can only be sent if the server supports the OTA_HotelRatePlanNotif_accept_RatePlanJoin capability. All these rate plans share the same RatePlanID: exactly one rate plan (the "master") for each RatePlanID value must have the RatePlanQualifier set to true, every other rate plan (the alternative versions) that shares the same RatePlanID must have the RatePlanQualifier set to false.

When the server joins rate plans, it must use these components from the "master" rate plan:

  • Descriptive content

  • Static information about rates (except the element MealsIncluded)

  • Offers

  • Static information about supplements

and must take these components from the alternative versions:

  • Booking rules

  • Date dependent information about rates

  • Date dependent information about supplements.

4.5.2. Computing the cost of a stay

The information contained in a rate plan message (together with information about the stay and the inventory) can be used to compute the total cost of a given stay, provided the stay is possible at all.

The computation is somewhat complex due to the large number of rules involved. The rationale is that the algorithm should be as unambiguous and as top-down as possible. It is never necessary to perform permutations or recursion to find an "optimized solution". Elements with Start and End attributes, for example, must not overlap. The same is true for age brackets, as we’ve seen. The application of children rebates is very carefully designed to give a unique result and the same holds for offers, etc.

The required steps to perform such a computation are outlined in this section. Also see the section "Implementation tips and best practice" below for a link to a reference implementation.

The following information is needed about the stay:

  • The number of adult guests: n ≥ 0.

  • The ages (in years) of all guest that are considered children (the cut-off age above which guests are considered adults is defined in the first OfferRule element): an array of integers c.

  • The requested room category (i.e. InvTypeCode / Code): code.

  • The arrival date arr and the departure date dep where dep > arr.

The total number of guests (n + the length of the array c) must be > 0.

The following information is needed about the requested room category from inventory (see section 4.4):

  • The value of MinOccupancy min > 0,

  • The value of StandardOccupancy stdmin,

  • The value of MaxOccupancy maxstd,

  • (Optional) the value of MaxChildOccupancy mco, such that 0 ≤ mcomax.

From these values the minimum number of guests that ought to pay the full rate (minfull) can be computed:

  • If MaxChildOccupancy is not given, minfull = std,

  • Otherwise, minfull = minimum(max - mco std).

Then, to verify that a stay is allowed and to compute its total cost, the following steps need to be performed.

Step 1 (total occupancy check)

Verify that min ≤ total number of guests (n + the length of the array c) ≤ max. Unless this inequation holds, the stay in the selected room category is not possible and no cost can be computed.

Step 1b (offer rule check)

Verify that arr, n and c are consistent with the first OfferRule element explained in the Offers section. It is not allowed to promote children to "adults" (that is remove elements from c and increment n) to force a match.

Step 2 (transformation)

While n < minfull and the length of c is > 0, keep removing the greatest element from the array c and incrementing n by 1. In simple words: transform kids to adults as long as there are any left in an attempt to reach the minimum number of guests that pay the full rate.

Step 3 (family offers)

If there are any matching family offers, apply them. When a family offer is applied, the corresponding elements from the array c are removed. The number of removed elements is referred to as numfree below.

A rate plan can be booked for a given a stay, even if it contains family offers that do not match the stay (of course the discount is not applied in that case).

Step 4a (restrictions check)

Verify that no BookingRule elements impose restrictions that forbid the stay. The restrictions to consider have been detailed earlier in this section (see the section "booking rules"): the minimum/maximum length of stay (LOS), the arrival/departure day of week (DOW), the master restriction status.

Step 4b (compute cost)

Loop over the dates of the period of stay, finding the rate with matching Start and End values. Thanks to the fact that rates must not overlap, there is no ambiguity there.

It might be necessary, and it is explicitly allowed

  • To "stitch" rates together to cover longer stays, accumulating the amount due and/or.

  • To "split" rates having a UnitMultiplier > 1, dividing the amount due by the fraction of nights used.

A stay is only possible if every night of the stay can be covered by a rate.

The detailed implementation for this particular loop-over-and-match-rate step will likely depend on the data model used. However, for each rate, the following sub-steps are to be performed to pick the correct amount from the BaseByGuestAmt and AdditionalGuestAmount elements:

  • Each child (e.g. each element of the array c) is matched to the corresponding AdditionalGuestAmount element with AgeQualifyingCode set to 8 ("child"). At this point the fact that a match can be made for each child is guaranteed by the rules related to the first OfferRule element and by the check in step 1b.

  • Out of the n guests, up to and including std, each pay an amount given by the one BaseByGuestAmt element having:

    • A NumberOfGuests value of minimum(n + length of c + numfree, std) if the Type value is 7 ("per person") or

    • A NumberOfGuests value of minimum(n, std) if the Type is 25 ("per room")

    If the correct BaseByGuestAmt element is not available, the stay as a whole is not possible (the rate plan is incomplete and cannot be applied).

  • The remaining guests among the n - if any - each pay an amount given by the AdditionalGuestAmount elements with AgeQualifyingCode set to 10 ("adult").

    If the correct AdditionalGuestAmount element is not available, the stay as a whole is not possible (the rate plan is incomplete and cannot be applied).

At this point, unless a free nights offer applies to the date and rate just considered (note that free nights offers are compatible only with rates having a UnitMultiplier of 1), sum the contribution to the total cost.

Next, consider the supplements (mandatory and optional ones). Again, the exact implementation of the supplement matching algorithm will depend very much on the data model used. Note in any case, that free nights offers also apply to supplements, so the contribution to the cost from supplements that are per day is affected too.

Here is a flowchart of the whole process:

flowchart

4.5.3. Synchronization

Clients and servers often wish to exchange only delta information about rates in order to keep the total amount of data to be processed in check.

AlpineBits® uses the RatePlanNotifType attribute in each RatePlan element to define exactly how deltas have to be interpreted. In order to transmit new rate plans or to replace them RatePlanNotifType = New must be used. To transmit changes (deltas) a RatePlanNotifType value of Overlay must be used.

Note, however, that:

  • RatePlanNotifType = New

    At least one Description element must be present in the rate plan.The server adds the rate plan as a whole. If a rate plan with the same RatePlanCode already exists, it is replaced. In case of supplements, all static data must be sent within this message. Static rates must be sent within this message too. Offers are always considered static and hence must also be send within this message. The attributes RatePlanID and RatePlanQualifier - if supported by the server - might only be sent within this message.

  • RatePlanNotifType = Overlay

    The server updates the rate plan (identified by RatePlanCode) using the received data. At most one RatePlan element for each RatePlanCode is allowed within a single message. Elements that are not transmitted are not touched, elements that are transmitted are completely replaced (including all subelements). Since empty elements replace existing elements, sending empty elements can be a means to delete them (see clarification below). In case of supplements or rates, only date depending data may be sent within this message. Empty date depending rate elements are meant for deletion. Date depending supplements might be set as not available. Offers cannot be changed with an Overlay message. In order to update offers, the whole RatePlan has to be sent again (using New ). If the server has no rate plan with the given RatePlanCode, it may ignore the client request but must return a warning if it does.

  • RatePlanNotifType = Remove

    The rate plan must be empty (no child elements). The server deletes the rate plan (identified by RatePlanCode). If the server has no rate plan with the given RatePlanCode, it may ignore the client request but must return a warning in this case.

Generally sending a rate plan, BookingRule and Rate elements are always updated as a whole, single sub-elements (such as only the LengthOfStay restrictions) cannot be updated individually. Sending empty BookingRule or empty Rate elements will delete them including all sub-elements.

That being said, there is the special case of rate plan messages that contain a UniqueID element with attribute Instance set to CompleteSet.

In this case a client indicates it wishes to initiate sending the complete list of its rate plans. The server must then consider all rate plans it has on record that are not contained in the current message as expired. (hint: delete them). In that case, the RatePlan element will not have any RatePlanNotifType and no child elements must be present (the RatePlanCode must of course be present).

Also regarding the CompleteSet case, if the client wishes to reset all rate plans for a given hotel it can send a single empty RatePlan element (sending no RatePlan element at all would violate OTA validation).

Regarding these synchronization mechanisms, a server must support everything except RatePlanNotifType = Overlay. A server must set the corresponding capability if it does.

In order to limit the amount of transferred data and processing time, the following rules and recommendations must be taken into account:

  • RatePlanNotifType = New

    Complete RatePlans must be transmitted one at a time.

  • RatePlanNotifType = Overlay

    Updates to more than one RatePlan may be bundled into a single request. However, care should be taken to keep the data size within reasonable limits. In case of doubt, the updates should be transmitted for one RatePlan at a time.

4.5.4. Server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelRatePlanNotifRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed.

See Appendix A for details.

4.5.5. Implementation tips and best practice

A server, before declaring support for the capability OTA_HotelRatePlanNotif_accept_RatePlan_mixed_BookingRule must ensure that an update to a generic booking rule has no impact on existing specific rules.

About Supplements:

AlpineBits® supplements allow for the following use cases:

  • Exchange of included, mandatory or optional supplements

  • Exchange of multi-language descriptions of supplements with title and short text ("intro")

  • Exchange of date depending prices

  • Examples: cleaning fees, parking, New Year’s Eve dinner

  • Exchange of images

  • Categorization of supplements

AlpineBits® supplements don’t currently allow for the following use cases (these will be addressed in a future release of AlpineBits®, therefore it’s possible that substantial modifications will be made):

  • Supplements available

Other things to note about supplements:

  • AlpineBits® does not allow the child element RoomCompanions

  • A rate plan must describe any local taxes and fees in its description (as opposed to giving them as a supplement). The rationale behind this is that a portal does not have enough information to decide whether these local taxes and fees apply to a given booking request or not

Reference Implementation:

A reference implementation for the computation of the cost of a stay is available at https://development.alpinebits.org/#/rtapp. This implementation can be used manually (by using the website) or automatically (by sending data to a web service). The implementation can also be run from the command line, source code is available.

Please let the AlpineBits Alliance know if you find a discrepancy between this document and the reference implementation.

If there is a discrepancy the following rules can be used to solve it:

  • If the document is clear, the document prevails.

  • If the document is ambiguous, the reference implementation prevails.

4.6. BaseRates

If the action parameter is OTA_HotelRatePlan:BaseRates, the client sends a pull request to query rate plans from the server in order to import data back into a PMS or portal.

4.6.1. Client request

The parameter request contains an OTA_HotelRatePlanRQ document.

Nested inside one RatePlan element the following sub-elements are given in order:

  • Zero or one DateRange element with Start and End attributes.

  • Zero or more RatePlanCandidate elements with attributes RatePlanCode and RatePlanID.

  • One HotelRef element with attributes HotelCode and HotelName - the rules are the same as for room availability notifications (section 4.1.1).

Here is an example:

---- <OTA_HotelRatePlanRQ xmlns="http://www.opentravel.org/OTA/2003/05" Version="3.000"> <RatePlans> <RatePlan> <DateRange Start="2016-12-25" End="2017-01-03" /> <RatePlanCandidates> <RatePlanCandidate RatePlanCode="DZ" RatePlanID="DailyRate"/> <RatePlanCandidate RatePlanCode="SPECIAL"/> </RatePlanCandidates> <HotelRef HotelCode="123" HotelName="Frangart Inn" /> </RatePlan> </RatePlans> </OTA_HotelRatePlanRQ> ----

Regarding DateRange and RatePlanCandidate six cases need to be distinguished:

  1. DateRange omitted, RatePlanCandidate present:

    The server will answer with the matching rate plans.

  2. DateRange omitted, RatePlanCandidate omitted:

    The server will answer with all the rate plans it has on record. Note that the Rate elements are omitted, the response contains just the RatePlan elements with the Description whose Name attribute is set to Title.

  3. DateRange empty, RatePlanCandidate present:

    If the server supports deltas, it must return the changes to the requested rate plans since the last request by the same client. If the server does not support deltas, this is not possible and will trigger a warning response.

  4. DateRange empty, RatePlanCandidate omitted:

    This is not possible and will trigger a warning response.

  5. DateRange set, RatePlanCandidate present:

    Server responds with all rates matching the given date range and rate plan.

  6. DateRange set, RatePlanCandidate omitted:

    The server response contains descriptions of the rate plans having rates in the given date range. Note that the Rate elements are omitted, the response contains just the RatePlan elements with the Description whose Name attribute is set to Title.

4.6.2. Server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelRatePlanRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed. See Appendix A for details.

In case of a successful outcome, the Success element is followed by a RatePlans element with the information about the hotel.

Here is an example:

---- <OTA_HotelRatePlanRS xmlns="http://www.opentravel.org/OTA/2003/05" Version="3.000"> <Success/> <RatePlans HotelCode="123" HotelName="Frangart Inn"> <RatePlan RatePlanCode="Base" CurrencyCode="EUR"> <Rates> <Rate RateTimeUnit="Day" UnitMultiplier="1"> <BaseByGuestAmts> <BaseByGuestAmt Type="7"/> </BaseByGuestAmts> <MealsIncluded MealPlanIndicator="true" MealPlanCodes="12"/> </Rate> <Rate Start="2016-12-29" End="2016-12-31" InvTypeCode="EZ"> <BaseByGuestAmts> <BaseByGuestAmt NumberOfGuests="1" AmountAfterTax="130.00"/> </BaseByGuestAmts> </Rate> <Rate Start="2016-12-29" End="2016-12-31" InvTypeCode="DZ"> <BaseByGuestAmts> <BaseByGuestAmt NumberOfGuests="2" AmountAfterTax="180.00"/> </BaseByGuestAmts> </Rate> </Rates> <Description Name="title"> <Text TextFormat="PlainText" Language="en">Lorem ipsum.</Text> <Text TextFormat="PlainText" Language="it">Lorem ipsum.</Text> </Description> </RatePlan> </RatePlans> </OTA_HotelRatePlanRS> ----

4.7 ActivityData

If the action parameter is OTA_HotelPostEventNotif:EventReports the client intends to send information about hotel internal activities made available to their guests.

4.7.1 Exchange of hotel activities

The request parameter contains an OTA_HotelPostEventNotifRQ document.

Here is the global structure of the document:

<?xml version="1.0" encoding="UTF-8"?> <OTA_HotelPostEventNotifRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelPostEventNotifRQ.xsd" Version="8.000"> <EventReports> <EventReport> <EventSites> <EventSite HotelCode="00001" HotelName="TestHotel" > <Event_ID Type="18" ID="41654" ID_Context="providerNameSrl" /> </EventSite> </EventSites> <GeneralEventInfo Type="4" URL="https://example.com/event-permalink" Acronym="YO-CES" > <EventContacts> </EventContacts> <AttendeeInfo TotalQuantity="50" PreRegisteredQuantity="0"/> <Dates> </Dates> <Comments> <Comment Name="Title"> </Comment> <Comment Name="Category"> </Comment> <Comment Name="Gallery"> </Comment> <Comment Name="Description"> </Comment> </Comments> </GeneralEventInfo> </EventReport> </EventReports> </OTA_HotelPostEventNotifRQ>

samples/ActivityData/ActivityData-OTA_HotelPostEventNotifRQ.xml - outer part

Each document contains one EventReports element which MUST contain at least one and at most 99 EventReport elements. Each EventReport element contains two elements EventSites and GeneralEventInfo, both mandatory.

EventSites requires exactly one EventSite element.

For the attributes HotelCode and HotelName, inside the EventSite element, the rules are the same as for room availability notifications (section 4.1.1). While it is possible to send more than one EventReport element, AlpineBits® requires that all EventReport elements refer to the same hotel. Hence exactly one hotel can be dealt with in a single request.

An AlpineBits® server must return an error if it receives a request referring to more than one hotel.

The mandatory Event_ID element has no content and three attributes, all mandatory:

  • Type must have the value 18.

  • ID an identifier of the activity as set by the provider.

  • ID_Context the context referring to the ID. Usually it’s the name of the provider for the activity.

The pair ID,ID_Context is the unique identifier of the activity: it MUST appear only once in a single message and MUST be used as reference for further synchronization messages.

An AlpineBits® server must return an error if the same activity (i.e. multiple conflicting Event_ID elements) are sent in the same message.

The GeneralEventInfo holds the information about the activity. It contains the following attributes:

  • Type.

  • URL. Optional, a URL where the activity can be accessed in the providing system.

  • Acronym. Optional, an acronym of the activity. If specified, it must be comprehensible for humans.

Further, the GeneralEventInfo element contains the following 4 elements:

  • EventContacts. Optional. It must contain at least one EventContact sub-element.

  • AttendeeInfo. Optional. See below for explanation.

  • Dates. Optional. It must contain at least one and at most 99 Date sub-elements.

  • Comments. Mandatory. See below for explanation.

An example of the complete structure of the EventContact element is the following:

<EventContact Role="chief"> <PersonName> <GivenName>Werner</GivenName> <Surname>Call</Surname> </PersonName> <URL Type="Image">https://example.com/image.jpg</URL> <EmployeeInfo EmployeeId="Chief cook"/> </EventContact>

samples/ActivityData/ActivityData-OTA_HotelPostEventNotifRQ.xml - inner part

Each EventContact element describes one contact that pertains to the activity. Its optional attribute Role, due the fact that of not being localized, must be agreed upon by the AlpineBits® partners and is used to transmit the Role of this person with regard to this activity (The same person might have different roles in different activities, for instance the "Guide" in an Hiking activity and "Instructor" in a skiing activity).

Further, the EventContact element contains the following elements:

  • The optional PersonName element describes the referer person for the activity, surname and first name are sent using the mandatory Surname element and the optional GivenName element respectively.

  • The optional URL element with the mandatory Type attribute set to Image, contains a link to a picture of the contact.

  • The optional EmployeeInfo element contains in the mandatory EmployeeId is used to assign a unique Identifier to the contact person. This could be useful for further synchronization. (Be aware that this attribute is limited to a maximum length of 16 character)

The optional element AttendeeInfo contains the TotalQuantity attribute that is used to specify the maximum number of guests that can participate to the activity. The attribute PreRegisteredQuantity contains the number of slots that are already busy, hence if the two attributes hold the same value the activity can be considered "sold out". Please note that AlpineBits® currently does not specify a way to book or reserve a slot for activities.

The Dates element contains at least one and up to 99 Date elements, which are the dates when the activity is scheduled. The main structure of the Date element is the following:

<Date Start="2018-02-23T09:30:00+02:00" End="2018-02-23T11:30:00+02:00"> <EndDateWindow LatestDate="2018-02-23T09:30:00+02:00"/> <LocationCategories> <Location AreaID="1" /> <Category Language="en">Wellness Area</Category> <Category Language="de">Wellnessbereich</Category> <Category Language="it">Area wellness</Category> </LocationCategories> </Date>

samples/ActivityData/ActivityData-OTA_HotelPostEventNotifRQ.xml - inner part

The attributes Start and End define the beginning and the end of the activity, both may also contain time information if available. The Start attribute is mandatory, the End attribute is optional and its absence means that the event is open-ended. The optional EndDateWindow element contains the mandatory LatestDate attribute: the deadline by which guests SHOULD subscribe to the activity.

The optional LocationCategories element is used to describe the meeting place / location where the activity is planned to happen. The optional Location element allows the exchange of a unique identifier for the meeting place through its mandatory AreaID attribute. At least one Category element must be specified and contain the mandatory Language attribute set to a two-letter lowercase language abbreviation according to ISO 639-1. At most one Category element is allowed for each Language. Each Category element is used to transmit the localized name of the location.

The Comment section is the part where descriptive elements are defined.

Here is a sample:

<Comments> <Comment Name="Title"> <Text Language="en">Yoga with Cesare</Text> <Text Language="de">Yoga mit Cesare</Text> <Text Language="it">Yoga con Cesare</Text> </Comment> <Comment Name="Category"> <Text>WELLNESS-MENTAL</Text> <Text Language="en">Mental wellness</Text> <Text Language="de">mentales Wohlbefinden</Text> <Text Language="it">Benessere mentale</Text> </Comment> <Comment Name="Gallery"> <Image>https://example.com/image1.jpg</Image> <Image>https://example.com/image2.jpg</Image> </Comment> <Comment Name="Description"> <Text Language="en">Yoga Lorem Ipsum …​</Text> <Text Language="de">Yoga Lorem Ipsum …​</Text> <Text Language="it">Yoga Lorem Ipsum …​</Text> </Comment> </Comments>

samples/ActivityData/ActivityData-OTA_HotelPostEventNotifRQ.xml - inner part

Inside the Comments element there are up to 4 Comment elements.

The Comment element with the attribute Name set to Title is mandatory and it contains at least one Text element with the mandatory attribute Language set to a two-letter lowercase language abbreviation according to ISO 639-1. Multiple Text elements can be specified, but each must specify a different Language: these are the title of the activity in the different languages.

The Comment element with the attribute Name equal to Category is mandatory and it contains at least one Text element with the optional attribute Language set to a two-letter lowercase language abbreviation according to ISO 639-1. Multiple Text elements can be specified, but each must specify a different Language: These are the categories of the activity in the different languages. At most one Text element can be specified without the Language attribute: this holds a unique identifier for the category, not meant for displaying to humans.

The Comment element with Name equal to Gallery is optional and it contains at least one Image element without attributes. Each Image element contains a valid url to an image that can be used to display the activity.

The Comment element with Name equal to Description is optional and it contains at least one Text element with the mandatory attribute Language set to a two-letter lowercase language abbreviation according to ISO 639-1. Multiple Text elements can be specified, but each must specify a different Language: These are the descriptions of the activity in the different languages.

4.7.2 ActivityData: Synchronization and deletion

Upon receiving an activity (identified by the given Event_ID) an AlpineBits® server MUST replace the previous activity stored with the same identificative in its entirety. This means that in case of rescheduling or cancellation of specific dates of an activity the whole activity must be sent again with up to date information.

In case of the complete cancellation of an activity, with all its dates, a client can notify to the server a deletion sending one EventReport element formed according to the following rules:

  • The EventSites element MUST contain the same data of the original message for new activity.

  • the GeneralEventInfo element MUST be empty (self closed tag).

Here is an example:

<EventReports> <EventReport> <EventSites> <EventSite HotelCode="00001" HotelName="TestHotel" > <Event_ID Type="18" ID="41654" ID_Context="providerNameSrl" /> </EventSite> </EventSites> <GeneralEventInfo /> </EventReport> </EventReports>

samples/ActivityData/ActivityData-OTA_HotelPostEventNotifRQ-deletion.xml - inner part

4.7.3. Server response

The server will send a response indicating the outcome of the request. The response is a OTA_HotelPostEventNotifRS document. Any of the four possible AlpineBits® server response outcomes (success, advisory, warning or error) are allowed. See Appendix A for details.

Here is an example:

<?xml version="1.0" encoding="UTF-8"?> <OTA_HotelPostEventNotifRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opentravel.org/OTA/2003/05" xsi:schemaLocation="http://www.opentravel.org/OTA/2003/05 OTA_HotelPostEventNotifRS.xsd" Version="8.000"> <Success/> </OTA_HotelPostEventNotifRS>

samples/ActivityData/ActivityData-OTA_HotelPostEventNotifRS-success.xml