Webhook Signatures
Gain confidence in the authenticity of your webhooks when you use a webhook signing key, a unique secret key shared between your application and Calendly, to verify the events sent to your endpoints. The webhook signing key will produce the Calendly-Webhook-Signature, which you can use to compare against an expected webhook signature, to verify events from Calendly.
Webhook signing keys for personal access tokens
When you authenticate with personal access tokens, you have the option to set a webhook signing key when you create the webhook subscription. You can use the same signing key for all webhooks or use a unique signing key for each webhook. Neither are required, but greatly enhance the security of the data you receive at your endpoint.
Using the same signing key for all webhooks lets you quickly verify the source of the events sent to your endpoints, but using a unique signing key for every webhook enhances the security of each one when working with multiple integrations.
Webhook signing keys for OAuth 2.0
When you create an OAuth 2.0 app, a webhook signing key will automatically be generated for all webhooks related to your application. The webhook signing key is a unique secret key shared between your application and Calendly.
Retrieve your webhook signing key
If you didn’t receive a webhook signing key for an OAuth 2.0 application you’ve previously created or need to retrieve one because you lost it, then contact support+developer@calendly.com.
Verifying Signatures
When Calendly sends your app a webhook, it will include the Calendly-Webhook-Signature header in the following format:
Compare the Calendly-Webhook-Signature, prefixed by v1=, to the expected signature. If they match, then you can trust that the event payload was issued by Calendly and has not been tampered with.
Prevent Replay Attacks
So you can mitigate replay attacks, Calendly utilizes a timestamp in the Calendly-Webhook-Signature header, prefixed by t=, that you can use to reject the webhook if the timestamp in the signature header is too old based on the tolerance zone.
In the example below, the tolerance zone is set to 3 minutes, so any webhooks received that are older than 3 minutes will be rejected. See the examples of webhook signature verification code in different languages below.