Introduction
Hi! welcome to the Booking Experts App Guide. This explains the basic concepts of a Booking Experts App. If you're looking for the API reference, please see our App Api.
We hope you can find your way around. If not, please reach out to api@bookingexperts.nl. We are happy to help and discuss on new ideas.
The best way to build an integration is by using Booking Experts Apps. You could also use the deprecated Tour operator Api but we strongly advise to build Booking Expert Apps from this point onward.
Booking Experts Apps
We call it Booking Experts Apps because it's a little more than a standard integration. You can create an App for your own use or make it publicly available for other Booking Experts users.
It was born out of the many requests for new integrations we got on a weekly basis. We don't want to limit our users so we thought of a set of API's, tooling etc. to facilitate other parties.
With Booking Experts Apps you can think of Booking Experts as a platform. Booking Experts (without Apps) solves 80% of the common use cases in property rental out of the box. We provide and invest in a good and stable foundation while others can extend Booking Experts to fit their needs.
There are many use cases for which Booking Experts Apps is good fit. Examples:
- Access control
- Thermostats
- Channel management
- Tour operators
- Websites
- Payment providers
- etc.
Some use cases are quite specific. See Guides for examples.
App characteristics
An App is a little more than a one-way integration.
- Let Booking Experts call your system by using Webhooks.
- Extend the Booking Experts UI by adding Commands which can be invoked by normal Booking Experts users.
- Send e-mail and SMS messages to guests through Booking Experts by using Message Templates.
Begin with a basic App
Select all the permissions you need and install your App on a single administration. Grab the API key to start making API calls. Sign up for a Demo if you don't have access to a Booking Experts administration.
See API key
Level up with an OAuth2 flow
Drop the API key and implement the OAuth2 flow and submit your App for validation. Now other Booking Experts users can install your App on their administration.
See OAuth2 flow
Demo
Currently Booking Experts Apps is still on invite only basis. To get access to Booking Experts Apps, please use the form below.
We will give you access to a Demo administration so you can start developing.
After you have access to your demo you can create Apps through the App Store. Follow the icon in your demo administration:
App Setup
Webhooks
Webhooks can be configured in the admin UI for managing Booking Experts Apps.
You can subscribe to various events that happen in Booking Experts.
Think of events like reservation:checked_in
, reservation:checked_out
, reservation:created
, category:updated
etc.
See the admin UI for a complete list.
Requirements
In order to receive webhook events for a resource, the following conditions apply:
- You must have read permissions for the given resource. Ensure you have properly set the permissions in your App configuration;
- In case the resource belongs to a specific administration, the status of the administration must be 'Test' or 'Production'.
Target URL
When an event is triggered in Booking Experts, the target URL you specified will be called. When you have configured the webhook to wait for confirmation, the target URL will be called until a 200 Success response is returned by your server.
Payload
The webhook payload contains the following attributes:
event
- The name of the eventsubscription_id
- The subscription_id to which this even appliesrecord
- The subject to which the event applies. For example, whenreservation:checked_in
is triggered, you will receive aReservation
resource as documented by the Reservation schema.context
- An event occurs always occurs within a certain context. Possible values are 'administration', 'organization' or 'global'.context_id
- When an event occurs within an Administration or Organization, the context_id will contain the Administration ID or Organization ID, respectively.event_metadata
- Optional. Contains extra metadata like a list of attribute changes. See the next section for more info.
Event metadata
Event metadata may be passed for certain events:
updated
eventschanges
- Every key in the
changes
object is an attribute name and its value is an array[old_value, new_value]
. - For example, when you receive the
channel|updated
event, you might receive the following changes:"changes": { "name": ["HomeAway", "Vrbo"] }
.
category|prices_updated
orcategory|availability_updated
date_ranges
- An array of
[start_date, end_date)
arrays (exclusive end_date). It yields to which date ranges the price or availability update applies. When not specified, it applies to every current or future date. original_event
- Mostly for debugging purposes. It hints on the origin of the change.
category|prices_updated
pricing_types
- An array listing to which pricing types the change applies. Possible values are
los_prices
andnight_prices
.
Commands
Let users trigger an interaction with your App by pressing a button in the Booking Experts UI.
Example use case: - Add a button called "Open door" to every Reservation detail page that can be triggered by receptionists.
Command responses
A submitted Command will cause a payload of data to be sent from Booking Experts to your App. The App can respond in different ways using the context provided by that payload.
I-frame URL
{ "iframe_url": "http://your-app.com/action-to-perform" }
The url is loaded in an iFrame inside Booking Experts. This gives the user the feeling that it all happens inside one system. Use our the Booking Experts Design System to create UIs by using UI components that are familiar to Booking Experts users.
Note: As a security measure, most browsers will require iframe sources to be on the same domain as the parent domain. If you are planning to use iFrames, please let us know so we can support your domain (for example by adding appropriate CORS headers).
Redirect URL
{ "redirect_url": "http://your-app.com/action-to-perform" }
The user is redirected to this URL. It's the responsibility of the App to provide a way back to Booking Experts.
Notice message
{ "notice": "Great success!" }
The message is shown to the user in a flash message inside Booking Experts.
Alert message
{ "alert": "Something went wrong!" }
The alert is shown to the user in a flash message inside Booking Experts.
Context model
Choose a context model to make commands available for a specific model.
For example, when you choose reservation
, the command will be available for reservations.
Mostly on the #show page (in CRUD terms) but not exclusively.
Activation options
Often, you'd like your command to be available when the context model meets certain conditions. You can choose which conditions should apply here. Please let us know when you're missing any options!
Message templates
Define standard templates for communication with a guest.
Booking Experts takes care of delivering the message to the guest. Messages can be delivered by e-mail or SMS. Configured templates can be modified by administrators of an administration to suit their way of communication.
Booking Experts variables
{{ reservation.greeting }},
Welcome to {{ park.name }}!
The access code for accommodation {{ accommodation.name }} is: {{ access_code }}.
See you!
Within a template, you can use variables that are provided by Booking Experts, which are interpolated when the message is sent. Please see the Templates section of our support documentation for details.
Custom variables
Aside from Booking Experts variables, you can supply your own variables. Upon sending a message the App must provide the values for these custom variables.
In the example on the right {{ access_code }}
would be a custom veriable passed by the App.
Sending a message using a message template
See POST messages
Validation
Done with making your test integration? Let's book a validation. After validation, your App will be available in the Booking Experts App Store. Users can install your App at the touch of a button. A great way to reach new customers 😉.
A validation can be requested from the App admin page. The only requirement is an implemented OAuth2 flow.
Authentication
API key
Ideal for making one off Apps for your own use.
- Configure your App through My Apps and make sure to set "API key" as the Authentication method.
- Install your App within your own organization and you will be prompted with an "API key".
OAuth2 flow
1) User clicks "Install" in App Store 2) User is redirected to callback url hosted by the App. The Authorization Response is send to the App Server. For example:
HTTP/1.1 302 Found
Location: https://your-domain.com/booking_experts/oauth_callback?code=P66tmn20oiwyJRoHsN1iyNOzy37vKpRg8pEapG7s_ps
3) The App can then use the
code
url parameter to fetch the OAuth tokens. The App sends the Authorization Code Request For example:
POST /oauth/token HTTP/1.1
Host: app.bookingexperts.nl
code=P66tmn20oiwyJRoHsN1iyNOzy37vKpRg8pEapG7s_ps
&grant_type=authorization_code
&redirect_uri=https://your-domain.com/booking_experts/oauth_callback
&client_id=[CLIENT_ID]
&client_secret=[CLIENT_SECRET]
4) Booking Experts server returns the Access Token Response for example:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
"token_type":"Bearer",
"expires_in":604800,
"refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
"scope":"create"
}
5) Now you can make API requests to the Booking Experts API for example:
curl --request GET \
--url https://api.bookingexperts.nl/v3/administrations \
--header 'accept: application/vnd.api+json' \
--header 'accept-language: en,nl' \
--header 'authorization: Bearer [ACCESS_TOKEN]'
6) After a while the access token will expire. In that case you will receive a response from the Booking Experts something like:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token" error_description="The access token expired"
Content-type: application/json
{
"error": "invalid_token",
"error_description": "The access token expired"
}
7) In that case you should request a new acces_token using the refresh_token. The App should send a Refresh token request.
POST /oauth/token HTTP/1.1
Host: app.bookingexperts.nl
grant_type=refresh_token
&refresh_token=[REFRESH_TOKEN]
&client_id=[CLIENT_ID]
&client_secret=[CLIENT_SECRET]
8) The Booking Experts server returns a Token response which should be used for new API requests untill the token expires (see step 6.)
{
"access_token": "BWjcyMzY3ZDhiNmJkNTY",
"refresh_token": "Srq2NjM5NzA2OWJjuE7c",
"token_type": "Bearer",
"expires": 3600
}
You can authenticate organizations by using OAuth2. For on the fly needs you can make use of an API key but this has limited access to only the organization and its administrations to which it is registered.
If you want others to make use of your app you will need to support OAuth2. The flow for authenticating organizations via OAuth2 is described in the following diagram:
- First, store your OAuth2 client UID and secret. These have been supplied after your app was created and can be found on the admin page of the app
- When a user installs an app on behalf of the organization, a dialog will be shown listing all permissions that the app will need. When accepted, your specified redirect URI will be called with a code in the query string and nothing else. This follows the standard OAuth2 protocol. You need to use this code to fetch a token and refresh token via the
https://api.bookingexperts.nl/oauth/token
endpoint by passing the supplied code. Most oauth2 clients will use this path by default. - Per organization that successfully installs the app, you will receive a unique code which you need to turn into a token.
- After fetching a token, you can now access the API. Usually, the first thing to do is to fetch and persist the details of the subscription for the token you just received via the endpoint
https://api.bookingexperts.nl/v3/subscription
. This will yield the current subscription ID, the adminstration IDs to which you've been granted access and a return URL back to the BookingExperts app page. - You can now render a success response to the user. This could include a message explaining that the app has successfully been installed and an introductory message of how the user should proceed. It can also include a button back to the app page in BookingExperts as returned by the subscription details.
App API key
The App API key can only be used for the 'App' namespace of the API. This namespace contains endpoints that are not dependent on a specific organization or administration. For example, the App namespace provides the 'App Availabilities' endpoint, which can be used to perform an Availabilty Search over multiple subscriptions at once.
Guides
BookingExperts API client
There is a BookingExperts client example available, written in Ruby. This client supports the following use cases:
- OAuth2 workflow
- OAuth2 token management
- Incoming request verification using the HTTP_X_BE_SIGNATURE header
- Requesting resources and resource collections
Bookings & Reservations
Currently, Booking Experts only supports creating reservations for a single accommodation. Support for ordering multiple accommodations is under active development. This will be accomplished by supporting Bookings. Bookings will be able to contain multiple Reservations, as illustrated in the diagram below.
The current API leverages this redesigned structure by already supporting creation of bookings with a single reservation via POST reservation. When creation of bookings with multiple reservations is added, this will become possible via the endpoint POST booking.
Sideposting
As can be seen in the diagram, a Reservation belongs to an Booking and and Booking belongs to a Customer. As the JSON:API specification does not yet support
submission of multiple resources at once, we have introduced the concept of Sideposting. Sideposting will allow you to post new related resources using
the standard included array. These resources don't have an ID yet, therefore it is required to link these resources by setting /meta/temp_id
. You will also
need to define what the system needs to do with these resources by specifying /meta/method
(= create or update) on the relationship.
Creating a reservation
Endpoint: POST reservation
{
"data": {
"type": "reservation",
"attributes": {
"start_date": "2014-01-08",
"end_date": "2014-01-15",
"guest_group": {
"seniors": 0,
"adults": 2,
"adolescents": 0,
"children": 0,
"babies": 0,
"pets": 0
}
},
"relationships": {
"rentable_type": {
"data": {
"id": "123",
"type": "rentable_type"
}
}
}
}
}
For a reservation to be accepted, you need to (at least) specify the following attributes:
start_date
end_date
rentable_type
guest_group
A valid example can be seen on the right.
Creating an option
Endpoint: POST reservation
{
"data": {
"type": "reservation",
"attributes": {
"start_date": "2014-01-08",
"end_date": "2014-01-15",
"option_validity": 5,
"guest_group": {
"seniors": 0,
"adults": 2,
"adolescents": 0,
"children": 0,
"babies": 0,
"pets": 0
}
},
"relationships": {
"rentable_type": {
"data": {
"id": "123",
"type": "rentable_type"
}
}
}
}
}
In Booking Experts, an option is just a kind of reservation. To create an option, you
can use the same endpoint and pass the option_validity
attribute, which defines the option validity in days.
Creating a reservation with customer and booking details
Endpoint: POST reservation
{
"data": {
"type": "reservation",
"attributes": {
"start_date": "2014-01-08",
"end_date": "2014-01-15",
"late_checkout": false,
"locale": "en",
"note": "Please note",
"currency": "EUR",
"price_according_to_channel": { "currency": "EUR", "value": "85.75" },
"guest_group": {
"seniors": 0,
"adults": 1,
"adolescents": 0,
"children": 1,
"babies": 0,
"pets": 0
},
"license_plates": ["19XNZ1"]
},
"relationships": {
"rentable_type": {
"data": {
"id": "123",
"type": "rentable_type"
}
},
"booking": {
"data": {
"type": "booking",
"meta": {
"temp_id": "booking-id",
"method": "create"
}
}
},
"primary_package": {
"data": {
"id": "1",
"type": "primary_package"
}
},
"extra_packages" : {
"data": [{
"id": "101",
"type": "extra_package"
}]
},
"extra_order_items": {
"data": [{
"type": "extra_order_item",
"meta": {
"temp_id": "extra-id",
"method": "create"
}
}]
},
"cancellation_rules": {
"data": [{
"type": "cancellation_rule",
"meta": {
"temp_id": "cancellation-rule-1",
"method": "create"
}
},{
"type": "cancellation_rule",
"meta": {
"temp_id": "cancellation-rule-2",
"method": "create"
}
}]
}
}
},
"included": [{
"type": "booking",
"attributes": {
"remote_booking_nr": "12345",
"after_payment_return_url": "https://www.example.com/callback",
"redeemable_codes": ["DISCOUNT2021"]
},
"relationships": {
"customer": {
"data": {
"type": "customer",
"meta": {
"temp_id": "customer-id",
"method": "create"
}
}
}
},
"meta": {
"temp_id": "booking-id"
}
},{
"type": "customer",
"attributes": {
"title": "family",
"first_name": "RIV",
"last_name": "Rowe",
"email": "leonmcglynn@example.com",
"phone": "+31612345678",
"is_company": false,
"date_of_birth": "1955-05-05",
"receive_newsletter": false,
"address": "78229 Marquerite Flat",
"number": null,
"postalcode": "03756",
"city": "Amsterdam",
"country_code": "NL",
"has_custom_invoice_details": true,
"custom_invoice_details": {
"name": "Ali",
"email": "mycompany@example.com",
"address": "Het Eeftink 11-12",
"postalcode": "7541 WH",
"city": "Enschede",
"country_code": "NL"
}
},
"meta": {
"temp_id": "customer-id"
}
},{
"type": "extra_order_item",
"attributes": {
"quantity": 2,
"guest_answer": "Guest answer"
},
"relationships": {
"extra": {
"data": {
"id": "245",
"type": "extra"
}
}
},
"meta": {
"temp_id": "extra-id"
}
},{
"type": "cancellation_rule",
"attributes": {
"percentage": 33.3,
"days_before_arrival": 28,
"administration_costs": { "currency": "EUR", "value": "0.00" }
},
"meta": {
"temp_id": "cancellation-rule-1"
}
},{
"type": "cancellation_rule",
"attributes": {
"percentage": 100,
"days_before_arrival": 14,
"administration_costs": { "currency": "EUR", "value": "10.00" }
},
"meta": {
"temp_id": "cancellation-rule-2"
}
}]
}
Usually, you'll want to add some Customer details. Also, certain Booking attributes may be relevant as well, like redeemable codes
or an after payment return url
. In this
case, you will need to use Sideposting to include these details when creating a new reservation.
The example on the right is a more complex example that shows how this can be accomplished This example does not only specify booking and customer details, but also includes
some ordered extras (ExtraOrderItem) and a couple of custom cancellation rules (CancellationRule). Resource linking has been realized by properly setting temp_id
. As
these resources are new, the method passed in each relationship is create
.
Updating a reservation
Endpoint: PATCH reservation
{
"data": {
"id": "3245",
"type": "reservation",
"attributes": {
"start_date": "2014-01-08",
"end_date": "2014-01-15",
"currency": "EUR",
"guest_group": {
"seniors": 0,
"adults": 2,
"adolescents": 0,
"children": 0,
"babies": 0,
"pets": 0
}
},
"relationships": {
"rentable_type": {
"data": {
"id": "123",
"type": "rentable_type"
}
},
"booking": {
"data": {
"id": "3245",
"type": "booking",
"meta": {
"method": "update"
}
}
}
}
},
"included": [{
"id": "3245",
"type": "booking",
"attributes": {
"redeemable_codes": ["DISCOUNT2021", "FREEFORALL"]
}
}]
}
A reservation and its booking and customer details can be updated much in the same way as creating reservations. Of course, for existing resources you are now required to pass
their actual ID in stead of their temp_id
. If you like to update a related resource, you need to explicitly specify this by setting /meta/method
to update on the relationship.
As an example, consider the code on the right. It shows an example of how to update the redeemable codes
array of the booking of a reservation.
Payment of reservations
To initiate a payment of a Reservation, you should look at the Booking of the Reservation. When this Booking can be paid, it will have a pay_url
link to which the user should be redirected.
After payment, the user will be redirected back to the after_payment_return_url
that was set when the Booking was created. A query parameter status
will be passed that can have the following values:
success
, open_but_confirmed
, failure
, failure_final
or cancelled
.
success
: The amount to be paid has been paid. You can show a 'Thank you' page in this case. The guest has received a confirmation of the Reservation via email.open_but_confirmed
: The amount has not been paid yet, but the Reservation has been confirmed. This can happen when a bank transfer is initiated. It should be handled as asuccess
.failure
: The payment has been failed, but there is a possibility that the status may still change. In the booking process, this should be handled in the same way asfailure_final
.failure_final
: The payment has failed and this will not change anymore (end state). In this case you can ask the user to initiate a new payment by rendering a payment link to thepay_url
again.cancelled
: The payment has been cancelled, probably by the user. In this case you can ask the user to initiate a new payment by rendering a payment link to thepay_url
again.
Error codes
When mutating reservations fail, error messages usually contain a detailed error code in meta.error
, which you can use to generate a custom error message.
allotment_full
: Accommodation is already occupied or not rentable for the given period since it is needed for an allotment.blocked
: Accommodation is blockedcannot_be_in_the_past
: Start date cannot be in the pastcurrent_allotment_full
: Allotment is full for the current channelinvalid_guest_group
: The specified guest group is invalidmaximum_stay
: Reservation exceeds maximum stayminimum_stay
: Reservation does not meet minimum staymust_contain_at_least_one_adult_or_senior
: At least one senior or adult must be part of the guest groupno_accommodation_found_for_amenities
: No accommodation found for the passed amenitiesno_accommodation_found_for_pets
: No accommodation found in which pets are allowedno_arrival
: The given start date is not a valid arrival dateno_available_accommodation_found
: All accommodations are occupied in the given periodno_checkout
: The given start date is not a departure dateno_prices
: There are no prices in the given period for the chosen accommodationoccupied
: The accommodation is already occupied in the given periodpast_or_already_closed_reception
: The arrival date is in the past or the reception has already been closed for today
Cancelling a reservation
Endpoint: POST cancel
{
"data": {
"id": "3245",
"type": "reservation",
"attributes": {
"cancel_date": "2014-01-05",
"cancel_reason": "CORONA",
}
}
}
A reservation can be cancelled by sending an existing reservation resource. Optionally, you can pass the cancel_date
and cancel_reason
attributes to set a custom date and reason for cancelling.
Access control
Access control systems can build an App to provide access to guests or accommodation owners of an administration. Using webhooks, access can automatically be granted at the appropriate time for reservations. Furthermore, commands can be used for manual creation of access cards or exemptions.
Setup
Nearly every app will have some form of authentication. You can easily create a Settings page
for your app by defining it as a command using the context model subscription
:
{ "iframe_url": "http://your-app.com/settings" }
When called, you can then respond with a redirect to your Settings page. An example response can be seen on the right.
Automatically granting access for reservations
Typically, the following webhooks are needed for automatically granting access for reservations:
reservation|confirmed
- To grant access when a reservation is confirmed
reservation|checked_in
- To grant access when a reservation is checked in
-
reservation|moved
- Will be triggered when the stay period or accommodation of the reservation has been changed, so you can update its access.
-
reservation|checked_out
- To revoke access when the reservation is checked out
-
reservation|cancelled
- To revoke access when the reservation is cancelled
Manually granting access for reservations
Using commands, you can also add buttons to reservations to allow users of the system to manually manage access for a reservation.
Energy management
{
"command": "measurements",
"back_url": null,
"locale": "en",
"subscription_id": "1",
"record": {
"data": {
"id": "1",
"type": "rentable_identity",
"attributes": {
"name": "1"
}
}
},
"start_date": "2017-05-23",
"end_date": "2017-05-24"
}
{
"data": [
{
"type": "measurement",
"attributes": {
"timestamp": "2017-05-23T11:54+02:00",
"utility": "electricity",
"rate": null,
"value": 49.9
}
},
{
"type": "measurement",
"attributes": {
"timestamp": "2017-05-23T11:54+02:00",
"utility": "gas",
"rate": null,
"value": 40.584
}
},
{
"type": "measurement",
"attributes": {
"timestamp": "2017-05-24T11:54+02:00",
"utility": "electricity",
"rate": "low",
"value": 52.9
}
},
{
"type": "measurement",
"attributes": {
"timestamp": "2017-05-24T11:54+02:00",
"utility": "gas",
"rate": "high",
"value": 45.223
}
}
]
}
Energy management system Apps are usually implemented in the same way as Access Control Apps: there is some initial configuration, after which all booked accommodations are managed by listening to Reservation webhook events.
Supplying measurements
As it is possible in Booking Experts to store accommodation measurements, an Energy Management App is also able to send measurements back to Booking Experts. This can be realized by creating a special command that willl only be called by Booking Experts when an App is defined as an Energy system.
The command itself must conform to the following specifications:
- Its identifier must be
measurements
- Its context model must be
rentable_identity
- The response of the command must by a list of resources that conforms to the Measurement Schema.
- utility - must be 'gas', 'electricity' or 'water'
- rate - must be 'low', 'high' or blank when no distinction can be made.
An example request and response can be seen on the right. When your endpoint is called, you will receive the metadata of the RentableIdentity and the
desired start_date
and end_date
of the measurements that are requested by the user.
Payments
Payment service providers can build an App to handle payments. There are a couple of requirements. See below the headers below.
Settings
Apps will most likely have to be configured with api keys and other credentials.
In this case, we recommend adding a command with identifier settings
and context model payment_handler
to allow the user to configure these credentials for a specific payment_handler
.
The user can create multiple payment_handlers
within a single administration for a single payment service provider app, each with different configurations,
so we recommend you to store these credentials together with a payment handler id.
Initiate payment
Payload for the endpoint of the initiate_payment command
{
"data": {
"id": "541",
"type": "payment_request",
"attributes": {
"price": { "currency": "EUR", "value": "312.56" },
"locale": "nl",
"description": "Rent for reservation B123"
},
"relationships": {
"payment_handler": {
"data": {
"id": "24",
"type": "payment_handler"
}
},
"debtor": {
"data": {
"id": "11",
"type": "debtor"
}
},
"administration": {
"data": {
"id": "3",
"type": "administration"
}
}
}
}
}
Response to the initiate_payment command, that will redirect the customer to the given url.
{ "redirect_url": "https://mypaymentprovider.com/start_payment/2abe47d423f0" }
Endpoint: POST payment_results
{
"data": {
"type": "payment_result",
"attributes": {
"amount": {
"currency": "EUR",
"value": "312.56"
},
"result": "success",
"enable_recurring_payments": false
},
"relationships": {
"payment_request": {
"data": {
"id": "541",
"type": "payment_request"
}
}
}
}
}
Apps that act as a payment provider must provide an command with identifier initiate_payment
and context model payment_request
. This command will be invoked when a user makes an online payment.
The response of this command must be a redirect URL to a payment page when no issues occur, otherwise it should return a notice or an alert.
When you receive a status update on the payment from the psp, e.g. when the payment is successful or failed, you must invoke the payment result endpoint to update the payment state of the payment request. After having done this, the user must be redirected to the url passed as the back_url
parameter to the initiate_payment
command.
To the right, there is an example of a payment_request
, sent to the endpoint handling the initiate_payment
command, followed by the response to this command, and an example of the payment_result
that the app sent when a payment arrives. See POST payment_results for more information about payment_results
.
Recurring payments
Apps that support recurring payments must provide commands with identifiers initiate_initial_recurring_payment
, initiate_recurring_payment
and delete_mandates
, and respective context models of payment_request
, payment_request
and debtor
.
Initiate initial recurring payment
Endpoint: POST payment_results
{
"data": {
"type": "payment_result",
"attributes": {
"amount": {
"currency": "EUR",
"value": "312.56"
},
"result": "success",
"enable_recurring_payments": true
},
"relationships": {
"payment_request": {
"data": {
"id": "541",
"type": "payment_request"
}
}
}
}
}
This command will be invoked when an owner wants to give a mandate for automatic recurring payments.
The response of this command must be a redirect URL to a payment page when no issues occur, otherwise it should return a notice or an alert.
When the mandate is succesful you must communicate this using the payment_result endpoint and enable recurring payments by setting the enable_recurring_payments
parameter.
After having done this, the user must be redirected to the url passed as the return_url
parameter to the initiate_payment
command.
All in all it is very similar to the initiate_payment
command, except for having to set the enable_recurring_payments
property as shown in the example.
Initiate recurring payment
Response to the
initiate_recurring_payment
command if successful
{ "data": { "success": true } }
Response to the
initiate_recurring_payment
command if failed
{ "data": { "success": false, "error": "no_mandate" } }
This command will be invoked whenever a recurring payment is made. This always happens without any user involvement. Instead of a redirect you must return the json shown to the right. If unsuccessful, you may return one of the following errors:
- no_mandate: Owner will receive a message describing them how to create a new mandate. Recurring payments will be disabled for that owner in bookingexperts.
- no_customer: Owner will receive a message informing them that they are not known at the side of the payment provider. Recurring payments will be disabled for that owner in bookingexperts.
- amount_too_high: Owner will receive a message explaining the amount on the invoice is too high to be paid through recurring payments and the owner will be instructed to pay this invoice manually. In this case recurring payments will remain enabled for the owner, but this invoice will no longer be retried.
Delete mandates
Response to the
delete_mandates
command if successful
{ "data": { "success": true } }
Response to the
delete_mandates
command if failed
{ "data": { "success": false, "error_message": "Mandate does not exist" } }
This command will be invoked whenever an owner want to delete their mandate. In that case you could delete the mandate in the psp. You must return the json shown to the right.
Sync payment methods
Response to the
sync_payment_methods
[command](#commands]
{
"data": {
"payment_methods": [ "ideal", "bank_transfer" ]
}
}
Apps may provide a command with identifier sync_payment_methods
and a payment_handler
context model. If this command is present the user managing the payment service provider cannot configure which payment methods are supported in BE.
This command will be invoked with a payment handler whenever a payment handler is created, and periodically afterwards. Whenever it is called you should return a list of supported payment methods for the payment handler like shown in the example on the right. Valid payment methods are:
- american_express
- applepay
- bancontact
- banktransfer
- belfius
- creditcard
- directdebit
- eps
- giftcard
- giropay
- ideal
- inghomepay
- kbc
- klarnapaylater
- klarnasliceit
- maestro
- mastercard
- mistercash
- overboeking
- paypal
- paysafecard
- przelewy24
- sofort
- visa
- visa_electron
- vpay
Redirect to psp backoffice
Payload for the endpoint of the redirect_to_psp_backoffice command
{
"data": {
"id": "541",
"type": "payment_request",
"attributes": {
"price": { "currency": "EUR", "value": "312.56" },
"locale": "nl",
"description": "Rent for reservation B123"
},
"relationships": {
"payment_handler": {
"data": {
"id": "24",
"type": "payment_handler"
}
},
"debtor": {
"data": {
"id": "11",
"type": "debtor"
}
},
"administration": {
"data": {
"id": "3",
"type": "administration"
}
}
}
}
}
Response to the redirect_to_psp_backoffice command, that will redirect the customer to the given url.
{ "redirect_url": "https://mypaymentprovider.com/show_payment/2abe47d423f0" }
Apps may provide a command with identifier redirect_to_psp_backoffice
and a payment_request
context model. If this command is present, payment requests in BE will have a link the user can click that invokes this command.
The response of this command must be a redirect to the page that shows this payment request in the psp backoffice, so the user can inspect the payment's status in there. See the example on the right.
Reviews
Endpoint: POST review
Creating reviews
A review can be created for a given ReviewForm. Your Review input should therefore also correspond to this form. Each ReviewQuestion of the ReviewForm must have a ReviewAnswer.
This can be achieved by using Sideposting: the ReviewAnswers are sideposted in the included
object. An example Review can be seen on the right. Each ReviewAnswer must have a relationship
to a ReviewQuestion belonging to the ReviewForm. These resources don't have an ID yet, therefore it is required to link these resources by setting /meta/temp_id
. You will also
need to define what the system needs to do with these resources by specifying /meta/method
create on the relationship.
{
"data": {
"type": "review",
"attributes": {
"name": "M Rowe",
"locale": "nl",
"stayed_nights": 7,
"stayed_date": "2014-01-15",
"original_identifier": "review-1"
},
"relationships": {
"rentable_type": {
"data": {
"id": "1",
"type": "rentable_type"
}
},
"review_answers": {
"data": [
{
"type": "review_answer",
"meta": {
"temp_id": "open-answer-id",
"method": "create"
}
},{
"type": "review_answer",
"meta": {
"temp_id": "boolean-answer-id",
"method": "create"
}
},{
"type": "review_answer",
"meta": {
"temp_id": "rating-answer-id",
"method": "create"
}
},{
"type": "review_answer",
"meta": {
"temp_id": "not-applicable-answer-id",
"method": "create"
}
}
]
}
}
},
"included": [{
"type": "review_answer",
"attributes": {
"answer": "It was great"
},
"relationships": {
"review_question": {
"data": {
"id": "1",
"type": "review_question"
}
}
},
"meta": {
"temp_id": "open-answer-id"
}
},{
"type": "review_answer",
"attributes": {
"boolean_answer": "true"
},
"relationships": {
"review_question": {
"data": {
"id": "2",
"type": "review_question"
}
}
},
"meta": {
"temp_id": "boolean-answer-id"
}
},{
"type": "review_answer",
"attributes": {
"rating": 8
},
"relationships": {
"review_question": {
"data": {
"id": "3",
"type": "review_question"
}
}
},
"meta": {
"temp_id": "rating-answer-id"
}
},{
"type": "review_answer",
"attributes": {
"not_applicable": true
},
"relationships": {
"review_question": {
"data": {
"id": "4",
"type": "review_question"
}
}
},
"meta": {
"temp_id": "not-applicable-answer-id"
}
}]
}
Master price lists
Each type in Booking Experts is associated to a Master price list. A master price list can consist of simple (night) prices or complex (LOS) prices.
To support dynamic price updates, apps can manage these master price lists if they have the appropriate permission (master_price_list|write
).
This guide explains how you can define and update prices of master price lists.
Creating a master price list
An app can create master price lists using the endpoint POST master_price_list. Only a name is required, but you do not need to provide any prices here (although this is possible). The administration can associate this price list to any existing type.
NOTE With the permission master_price_list|write
, any master price list within the administration can be updated. However, the recommendation is to create a separate price list
instead to ensure manually defined price lists are not overwritten by accident.
Sideposting prices
Prices of master price lists can only be created or updated in bulk by using Sideposting. Sideposting will allow you to define prices using
the standard JSONAPI included array. Prices are upserted by checking for existing resources based on date
and length_of_stay
(for complex prices).
You don't need to specify an ID for these prices, but in order to link these resources in your input, you need to define /meta/temp_id
. Also /meta/method
must be
set to create as a logical consequence of the missing IDs.
Creating a master price list
Endpoint: POST master_price_list
The example on the right created a new Master price list with name 'My master price list'. The master price list will be returned in the response if successful.
{
"data": {
"type": "master_price_list",
"attributes": {
"name": "My master price list"
}
}
}
}
Updating a master price list's simple prices
Endpoint: PATCH master_price_list
The example on the right updates a Master price list with some simple prices. The master price list will be returned in the response if successful.
{
"data": {
"id": "1",
"type": "master_price_list",
"relationships": {
"simple_prices": {
"data": [{
"type": "simple_price",
"meta": {
"temp_id": "price1",
"method": "create"
}
}, {
"type": "simple_price",
"meta": {
"temp_id": "price2",
"method": "create"
}
}]
}
}
},
"included": [{
"type": "simple_price",
"attributes": {
"date": "2014-01-01",
"price": {
"currency": "EUR",
"value": "12.75"
}
},
"meta": {
"temp_id": "price1"
}
}, {
"type": "simple_price",
"attributes": {
"date": "2014-01-02",
"price": {
"currency": "EUR",
"value": "14.15"
}
},
"meta": {
"temp_id": "price2"
}
}]
}
Updating a master price list's complex prices
Endpoint: PATCH master_price_list
The example on the right updates a Master price list with some complex prices. The master price list will be returned in the response if successful.
{
"data": {
"id": "1",
"type": "master_price_list",
"relationships": {
"complex_prices": {
"data": [{
"type": "complex_price",
"meta": {
"temp_id": "price1",
"method": "create"
}
}, {
"type": "complex_price",
"meta": {
"temp_id": "price2",
"method": "create"
}
}]
}
}
},
"included": [{
"type": "complex_price",
"attributes": {
"arrival_date": "2014-01-01",
"length_of_stay": 7,
"price": {
"currency": "EUR",
"value": "12.75"
}
},
"meta": {
"temp_id": "price1"
}
}, {
"type": "complex_price",
"attributes": {
"arrival_date": "2014-01-15",
"length_of_stay": 5,
"price": {
"currency": "EUR",
"value": "14.15"
}
},
"meta": {
"temp_id": "price2"
}
}]
}
Tour operators
A tour operator App is usually responsible for the following actions:
- Creating a channel in Booking Experts
- Creating type mappings (Booking Experts type X corresponds to external resource Y)
- Pushing the latest availability of categories
- Pushing the latest prices of categories
- Fetching new reservations and pushing updates to Booking Experts
This guide is applicable to Channel management as well.
Relevant permissions
A tour operator will usually need the following permissions:
availability|read
channel::reservation|read
channel::customer|read
channel::booking|read
rentable_type|read
reservation|write
channel|write
internal_message|write
Relevant webhooks
A tour operator will usually need the following webhooks:
rentable_type|reindexed
- Triggered when the availability or prices of a type have been changed. In a future version, availibility and price update events will be split into two separate events.
rentable_type|updated
- Triggered when attributes of the type have changed.
A special case is that a type can also become
archived
, which means it is not used anymore, but has not permanently been deleted because it is still asociated to certain reservations. Therefore, when the attributearchived
istrue
, the availability and prices of the type must be cleared.
- Triggered when attributes of the type have changed.
A special case is that a type can also become
rentable_type|deleted
- When a type is permanently deleted, the mapping can be removed and the availability and prices must be cleared.
Creating a channel
{
"data": {
"type": "channel",
"attributes": {
"name": "TourOperator.com",
"kind": "tour_operator",
"available_currencies": ["EUR"]
}
}
}
Channels in Booking Experts are used to track the origin of reservations. A channel can also store the pricing type used. We currently support 'simple prices' (night prices) and 'complex prices' (LOS prices). When an organization subscribes to your App, it is possible to associate a channel to each administration of the organization you get access to. However, it is also possible for the App to create a new channel instead.
To create a channel, you will need the channel|write
permission. Please see the POST channels
endpoint for more information. An example can be seen on the right.
Pushing availability and prices
Availability and prices for a type can be fetched in a couple of ways. The way to go is dependent
on the information you need and the pricing type that you use. You will need the avaiability|read
permission for these endpoints.
- When using simple night prices, use the GET night prices endpoint.
It returns the price and stock for each available date. This endpoint also supports the
If-Modified-Since
header.- When using complex LOS prices, use the GET LOS prices endpoint.
For each date, it returns a record with price and stock for each LOS. This endpoint also supports the
If-Modified-Since
header. - When using complex LOS prices, you can also use the GET availabilities endpoint instead. Besides price and availability, this will also return the rent price, original price and discount price. It also returns the expected check-in and check-out time of reservations.
- When using complex LOS prices, use the GET LOS prices endpoint.
For each date, it returns a record with price and stock for each LOS. This endpoint also supports the
Note Currently, when receiving a rentable_type|reindexed
event, you need to manually figure out which prices have changed if you only want to store differences in availability and prices.
This can easily be achieved by storing the last processed response and comparing this to the current response.
Pushing updates to Booking Experts
To create, update or cancel reservations, you can use the Channel Reservations endpoint. You will
need the reservation|write
permission to do this. More information on how to create or update reservations can be found in the Reservations guide.
When things go wrong
Occasionally, problems may occur when keeping reservations in sync. For example, a conflict may occur when a certain period has already been booked in Booking Experts. For these cases, it
is possible to send an internal message to the administration. You can use the POST internal_message endpoint. You will
need the internal_message|write
permission to do this.
Upgrading
This guide contains details on how to upgrade from the Tour operator API (V2) to the App API (V3).
Authentication
The Tour operator API authenticates using an API key for an Agency. Access to multiple administrations is realized by associating channels with the Agency. For the App API, you will need an App to be able to connect. Furthermore, organizations need to install your App, resulting in a Subscription. Each subscription will provide you with an API key or OAuth2 token that can be used to fetch metadata that is part of the organization.
Channel Access
In the App API, there are two ways in which channels can be associated to a Subscription:
- Manually
- Manual selection is enabled when no
channel|write
permission is configured - On installation of the App, the organization user can specify per administration which channel can be used for fetching prices and availability.
- Manual selection is enabled when no
- Via the App
channel|write
permission is required- Channels can be created via the API. In this case, the App itself should manage the channels it is using for fetching prices and availability.
Fetching prices & availability
The App API has introduced a 'Channel' namespace for fetching prices and availability. These API calls
require you to specify a channel_id
, which must be the ID of a channel that has been associated with
your App.
Previewing & creating Reservations
Reservations must be created via the Channel namespace, requiring you to pass a channel_id
.
The Tour operator API only knows the concept of a Reservation, while the App API also introduces
the concept of an Booking and a Customer. Where originally you would be able to specify
customer and booking data on the Reservation itself, you will now need to split these. The attribute names
are mostly the same though. Please see the Booking & Reservations guide for examples.
after_payment_return_url
is now part of the Bookingcoupon_codes
andpending_vouchers
are now part of the Booking and must be specified asredeemable_codes
A Reservation preview can be created in exactly the same way as creating a Reservation, but it uses a different API endpoint.
Available add-ons (discount cards / primary packages / extras)
Available add-ons can be fetched by including the optional relationships available_discount_cards
, available_primary_packages
and available_extras
when
fetching (previewing) a Reservation. The included resources will contain the price of the add-on when it is added to the Reservation.
In the Tour operator API, extras needed to be ordered by using the chosen_extras
attribute. In the App API, this is handled via the extra_order_items
relationship. To add an extra, you need to specify an ExtraOrderItem that has a relationship to an Extra.
Options
Options are very similar to Reservations, that's why there is no special endpoint anymore for creating Options. To create an Option,
you should just create a Reservation in which the attribute option_validity
is specified.
The 'All Reservations' Endpoint
The Tour operator API has an experimental endpoint to retrieve all reservations of an administration.
The App API just exposes this outside of the Channel namespace in GET reservations.
You will need the reservation|read
permission to use this. Note that you will also need the booking|read
and customer|read
permissions to
be able to read personal details.
Blog
This blog will elaborate on changes made to the App API.
Renaming Categories to RentableTypes
Date: October 31, 2022 - Affected versions: 0.45.0
Within BE, accommodations (and other rentals) are referred to as RentableIdentities, and specific setups of accomodations are referred to as Rentables. Rental segments are referred to as RentableSegments. On the other hand, the type of an accommodation was referred to as Category. For consistentency, we decided it would be better to rename Categories to RentableTypes.
Henceforth, as of App API release 0.45.0, Categories in BE will be internally and externally available as RentableTypes. If you are using RentableTypes in the App API, you should rename all occurrences of Categories to RentableTypes after this release, including any Category-related endpoints. There are also some other Category-related attributes and query parameters that need to be renamed. Please see the Release Notes for a full list of changes. To allow for a smooth transition, support for Categories (and derived attributes and query parameters) will remain in place until the date of removal as mentioned in the Release Notes has passed.
NOTE The TourOperator API will remain unaffected.
Renaming AccommodationTypes to RentableSegments
Date: July 5, 2022 - Affected versions: 0.33.0
Within BE, accommodations (and other rentals) are referred to as RentableIdentities, and specific setups of accomodations are referred to as Rentables. On the other hand, the rental segment an accommodation belongs to was referred to as AccommodationType. For consistentency, we decided it would be better to rename AccommodationTypes to RentableSegments.
Henceforth, as of App API release 0.33.0, AccommodationTypes in BE will be internally and externally available as RentableSegments. If you are using AccommodationTypes in the App API, you should rename all occurrences of AccommodationTypes to RentableSegments after this release. There are also some other AccommodationType-related attributes that need to be renamed. Please see the Release Notes for a full list of changes. To allow for a smooth transition, support for AccommodationTypes (and derived attributes) will remain in place until the date of removal as mentioned in the Release Notes has passed.
NOTE The TourOperator API will remain unaffected.
Renaming Tags and Custom Attributes to Amenities
Date: June 21, 2021 - Affected versions: 0.0.4
Within BE, there has always been a lot of confusion regarding the term 'Tag'. Externally, they were always translated as 'Features' or 'Amenities', but internally they were represented by tags. Over time, the need for assigning values to Tags was introduced, for example to store the number of square meters when the Tag 'Garden' was associated to an accommodation. These were externally exposed as 'Custom Attributes', while they were still stored as Tags in the database.
As of App API release 0.0.4, Tags in BE will be internally and externally available as Amenities instead. If you are using Tags in the App API, you should rename all occurrences of Tags or Custom Attributes to Amenities after this release. Please see the Release Notes for a full list of changes. To allow for a smooth transition, support for Tags will remain in place until the date of removal as mentioned in the Release Notes has passed.
NOTE The TourOperator API will remain unaffected.
Release Notes
All notable changes to this API will be documented here.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.74.0] - 2023-05-00
Added
- Added the following relationships to schema
Reservation
:- extra_packages - The extra packages collection must now be set through this relationship.
- available_extra_packages
- Added the following relationships to schema
ExtraOrderItem
:- extra_package
[0.73.0] - 2023-05-03
Added
- Added the following attributes to schema
Administration
:- address
- postal_code
- city
- latitude
- longitude
- guest_list_group
- guest_accepted_document_type
- guest_identification_required
- ask_for_guest_gender
- ask_for_guest_address
- ask_for_guest_email
- ask_for_guest_profession
[0.72.0] - 2023-04-26
Added
- Added the following attributes to schema
Todo
:- memo
[0.71.0] - 2023-04-20
Added
GET /v3/checkout_portal/channels/:channel_id/bookings
- Fetch all Checkoutportal Bookings for the given channel
[0.70.0] - 2022-04-20
Added
- `POST /v3/administrations/:administration_id/maintenance_agenda_periods
- Creates an agenda period of type
MaintenanceAgendaPeriod
- Creates an agenda period of type
- `PATCH /v3/administrations/:administration_id/maintenance_agenda_periods/:id
- Updates an agenda period of type
MaintenanceAgendaPeriod
- Updates an agenda period of type
- `DELETE /v3/administrations/:administration_id/maintenance_agenda_periods/:id
- Deletes an agenda period of type
MaintenanceAgendaPeriod
- Deletes an agenda period of type
[0.69.0] - 2023-04-17
Added
- Added the following attributes to schema
MainOrderItem
andExtraOrderItem
:- quantity_type
[0.68.0] - 2023-04-12
Added
- Added the following attributes to schema
MainOrderItem
andExtraOrderItem
:- sku
[0.67.0] - 2023-04-03
Added
- Added the following relationships to schema
RentableIdentity
:- administration
[0.66.0] - 2023-03-29
Added
- Added the following attributes to schema
Subdomain
:- redirects
[0.65.0] - 2023-03-17
Added
- Added the following attributes to schema
Reservation
:- letter_in_booking
[0.64.0] - 2023-03-13
Added
- Added the following attributes to schema
Channel
:- requires_night_prices
Deprecated
- Schema changes:
Channel#pricing_type
is deprecated, useChannel#requires_night_prices
instead
[0.63.0] - 2023-03-08
Added
- Added the following attributes to schema
RentableIdentity
:- name_with_type
[0.62.0] - 2023-03-06
Added
- Added the following relationsips to schema
Agreement
:- commission_agreement
[0.61.0] - 2023-03-02
Added
PATCH /v3/administrations/:administration_id/reservations/:id
- Update a reservation (license_plates)
[0.60.0] - 2023-02-23
Added
DELETE /v3/subscription
- Deletes the current Subscription
[0.59.0] - 2023-02-21
Added
POST /v3/channels/:channel_id/reservations/:id/split
- Splits off a Reservation from a (multi) Booking
[0.58.0] - 2023-02-21
Added
- Added the following attributes to schema
Booking
:- guest_total_paid
[0.57.0] - 2023-02-03
Added
GET /v3/subdomains
- Returns all
Subdomains
of the organization
- Returns all
GET /v3/subdomains/:id
- Gets a
Subdomain
- Gets a
[0.56.0] - 2023-01-16
Added
- Added the following attributes to schema
Subscription
:- current_scopes
[0.55.0] - 2022-12-22
Added
- Added the following relationships to schema
DiscountAction
:- administration
[0.54.0] - 2022-12-19
Added
- Added the following attributes to schema
Availability
:- available_for_pets (only included when explicitly defined in a sparse fieldset)
[0.53.0] - 2022-12-15
Added
GET /v3/administrations/:administration_id/discount_actions
- Returns discount actions of an Administration
- Added the following attributes to schema
DiscountAction
:- discount_percentage
- fixed_discount
- minimum_number_of_nights
- maximum_number_of_nights
- archived
- created_at
- updated_at
[0.52.0] - 2022-12-14
Added
- Added the following attributes to schema
Todo
:- blocker
[0.51.0] - 2022-12-07
Added
GET /v3/rentable_segments
- Returns all
RentableSegments
of the organization
- Returns all
GET /v3/rentable_segments/:id
- Gets a
RentableSegment
- Gets a
[0.50.0] - 2022-11-21
Added
- Added the following attributes to schema
TodoList
:- archived
[0.49.0] - 2022-11-09
Added
- Added the following relationships to schema
Cost
andExtra
:- ledger_account
[0.49.0] - 2022-11-09
Added
- Added the following attributes to schema
RentableType
:- virtual
[0.48.0] - 2022-11-03
Added
GET /v3/administrations/:administration_id/administration_amenities
- Returns AdministrationAmenities of an Administration.
[0.47.0] - 2022-11-01
Deprecated
- Schema changes:
Availabilities
andApp::Availabilities
endpoints:- filtering by
accommodation_subtype_ids
and-accommodation_subtype_ids
is deprecated, filter byrentable_segment_ids
, respectively-rentable_segment_ids
, instead RentableType#accommodation_subtype
is deprecated, useRentableType#rentable_segment
instead
Date of removal for abovementioned deprecations: 01-11-2023.
[0.46.0] - 2022-11-01
Added
- Added the following relationships to schema
ReceiptItem
:- ledger_account
- vat_tariff
[0.45.0] - 2022-10-31
Deprecated
- Schema changes:
Availabilities
andApp::Availabilities
endpoints:- filtering by
category_ids
and-category_ids
is deprecated, filter byrentable_type_ids
, respectively-rentable_type_ids
, instead - limiting by
categories
is deprecated, limit byrentable_types
instead - limiting by
administrations[categories]
is deprecated, limit byadministrations[rentable_types]
instead - The
Categories
endpoint is deprecated, use theRentableTypes
endpoint instead - The
Category Amenities
endpoint is deprecated, use theRentableType Amenities
endpoint instead - The
Category Images
endpoint is deprecated, use theRentableType Images
endpoint instead - The
Channel Categories
endpoint is deprecated, use theChannel RentableTypes
endpoint instead - The
Channel Category Availability
endpoint is deprecated, use theChannel RentableType Availability
endpoint instead - The
Channel Category Costs
endpoint is deprecated, use theChannel RentableType Costs
endpoint instead - The
Channel Category Extras
endpoint is deprecated, use theChannel RentableType Extras
endpoint instead - The
Channel Category LOS Prices
endpoint is deprecated, use theChannel RentableType LOS Prices
endpoint instead - The
Channel Category Night Prices
endpoint is deprecated, use theChannel RentableType Night Prices
endpoint instead Availability#category
is deprecated, useAvailability#rentable_type
insteadRentable#category
is deprecated, useRentable#rentable_type
insteadReservation#category
is deprecated, useReservation#rentable_type
insteadReview#category
is deprecated, useReview#rentable_type
instead
Date of removal for abovementioned deprecations: 31-10-2023.
[0.44.0] - 2022-10-11
Added
GET /v3/administrations/:administration_id/ledger_accounts/:ledger_account_id/journal_transactions
- Returns unaggregated journal transactions of a LedgerAccount
[0.43.0] - 2022-10-04
Added
- Added the following attributes to schema
Booking
:- customer_desires_downpayment
[0.42.0] - 2022-09-27
- Added the following relationships to schema
Payment
:- payment_method (
payment_method|read
permission required)
- payment_method (
[0.41.0] - 2022-09-21
Added
POST /v3/administrations/:administration_id/payment_requests/:payment_request_id/chargebacks
- Create a Chargeback for a PaymentRequest
POST /v3/administrations/{administration_id}/refund_results
- Create a result for a RefundRequest
[0.40.0] - 2022-09-14
Added
- Added the following attributes to schema
Reservation
:- cancellation_insurance (only for administrations that support it)
[0.39.0] - 2022-09-13
Fixed
- Fixed several 'administration' relationships having the type 'administrations' instead of 'administration'.
[0.38.0] - 2022-09-12
Added
- Added the following attributes to schema
Todo
:- automatically_generated
[0.37.0] - 2022-08-08
Added
PATCH /v3/administrations/:administration_id/bookings/:booking_id/customer
- Update the customer details of a Booking
[0.36.0] - 2022-07-28
Added
- Added the following attributes to schema
PaymentRequest
:- reference
POST /v3/administrations/:administration_id/categories/:category_id/images
- Create a Image of a Category
PATCH /v3/administrations/:administration_id/categories/:category_id/images/:id
- Update a Image of a Category
DELETE /v3/administrations/:administration_id/categories/:category_id/images/:id
- Delete an Image of a Category
POST /v3/administrations/:administration_id/rentable_identities/:rentable_identity_id/images
- Create a Image of a RentableIdentity
PATCH /v3/administrations/:administration_id/rentable_identities/:rentable_identity_id/images/:id
- Update a Image of a RentableIdentity
DELETE /v3/administrations/:administration_id/rentable_identities/:rentable_identity_id/images/:id
- Delete an Image of a RentableIdentity
POST /v3/administrations/:administration_id/categories/:category_id/category_amenities
- Create a CategoryAmenity for a Category
PATCH /v3/administrations/:administration_id/categories/:category_id/category_amenities/:id
- Update a CategoryAmenity of a Category
DELETE /v3/administrations/:administration_id/categories/:category_id/category_amenities/:id
- Delete a CategoryAmenity of a Category
[0.35.0] - 2022-07-20
Added
PATCH /v3/administrations/:administration_id/rentable_identities/:id
- Update a RentableIdentity
POST /v3/administrations/:administration_id/rentable_identities/:id/archive
- Archive a RentableIdentity
DELETE /v3/administrations/:administration_id/rentable_identities/:id
- Delete a RentableIdentity
POST /v3/administrations/:administration_id/rentables
- Create a Rentable
PATCH /v3/administrations/:administration_id/rentables/:id
- Update a Rentable
DELETE /v3/administrations/:administration_id/rentables/:id
- Delete a Rentable
[0.34.0] - 2022-07-06
Added
POST /v3/administrations/:administration_id/categories
- Create a Category
PATCH /v3/administrations/:administration_id/categories/:id
- Update a Category
POST /v3/administrations/:administration_id/categories/:id/archive
- Archive a Category
[0.33.0] - 2022-07-05
Deprecated
- Schema changes:
Availabilities
andApp::Availabilities
endpoints:- filtering by
rentable_types
and-rentable_types
is deprecated, filter bysemantic_segments
, respectively-semantic_segments
, instead - the
include_rentable_type_counts
option is deprecated, useinclude_semantic_segment_counts
instead Category#accommodation_type
is deprecated, useCategory#rentable_segment
insteadCategory#rentable_type
is deprecated, useCategory#rentable_segment
instead to determine the rentable segment of the category, and then useRentableSegment#semantic_segment
AccommodationSubtype#accommodation_type
is deprecated, useAccommodationSubtype#rentable_segment
insteadReviewForm#accommodation_types
is deprecated, useReviewForm#rentable_segments
instead
Date of removal for abovementioned deprecations: 31-10-2023.
[0.32.0] - 2022-07-01
Added
- `GET /v3/administrations/:administration_id/agenda_periods/:id
- Gets an agenda period
- `POST /v3/administrations/:administration_id/external_blocked_agenda_periods
- Creates an agenda period of type
ExternalBlockedAgendaPeriod
- Creates an agenda period of type
- `PATCH /v3/administrations/:administration_id/external_blocked_agenda_periods/:id
- Updates an agenda period of type
ExternalBlockedAgendaPeriod
- Updates an agenda period of type
- `DELETE /v3/administrations/:administration_id/external_blocked_agenda_periods/:id
- Deletes an agenda period of type
ExternalBlockedAgendaPeriod
- Deletes an agenda period of type
[0.31.0] - 2022-06-15
Added
- Added the following relationships to schema
PaymentRequest
:- receipt (optional)
GET /v3/administrations/:administration_id/receipts?include_concept=true
- Gets receipts including concept receipts
[0.30.0] - 2022-06-09
Added
- Added the following attributes to schema
PaymentHandler
:- pos_enabled
- invoice_type
- created_at
- updated_at
GET /v3/administrations/:administration_id:/payment_handlers
- Gets payment handlers
GET /v3/administrations/:administration_id:/payment_handlers/:id
- Gets a payment handler
POST /v3/administrations/:administration_id:/payment_handlers
- Creates a payment handler. Can be used by payment or POS provider apps.
PATCH /v3/administrations/:administration_id:/payment_handlers/:id
- Updates an associated payment handler. Can be used by payment or POS provider apps.
DELETE /v3/administrations/:administration_id:/payment_handlers/:id
- Deletes an associated payment handler. Can be used by payment or POS provider apps.
[0.29.0] - 2022-05-31
Added
- Added the following attributes to schema
PrimaryPackage
:- applies_to_all_categories
GET /v3/channels/:channel_id/primary_packages/:primary_package_id/categories
- Yields the categories to which the given PrimaryPackage applies
[0.28.0] - 2022-05-30
Added
GET /v3/app/supported_payment_methods
- Yields all supported payment methods in BEX
[0.27.0] - 2022-05-23
Added
- Added the following relationships to schema
Reservation
:- question_answers (
question_answer|read
permission required)
- question_answers (
[0.26.0] - 2022-05-05
Added
- Added the following attributes to schema
Contact
:- is_company
- company
- first_name
- last_name
- phone
- mobile_phone
GET /v3/contacts/search/first
- Returns the first found contact that matches a given email address or phone number
[0.25.0] - 2022-04-29
Added
- Added the following attributes to schema
Owner
:- memo
[0.24.0] - 2022-04-06
Added
GET /v3/users
- Returns all users that belong to an organization (
user|read
permission required)
- Returns all users that belong to an organization (
GET /v3/users/:id
- Returns a user of an organization.
GET /v3/administrations/:administration_id/todo_lists/:todo_list_id/planners
- Returns all planners of a todo list (
planner|read
permission required)
- Returns all planners of a todo list (
GET /v3/administrations/:administration_id:/facilities
- Gets available facilities of the administration
- Added schema
Planner
- Added the following attributes to schema
Executor
:- user
- Added the following attributes to schema
Todo
:- rentable_identity
- facility
- creator
- Added the following attributes to schema
User
:- created_at
- updated_at
[0.23.0] - 2022-04-05
Deprecated
- Schema changes:
Booking#guest_invoice
is deprecated, useBooking#customer_invoice
instead
Fixed
- Undo removal of relationship
Order#customer_invoice
[0.22.0] - 2022-03-30
Added
- Added the following attributes to schema
Review
:- visible
[0.21.0] - 2022-03-22
Added
- Added the following relationships to schema
Todo
:- invoice
Deprecated
- Renamed
order
tobooking
where applicable. Date of removal: 2022-07-01 - Some attributes of
Reservation
where moved toBooking
. Date of removal of attributes on reservation: 2022-07-01 GET /v3/administrations/:administration_id/order
- Use
GET /v3/administrations/:administration_id/booking
instead
- Use
GET /v3/administrations/:administration_id/orders
- Use
GET /v3/administrations/:administration_id/bookings
instead
- Use
- Schema changes:
Reservation#order
will be replaced byReservation#booking
Reservation#option_validity
is deprecated, useBooking#option_validity
insteadReservation#remote_booking_nr
is deprecated, useBooking#remote_booking_nr
insteadReservation#locale
is deprecated, useBooking#locale
insteadReservation#currency
is deprecated, useBooking#currency
insteadReservation#memo
is deprecated, useBooking#memo
insteadReservation#state
is deprecated, useBooking#state
insteadReservation#deposit_completed
is deprecated, useBooking#deposit_completed
insteadReservation#booking_nr
is deprecated, useBooking#booking_nr
insteadReservation#token
is deprecated, useBooking#token
insteadReservation#confirmed_at
is deprecated, useBooking#confirmed_at
insteadReservation#owner_reservation
is deprecated, useBooking#owner_reservation
insteadReservation#paid_by_customer
is deprecated, useBooking#paid_by_customer
insteadReservation#option_expires_at
is deprecated, useBooking#option_expires_at
insteadInvoice#reservation
is deprecated since an invoice can have many reservations, useInvoice#booking
instead
[0.20.0] - 2022-03-11
Added
- Added the following attributes to schema
Reservation
:- base_rent_including_discount
[0.19.0] - 2022-02-11
Added
- Added the following relationship to schema
Debtor
:- administration
[0.18.0] - 2022-01-26
Added
- Added the following attributes to schema
Todo
:- quantity
[0.17.0] - 2022-01-25
Added
- Added the following attributes to schema
Cost
:- invoiced_to
[0.16.0] - 2022-01-21
Added
- Added the following attributes to schema
Invoice
andInvoiceItem
:- period_start_date
- period_end_date
[0.15.0] - 2022-01-19
Added
- Added the following attributes to schema
Reservation
:- blocking_todos_finished
[0.14.0] - 2022-01-18
Added
- Added the following relationships to schema
PaymentHandler
:- administration
[0.13.0] - 2022-01-05
Added
GET /v3/administrations/{administration_id}/measurers
[0.12.0] - 2021-12-16
- Added the following attributes to schema
Rentable
:- unbooked_date_ranges
[0.11.0] - 2021-12-07
- Added the following relationships to schema
Category
:- accommodation_type
[0.10.0] - 2021-11-29
- Added the following attributes to schema
Reservation
:- memo
[0.9.0] - 2021-11-22
Added
GET /v3/administrations/:administration_id:/(channels|rentable_identities|primary_packages|extra_packages)
- Added an
include_archived
query paramater
- Added an
- Added the following attributes to schema
Cost
,Extra
,ReviewAnswer
,ReviewQuestion
andReview
:- created_at
- updated_at
- Added the following relationships to schema
PrimaryPackage
andExtraPackage
:- administration
- Added the following attributes to schema
PrimaryPackage
andExtraPackage
:- archived
- created_at
- updated_at
[0.8.0] - 2021-11-16
Added
- Added the following attribute to schema
ComplexPrice
:- is_active - returns whether the price is currently active
GET /v3/administrations/:administration_id/master_price_lists/:master_price_list_id/complex_prices
- added an
include_inactive
query option for including inactive complex prices
- added an
[0.7.0] - 2021-10-19
Added
- Added the following financial attributes to schema
Reservation
:- created_at_date - local reservation creation date
- total
- total_without_vat
- deposit
- rent_turnover
- rent_turnover_without_vat
- provision
- Added the following attributes to schema
Order
:- currency
- created_at
- updated_at
- Added the following attributes to schema
AgendaPeriod
:- created_at
- updated_at
- Added the following attributes to schema
RentableIdentity
:- created_at
- updated_at
- Added the following attributes to schema
Rentable
:- created_at
- updated_at
[0.6.0] - 2021-10-13
Added
POST /v3/labels
- Creates a new label
PATCH /v3/labels
- Updates a label
PATCH /v3/channels/:channel_id/reservations/:id
- Added support for setting labels
PATCH /v3/administrations/:administration_id:/customers/:id
- Added support for setting labels
- Added the following relationship to schema
Customer
andReservation
:- labels
[0.5.0] - 2021-10-11
Added
POST /v3/administrations/:administration_id:/payments
- Adds a payment to an invoice
GET /v3/administrations/:administration_id:/registers
- Gets available registers of the administration
GET /v3/administrations/:administration_id:/registers/:id
- Fetches a single register
- Added the following relationship to schema
PaymentRequest
:register
- the register used for a POS payment request
POST /v3/administrations/:administration_id/review_forms/:review_form_id/reviews
.- Creates reviews for a given review form
- Your app needs the
review|write
permission to be able to use this endpoint
- Added the following relationships to schema
Review
:category
- The Category to which this review appliesrentable_identity
- The RentableIdentity to which this review applies (optional)
- Added the following attributes to schema
Review
:original_identifier
- The identifier of the Review in an external system or import.
- Added the following attributes to schema
ReviewQuestion
:allow_not_applicable
- Whether a not_aplicable answer is allowed
Fixed
- Filtering by null or empty values is now possible by not specifying a value for a filter, for example
filter[finished_at]=
.
[0.4.0] - 2021-09-08
Added
- Added the following attributes to schema
Category
:master_price_list_price_factor
- The prices in the price list are multiplied by this value.master_price_list_fixed_rate
- This rate is added to (or subtracted from if negative) the prices of the price list.
- Added a MasterPriceLists endpoint:
GET /v3/administrations/:administration_id/master_price_lists
- Added a MasterPriceList create endpoint:
POST /v3/administrations/:administration_id/master_price_lists
- Added a MasterPriceList show endpoint:
GET /v3/administrations/:administration_id/master_price_lists/:master_price_list_id
- Added a MasterPriceList update endpoint:
PATCH /v3/administrations/:administration_id/master_price_lists/:master_price_list_id
- Added a SimplePrices endpoint:
GET /v3/administrations/:administration_id/master_price_lists/:master_price_list_id/simple_prices
- Added a ComplexPrices endpoint:
GET /v3/administrations/:administration_id/master_price_lists/:master_price_list_id/complex_prices
Removed
- Removed deprecated attribute
stock
from schemaNightPriceSerializer
[0.3.1] - 2021-09-07
Fixed
GET /v3/administrations/:administration_id:/owners
- Return all
Owners
(active and inactive), fixes filtering on inactive owners.
- Return all
[0.3.0] - 2021-09-01
Added
- Added
debtor_code
toCustomers
,Owners
andChannels
[0.2.0] - 2021-08-26
Added
- Added the following attributes to schema
Invoice
:date
- the date of the invoicedebtor_code
- the debtor code of the invoicepayment_deadlines
- the deadlines of the required payments with their respective amounts
- Added a Rentables endpoint:
GET /v3/administrations/:administration_id/rentables
- Added the following attributes to schema
Rentable
:for_rental
- whether a rentable accepts reservations
[0.1.0] - 2021-08-25
Added
GET /v3/channels/:channel_id/categories/:category_id/availabilities
- Added
multibook_safety_margin
query parameter
- Added
[0.0.4] - 2021-07-28
Deprecated
- Renamed
tag
toamenity
where applicable. Date of removal: 2021-10-01 GET /v3/tags
- Use
GET /v3/amenities
instead
- Use
GET /v3/tags/{id}
- Use
GET /v3/amenities/{id}
instead
- Use
GET /v3/availabilities
- Replace query param
filter[tag_ids]
byfilter[amenity_ids]
- Replace query param
include_tag_counts
byinclude_amenity_counts
. This will yield/meta/amenity_counts
instead of/meta/tag_counts
- Replace sorter
tag_ids_match_score
byamenity_ids_match_score
- Replace query param
- Schema changes:
Availability#missing_tags
will be replaced byAvailability#missing_amenities
Category#custom_attributes
will be replaced byCategory#category_amenities
Category#tags
will be replaced byCategory#category_amenities
Category#optional_tags
will be replaced byCategory#optional_amenities
CustomAttribute
will be removed in favor ofCategoryAmenity
,RentableAmenity
,ReservationAmenity
orRoomAmenity
Rentable#tags
will be replaced byRentable#rentable_amenities
Reservation#tags
will be replaced byReservation#reservation_amenities
Room#custom_attributes
will be replaced byRoom#room_amenities
TagGroup
will be removed in favor ofAmenityGroup
Tag
will be removed in favor ofAmenity
[0.0.3] - 2021-06-10
Added
POST /v3/administrations/{administration_id}/reservations/{reservation_id}/memos
GET /v3/administrations/{administration_id}/agenda_periods
Fixed
PATCH /v3/administrations/{administration_id}/channels/{id}
:pricing_type
was incorrectly parsedarchivable
could not be changed
[0.0.2] - 2021-01-05
Added
- Payment provider app support
[0.0.1] - 2020-07-13
Added
- Initial endpoints