This feature is available on these plans (view pricing)
Receive BookingTimes events in your webhook endpoint
Overview
Create an event destination to receive events at an HTTPS webhook endpoint. After you register a webhook endpoint, BookingTimes can push event data to your webhook endpoint as they happen in your BookingTimes website.
You can register and create one endpoint to handle several different event types at the same time, or set up individual endpoints for specific events.
Events are sent by a background process that runs about once a minute, so an event normally arrives within a minute or two of the action that raised it.
To enable, you must be on the Nail & Scale plan and contact BookingTimes to enable.
Steps
Navigate to Setup > Integrations > Webhooks
Click "Add Webhook"
Add the Webhook's Endpoint URL, Description and API Key. The Endpoint URL must start with https://. The API Key is sent to your endpoint in the
x-api-keyheader of every call.The API Secret is optional. When one is set, every call is signed so your endpoint can prove it came from BookingTimes (see Verifying the signature below).
Select which events are going to the endpoint. You can create multiple endpoints.

Event Type | Description |
|---|---|
client.create | Fired on new client records. |
client.update | Fired on updates to existing client records. |
client.membership | Fired when a client is added to or removed from a membership. |
booking.create | Fired on new bookings. |
booking.update | Fired on updates to existing bookings, including when a booking is paid. |
booking.cancel | Fired when a booking is cancelled. |
booking.pass | Fired when a booking is marked as passed. |
booking.fail | Fired when a booking is marked as failed. |
booking.postbooking | Fired once, about 15 minutes after a booking's end time, for a booking that took place. |
payment.received | Fired when a booking, package, voucher, account top-up, deposit or online shop order is paid. |
payment.refunded | Fired when a refund is recorded. Every amount on the payload is negative. |
payment.cancelled | Fired when a payment is cancelled (reversed) on a booking or sale. The payload carries the amounts that were cancelled. |
Delivery and retries
Every event is an HTTPS POST to your Endpoint URL with a JSON body, Content-Type: application/json, and your API Key in the x-api-key header.
Respond with any 2xx status code (for example 200 or 204) to confirm receipt. Any other response, or no response at all, is treated as a failed attempt. A failed event is retried on each later run, up to 5 attempts, for up to a week after the event was raised. After that it is no longer sent automatically and can be resent from the Webhook Event History.
A retried delivery is a fresh call with the same body and the same WebhookEventId. Use WebhookEventId to ignore an event you have already processed.
Verifying the signature
When your webhook has an API Secret, every call also carries two headers:
Header | Description |
|---|---|
| The send time in Unix seconds (UTC). |
| Lowercase hex HMAC-SHA256, keyed with your API Secret, of the string |
To verify a call:
Read the raw request body as bytes before any JSON parsing.
Compute HMAC-SHA256 with your API Secret as the key over the
x-timestampheader value, a full stop, then the body bytes.Hex-encode the result in lowercase and compare it to
x-signatureusing a constant-time comparison.Reject the call if the signatures differ, or if
x-timestampis more than 5 minutes from your clock.
Each attempt is signed afresh, so a retried delivery carries a new timestamp and signature. A webhook with no API Secret is sent without these headers.
Webhook Event History
Steps
You can click on the webhook to view the events that have been sent.

Click on the eye icon to view the JSON request and the response that was received, or the Resend button to resend the event to your server. An event that has not been tried yet shows as Pending, and a failed attempt shows its response code in red while it is being retried.

Client JSON
Sent for:
client.createclient.update
Dates and times are in your business's local time unless the description says otherwise.
Field | Type | Description |
|---|---|---|
Event | String | The event type Example: |
SiteUrl | String | The website the event came from Example: |
ClientId | Integer | Unique Client ID Example: |
WebhookEventId | Integer | Unique ID of this event. The same value is sent again on a retry or resend Example: |
FirstName | String | The client's first name Example: |
LastName | String | The client's last name Example: |
String | The client's primary Email address Example: | |
DateOfBirth | Date | The client's date of birth (yyyy-MM-dd). Omitted when not recorded Example: |
Gender | String | Male, Female, NonBinary or Other. Null when not recorded Example: |
Mobile | String | The client's mobile phone number. Omitted when blank Example: |
HomePhone | String | The client's home phone number. Null when blank Example: |
WorkPhone | String | The client's work phone number. Null when blank Example: |
Active | Boolean | Whether the client record is active Example: |
AddressLine1 | String | Address line 1. Null when blank Example: |
AddressLine2 | String | Address line 2. Null when blank Example: |
AddressSuburb | String | Suburb or city. Null when blank Example: |
AddressState | String | State or province. Null when blank Example: |
AddressPostCode | String | Post code or ZIP. Null when blank Example: |
CreatedDate | DateTime | When the client record was created (yyyy-MM-ddTHH:mm:ss, server time) Example: |
CreatedBy | String | Client when the client signed up online, Staff when a staff member added them, Import when imported Example: |
LastModDate | DateTime | When the client record was last changed (yyyy-MM-ddTHH:mm:ss, server time, like CreatedDate) Example: |
LastModBy | String | Staff when a staff member made the last change, otherwise Client Example: |
ReferredByTypeDescr | String | How the client said they heard about you. Omitted when blank Example: |
MembershipNumber | String | The client's membership number. Only sent when your site shows the Membership Number field, and omitted when blank Example: |
IsAuthenticated | Boolean | Whether the client has verified their login Example: |
NewsletterSubscriber | Boolean | Marketing consent: the client receives newsletters, bulk SMS and marketing sequences Example: |
UnsubscribeDate | DateTime | When the client unsubscribed from marketing. Null while subscribed Example: |
ReceiveReminders | Boolean | Communication consent: the client receives reminders about their bookings Example: |
TermsAccepted | Boolean | Whether the client has accepted your terms, which they do when they first log in Example: |
TermsAcceptedDate | DateTime | When the client first logged in and accepted your terms. Null until they have logged in Example: |
TermsAcceptedIp | String | The IP address the terms were accepted from. Null until they have logged in Example: |
TermsAcceptedCountry | String | The country the terms were accepted from. Null until they have logged in Example: |
Memberships | Array | The memberships the client currently holds. Empty when none Example: |
Attribution | Object | The marketing source recorded when the client signed up. Omitted when there is none Example: |
Client Membership JSON
Sent for:
client.membership
Field | Type | Description |
|---|---|---|
Event | String | The event type Example: |
WebhookEventId | Integer | Unique ID of this event. The same value is sent again on a retry or resend Example: |
ClientId | String | Unique Client ID, sent as a string Example: |
MembershipId | String | Unique Membership ID, sent as a string Example: |
Membership | String | The membership's name Example: |
Active | Boolean | true when the client was added to the membership, false when removed Example: |
Booking JSON
Sent for:
booking.createbooking.updatebooking.cancelbooking.passbooking.failbooking.postbooking
Dates and times are in the location's local time unless the description says otherwise.
Field | Type | Description |
|---|---|---|
EventCode | String | The event type Example: |
SiteUrl | String | The website the event came from Example: |
BookingId | Integer | Unique booking ID Example: |
BookingDate | String | Date of the booking (yyyy-MM-dd) Example: |
BookingTime | String | Time of the booking (HH:mm, 24-hour) Example: |
BookingDateTimeUtc | DateTime | The booking's start in UTC Example: |
LocationName | String | Name of the location Example: |
StaffId | Integer | Unique ID of the assigned staff member Example: |
StaffFirstName | String | First name of the assigned staff member Example: |
StaffLastName | String | Last name of the assigned staff member Example: |
StaffEmail | String | Email address of the assigned staff member Example: |
StaffAccreditation | String | The staff member's accreditation (National Provider ID# on US sites). Blank when not recorded Example: |
ClientId | Integer | Unique Client ID Example: |
ClientName | String | Client's full name Example: |
ClientFirstName | String | Client's first name Example: |
ClientLastName | String | Client's last name Example: |
ClientEmail | String | Client's primary Email address Example: |
ClientMobile | String | Client's mobile phone number Example: |
ClientServiceCount | Integer | How many bookings this client has had for the services on this booking, counting this one Example: |
BookingStatus | String | Booked, Paid, Cancelled or No Show Example: |
ServiceNames | String | Services associated with the booking, comma separated Example: |
WebhookEventId | Integer | Unique ID of this event. The same value is sent again on a retry or resend Example: |
DurationMinutes | Integer | The booked length in minutes across all services on the booking Example: |
SuburbName | String | Pick-up suburb. Blank when not set Example: |
PostCode | String | Pick-up post code. Blank when not set Example: |
DropOffSuburbName | String | Drop-off suburb. Blank when not set Example: |
DropOffPostCode | String | Drop-off post code. Blank when not set Example: |
BookingSource | String | Client when booked online by the client, Staff when made by a staff member, Recurring when generated by a repeating booking, Import when imported Example: |
CreatedDate | DateTime | When the booking was made (yyyy-MM-ddTHH:mm:ss, server time) Example: |
PaidDate | DateTime | When the booking was paid. Null while unpaid Example: |
RetailPrice | Decimal | Full retail price of the booking's services Example: |
SalePrice | Decimal | Price charged after any discount Example: |
AmountPaid | Decimal | Total paid so far, including voucher and account balance redemptions Example: |
VoucherAmount | Decimal | The part of AmountPaid that was paid by voucher or package Example: |
PaymentStatus | String | Unpaid, Deposit (a deposit or part payment is held against an outstanding balance), Paid, or Refunded (a cancellation credited the payment back) Example: |
InvoiceNbr | Integer | The booking's invoice number. Null when none has been issued Example: |
InvoiceUrl | String | Admin link to the booking, relative to https://SiteUrl Example: |
PaymentMethod | String | Cash, Card, Eft, Other, Voucher, ClientAccount or OrganisationAccount; Mixed when more than one carries the payment. Null while unpaid Example: |
PaymentGateway | String | The online payment gateway used. Blank for a manual payment Example: |
GatewayTransactionId | String | The gateway's transaction reference. Blank for a manual payment Example: |
CreditCardSurchargeAmt | Decimal | Card surcharge charged on top of the price Example: |
CancelledDate | DateTime | When the booking was cancelled. Null while the booking stands Example: |
CancelledBy | String | Client or Staff. Blank while the booking stands Example: |
CancelledReason | String | The cancellation reason code. Blank while the booking stands Example: |
CancelledReasonText | String | Free-text cancellation note. Blank when none Example: |
Attribution | Object | The marketing source recorded when the booking was made. Omitted when there is none Example: |
Payment JSON
Sent for:
payment.receivedpayment.refundedpayment.cancelled
On payment.refunded every amount is negative. On payment.cancelled the amounts are those that were cancelled.
Amount is money actually received. A voucher, package or account balance redemption spends money that was received when the voucher, package or top-up was sold, so it is reported in its own field and left out of Amount. A payment made wholly by voucher or account balance has an Amount of 0.
A payment on a booking carries the booking's totals to date, so a booking paid in several part payments reports the running total each time.
Field | Type | Description |
|---|---|---|
Event | String | The event type Example: |
SiteUrl | String | The website the event came from Example: |
WebhookEventId | Integer | Unique ID of this event. The same value is sent again on a retry or resend Example: |
CurrencyCode | String | ISO 4217 code every amount on the payment is in Example: |
SaleType | String | B for a booking, S for a product sale or refund, W for an online shop order Example: |
SaleId | Integer | The booking, sale or order ID, as SaleType says Example: |
InvoiceNbr | Integer | The invoice number. A deposit sale has its own invoice number, separate from its booking's Example: |
InvoiceUrl | String | Admin link to the booking, sale, refund or order, relative to https://SiteUrl Example: |
BookingId | Integer | The booking paid for, or the booking a deposit or cancellation fee sale was taken for. Null for any other sale Example: |
PaidDate | DateTime | When the payment was taken, in your business's local time Example: |
PaidDateUtc | DateTime | When the payment was taken, in UTC Example: |
Amount | Decimal | Money received: CashAmt + CreditAmt + EftAmt + HealthInsuranceAmt + MedicareAmt + DvaAmt + OtherAmt + CreditCardSurchargeAmt. Negative on a refund Example: |
CashAmt | Decimal | Paid in cash Example: |
CreditAmt | Decimal | Paid by card Example: |
EftAmt | Decimal | Paid by bank transfer (including POLi, PayTo and account-to-account online payments) Example: |
HealthInsuranceAmt | Decimal | Paid by health insurance claim Example: |
MedicareAmt | Decimal | Paid by Medicare claim Example: |
DvaAmt | Decimal | Paid by DVA claim Example: |
OtherAmt | Decimal | Paid by another method Example: |
VoucherAmt | Decimal | Redeemed from a voucher or package. Not included in Amount Example: |
ClientAccountAmt | Decimal | Redeemed from the client's account balance. Not included in Amount Example: |
OrganisationAccountAmt | Decimal | Redeemed from an organisation's account balance. Not included in Amount Example: |
CreditCardSurchargeAmt | Decimal | Card surcharge charged on top of the price Example: |
VatAmount | Decimal | Tax (GST, VAT or sales tax) included in the payment Example: |
Tips | Decimal | Tip included in the payment Example: |
PaymentGateway | String | The online payment gateway used. Blank for a manual payment Example: |
GatewayTransactionId | String | The gateway's transaction reference. Blank for a manual payment Example: |
PaymentMethod | String | Cash, Card, Eft, Other, Voucher, ClientAccount or OrganisationAccount; Mixed when more than one carries the payment Example: |
ClientId | Integer | Unique Client ID of the client the booking or sale belongs to Example: |
ClientFirstName | String | Client's first name Example: |
ClientLastName | String | Client's last name Example: |
ClientEmail | String | Client's primary Email address Example: |
ClientMobile | String | Client's mobile phone number Example: |
PaidByClientId | Integer | The client who made the payment: the client themselves, or someone paying on their behalf such as a parent. Null when not recorded Example: |
PaidBy | String | Full name of the client who made the payment. Null when not recorded Example: |
CreatedDate | DateTime | When this payment, refund or cancellation was recorded Example: |
CreatedBy | String | Staff when a staff member recorded this payment, refund or cancellation, otherwise Client, including a payment the client made online and a saved card charged automatically Example: |
StaffId | Integer | The staff member on the booking or sale. Null when none Example: |
LocationName | String | Name of the location Example: |
Items | Array | The product lines on the sale. Empty for a booking with no products Example: |
Attribution | Object | The marketing source recorded for the booking or order. Omitted when there is none Example: |
Payment Item JSON
Each entry in Items. On a refund the unit price, line total and tax are negative. The item lines' tax adds up to the product tax only: the payment's VatAmount also carries the tax on a booking's services and on the card surcharge.
Field | Type | Description |
|---|---|---|
ProductId | Integer | Unique product ID Example: |
ProductName | String | The product's name Example: |
ProductTypeCd | String | A account adjustment, B bundle, F downloadable file, G physical product, I external course, L online course, M gift certificate, R membership, S general item or service, V voucher Example: |
CategoryName | String | The product's category. Null when it has none Example: |
Quantity | Decimal | Quantity sold Example: |
RetailUnitPrice | Decimal | The price of one Example: |
RetailPrice | Decimal | The line's price across its whole quantity Example: |
VatAmount | Decimal | The tax on the line across its whole quantity Example: |
Attribution JSON
The Attribution object on booking, payment and client events. It is only sent when BookingTimes recorded the marketing source of the visit that made the booking, order or sign-up, which requires the Traffic+ add-on. When there is no attribution the key is left out of the payload altogether.
Field | Type | Description |
|---|---|---|
Source | String | Where the visit came from. The campaign source (utm_source) when the link carried one, otherwise the search engine or ad network (google, bing, facebook), the referring site's domain, or newsletter or sequence for your own emails. Null for a direct visit. On client events this is the visit on which the client signed up Example: |
Medium | String | Campaign medium (utm_medium) Example: |
Campaign | String | Campaign name (utm_campaign) Example: |
CampaignId | String | Campaign ID (utm_id) Example: |
AdClickId | String | The ad click ID the visit arrived with (gclid, fbclid, gbraid, wbraid, ttclid and similar) Example: |
Keywords | String | Campaign keywords (utm_term) Example: |
AdContentDesc | String | Campaign content (utm_content) Example: |
UrlReferrer | String | The referring page Example: |
LandingPage | String | The first page of the visit Example: |
IsPaid | Boolean | The visit came from paid advertising Example: |
IsOrganic | Boolean | The visit came from an organic search result Example: |
IsReferral | Boolean | The visit came from a link on another website Example: |
IsDirect | Boolean | The visitor typed the address or used a bookmark Example: |
Contact and Support
For additional assistance or to report issues with Webhooks, please contact support@bookingtimes.com or visit our Support Page.