Please note that the webhooks can be associated with user as well as individual event types, including team event types.
Creating a webhook subscription
To create a new webhook subscription, visit/settings/developer/webhooks and proceed to enter the following details:
- Subscriber URL: The listener URL where the payload will be sent to, when an event trigger is triggered.
-
Event triggers: You can decide which triggers specifically to listen to. Currently, we offer listening to
Booking Cancelled,Booking Created,Booking Rescheduled,Booking Rejected,Booking Requested,Booking Payment Initiated,Booking Paid,Meeting Started,Recording Ready,Form Submitted,Meeting EndedandInstant Meeting Created. - Secret: You can provide a secret key with this webhook and then verify it on the subscriber URL when receiving a payload to confirm if the payload is authentic or adulterated. You can leave it blank, if you don’t wish to secure the webhook with a secret key.
- Custom Payload: You have the option to customize the payload you receive when a subscribed event is triggered.
An example webhook payload
Verifying the authenticity of the received payload
- Simply add a new secret key to your webhook and save.
- Wait for the webhook to be triggered (event created, cancelled, rescheduled, or meeting ended)
-
Use the secret key to create an
hmac, and update that with the webhook payload received to create an SHA256. -
Compare the hash received in the header of the webhook
(X-Cal-Signature-256)with the one created using the secret key and the body of the payload. If they don’t match, the received payload was adulterated and cannot be trusted.
Adding a custom payload template
Customizable webhooks are a great way reduce the development effort and in many cases remove the need for a developer to build an additional integration service. An example of a custom payload template is provided here:{{type}} represents the event type slug and {{title}} represents the title of the event type. Note that the variables should be added with a double parenthesis as shown above. Here’s a breakdown of the payload that you would receive via an incoming webhook, with an exhaustive list of all the supported variables provided below:
Webhook variable list
| Variable | Type | Description |
|---|---|---|
| triggerEvent | String | The name of the trigger event [BOOKING_CREATED, BOOKING_RESCHEDULED, BOOKING_CANCELLED, MEETING_ENDED, BOOKING_REJECTED, BOOKING_REQUESTED, BOOKING_PAYMENT_INITIATED, BOOKING_PAID, MEETING_STARTED, RECORDING_READY, FORM_SUBMITTED] |
| createdAt | Datetime | The Time of the webhook |
| type | String | The event type slug |
| title | String | The event type name |
| startTime | Datetime | The event’s start time |
| endTime | Datetime | The event’s end time |
| description | String | The event’s description as described in the event type settings |
| location | String | Location of the event |
| organizer | Person | The organizer of the event |
| attendees | Person[] | The event booker & any guests |
| uid | String | The UID of the booking |
| rescheduleUid | String | The UID for rescheduling |
| cancellationReason | String | Reason for cancellation |
| rejectionReason | String | Reason for rejection |
| team.name | String | Name of the team booked |
| team.members | String[] | Members of the team booked |
| metadata | JSON | Contains a metadata of the booking, including the meeting URL (videoCallUrl) in case of Google Meet and Cal Video |
Person Structure
| Variable | Type | Description |
|---|---|---|
| name | String | Name of the individual |
| Email of the individual | ||
| timezone | String | Timezone of the individual (“America/New_York”, “Asia/Kolkata”, etc.) |
| language?.locale | String | Locale of the individual (“en”, “fr”, etc.) |

