API v3 webhooks
When building bookingkit integrations, you might want your applications to receive events as they occur in your bookingkit accounts, so that your backend systems can execute actions accordingly.
Currently bookingkit provides webhook events for orders creation and update. You can receive information every time an order is created or updated. This integration approach is much more efficient than actively requesting for orders.
Authentication
While we support oauth2 client credentials workflow, it's not mandatory, but it's good to have. When using OAuth, the authentication token will be obtained first and then used as a Bearer Authorization token in the webhook endpoints calls.
Order update and creation event
Bookingkit will make a PATCH request to the webhook endpoint (oauth_endpoint_url) every time an order is created or updated.
The same webhook endpoint is called for both order creation and order update. Please check the order identifier (id in the response) with existing records to see if the order is new or existing.
Order info is sent as JSON object with the same format as the APIv3 Order Response.
Webhook request flow
Token endpoint (OAuth flow)
If you're using OAuth authentication, bookingkit will make POST call to oauth_endpoint_token_url with oauth_endpoint_client_id, oauth_endpoint_client_secret and grant_type = client_credentials in order to obtain a token for authentication against the webhook endpoint.
Example call made by bookingkit:
curl -X POST https://example.com/oauth/token -d "client_id=oauth_endpoint_client_id&client_secret=oauth_endpoint_client_secret&grant_type=client_credentials"
Your endpoint should return the oauth authentication token Access Token Response - OAuth 2.0 Simplified
Sample response of the token endpoint:
{"access_token":"b4540b431b513cdaa44ab604cb88a7c4992477d5","expires_in":3600,"token_type":"Bearer"}
Order update and creation endpoint
When using OAuth, bookingkit will make a call to oauth_endpoint_url with the token obtained in the previous step as Bearer Token in the request header.
Example call made by bookingkit:
curl -X POST https://example.com/orderUpdate -H "Authorization: Bearer b4540b431b513cdaa44ab604cb88a7c4992477d5" -H "Content-Type: application/json" --d '{"id":"265dac0b8ad51dad90344defd582f32e", "code":"ABC-123CC4", ...}'
Registering webhooks
To enable webhook events, you need to register webhook endpoints. Please provide the required information to bookingkit support:
If you're using OAuth authentication, provide the following information regarding the token Endpoint:
oauth_endpoint_token_url- URL of your token endpointoauth_endpoint_client_id- oauth client id (defined by you)oauth_endpoint_client_secret- oauth client secret (defined by you)
Information regarding the order update and creation webhook endpoint:
oauth_endpoint_url- URL of your order order creation and update endpoint
Use Cases
Sending custom emails after an order update
You can use the order update webhook to trigger sending a custom email to the end customer. By inspecting the webhook payload, your application can determine the nature of the update (e.g., status change) and send a relevant notification.
The email can also include a self-service link allowing customers to view their order details:
https://web.admin.bookingkit.com/selfService/viewOrder/$orderId
Example webhook of a paid order
{
"id": "1a3c5e7f9b2d4f6a8c0e1f23456789ab",
"code": "RQW-ETD72D",
"external_reference": "",
"vendor_id": "0f1e2d3c4b5a69788796a5b4c3d2e1f0",
"date": "2025-11-08T14:36:19Z",
"payment_date": "2025-11-11T14:36:45Z",
"expire_date": "",
"status": "ACCEPTED",
"lang": "en",
"currency": "EUR",
"email": "iamhomersimpson@hotmail.com",
"name": "Frank Grimes",
"company": "",
"vat_number": "",
"phone": "0177 1234 789",
"street": "",
"streetnr": "",
"zip": "",
"city": "",
"country": "",
"internal_notes": "",
"comment": "",
"cancellation_date": "",
"total_invoice": "20.00",
"additional_discount": "0.00",
"shipping_country": "",
"shipping_city": "",
"shipping_zip": "",
"shipping_street": "",
"shipping_streetnr": "",
"shipping_name": "",
"sale_params": "",
"external_order_url": "",
"affiliate_id": "",
"email_newsletter_opt_in": "",
"tickets": [
{
"id": "645f68637614967689b2b3ebc441138a",
"event_date_id": "8e4f8e59727e843f87d58930e1676565",
"date_id": "8e4f8e59727e843f87d58930e1676565",
"event_id": "8f9f810d91b7323a7a433d303b80cc77",
"code": "2M388R",
"status": "ACCEPTED",
"comment": "",
"cancellation_date": "",
"title": "Some awesome experience",
"date": "2025-11-23T10:01:00Z",
"vat": "19.00",
"participants": [
{
"id": "5677664545693063f1209942b9190b35",
"status": "ACCEPTED",
"name": "",
"email": "",
"phone": "",
"comment": "",
"price_id": 5,
"price_value": "10.00",
"price_title": "standard",
"vat": "19.00",
"cancellation_date": "",
"code": "XN3-CSJG87-HNH",
"checked_in": "",
"entry_units": [
{
"type": "ADULT"
}
],
"redeemed_flexTicket": []
},
{
"id": "76f46c39e491221e4004fef6edea987f",
"status": "ACCEPTED",
"name": "",
"email": "",
"phone": "",
"comment": "",
"price_id": 5,
"price_value": "10.00",
"price_title": "standard",
"vat": "19.00",
"cancellation_date": "",
"code": "XN3-CSJG87-R93",
"checked_in": "",
"entry_units": [
{
"type": "ADULT"
}
],
"redeemed_flexTicket": []
}
]
}
],
"voucherOrders": [],
"products": [],
"flexTickets": [],
"redeemed_vouchers": [],
"redeemed_coupons": [],
"additional_information": [],
"booking_channel": [],
"payments": [
{
"id": "8b38027ccab4c18531f3a724203c9a09",
"code": "StripeBankWire",
"payment_method": "StripeBankWire",
"name": "Bank wire",
"value": 20,
"type": "payment",
"payment_date": "2025-11-11T14:36:45Z"
}
]
}
Unified example
This superset shows the structure of possible webhooks in a unified example to illustrate typical shapes and data types. Fields not applicable to a specific event will be omitted in actual deliveries.
{
"id": "1a3c5e7f9b2d4f6a8c0e1f23456789ab",
"code": "QBP-UPRHC4",
"external_reference": "GYG_GYGN11111111",
"vendor_id": "0f1e2d3c4b5a69788796a5b4c3d2e1f0",
"date": "2025-11-04T16:37:52Z",
"payment_date": "2025-11-04T16:42:27Z",
"expire_date": "2027-11-04T16:42:27Z",
"status": "ACCEPTED",
"lang": "en",
"currency": "EUR",
"email": "iamhomersimpson@hotmail.com",
"name": "Frank Grimes",
"company": "Bookingkit GmbH",
"vat_number": "DE123456789",
"phone": "0177 1234 789",
"street": "Muehlenweg",
"streetnr": "7",
"zip": "10407",
"city": "Berlin",
"country": "Germany",
"internal_notes": "Notes",
"comment": "Comment",
"cancellation_date": "",
"total_invoice": "100.00",
"additional_discount": "0.00",
"shipping_country": "Germany",
"shipping_city": "Berlin",
"shipping_zip": "11111",
"shipping_street": "Buntestrasse",
"shipping_streetnr": "22",
"shipping_name": "Product receiver",
"sale_params": "source=partner_website&campaign=summer_sale",
"external_order_url": "https://partner-system.example.com/orders/12345",
"affiliate_id": "abcd",
"email_newsletter_opt_in": "2025-11-14T10:00:00Z",
"tickets": [
{
"id": "11223344556677889900aabbccddeeff",
"event_date_id": "aa00bb11cc22dd33ee44ff5566778899",
"date_id": "aa00bb11cc22dd33ee44ff5566778899",
"event_id": "fedcba98765432100123456789abcdef",
"code": "H88LR2",
"status": "ACCEPTED",
"comment": "Ticket comment",
"cancellation_date": "",
"title": "Black Mesa Transit System Tram",
"date": "2025-11-14T10:00:00Z",
"vat": "19.00",
"participants": [
{
"id": "1sd2e34f09ds43acx0011223344556677",
"status": "ACCEPTED",
"name": "Maxi Muster",
"email": "maximuster@gmail.com",
"phone": "0162 9999 9999",
"comment": "Customer Comment",
"price_id": 813,
"price_value": "100.00",
"price_title": "Preiskategorie",
"vat": "19.00",
"cancellation_date": "",
"code": "QBP-UPRHC4-ZUN",
"checked_in": "2025-11-16T10:00:00Z",
"entry_units": [
{ "type": "ADULT" }
],
"redeemed_flexTicket": [
{
"id": "f32e9fb7fcb9f4a3f02b84e2902a9db1",
"redeemed_value": "100.00",
"creation_date": "2025-11-11T15:31:48Z",
"purchasing_order_id": "83ab6f7d03a8b87cf44953b0c2388bc9"
}
]
}
]
}
],
"voucherOrders": [
{
"id": "13579bdf2468ace00112233445566778",
"status": "",
"vat": "0.00",
"voucher": [
{
"id": "abcdef0123456789fedcba9876543210",
"code": "7648V-W5P3F-5R6DH",
"value": "100.00",
"currency": "EUR"
}
],
"related_items": {
"refundedOrders": [
{ "order_id": "1a3c5e7f9b2d4f6a8c0e1f23456789ab", "order_code": "QBP-UPRHC4" }
],
"payments": [
{ "id": "8899aabbccddeeff0011223344556677" }
]
}
}
],
"products": [
{
"product_id": "b47570f18b3c990509ffa6fd04beba79",
"status": "ACCEPTED",
"title": "Product name",
"price": "3.00",
"amount": 1,
"currency": "EUR",
"vat": "19.00"
}
],
"flexTickets": [
{
"id": "f32e9fb7fcb9f4a3f02b84e2902a9db1",
"code": "M7W7W-974HL-US9PT",
"status": "ACCEPTED",
"title": "Flex Ticket Offer",
"redemption_total": 5,
"redemption_available": 5,
"unlimited_redemptions": 0,
"price": "500.00",
"price_title": "Standard",
"currency": "EUR",
"vat": "0.00",
"flexOffer": [
{
"id": "b23eb1c9ccc9b185af5dc1869d306831",
"price_category_id": 836,
"event_id": "3c6315e9b79a4af73eefeb5fdbedcbd4"
}
]
}
],
"redeemed_vouchers": [
{
"id": "59638e924822be1d0dc305873c798315",
"redeemed_value": "100.00",
"usage_date": "2025-11-04T16:37:52Z",
"creation_date": "2025-10-03T14:36:19Z",
"purchasing_order_id": "2c7fcf4de0a159ee0828349fdaf7f77f"
}
],
"redeemed_coupons": [
{
"id": "3134a04cb9f55c8df9489fb5ad5be918",
"title": "Coupon name",
"redeemed_value": "2.00",
"usage_date": "2025-11-04T16:37:52Z"
}
],
"additional_information": [
{
"id": "09b6615d0f8d96554172a10cfe62e460",
"title": "I agree to checkbox",
"value": "true"
},
{
"id": "050bcef45bac06b499c94dc33cd791d6",
"title": "Short Answer Field",
"value": "Typed Answer"
},
{
"id": "d6dad9b9ff40c1460fd093821081dc4b",
"title": "Dropdown Label",
"value": "Dropdown answer 1"
}
],
"booking_channel": [
{
"name": "Reseller Name",
"id": "C12asdXas13"
}
],
"payments": [
{
"id": "00112233445566778899aabbccddeeff",
"code": "StripeBankWire",
"payment_method": "StripeBankWire",
"name": "Bank wire",
"value": 110,
"type": "payment",
"payment_date": "2025-11-04T16:38:20Z"
},
{
"id": "99392919391329338899aabbccddeeff",
"code": "StripeBankWire",
"payment_method": "StripeBankWire",
"name": "Bank wire",
"value": -10,
"type": "refund",
"payment_date": "2025-11-06T16:58:20Z"
}
]
}
TypeScript types (reference only)
export interface OrderPayload {
id: string;
code: string;
external_reference?: string;
vendor_id: string;
date: string; // ISO-8601
payment_date?: string; // ISO-8601 or empty string
expire_date?: string; // ISO-8601 or empty string
status: 'ACCEPTED' | 'CANCELLED' | 'PENDING' | 'DECLINED' | 'OPEN' | 'ALL';
lang: string; // e.g., 'en'
currency: string; // e.g., 'EUR'
email: string;
name: string;
company?: string;
vat_number?: string;
phone: string;
street?: string;
streetnr?: string;
zip?: string;
city?: string;
country?: string;
internal_notes?: string;
comment?: string;
cancellation_date?: string; // ISO-8601 or empty string
total_invoice: string; // decimal-as-string
additional_discount?: string; // decimal-as-string
shipping_country?: string;
shipping_city?: string;
shipping_zip?: string;
shipping_street?: string;
shipping_streetnr?: string;
shipping_name?: string;
sale_params?: string;
external_order_url?: string;
affiliate_id?: string;
email_newsletter_opt_in?: string; // ISO-8601 or empty string
tickets?: Ticket[];
voucherOrders?: VoucherOrder[];
products?: Product[];
flexTickets?: FlexTicket[];
redeemed_vouchers?: RedeemedVoucher[];
redeemed_coupons?: RedeemedCoupon[];
additional_information?: AdditionalInformation[];
booking_channel?: BookingChannel[];
payments?: Payment[]; // Only included in the order object in the webhook, not present in API v3
}
export interface Ticket {
id: string;
event_date_id: string;
date_id: string;
event_id: string;
code: string;
status: "ACCEPTED" | "CANCELED" | "PENDING" | "OPEN";
comment?: string;
cancellation_date?: string; // ISO-8601 or empty string
title: string; // Only included in the ticket object in the webhook, not present in API v3
date: string; // ISO-8601 & only included in the ticket object in the webhook, not present in API v3
vat: string; // decimal-as-string
participants: Participant[];
}
export interface Participant {
id: string;
status: "ACCEPTED" | "CANCELED";
name: string;
email: string;
phone: string;
comment?: string;
price_id: number;
price_value: string; // decimal-as-string
price_title: string;
vat: string; // decimal-as-string
cancellation_date?: string; // ISO-8601 or empty string
code: string;
checked_in?: string; // ISO-8601 or empty string
entry_units: Array<{ type: string }>;
redeemed_flexTicket?: RedeemedFlexTicket[];
}
export interface Product {
product_id: string;
status: "ACCEPTED" | "CANCELED";
title: string;
price: string; // decimal-as-string
amount: number; // numeric amount
currency: string; // e.g., 'EUR'
vat: string; // decimal-as-string
}
export interface Payment {
id: string;
code: string;
payment_method: string; // like "StripePayment", not the enum from the API v3 payment object
name?: string;
value: number; // numeric amount, negative for refund
type: "payment" | "refund";
payment_date: string; // ISO-8601
}
export interface FlexTicket {
id: string;
code: string;
status: "ACCEPTED" | "CANCELED" | "FAILURE" | "PENDING";
title: string;
redemption_total: number;
redemption_available: number;
unlimited_redemptions: number;
price: string; // decimal-as-string
price_title: string;
currency: string;
vat: string; // decimal-as-string
flexOffer: Array<{ id: string; price_category_id: number; event_id: string }>;
}
export interface RedeemedFlexTicket {
id: string;
redeemed_value: string; // decimal-as-string
creation_date: string; // ISO-8601
purchasing_order_id: string;
}
export interface VoucherOrder {
id: string;
voucher: Array<{ id: string; code: string; value: string; currency: string }>;
related_items?: {
refundedOrders?: Array<{ order_id: string; order_code: string }>;
payments?: Array<{ id: string }>;
};
}
export interface RedeemedVoucher {
id: string;
redeemed_value: string; // decimal-as-string
usage_date: string; // ISO-8601
creation_date: string; // ISO-8601
purchasing_order_id: string;
}
export interface RedeemedCoupon {
id:string;
title:string;
redeemed_value:string; // decimal-as-string
usage_date:string; // ISO-8601
}
export interface AdditionalInformation {
id: string;
title: string;
value: string; // bool-as-string for checkbox, else text
}
export interface BookingChannel{
name: string;
id: string;
}