Calendly Webhook Explained

Calendly offers 2 ways to integrate with your external applications.

Jun 17, 2024
Calendly offers 2 ways to integrate with your external applications.

Native Integration

Native integration - Calendly offers one-click-connect options to ~130 apps, from external calendars to payment gateways.
Common apps include Zoom, Salesforce, Hubspot.
 
The usecases include:
  • After a meeting is scheduled, Calendly will automatically include the Zoom meeting details in the confirmation notifications and calendar event that are sent to your invitees.
  • When using Calendly to schedule meetings with potential clients, Salesforce will automatically generate a new lead, contact, or opportunity.
  • When meetings are scheduled through Calendly, HubSpot will automatically create new leads or contacts and activities.
 

Webhook connection

Webhook integration - This is for usecases other than those 130 apps or other actions you want your external apps to perform.
Specifically, you can subscribe to:
  • Invitee Created Events to receive notifications when a new Calendly event is scheduled Invitee
  • Canceled Events to receive notifications when a Calendly event is canceled Routing Form
  • Submissions to receive notifications when a user submits a Calendly routing form (whether an event is scheduled or not)
 

Lets say I am an organization user instead of a single user. Here are the webhook connection procedures:

1. Find your OAuth or personal access token on the Calendly UI

Homepage → Integration & Apps → API & Webhooks → Generate New Token

2. Find the organization or user URI

  • Make a GET request to /users/me on Postman
  • Replace the {access_token} value with your OAuth or personal access token.
curl --request GET \ --url https://api.calendly.com/users/me \ --header 'Authorization: Bearer {access_token}' \ --header 'Content-Type: application/json'
 
You can find
  • the user URI is given as the value of uri
  • the organization URI is given as the value of current_organization
{ "resource": { "uri": "https://api.calendly.com/users/AAAAAAAAAAAAAAAA", "name": "John Doe", "slug": "acmesales", "email": "user@example.com", "scheduling_url": "https://calendly.com/acmesales", "timezone": "America/New York", "avatar_url": "https://01234567890.cloudfront.net/uploads/user/avatar/0123456/a1b2c3d4.png", "created_at": "2019-01-02T03:04:05.678123Z", "updated_at": "2019-08-07T06:05:04.321123Z", "current_organization": "https://api.calendly.com/organizations/AAAAAAAAAAAAAAAA", "resource_type": "User" } }

3. Create a webhook subscription

Make a POST request to the /webhook_subscriptions endpoint.
  • Add your personal access token to authenticate the request.
  • Set your server endpoint in the url value. This is the webhook url you generated from e.g. make.com / zapier.
  • Set invitee.created, or invitee.canceled, or routing_form_submission.created (or all 3) for the events value
  • Choose the user or organization value in scope to isolate scheduled events to yourself or the organization.
curl --request POST \ --url https://api.calendly.com/webhook_subscriptions \ --header 'Authorization: ' \ --header 'Content-Type: application/json' \ --data '{ "url": "https://blah.foo/bar", "events": [ "invitee.created", "invitee.canceled", "invitee_no_show.created", "invitee_no_show.deleted" ], "organization": "https://api.calendly.com/organizations/AAAAAAAAAAAAAAAA", "user": "https://api.calendly.com/users/BBBBBBBBBBBBBBBB", "scope": "user", "signing_key": "5mEzn9C-I28UtwOjZJtFoob0sAAFZ95GbZkqj4y3i0I" }'
Example Request:
curl --request POST --url https://api.calendly.com/webhook_subscriptions --header 'Content-Type: application/json' --header 'authorization: Bearer <your personal access token>' --data '{ "url":"http://yourserverendpoint.com", "events":["invitee.created", "invitee.canceled"], "organization":"https://api.calendly.com/organizations/AAAAAAAAAAAAAAAA", "scope":"organization"}'
You are now created webhooks to pass data from Calendly when an invitee created/cancelled events.

4. Once you've created a webhook

When your visitors created/updated an event, your system will get a payload like this.
//Example: Invitee { "created_at": "2020-11-23T17:51:19.000000Z", "created_by": "https://api.calendly.com/users/AAAAAAAAAAAAAAAA", "event": "invitee.created", "payload": { "cancel_url": "https://calendly.com/cancellations/AAAAAAAAAAAAAAAA", "created_at": "2020-11-23T17:51:18.327602Z", "email": "test@example.com", "event": "https://api.calendly.com/scheduled_events/AAAAAAAAAAAAAAAA", "name": "John Doe", "new_invitee": null, "old_invitee": null, "questions_and_answers": [], "reschedule_url": "https://calendly.com/reschedulings/AAAAAAAAAAAAAAAA", "rescheduled": false, "status": "active", "text_reminder_number": null, "timezone": "America/New_York", "tracking": { "utm_campaign": null, "utm_source": null, "utm_medium": null, "utm_content": null, "utm_term": null, "salesforce_uuid": null }, "updated_at": "2020-11-23T17:51:18.341657Z", "uri": "https://api.calendly.com/scheduled_events/AAAAAAAAAAAAAAAA/invitees/AAAAAAAAAAAAAAAA", "scheduled_event": { "uri": "https://api.calendly.com/scheduled_events/GBGBDCAADAEDCRZ2", "name": "15 Minute Meeting", "meeting_notes_plain": "Internal meeting notes", "meeting_notes_html": "<p>Internal meeting notes</p>", "status": "active", "start_time": "2019-08-24T14:15:22.123456Z", "end_time": "2019-08-24T14:15:22.123456Z", "event_type": "https://api.calendly.com/event_types/GBGBDCAADAEDCRZ2", "location": { "type": "physical", "location": "string", "additional_info": "string" }, "invitees_counter": { "total": 0, "active": 0, "limit": 0 }, "created_at": "2019-01-02T03:04:05.678123Z", "updated_at": "2019-01-02T03:04:05.678123Z", "event_memberships": [ { "user": "https://api.calendly.com/users/GBGBDCAADAEDCRZ2", "user_email": "user@example.com", "user_name": "John Smith" } ], "event_guests": [ { "email": "user@example.com", "created_at": "2019-08-24T14:15:22.123456Z", "updated_at": "2019-08-24T14:15:22.123456Z" } ] } } }

5. (Optional) Passing custom event data fields

If you need data about an invitee, such as their name, email, and responses to custom questions on an event booking page, use the URI property in the webhook payload. Make a GET request to the /scheduled_events/{event_uuid}/invitees/{invitee_uuid} endpoint.

Notes:
  • For all the API requests here, you can make them through Postman.
  • The automation feature in Calendly is only for sending text messages or emails, not for external integrations.
 
 

References