AlpineBits® is an interface specification for exchanging data in the tourism sector, specially tailored for alpine tourism.
The interface is based on XML messages that validate against version 2015A of the OpenTravel Schema by the OpenTravel Alliance.
© AlpineBits Alliance. This document is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License 0.
Permissions beyond the scope of this license may be available at https://www.alpinebits.org.
Disclaimer
This specification is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
If you find errors or you have proposals for enhancements, do not hesitate to contact us using the online discussion group: https://groups.google.com/forum/#!forum/alpinebits.
About the AlpineBits Alliance
The "AlpineBits Alliance" is a group of SME operating in the tourism sector working together to innovate and open the data exchange in alpine tourism, and therefore to optimize the online presence, sales and marketing efforts of the hotels and other accommodations in the alpine territory and also worldwide.
AlpineBits Alliance
Via Bolzano 63/A
39057 Frangarto / Appiano s.s.d.v. (BZ) - ITALY
VAT Reg No: IT02797280217
https://www.alpinebits.org
info@alpinebits.org
AlpineBits Alliance Members
ADDITIVE d. Ebner Matthias & Leiter Joachim OHG - https://www.additive.eu
Altea Software Srl - https://www.altea.it
aries.creative KG - https://www.ariescreative.com
ASA des Spitaler Gerhard & Co. KG - https://www.asaon.com
Brandnamic GmbH - https://www.brandnamic.com
Consisto GmbH - https://www.consisto.it
Destination Srl - https://www.destinationsrl.it
GardenaNet snc - https://www.gardena.net
HGV Service Genossenschaft - https://www.hgv.it
IDM Südtirol - Alto Adige - https://www.idm-suedtirol.com
Internet Consulting GmbH - https://www.inetcons.it
Internet Service GmbH - https://www.internetservice.it
LTS - Landesverband der Tourismusorganisationen Südtirols - https://www.lts.it
Marketing Factory GmbH - https://www.marketingfactory.it
NOI Spa/AG - https://noi.bz.it
Outdooractive AG - https://corporate.outdooractive.com/
PCS GmbH - https://www.pcs-software.it
Peer GmbH - https://www.peer.biz
Rateboard GmbH - https://www.rateboard.info
Schneemenschen GmbH - https://www.schneemenschen.de
SiMedia GmbH - https://www.simedia.com
Südtiroler Bauernbund - Roterhahn - https://www.roterhahn.it
XLbit snc - https://www.xlbit.com
Yanovis GmbH - https://www.yanovis.com
Authors of this document:
AlpineBits® repository Contributors - https://gitlab.com/alpinebits/hoteldata/standard-specification/-/graphs/master
Document Change Log
Important note: make sure to have the latest version of this document! The latest version is available from https://www.alpinebits.org.
protocol version | doc. release date | description |
---|---|---|
2022-10 |
2022-10-20 |
Status:
Updates and Additions:
|
2020-10 |
2020-10-15 |
Status:
Updates and Additions:
|
2018-10 |
2018-11-30 |
Status:
Notable documentation changes:
Updates and Additions:
|
2017-10 |
2017-11-08 |
Status:
Notable documentation changes:
Updates and additions:
Reorganization of the appendices:
Removals:
|
2015-07b |
2016-08-01 |
Status:
Updates and additions:
|
2015-07 |
2015-10-28 |
Status:
Updates and additions:
|
2014-04 |
2014-12-23 |
Status:
|
2014-04 |
2014-10-15 |
Status:
Updates and additions:
|
2013-04 |
2013-05-24 |
Status:
Updates:
|
2012-05b |
2012-10-01 |
Status:
Updates:
|
2012-05 |
2012-05-31 |
Status:
Updates:
Additions:
|
2011-11 |
2011-11-18 |
minor alterations and release under Creative Commons Attribution-NoDerivs 3.0 Unported License |
2011-10 |
2011-10-20 |
production release with minor alterations |
2011-09 |
2011-09-08 |
first draft of redesigned version (using POST instead of SOAP) |
2010-10 |
2010-10-20 |
second draft |
2010-08 |
2010-08-01 |
first draft |
1. Introduction¶
This documents describes a standard for exchanging traveling and booking information, called AlpineBits®.
AlpineBits® builds upon established standards:
-
client-server communication is done through stateless HTTPS (the client POSTs data to the server and gets a response) with basic access authentication 1 and
-
traveling and booking information is encoded in XML, following version 2015A of the OpenTravel Schema 3, 4, 5 (from here on called OTA2015A) by the OpenTravel Alliance 2.
At the current version of the standard, the scope of AlpineBits® covers exchanging the following types of information:
-
room availability (FreeRooms),
-
reservation inquiries (GuestRequests),
-
room category information (Inventory) and
-
prices (RatePlans).
AlpineBits® relies on its underlying transport protocol to take care of security issues. Hence the use of HTTPS is mandatory.
2. The HTTPS request and response structure¶
An AlpineBits® compliant server exposes a single HTTPS URL. Clients send POST requests to that URL.
The POST request must transmit the access credentials using basic access authentication.
The HTTPS header of the POST request must contain an X-AlpineBits-ClientProtocolVersion field. The value of this field is the protocol version supported by the client (see the first column of the changelog table). A server that does not receive the field will simply conclude that the client speaks a protocol version preceding the version when this field was introduced (2013-04).
The HTTPS header of the POST request may contain an X-AlpineBits-ClientID field. The value of this field is an arbitrary string which a server implementer might want to use to identify the client software version or installation ID.
The POST request must follow the multipart/form-data encoding scheme, as commonly used in the context of HTML forms for file uploads.
The POST request may be compressed using the gzip algorithm, in which case the HTTP request header Content-Encoding must be present and have "gzip" as a value. A POST request compressed with gzip must be compressed by the client in its entirety (i.e. the whole message must be compressed, not the single parts of the multipart/form-data content). It is the responsibility of the client to check whether the server supports content compression, this is done by checking the value of the HTTP response header X-AlpineBits-Server-Accept-Encoding which is set to "gzip" by servers which support this feature. The so called "Handshaking" actions must not be compressed.
The POST requests must have at least one parameter named action
. Depending on the value of action
, one additional parameter named request
might be required.
A exemplary handshake on command line using cURL with file samples/Handshake-OTA_PingRQ.xml
would look as follows.
curl --trace-ascii - -H "X-AlpineBits-ClientProtocolVersion: 2022-10" --user chris:secret -F "action=OTA_Ping:Handshaking" -F "request=<Handshake-OTA_PingRQ.xml" http://development.alpinebits.org/server-2022-10/ |
Following is the capture of the example POST from the command above. The first value of action
is the string action_OTA_Ping
, indicating the client wishes to perform the handshake, and the rest of the action listed in samples/Handshake-OTA_PingRQ.xml
. The value of request
is an XML document (not fully shown).
POST /server-2022-10/ HTTP/1.1 Host: development.alpinebits.org Authorization: Basic Y2hyaXM6c2VjcmV0 User-Agent: curl/7.64.0 Accept: / X-AlpineBits-ClientProtocolVersion: 2022-10 Content-Length: 1472 Content-Type: multipart/form-data; boundary=cd287e7912d06e8f Expect: 100-continue --cd287e7912d06e8f Content-Disposition: form-data; name="action" OTA_Ping:Handshaking --cd287e7912d06e8f Content-Disposition: form-data; name="request" Content-Type: application/xml [here is the content of the file Handshake-OTA_PingRQ.xml] --cd287e7912d06e8f-- |
Note the Authorization
field, with the username/password string (chris:secret
) encoded in base64 (Y2hyaXM6c2VjcmV0
) as defined by the basic access authentication standard 1.
Also note the X-AlpineBits-ClientProtocolVersion
and X-AlpineBits-ClientID
fields and the multipart content with the values of parameters action
and request
.
As a result of the POST request, the server answers with a response. Of course, the content of the response depends on the POSTed parameters, in particular the value of action
. AlpineBits® currently identifies two kinds of actions: the so-called handshaking actions explained in section 3 and the actual data exchange actions explained in section 4.
HTTP/1.1 200 OK Date: Thu, 21 Oct 2021 15:16:42 GMT Server: Apache X-Powered-By: Express Access-Control-Allow-Origin: * Content-Type: application/xml; charset=utf-8 Content-Length: 1653 ETag: W/"675-SunhP4r+79pVYE64e5ahe7LFpDs" Vary: Accept-Encoding X-AlpineBits-Server-Accept-Encoding: gzip [here is the response, that is identical to Handshake-OTA_PingRS.xml in the samples] |
The expected status code of the response is 200 (Ok), indicating that the server could authenticate the user (with or without being able to actually process any action).
In case of authentication failure (either an invalid or missing username/password or a value of X-AlpineBits-ClientID that is not acceptable to the server) the status code is 401 (Authorization Required) and the content is ERROR
, followed by a colon (:
) and an error message indicating the reason for the failure, such as no username/password was provided or the password expired, etc. Regarding the X-AlpineBits-ClientID
, a server chooses to require the ID or to ignore the ID. If the server chooses to ignore the ID, it must do so silently, i.e. it must not return a 401 status because of the presence of the ID.
In case of an internal server problem the status code is 500 (Internal Server Error).
A server that has not announced support for requests compressed with gzip may return the status code 501 (not implemented) in case it receives such requests.
An AlpineBits® client must be able to handle these status codes. It should retry a request that has failed (error code 500 or timeout) and only escalate the failure after 2 retries with an appropriate delay.
2.1. Implementation tips and best practice¶
-
For maximum compatibility across different implementations AlpineBits®, implementers are asked to handle POST requests using a supporting API in their language of choice. See appendix B for more resources.
-
All POSTs to an AlpineBits® server are sent to a single URL. However, a server implementer might make more than one URL available for independent servers, such as servers with support for different versions:
-
https://server.example.com/alpinebits/2011-11
-
https://server.example.com/alpinebits/2012-05b
-
etc…
-
-
Gzip compression can make a request smaller by a factor of ten, therefore it was introduced in AlpineBits® even though its usage in POST requests isn’t very common (as opposed to responses where its use is widespread). According to the various RFCs, compressing the requests is not forbidden, but there are no implementation recommendations. It was decided to use an approach major web servers were already supporting at the time of this writing.
-
When negotiating an AlpineBits® version, clients and servers should behave in the following way (this works starting from 2013-04):
-
Client: the client queries the server version, sending a header with the highest version it supports.
-
Server: if the server supports this same version, it answers with this version and the negotiation terminates successfully; otherwise the server answers with the highest version it supports.
-
Client: if the client recognizes the server version, it starts using the server version and the negotiation terminates successfully; otherwise no communication is possible, since the two parties don’t share a common version.
-
3. Handshaking action¶
The handshaking action allows client and server to agree on the supported AlpineBits® versions and capabilities. Any AlpineBits® client or server must be able to handle this request. In the rest of this chapter the word "actor" will be used when referring to either client or server.
It is the client’s responsibility to ensure the server can handle the actions it intends to perform. The client should update capabilities periodically. The server may request an update of the capabilities from the client by sending a response described in Appendix A under paragraph "Responses with a request for complete sets of data"
Please note that this chapter was completely rewritten in AlpineBits® 2018-10 version, and it introduces breaking changes. This was needed to significantly streamline the handshaking progress.
The following table lists all available handshaking actions.
usage (since) |
mandatory | parameter action (string) |
parameter request and server response (XML document) [small] |
---|---|---|---|
client sends its supported actions and capabilities (since 2018-10) |
YES |
|
OTA_PingRQ |
3.1. Client request¶
The parameter request
must contain an OTA_PingRQ
document.
The EchoData element must contain a JSON
object, and adhere to the following rules:
-
The root element is a JSON array with name
versions
. -
Each element of the array
versions
is a JSON object.
Each object of the versions
array is built according to the following rules:
-
A member with name
version
and value corresponding to a valid AlpineBits® version string must be present (see the first column of the changelog table, e.g. 2018-10 for the first version of AlpineBits® that supports handshaking) -
A JSON array with name
actions
may be present.
Each element of the actions
array is a JSON object built according to the following rules:
-
A member with the name
action
and value corresponding to one supportedaction
. -
A JSON array with name
supports
, listing all the supportedcapabilities
for the siblingaction
.
In general the client should always start handshakes with the highest version he supports. If the client doesn’t receive a positive response from the server, the client should try to reconnect by decreasing to the next lower version he supports. If there is no common version, no communication is possible. For more details on server responses in the handshake see section 3.2.
|
example of Handshake client request, only the EchoData element is shown. |
For every succesfully negotiated (see below) action
, the client must set the X-AlpineBits-ClientProtocolVersion
HTTP header according to the sibling version
when performing the subsequent data exchange with the server.
In order to avoid misintepretations, the AlpineBits® versions below 2018-10
may be part of the JSON object, but there must not be any actions
array specified for them. The handshaking of the legacy versions must happen in subsequent requests following the legacy rules.
3.2. Server Response¶
The response is an OTA_PingRS
document.
As mandated by OTA, the content of the EchoData element must be identical to what the client sent.
The server must add to the response a Warning element with Type 11
and Status ALPINEBITS_HANDSHAKE
. The content of this element must be the intersection between the client announced versions
, actions
and capabilities
and what the server actually supports.
If a server receives a handshake request with a version he doesn’t support or doesn’t know, the server is allowed to reject the message with an error and a textual description about version incompatibility. This error is thrown by only checking the X-AlpineBits-ClientProtocolVersion.
For better compatibility the server may not directly reject the connection based on the header information, but trying to fulfill the handshake by checking if he supports one of the versions indicated by the client. The answer would be an intersection of common versions in order to give a more specific answer to the client. In that case compatibility between client and server is found within the handshake on the first connection.
In any case this is also valid for the OTA_Ping. If the server supports the version, but no intersection other than OTA_Ping is found, a server should answer to be exclusively compatible with OTA_Ping. This implies there are no common actions between client and server. Otherwise the server should not reply supporting this version at all.
|
example of Handshake server response. |
3.3. List of AlpineBits® supported actions
and capabilities
¶
-
action_OTA_Ping
handshaking action (support for this action is mandatory) -
action_OTA_HotelInvCountNotif
the actor implements handling room availability notifications (FreeRooms) -
OTA_HotelInvCountNotif_accept_rooms
for room availability notifications (FreeRooms), the actor handles availabilities for specific rooms -
OTA_HotelInvCountNotif_accept_categories
for room availability notifications (FreeRooms), the actor handles availabilities for room categories -
OTA_HotelInvCountNotif_accept_complete_set
for room availability notifications (FreeRooms), the actor handles CompletSet messages -
OTA_HotelInvCountNotif_accept_deltas
for room availability notifications (FreeRooms), the actor handles partial information (deltas) -
OTA_HotelInvCountNotif_accept_out_of_order
for room availability notifications (FreeRooms), the actor handles the number of rooms that are considered out of order -
OTA_HotelInvCountNotif_accept_out_of_market
for room availability notifications (FreeRooms), the actor handles the number of rooms that are considered free but not bookable -
OTA_HotelInvCountNotif_accept_closing_seasons
for room availability notifications (FreeRooms), the actor handles closing seasons -
action_OTA_Read
the actor implements handling quote requests, booking reservations and cancellations (GuestRequests Pull) -
action_OTA_HotelResNotif_GuestRequests
the actor implements pushing quote requests, booking reservations and cancellations (GuestRequests Push) -
action_OTA_HotelResNotif_GuestRequests_StatusUpdate
the actor implements the status update for quote requests (GuestRequests Push status update) -
action_OTA_HotelDescriptiveContentNotif_Inventory
the actor implements handling Inventory/Basic (push) -
OTA_HotelDescriptiveContentNotif_Inventory_use_rooms
for room category information (Inventory), the actor needs information about specific rooms -
OTA_HotelDescriptiveContentNotif_Inventory_occupancy_children
for room category information (Inventory), the actor supports applying children rebates also for children below the standard occupation -
action_OTA_HotelDescriptiveContentNotif_Info
the actor implements handling Inventory/HotelInfo (push) -
action_OTA_HotelDescriptiveInfo_Inventory
the actor implements handling Inventory/Basic (pull) -
action_OTA_HotelDescriptiveInfo_Info
the actor implements handling Inventory/HotelInfo (pull) -
action_OTA_HotelRatePlanNotif_RatePlans
the actor implements handling prices (RatePlans) -
OTA_HotelRatePlanNotif_accept_ArrivalDOW
for prices (RatePlans), the actor accepts arrival DOW restrictions in booking rules -
OTA_HotelRatePlanNotif_accept_DepartureDOW
for prices (RatePlans), the actor accepts departure DOW restrictions in booking rules -
OTA_HotelRatePlanNotif_accept_RatePlan_BookingRule
for prices (RatePlans), the actor accepts "generic" booking rules -
OTA_HotelRatePlanNotif_accept_RatePlan_RoomType_BookingRule
for prices (RatePlans), the actor accepts "specific" booking rules for the given room types -
OTA_HotelRatePlanNotif_accept_RatePlan_mixed_BookingRule
for prices (RatePlans) and within the same rate plan, the actor accepts both "specific" and "generic" booking rules. Both "generic" and "specific" rules capabilities must still be announced by the actor. -
OTA_HotelRatePlanNotif_accept_Supplements
for prices (RatePlans), the actor accepts supplements -
OTA_HotelRatePlanNotif_accept_FreeNightsOffers
for prices (RatePlans), the actor accepts free nights offers -
OTA_HotelRatePlanNotif_accept_FamilyOffers
for prices (RatePlans), the actor accepts family offers -
OTA_HotelRatePlanNotif_accept_overlay
for prices (RatePlans), the actor accepts the rate plan notif type valueOverlay
-
OTA_HotelRatePlanNotif_accept_RatePlanJoin
for prices (RatePlans), the actor supports grouping RatePlans with different MealPlanCodes under a single price list -
OTA_HotelRatePlanNotif_accept_OfferRule_BookingOffset
for prices (RatePlans), the actor accepts the OfferRule restrictions MinAdvancedBookingOffset and MaxAdvancedBookingOffset -
OTA_HotelRatePlanNotif_accept_OfferRule_DOWLOS
for prices (RatePlans), the actor accepts the OfferRule restrictions ArrivalDaysOfWeek, DepartureDaysOfWeek, SetMinLOS and SetMaxLOS -
action_OTA_HotelRatePlan_BaseRates
the actor implements handling BaseRates -
OTA_HotelRatePlan_BaseRates_deltas
the actor supports delta information with BaseRates -
action_OTA_HotelPostEventNotif_EventReports
the actor implements handling hotel internal activities
AlpineBits® requires an actor to support at least all mandatory handshaking actions.
All other capabilities are optional. It is a client’s responsibility to check for server capabilities before trying to use them. A server implementation is free to ignore information that requires a capability it doesn’t declare. A server must, however, implement all capabilities it declares.
3.4. Unknown or missing actions¶
Upon receiving a request with an unknown or missing value for action, the server response is the string: ERROR:unknown or missing action
.
Please note that the legacy "housekeeping actions" (namely: getVersion
and getCapabilities
) have been removed from this version of AlpineBits® and will yield to such a response.
3.5. Implementation tips and best practice¶
-
OTA requires the root element of an XML document to have a version attribute. In regards to AlpineBits®, the value of this attribute is irrelevant.
-
The handshaking action allows actors that are able to support multiple AlpineBits® versions to negotiate the best combinations of versions and capabilities with a single request. The suggested approach for a client is to list all the AlpineBits® versions and the related
actions
/capabilities
it supports in a single request. -
Since the server is performing an intersection between the received JSON object and its supported versions and capabilities the response might be an empty JSON object (
{}
), this is an indication that there was a failure in parsing the JSON of the request. -
When a client upgrades its AlpineBits® version, it is advised for it to re-configure all connections with its partner servers (provided they support the new version) starting from the handshaking and dealing with each data exchange action as a first synchronization in order to overwrite servers' data. This is to avoid any ambiguity or data-loss due to possible breaking changes between the old and new version. Examples of such breaking changes could be found when upgrading to version 2017-10 (or higher) with the introduction of static rates or when upgrading to version 2020-10 (or higher) with the re-writing of the FreeRooms action introducing the new out-of-order categories. In case a server receives a delta message with an AlpineBits® version which is inconsistent with the previously stored data, a server is free to decide whether to alert the client by sending a warning, to delete the stored data and/or to request a full re-synchronisation from the client (complete set).
-
A server may inform the client regarding the deprecation of the current request through the headers
Deprecation
andLink
, as defined by the IETF (https://datatracker.ietf.org/doc/draft-ietf-httpapi-deprecation-header). These headers may be added to the response of any type of action that the server deems appropriate to deprecate, and applies to that specific action.For the complete explanation of the headers, their syntax and use cases, please refer to the source linked above. As example, one endpoint serving an obsolete version of AlpineBits could be returning the following headers:
Deprecation: Mon, 19 Oct 2020 23:59:59 GMT Link: <\https://developer.alpinebits.org/deprecation.txt>; rel="deprecation"; type="text/plain"
The linked resource may contain information about the deprecation that happened in the specified date (e.g. introducing a new endpoint replacing the one the client is currently using), sharing details about it. Since this information is not useful for users, a client is not required to show it and may choose to collect it and report it to its developers or administration team. In case the scope of the deprecation is broader than the specific action, this information might be added to the linked resource. These information are meant as helpful way to armonize server and clients versions, and they might be ignored by the client.
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 |
|
|
GuestRequests (since 2012-05) |
a client sends a request to receive requests for a quote or booking requests from the server |
|
|
GuestRequests (Push) (since 2018-10) |
a client sends requests for a quote or booking requests to the server |
|
|
GuestRequests Status Update (Push) (since 2022-10) |
a client sends status updates for a quote or booking requests to the server |
|
|
GuestRequests/Acknowledgments (since 2014-04) |
a client acknowledges the requests it has received |
|
|
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 |
|
|
Inventory/Basic (Pull) (since 2017-10) |
a client requests room category information and room lists |
|
|
Inventory/HotelInfo (Push) (since 2015-07) |
a client sends additional descriptive content regarding properties |
|
|
Inventory/HotelInfo (Pull) (since 2017-10) |
a client requests additional descriptive content regarding properties |
|
|
RatePlans (since 2014-04) |
a client sends information about rate plans with prices and booking rules |
|
|
BaseRates (since 2017-10) |
a client requests information about rate plans |
|
|
Activities (since 2020-10) |
a client requests information about hotel activities |
|
|
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.
On copyright and license of exchanged contents¶
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
andX-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:
|
|
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.
|
|
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 theOTA_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 theOTA_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.
|
|
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:
|
|
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.
|
|
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).
|
|
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).
|
|
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
orHOTEL
. -
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”.
|
|
Example B: the customer will surely bring pets but no further information is given.
|
|
Example C: the customer will surely not have any pet with him.
|
|
-
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:
|
|
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.
|
|
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; |
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; |
OTA_NotifReportRS Success [small] |
server knows the client got 1, it will not be sent again [small] |
09:00 [small] |
action = OTA_Read:GuestRequests; |
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; |
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; |
OTA_NotifReportRS Success [small] |
server now knows the client got all three [small] |
11:00 [small] |
action = OTA_Read:GuestRequests; |
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
-
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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
-
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 -
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
-
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) -
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.
|
|
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.
|
|
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:
|
|
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 ≤ MaxChildOccupancy ≤ MaxOccupancy. 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 is42
). -
For apartments: RoomType value
2
(should only be used when RoomClassificationCode is13
). -
For mobile homes: RoomType value
3
(should only be used when RoomClassificationCode is13
). -
For bungalows: RoomType value
4
(should only be used when RoomClassificationCode is13
). -
For holiday homes: RoomType value
5
(should only be used when RoomClassificationCode is13
). -
For camping grounds (place for vehicles in a camping): RoomType value
6
(should only be used when RoomClassificationCode is5
). -
For pitches (place for tents in a camping): RoomType value
7
(should only be used when RoomClassificationCode is5
). -
For camping grounds/pitches (place for either tents or vehicles in a camping): RoomType value
8
(should only be used when RoomClassificationCode is5
). -
For resting places (beds in shared rooms, like hostels or mountain huts): RoomType value
9
(should only be used when RoomClassificationCode is42
).
Here is an example of such a heading GuestRoom element:
|
|
The MultimediaDescription elements follow these rules:
-
A MultimediaDescription element with attribute InfoCode =
25
or1
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:
|
|
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
orHTML
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 toPlainText
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:
|
|
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:
|
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:
|
|
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.
|
|
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:
|
|
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 or4s
for 4 stars superior properties.
Two examples of CodeDetail attribute content may be:
-
PCT2017_20:4s
wherePCT2017_20
is the reference to OTA (PCT) Property Class Type Codes (Version 2017) and its relative value, in this case20
means Hotel. The string4s
after the colon character is the class value of the property. -
ASTAT2020_11:4s
whereASTAT2020_11
is the custom reference property type table name and its relative value. The string4s
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
orHTML
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 toPlainText
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:
|
|
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
orHTML
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 toPlainText
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 value21
= 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
orfalse
. -
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 orCheckout
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:
|
|
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 consideredfalse
.
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:
|
|
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:
|
|
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:
|
|
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.
|
|
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
orRemove
(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:
|
|
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
orHTML
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 toPlainText
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:
|
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:
|
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:
|
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 Start ≤ End. 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 statusOpen
. -
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 withSetForwardMinStay
andSetForwardMaxStay
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.
|
|
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.
|
|
Alternatively, example B could also be written as:
|
|
The following example (C) forbids any stay in the suite in August (departure on the 1st of August is possible).
|
|
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).
|
|
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:
|
|
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 Start ≤ End.
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):
|
|
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) or10
("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:
-
If AdditionalGuestAmount are defined at all, at most one AdditionalGuestAmount element with a AgeQualifyingCode set to
10
("adult") may be present. -
AdditionalGuestAmount elements having AgeQualifyingCode set to
8
("child") must have at least one of the attributes MinAge or MaxAge. Contrary, those with AgeQualifyingCode set to10
("adult") must have neither. -
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:
|
|
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.
|
|
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:
|
|
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 the1
. 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.
|
|
Example B (last minute offer): cannot be booked more than 7 days in advance, guests ≥ 16 are considered adults, children of any age allowed.
|
|
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.
|
|
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).
|
|
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.
|
|
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.
|
|
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).
|
|
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 std ≥ min,
-
The value of MaxOccupancy max ≥ std,
-
(Optional) the value of MaxChildOccupancy mco, such that 0 ≤ mco ≤ max.
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:
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:
-
DateRange omitted, RatePlanCandidate present:
The server will answer with the matching rate plans.
-
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
. -
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.
-
DateRange empty, RatePlanCandidate omitted:
This is not possible and will trigger a warning response.
-
DateRange set, RatePlanCandidate present:
Server responds with all rates matching the given date range and rate plan.
-
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
A. AlpineBits® server response outcomes¶
For each data exchange action the server will send a specific response.
The response document type obviously depends on the action. For instance, a FreeRooms response will be a OTA_HotelAvailNotifRS
document, whereas a response to a GuestRequests message will be a OTA_ResRetrieveRS
document, as listed in section 4 (see the table at the beginning of the section for an overview). The information in the response varies accordingly. E.g. a successful OTA_ResRetrieveRS
response contains a ReservationsList element, whereas an OTA_HotelAvailNotifRS
obviously cannot contain such an element.
What all responses have in common, however, is that they indicate the success or failure of the data exchange action. AlpineBits® distinguishes four outcomes that are modeled using the three elements provided by OTA in this context: Success, Warnings and Errors. The four outcomes are: success, advisory, warning and error and are explained in the following sections.
Responses with an AlpineBits® success outcome
The client’s request could be completely received, correctly parsed, was deemed syntactically valid and its contents could be processed successfully by the server. All business rules were satisfied. In case of a successful outcome the response contains one empty Success element, no Warnings and no Errors:
The client, in order to safeguard the validity of the transmitted data, should always make sure that the following conditions are true:
-
The XML composed by the client does represent the actual data.
-
All the checks that are indicated in this document as "client responsibility" were performed by the client.
|
The client does not need to take any further action, upon receiving a response with a successful outcome.
Responses with an AlpineBits® advisory outcome
As is the case for the successful outcome, the request could be correctly parsed, was deemed syntactically valid and could be processed successfully in its entirety. All business rules were satisfied.
However, one or more non-fatal problems were detected and the server wishes to let the client know about them.
In this case, the response contains one empty Success element followed by one or more Warning elements with the attribute Type set to 11
, meaning "Advisory" according to the "Error Warning Type" (EWT) list in the OTA code list 5.
Each Warning element should contain a human readable text.
Here is an example of FreeRooms response with an advisory outcome. Let’s imagine a server that handles FreeRooms with delta messages but wishes to receive at least one full data set each 48 hours and a client that hasn’t send one in the last 48 hours. The server might then proceed to accept another delta message, but advise the client with the following response:
|
|
A server might or might not implement responses with advisory outcomes.
However, a client must recognize advisory outcomes and visualize or log the human readable text, so that the non-fatal problem can be analyzed and corrected at a later stage. Of course, there is no need to resend the message as the server has already processed it successfully.
Responses with an AlpineBits® warning outcome
The request could be correctly parsed, was deemed syntactically valid, but could not be processed successfully in its entirety, because some business rules were violated.
Some examples for messages that cause a business rule violation are:
-
A message with an unknown HotelCode.
-
A RatePlans message having overlapping Rate elements with the same InvTypeCode attribute.
-
A GuestRequests acknowledgement message with an unknown ID.
In this case, the response contains one empty Success element followed by one or more Warning elements with the attribute Type set to any value allowed by the "Error Warning Type" (EWT) list in the OTA code list 5 other than 11
("Advisory").
Each Warning element should contain human readable text.
Here is an example of RatePlans response with an warning outcome. Let’s imagine a client that sent rate information concerning dates in the year 2107 because there was a data entry error. While the request was formally correct, the server could not process the request (and thus could not store the information about the rates) because it does not deal with dates in the distant future. So the server will proceed to refuse the request with the following warning response:
|
|
The value 3
for attribute Type stands for "Biz rule" according to the EWT.
Upon receiving an AlpineBits® warning outcome, a client must consider the request as failed in its entirety and must act accordingly. Since the request violated a business rule, there is no use to just try resending it. The client must rather escalate the failure. When run interactively, this means alerting the user. When run in an automatized way, this means alerting someone using appropriate means.
It is important to understand that despite the meaning of the word "warning" in other contexts, an AlpineBits® warning outcome indicates a failed request (due to violation of business rules). It cannot be safely ignored.
Note that AlpineBits® uses the Warnings element also for acknowledgements in the GuestRequests section (see 4.2.3). Those messages are not considered responses (as indicated by the RQ in OTA_NotifReportRQ
) and are thus unrelated to the discussion in the present section.
Responses with an AlpineBits® error outcome
The request caused one or more of the following problems:
-
It could not be correctly parsed.
-
It was deemed syntactically invalid.
-
Some error occurred while processing the request.
and therefore the request could not be be processed successfully in its entirety.
In this case, the response contains one or more Error elements with the attribute Type set to 13
, meaning "Application error" according to the "Error Warning Type" (EWT) list and the attribute Code set to any value allowed by the "Error Codes" list in the OTA code list 5.
Each Error element should contain a human readable text.
As an example, let’s imagine a client sends a message that requires one of the attributes HotelCode or HotelName to be present, but doesn’t include any of the two. This makes the request invalid and the server must answer with a response indicating the error outcome. Here is an example:
|
Here, the Code 321
stands for "Required field missing" according to the "Error Codes" list.
Upon receiving an AlpineBits® error outcome, a client must consider the request to be failed in its entirety and must act accordingly.
If a client software has reason to assume the problem is temporary and occurred for the first time, it might try to resend the request at a later moment (and bail out after a small number of retries with no success).
The client must then escalate the failure. When run interactively, this means alerting the user. When run in an automated way, this means alerting someone using appropriate means.
Note that a server that receives a request that is not authenticated, has missing or invalid POST parameters, will just respond with an ERROR
string as explained in sections 2 and 3. Since at that point no action can be identified the request type and hence the response type is unknown and no exchange of XML documents takes place.
A server could perform additional checks after an outcome success answer (asynchronous checks). In case of inconsistencies with a previous stored state, a server may request a complete sets of data as decribed below.
Responses with a request for complete sets of data
Along with the previous response cases, a server can request the client to send a full data set right after the current communication ends. The requested data may refer to different data from that received in the originating AlpineBits® request (For instance the server may request a full transfer of Availability information upon receiving a request for Rateplans).
In this case, the response contains one or more additional elements whose type depend on the outcome of the request:
-
One or more Warning elements in case of a success, advisory or warning outcome.
-
One or more Error elements in case of an error outcome.
These elements must be empty, must have the attribute Type set to 11
(“Advisory”) and must have the mandatory attribute Status with a value chosen among the following, based on the desired complete data set:
-
Status =
ALPINEBITS_SEND_HANDSHAKE
to request the handshake update -
Status =
ALPINEBITS_SEND_FREEROOMS
to request the full set of free rooms data -
Status =
ALPINEBITS_SEND_RATEPLANS
to request the full set of rate plans data -
Status =
ALPINEBITS_SEND_INVENTORY
to request the room configuration
If the server sends more than one of such elements, they must be referred to different data types, meaning that, at the current AlpineBits® version, a server can send up to three different requests: one for each of the above Status values.
Upon receiving a response with one or more of these elements, the client should transmit the corresponding data set as soon as possible in any order (see Tips and best practice).
The server should only send requests for kind of data supported by the client (the logic by which the server keeps track of these information is beyond the scope of this specification). The client must support receiving requests regarding any data, even if it is not directly supported/handled by it. The client is free to ignore request for data it does not handle, but might process such requests as it deems more appropriate, for instance by notifying the user.
Tips and best practice
A server should not request a complete data set in response to a complete set just received regarding the same data type. In this case, a client must ignore the request.
It is a client’s responsibility to keep track of which data was requested by the server in case it receives more than one element requesting a different complete data set.
A server should use this feature with common sense and only when necessary in order to avoid useless heavy-data transfer.
A client should implement a precaution against too frequent complete set requests, for example limiting its number in a given timespan.
Some examples:
The server accepts the message and requests a full synchronization of FreeRooms data:
|
The server sends a warning together with a request for a full synchronization of RatePlans data:
|
The server sends an error together with a request for a full synchronization of Inventory and FreeRooms data:
|
B. AlpineBits® developer resources¶
The AlpineBits® development home page is at https://www.alpinebits.org/developers/. There are resources linked from that page that help test one’s implementation.
Public repositories with schema files and example code snippets are available online at https://gitlab.com/alpinebits/. Contributions are welcome (any programming language).
C. Protocol Version Compatibility¶
This chapter documents some of the major caveats between AlpineBits® clients and servers. The provided list of incompatibilities is not meant to be exhaustive and it is highly encouraged that partners use the same version of AlpineBits® for exchanging data whenever possible. Most notably a client is highly discouraged from using different AlpineBits® versions for different actions
when interacting with the same server.
C.1. Major overhaul in version 2022-10¶
GuestRequests¶
The SpecialRequests attribute Name has been replaced with RequestCode and a new CodeContext attribute has been added.
The special case which allowed to specify alternative periods by adding one optional RoomStay element with only one TimeSpan element has been removed in favor of the new RoomStayGroupID attribute.
FreeRooms¶
In version 2022-10 a server might not handle CompleSet messages for OTA_HotelInvCountNotif:FreeRooms
but it MUST provide the capability OTA_HotelInvCountNotif_accept_complete_set
if it does.
C.2. Major overhaul in version 2020-10¶
Currency¶
The version 2020-10 adds support for all currency codes from the ISO 4217 in all actions where amounts are used.
Copyright and License information on multimedia objects¶
Guidelines to exchange copyright and license information on multimedia objects like images have been added to the chapter data exchange.
GuestRequests¶
The version 2020-10 introduces some new options:
-
special requests regarding pets (SpecialRequests)
-
RoomType attribute now is mandatory only for reservations
FreeRooms¶
In version 2020-10 the FreeRooms message has been changed from OTA_HotelAvailNotif
to OTA_HotelInvCountNotif
. The chapter has been completely re-written and OTA_HotelAvailNotif
is to be considered deprecated. Even all relative capabilities and action names have been changed.
OTA_HotelAvailNotif (old) | OTA_HotelInvCountNotif (new) |
---|---|
action_OTA_HotelAvailNotif |
action_OTA_HotelInvCountNotif |
OTA_HotelAvailNotif_accept_rooms |
OTA_HotelInvCountNotif_accept_rooms |
OTA_HotelAvailNotif_accept_categories |
OTA_HotelInvCountNotif_accept_categories |
OTA_HotelAvailNotif_accept_deltas |
OTA_HotelInvCountNotif_accept_deltas |
OTA_HotelAvailNotif_accept_BookingThreshold |
OTA_HotelInvCountNotif_accept_out_of_market |
- |
OTA_HotelInvCountNotif_accept_out_of_order |
- |
OTA_HotelInvCountNotif_accept_closing_seasons |
The new message offers the same options as the one used previously, but introduces the following new options:
-
sending of closing seasons
-
rooms out-of-order
OTA_HotelInvCountNotif_accept_out_of_order
RatePlans¶
A new mandatory attribute CurrencyCode of the RatePlan element has been introduced to support all ISO 4217 currency codes.
Inventory/HotelInfo¶
The specification of Inventory/Hotelinfo has been expanded and provides an explicit structure for the exchange of hotel information. The version 2020-10 now defines the acceptable structure of HotelDescriptiveContent and its sub-elements. This action is no longer considered experimental.
Activities¶
This new action has been introduced with 2020-10. It is used to exchange information about hotel internal activities.
C.3. Major overhaul in version 2018-10¶
Housekeeping / Handshaking¶
The Housekeeping
action has been renamed to Handshaking
and the relative chapter has been completely rewritten introducing breaking changes. Through the introduction of the OTA_Ping:Handshaking
action it is now possible for clients to expose the capabilities they support.
New action GuestRequests (Push)¶
This functionality was introduced in version 2018-10.
It is now possible to push GuestRequests
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.
New attribute RoomType¶
This functionality was introduced in version 2018-10.
For Inventory
and GuestRequests
, in addition to the RoomClassificationCode attribute, the optional attribute RoomType has been added in order to allow a more precise classification of the guest accommodation.
Reference to the online presence of the lodging structure¶
This functionality was introduced in version 2018-10.
For Inventory
, the element ContactInfos can be used to transmit URIs where the lodging structure has a presence (like social networks, review aggregators, etc.).
Review price calculation¶
These changes were made to the price calculation algorithm:
-
The AdditionalGuestAmount element with attribute AgeQualifyingCode equal to 10 becomes optional.
-
The AdditionalGuestAmounts element can be transmitted also if the MaxOccupancy attribute is equal to the StandardOccupancy.
Interaction with channel managers¶
-
For
BaseRates
, a new case is described that allows servers to exchange information with clients that are only able to send RatePlans overlay information. -
For
GuestRequests
of typeReservation
, a recommendation to set the value of the mandatory RatePlanCode attribute to the string "Unknown" has been added to ease the integration with channel managers that do not provide a reference to the AlpineBits®RatePlan
which theGuestRequest
actually refers to.
Server request for complete data set¶
In case of a suspected misalignment of data, servers can now request the client to send a full data set.
RatePlans¶
Version 2018-10 introduced optional [xml_element_name]AdditionalGuestAmount# elements. Since they were mandatory in version 2017-10, a communication between both versions is only possible if the request from 2018-10 is gapless.
C.4. Major overhaul in version 2017-10¶
AlpineBits® server response outcomes¶
The AlpineBits® response outcomes (success, advisory, warning, error) are now uniformly and more thoroughly defined in the new appendix A.
In particular the distinction between warning and error outcomes is more in line with the OTA documentation 3 (see the section "OpenTravel Message Success, Warnings & Errors Elements").
Implementations of 2015-07b will likely signal as errors, things that in 2017-10 would be considered warnings. This should not lead to breakage, however, since both (warnings and errors) unambiguously indicate failed requests and this has been spelled out with greater clarity in the 2017-10 document.
In any case implementors are invited to have a close look at the new appendix A.
FreeRooms¶
Two new features have been added to FreeRooms: transmission of the number of bookable rooms and purge requests.
GuestRequests¶
Two new features have been added to GuestRequests: commissions and encrypted credit card numbers. The credit card holder name was made optional. Some info on how to fill out the ReservationID was added to the best practice section.
SimplePackages¶
The feature has been removed in version 2017-10.
Inventory¶
Inventory messages were introduced in version 2014-04 and overhauled in version 2015-07.
In version 2017-10 the section was again changed significantly. The former Inventory request action has been heavily refactored and split into four different actions:
-
Inventory/Basic: (push) action
OTA_HotelDescriptiveContentNotif:Inventory
(same string was also used in previous version) is now only used to send room category information and room lists (unlike previous versions, where it had multiple uses). -
Inventory/Basic (pull): action
OTA_HotelDescriptiveInfo:Inventory
(new) is used to request basic information. -
Inventory/HotelInfo (push): action
OTA_HotelDescriptiveContentNotif:Info
(new) is used to send additional descriptive content. -
Inventory/HotelInfo (pull): action
OTA_HotelDescriptiveInfo:Info
(new) is used to request additional descriptive content.
Of course the corresponding action capabilities have been defined.
Due to the split, these capabilities are no longer necessary and were removed:
-
OTA_HotelDescriptiveContentNotif_Inventory_accept_basic
-
OTA_HotelDescriptiveContentNotif_Inventory_accept_additional
RatePlans¶
Concerning booking rules, previously the attribute MinMaxMessageType of LengthOfStay could assume the two values SetMinLOS
and SetMaxLOS
and there were two corresponding capabilities (OTA_HotelRatePlanNotif_accept_MinLOS
and OTA_HotelRatePlanNotif_accept_MaxLOS
). With 2017-10 the list of values have been expanded to four by adding SetForwardMinStay
and SetForwardMaxStay
. As all four values must be supported the two capabilities have been removed.
It is now possible to define supplements that are only available on given days of the week and supplements that depend on room category.
Offers have been improved and extended: besides the discounts, the Offer element is now also used to transmit the age above which a guest is considered an adult and a number of restrictions (for which 2 new capabilities (starting with OTA_HotelRatePlanNotif_accept_OfferRule
) have been introduced). Free night discounts have also been slightly updated.
Changes have been made to the algorithm describing the computation of the cost of a stay (see section 4.5.2): there is now a new step 1b, step 3 has been changed (a rate plan is now applicable even if it has a family offer that doesn’t match the stat) and step 4b has been simplified (as we have complete and gapless age brackets for all possible child ages now).
Descriptions have been extended and documented more thoroughly.
BaseRates¶
This action has been introduced with 2017-10.
C.5. Minor updates in version 2015-07b¶
Version 2015-07b is a maintenance release. The section 4.5 about rate plans has been mostly rewritten with more precise and strict information about how to handle corner cases, especially regarding rebates.
While most of this does not lead to breaking changes per se, it is likely that 2015-07 servers that were implemented before the release of 2015-07b would compute costs for stays differently, for lack of a sufficiently strict description of details.
One deliberate breaking change of note is that 2015-07b requests the value of the AmountAfterTax attribute in BaseByGuestAmt elements to be > 0, while 2015-07 used to allow a value ≥ 0.
C.6. Major overhaul in version 2015-07¶
Inventory¶
In version 2015-07 the Inventory message was changed from OTA_HotelInvNotif
to OTA_HotelDescriptiveContentNotif
. The new message offers the same options as the one used previously beside sending the name of the specific rooms, but allows for much richer descriptions, including pictures. A high-level mapping between the old Inventory and the new one is as follows:
OTA_HotelInvNotif |
OTA_HotelDescriptiveContentNotif |
---|---|
SellableProduct |
GuestRoom |
SellableProduct InvTypeCode |
GuestRoom Code |
SellableProduct InvCode |
TypeRoom RoomID |
Quantities MaximumAdditionalGuests |
Not needed anymore, see StandardOccupancy |
Occupancy MinOccupancy |
GuestRoom MinOccupancy |
Occupancy MaxOccupancy |
GuestRoom MaxOccupancy |
Occupancy AgeQualifyingCode="8" |
GuestRoom MaxChildOccupancy |
Not previously possible |
TypeRoom StandardOccupancy |
Room RoomClassificationCode |
TypeRoom RoomClassificationCode |
Amenity AmenityCode |
Amenity RoomAmenityCode |
Text |
TextItem > Description |
Not previously possible |
ImageItem > URL |
Text (for specific Room) |
Not possible anymore |
C.7. Major overhaul in version 2014-04¶
Version 2014-04 was a major overhaul. In most cases, a pre-2014-04 client will not be compatible with a 2014-04 server and viceversa. Here is a list of major changes in 2014-04.
HTTPS layer¶
The possibility of compression with gzip has been added.
FreeRooms¶
The possibility to send booking restrictions in FreeRooms has been removed as have the corresponding capabilities. These are better handled by the new RatePlans.
The value of the action parameter has been changed from FreeRooms
to OTA_HotelAvailNotif:FreeRooms
for uniformity with the other action values that all follow the rootElement:actionValue
format.
The possible responses (OTA_HotelAvailNotifRS document) have been re-categorized into four classes: success, advisory (new), warning and error. For error responses the attributes have changed, fixing a bad OTA interpretation.
Finally, the way deltas and complete transmissions are distinguished has changed. All in all FreeRooms are not compatible with any previous version.
GuestRequests¶
GuestRequests have been heavily refactored. Previous AlpineBits® versions had two type of requests: quotes and booking requests, the current version has three: booking reservations, quote requests and booking cancellations. Also, the client can (and must) now send acknowledgements.
SimplePackages¶
The possible responses (OTA_HotelRatePlanNotifRS document) have been re-categorized into four classes: success, advisory (new), warning and error. For error responses the attributes have changed, fixing a bad OTA interpretation.
Inventory and RatePlans¶
These are new message types introduced with version 2014-04.
C.8. Compatibility between a 2012-05b client and a 2013-04 server¶
Housekeeping¶
The client will not send the X-AlpineBits-ClientID field in the HTTP header, since it is not aware of this feature. This will cause authentication problems with those 2013-04 servers that require an ID.
The client will not send the X-AlpineBits-ClientProtocolVersion field in the HTTP header, since it is not aware of this feature. This is no problem: a server that is interested in this, will simply recognize the client as preceding protocol version 2013-04.
If the client checks the server version it will see 2013-04 - a version it doesn’t recognize. Likewise, if the client checks the capabilities it might see the OTA_HotelAvailNotif_accept_deltas
capability. Client implementers interested to have their 2012-05b client talk to a 2013-04 server should verify this is not a problem for their client software.
FreeRooms¶
There is no compatibility problem in the request part: the client will not send partial information (deltas), since it is simply not aware of the existence of the feature. Please be aware that the lack of this feature (obviously) causes more data to be sent to the server, something not all companies that run servers will be happy with. The server response might contain a Warning element the client cannot process. If the client - as it should - carefully parses the response, it will treat this as an error situation and act accordingly. So basically the client is expected to treat the warnings as error, which might be an issue and this should be tested.
GuestRequests¶
No compatibility problems are expected.
SimplePackages¶
2013-04 introduced the limitation that all packages sent within a single request must refer to the same hotel. An older client not aware of this limit might incur an error returned from the server error.
Similar to the FreeRooms case, the server response might contain a Warning element the client cannot process. If the client - as it should - carefully parses the response, it will treat this as an error situation and act accordingly. So basically the client is expected to treat the warnings as an error, which might be an issue and should be tested for.
C.9. Compatibility between a 2013-04 client and a 2012-05b server¶
Housekeeping¶
The client sends the X-AlpineBits-ClientProtocolVersion field and may send the X-AlpineBits-ClientID field in the HTTP header, but the server will just ignore it - being unaware of the feature. If the client checks the server version and/or checks the capabilities - as it should - it will note the missing features and not use them. Hence, technically there is no problem with this combination.
FreeRooms¶
The client will not send partial information (deltas), since the server does not export the OTA_HotelAvailNotif_accept_deltas
capability.
The server will never send a response with a Warning element. This is not a problem for the client.
GuestRequests¶
In 2013-04 the form of the ID attribute is not any more restricted. It has become a free text field. An older server might insist on the old form and throw an error.
SimplePackages¶
The server will never send a response with a Warning element. This is not a problem for the client.
D. External links¶
[0] Creative Commons BY SA license:
https://creativecommons.org/licenses/by-sa/3.0/
[1] HTTP basic access authentication:
https://en.wikipedia.org/wiki/Basic_access_authentication
[2] OpenTravel Alliance:
https://opentravel.org/
[3] OTA2015A documentation:
http://opentravelmodel.net/pubs/specifications/OnlinePublicationDetails.html?spec=2015A&specType=1_0&group=19701
[4] OTA2015A XML schema files:
http://opentravelmodel.net/pubs/specifications/OnlinePublicationDetails.html?spec=2015A&specType=OTA_1_0
[5] OTA2015A code list:
http://opentravelmodel.net/pubs/specifications/OnlinePublicationDetails.html?spec=2015A&specType=1_0&group=19708
[6] browsable interface to the OTA XML schema files (choose model "OTA2015A"):
https://www.pilotfishtechnology.com/modelviewers/OTA/