With the channel integration you can subscribe for availability, rates and inventory (ARI), create new bookings and modify existing bookings. We built this to make channel manager integrations easy, but it turned out to be neat for reporting applications, too.
Before you start, we recommend to check out the end user guide for rate plans.
Distribution API
Get your test account and check out this guide to learn how you can connect to the apaleo APIs.
The Distribution API is especially designed for integrating channel managers as easy as possible. You can find the swagger documentation on https://distribution.apaleo.com.
API Client
All apaleo APIs are described as Swagger documents. That lets you generate API clients directly from the swagger.json files. There is a large community, providing client generators for almost every language. For example, swagger code generator is a good project, which allows generation of API clients for Java, PHP, C#, NodeJS and more. This gets you up to speed very fast and as a bonus you can access API documentation within the auto-generated methods and models.
Setup and configuration
Once a hotel successfully connected apaleo the rate plans from apaleo need to be mapped to the ones you're managing and maintaining. We do not store an external rate plan ID, so all the mapping is on your side. One way to simplify this mapping, and have happy users as a result, is to load all rate plans from apaleo, and then make those available when (1) creating, or (2) mapping to existing rate plans. That way nobody has to copy-paste any IDs between systems.
If you are wondering how to store mapping data: a table with your unique rate-plan identifier, and apaleo's unique ID (which consists of account, property and rate-plan) is pretty much all you need. On that note: we do have exactly one rate plan per room type (which we call 'unit group'), while you might have more. In this case, the mapping will be <your rate plan + your room type> to <apaleo rate plan>.
Once this is done, you can subscribe to availability, rates and inventory (ARI) updates for those rate plans.
POST /v1/subscriptions/
Check the documentation in Swagger for the full model, and an example of what to pass. The key field is the endpoint URL. This is the URL we call based on the configured time intervals, to deliver the ARI data. Make sure you protect this endpoint well, as an unprotected endpoint would allow everyone to set prices or availabilities for the hotels. Sounds like trouble. We recommend https, and some sort of token.
As a result, you'll get an ID back. Be sure to store this, as you'll need it later on for updating or deleting the subscription. The main reason to update is after a new rate plan is added, and needs to be synchronised.
PUT /v1/subscriptions/
Subscriptions are tied to an API client, so that other applications used by the same apaleo account cannot accidentally interfere with your subscriptions. Again, trouble.
Getting ARI data
Full Push
After you created and enabled the subscription, apaleo will push a full update of all the ARI data to the configured endpoint URL. Same is happening again each fullSyncPeriod. As this is quite some data, it is delivered in chunks of 90 time slices per request (a time slice is in most cases the same as a night except for some super special cases). This is how an example entry looks like:
{
"accountId": "XYZX",
"propertyId": "MUC",
"timeSlices": [ {
"from": "2018-11-17T09:00:00Z",
"to": "2018-11-18T08:00:00Z",
"ratePlanId": "MUC-NONREF_DBL",
"unitGroupId": "MUC-DBL",
"available": 23,
"prices": [{
"adults": 1,
"price": {
"grossAmount": 123,
"currency": "EUR"
}
},
{
"adults": 2,
"price": {
"grossAmount": 170,
"currency": "EUR"
}
}],
"restrictions": {
"minAdvanceBookingPeriod": "P1M",
"maxAdvanceBookingPeriod": "P1M14DT12H",
"closed": true,
"closedOnArrival": false,
"closedOnDeparture": false,
"minLengthOfStay": 2,
"maxLengthOfStay": 8
}
}]
}
Fields | Optional | Description |
---|---|---|
accountId and propertyId | no | The account ID identifies an apaleo customer. The propertyId is only unique within one apaleo account. The combination of accountId and propertyId is globally unique. |
timeSlices | no | List of time periods for one rate plan and unit group combination with availability, prices and restrictions. You will at least receive one time slice always. |
from and to | no | For standard overnight hotel business this defines the time range for the night. In the example above, it would be the night from November 17th to November 18th. Most channels consider this the night of November 17th. |
ratePlanId | no | The ID of the rate plan in apaleo, which is unique per account. |
unitGroupId | no | The ID of the unit group in apaleo, which is unique per account. The equivalent for the apaleo unit group in channels can be room type, room category or inventory type. |
available | no | Number of units available for the unit group during this night. apaleo has shared inventory, so all rate plans selling this unit group on that night will have the same number. |
prices | yes | List of gross prices including VAT and all service fees for breakfast etc. You will receive one price for each allowed occupancy. apaleo currently does not push special prices for children. If no rate is set for this night in apaleo you will not receive prices. |
restrictions | no | Restrictions set for this night. The 'length of stay' restrictions are arrival-based and they are optional. The closed restrictions will always be send. If no rate is set for this night in apaleo the 'master closed' restriction will be set. |
Delta Push
apaleo also keeps track of the data already sent to you for a subscription and calculates the diff. After each deltaSyncPeriod, apaleo sends the data which changed since the last successful update.
To know if an update was successful, we rely on you: Acknowledge successful receptions with a 2xx status code. If you don't, things will get messy, as your truth and our truth will diverge. There's always the full sync to recover from chaos, but better try avoiding it. You can also request a full push, whenever you need it.
PUT /v1/subscriptions/{id}/trigger-full-sync
The delta is calculated for the following fields and the data will also be delivered in chunks of 90 time slices per request:
Field | Description |
---|---|
available | Only if the number of available units for this night changed it will be send. |
prices | If one out of the prices changed you will again receive the whole list of prices. |
restrictions | If one of the restrictions changed you will receive the whole set of current restrictions. If a rate in apaleo was removed and a certain night was made unsellable, you will not receive prices, but the master closed restriction. |
Send Bookings
To create a new booking in apaleo all you need to do is send the the details you have to the Distribution API.
POST /v1/bookings
Each booking will be accepted and confirmed by apaleo. If we cannot process the booking, we will show the failed booking to the hotelier on the user interface and allow the hotelier to resolve the problems. You do not need to worry about errors on our side as long as you ensure the format and URL of your request is correct.
Booking vs. Reservation
In apaleo, the booking is a container for one or more reservations. One reservation is for one room, making a booking basically a 'multi room reservation'. Other systems call those differently: booking.com for example sends multiple rooms as 'room stay elements' in one reservation. You could combine all of them in one booking to apaleo.
Credit Cards
apaleo is certified to be compliant with the PCI-DSS standard and we assume you are as well. To achieve compliance, we are using the PCI proxy from DataTrans AG in Switzerland. You will not be able to send plain cardholder data directly to https://distribution.apaleo.com, and if you try, we will reject it. Instead please use https://secure-distribution.apaleo.com as a base-url whenever you send credit card data through to apaleo. For creating a booking with credit card data, you would have to call
POST https://secure-distribution.apaleo.com/v1/bookings
Credit cards will be handled by apaleo. Some OTAs collect the money for the hotels or allow other payment methods and then issue a virtual credit card for the hotel to capture the money from. Please mark virtual credit cards accordingly by setting the isVirtual property of the credit card to true.
Channel and Sources
apaleo currently supports two channels: BookingCom and ChannelManager. 'BookingCom' should only be used if your application is directly connecting booking.com to apaleo. Most likely, you are connecting multiple travel agents or a Central Reservation System (CRS), and should use ChannelManager. When setting ChannelManager as the channel, you have to specify more details in the source. The list of allowed sources you can define right now can be retrieved using the apaleo Booking API,
https://api.apaleo.com/booking/v1/types/sources
External ID, your ID, apaleo ID
Distribution channels do have their own booking codes they use to confirm the booking with the guest. Guests use these codes or IDs when they arrive at the hotel, want to check in online or call the hotel. Therefore, this information also needs to be forwarded to apaleo, using the externalId field of a reservation. It is important to make the externalId unique per apaleo account. Would be a bad identifier, if it would not be unique. A simple way to achieve this is appending an incremental number.
You probably also store those reservations, and provide the channels out there and your users to modify and see them. Lastly, apaleo has an ID too, which is generated when a reservation is created in our system. When you create a booking, we return the booking ID, and an ID for every single reservation in it. Your IDs and ours need to mapped, similar to how it is for rate plans. That way you know how to forward modification or cancellation requests to apaleo.
Modify Bookings
The request model for modifications is very similar to the one for creating bookings. You need the apaleo ID, and then just call
PUT /bookings/{id}
PUT /reservations/{id}/cancel
To make the API easier to use, we decided to deviate from how PUT should work in two areas:
Undeletable first level objects
On the first level of the request model for the booking modification we have:
- Credit Card
- Booker
- Comment
- Booker Comment
- List of Reservations
If you omit one of those objects, or send an empty object, we will not remove it or cancel it, but pretend you sent the exact data we already have stored. This allows you to add a reservation to an existing booking by just sending the new reservation without always having to repeat the data for the booker, the credit card or all the other rooms.
Reservations are identified by the apaleo reservation ID. Reservations without this ID are considered to be new and will be added to the booking. Reservations with an ID will be updated based on the provided information. The API behaves like a “create or update” request.
Merging of guest and booker data
OTAs often do not provide a rich set of data, and a lot of guest-related data is collected by the hotel and put to the guest profile in the property management system (like, apaleo). To not accidentally lose this information we only allow you to override the following fields:
- Guest Data
- Booker Data
- Travel Purpose
If you omit these fields or do send some of their properties empty or not at all, we will not remove it, we will just leave it untouched.
We know the integration of a channel manager is not exactly the most trivial thing to do - and if things go wrong, people easily get upset. Overselling, or having the wrong prices are unpleasant. We're here for you to make sure things work smoothly. Head over to https://github.com/apaleo/api if you have any questions.

Posted by
Andrea Stubbe