Webhooks let an application be notified of events occurring in Bookeo. For example Bookeo can notify the application when a new booking is created, or a booking is canceled.
When an application needs to be updated with events in Bookeo (ex. to take specific actions triggered by events, or to sync changed data), it is strongly recommended to use webhooks instead of polling the API for changed data.
An application can manage webhooks for each API key it has access to. Bookeo supports different webhook “domains”, i.e. the type of data that the webhook is notified for, and webhook “types”, i.e. types of event for which the application is notified.
For example, a webhook domain is “bookings”, and a webhook type is “created”. A webhook registered for API key ABC, for domain “bookings” and type “created” will be notified whenever a new booking is created for the account linked to the API Key “ABC”.
A full list of possible values for domain and type of a webhook is provided in the API reference for the POST /webhooks method: https://www.bookeo.com/apiref/#tag/Webhooks/paths/~1webhooks/post
Each webhook has a URL, which is the address where the notifications for that webhook will be sent to.
An application can register a different webhook for each combination of API key, domain and type. No more than one webhook can be registered for the same combination of API Key, domain and type. To create a webhook, simply submit an HTTP POST to the API endpoint /webhooks (see API reference for full details).
The webhook URL can contain custom parameters. You can use this to provide context information to your web service about the webhook call. For example you could use this URL:
https://www.mydomain.com/webhooks/newbooking?account=1234
or this URL:
https://www.mydomain.com/1234/webhooks?type=bookingCreated
… and so on. You can use any URL you want, as long as the protocol is https.
When the associated event occurs, Bookeo will send an HTTP POST request to the URL of the webhook registered for that event. Bookeo will assume that the message has been received successfully by the application only when it receives a 2xx HTTP response status code. Any other code will be interpreted as an error, and delivery will be attempted again later (see below).
The request entity body will contain a JSON object with this format:
WebhookMessage {
itemId (string),
item (object),
timestamp (date-time),
}
itemId is the unique identifier of the item that the notification is for. For bookings, this would be the bookingNumber. For customers and for payments, this would be the id. itemId can be used to take some action without having to decode the full item (see below)
item is the json representation of the item (ex. the booking) that the notification is for. See the API references for the full structure of these objects (the same as returned by GET /bookings/{itemId}, GET /customers/{itemId}, GET /payments/{itemId}, etc.)
timestamp is the time at which the notification was generated. Note that this may be considerably earlier than the time at which the message is eventually delivered.
{
"itemId": "85504203869114",
"timestamp": "2015-04-21T17:02:00+10:00",
"item": {
"bookingNumber": "85504203869114",
"startTime": "2015-04-22T17:00:00+10:00",
...
}
}
When delivered to the webhook registered for the domain “bookings” and the type “created”, this is a message to notify of the creation of a new booking 85504203869114.
If delivery of a webhook message fails for any reason (network error, HTTP response status code other than 2xx, etc.), Bookeo will retry delivery several times, at exponentially longer intervals between each attempt.
Note that webhooks are delivered in strict sequence for each API Key, meaning that if event A and B for an API Key occur in this order, Bookeo will not send notification for B until the notification for A is delivered successfully, or completely discarded (see below).
Due to network issues, it is possible that your application receives a webhook message, but Bookeo does not receive confirmation that it was successfully delivered. In this case Bookeo will send the message again. Your application should ensure it does not process the same message twice. In order to do so, your application should keep track of the HTTP request header X-Bookeo-MessageId that is included in every webhook message it receives. If this is the same as the value of the header it received for the last message, then this new message is a repeat, and should be ignored. Since message ordering is always enforced, your application only needs to compare the message id received with the last one.
Tip: a common cause of repeat messages is an application that takes more than 5 seconds to send a response to the HTTP request. Please see “Performance notes” below.
If Bookeo is unable to deliver a webhook message after multiple attempts, it will discard the message, and the message will be forever lost.
If more messages for the same webhook are due to be sent after the discarded one, Bookeo will try and deliver them as usual.
The first message successfully sent after a discarded message will include the HTTP request header X-Bookeo-PreviousMessageLost with a value of true. This header, when present, indicates that the message before the current one was discarded. Note that possibly other messages before that could have been discarded as well.
Bookeo will attempt delivery for at least 6 hours before discarding a message.
If Bookeo is unable to deliver any message to a webhook URL for prolonged periods of times (more than 24 hours), the webhook will be considered unresponsive, and it will be blocked. No more message deliveries will be attempted for this webhook.
An application that has not been receiving notifications for a while can periodically check the status of its webhooks (see API reference) to see if any of its webhooks was blocked. In this case, an application should fix the cause of the problem, and can then register a new webhook to replace the existing one.
Bookeo expects the webhook message to be processed quickly (within 5 seconds).
If your application needs to perform complex tasks as a result of receiving a webhook message, we strongly recommend queuing the message internally, returning the HTTP response to Bookeo quickly, and then processing the message in background.
Please note that webhooks are a resource-consuming feature. Bookeo reserves the right to block an application whose webhook URLs are often unreliable, not accessible, unresponsive, slow, etc.
It is recommended that the application processing webhook messages verify that the message was originated by Bookeo, and not by a malicious third party.
For this purpose, Bookeo adds two specific headers to the HTTP request of every webhook message: X-Bookeo-Timestamp and X-Bookeo-Signature .
To verify that a webhook message is authentic, the application should:
The message signature is calculated using the following steps:
The elements should be concatenated in exactly the given order, without any character between the elements
The following is an example of how the signature is calculated for a sample message. We recommend testing your authentication code by using these sample values, verifying that your calculated signature is the same as the one calculated in the example. Once your code calculates the correct signature, you can use it to authenticate real webhook messages.
X-Bookeo-Timestamp (HTTP header included in request)
1683025420401
X-Bookeo-MessageId (HTTP header included in request)
dvpwVQI0W7Pe187dc203154
Webhook URL (as set by your application when creating the webhook)
https://www.mywebsite.com/webhooktest?id=1234
Message content (body of HTTP request)
{"itemId":"2856MUMPA187DC203130","timestamp":"2023-05-02T04:01:00-07:00","item":{"credit":{"amount":"0","currency":"USD"},"acceptSmsReminders":true,"numBookings":0,"numCancelations":0,"numNoShows":0,"member":false,"id":"2856MUMPA187DC203130","firstName":"John","lastName":"Smith","streetAddress":{"countryCode":"US"},"creationTime":"2023-05-02T04:01:00-07:00","gender":"unknown"}}
Hashing message (concatenation of above elements)
1683025420401dvpwVQI0W7Pe187dc203154https://www.mywebsite.com/webhooktest?id=1234{"itemId":"2856MUMPA187DC203130","timestamp":"2023-05-02T04:01:00-07:00","item":{"credit":{"amount":"0","currency":"USD"},"acceptSmsReminders":true,"numBookings":0,"numCancelations":0,"numNoShows":0,"member":false,"id":"2856MUMPA187DC203130","firstName":"John","lastName":"Smith","streetAddress":{"countryCode":"US"},"creationTime":"2023-05-02T04:01:00-07:00","gender":"unknown"}}
Hashing key (application’s secret key obtained when registering the application)
iWQlbsuksGUqStFPk46WVjpGO7vVQoeO
Calculated signature (HMAC-SHA256 calculated using Hashing key and Hashing message)
a3cec455a9462fc524b02eeac7a26af743d512763271ab170f957aeafd6a636e