Cal.com
The Cal.com integration lets Helios agents manage your scheduling through the Cal.com API v2, and run agents automatically when bookings change, meetings start or end, recordings are ready, or routing forms are submitted.
What your agents can do
Helios agents use Cal.com API v2 to check availability and manage bookings. Access depends on your API key or OAuth scopes and the connected user's role. Helios attaches the credentials to requests and sets the cal-api-version header for endpoints that need it.
- Find open slots for an event type and book one for an attendee
- Reschedule or cancel bookings, and confirm or decline booking requests
- List upcoming and past bookings and read the attendees' answers
- Create and change event types, availability schedules, and out-of-office entries
- Manage teams, memberships, and routing forms, as a team or organization admin
The agent's API tool can only reach Cal.com's hosted API at api.cal.com.
Authentication
| Method | Type | Description |
|---|---|---|
| Cal.com API Key | API Key | A Cal.com API key |
| Your own Cal.com OAuth app | OAuth 2.0 | An OAuth client you register in Cal.com |
See Integration authentication for how credentials are stored and injected.
Cal.com API Key
Any Cal.com user can create an API key, including on the free plan.
- In Cal.com, open Settings → Developer → API keys and click Add.
- In Name this key, enter a name such as
Helios. - Under Expiration date, turn on Never expires, or pick 7 days, 30 days, 3 months, or 1 year. The default is 30 days.
- Click Create, then Copy. Cal.com doesn't show the key again.
- In Helios, choose Cal.com API Key and paste the key into Cal.com API Key.
- Optional: if the key's user is an organization admin, turn on Admin access to also register an organization webhook. See Triggers.
- Save.
Cal.com API keys have no scopes or permissions to pick. The key acts as the Cal.com user who created it and can call every endpoint that user can. Most team and organization endpoints also need the user to be a team admin or organization admin, so create the key as an admin for full access.
Cal.com doesn't let you change a key's expiry date later. If the key expires, create a new one, enter it through Manage, and save.
Your own Cal.com OAuth app
-
In Cal.com, create an OAuth client under Settings → Developer → OAuth.
-
Add this redirect URI to the client:
https://api.heliosapp.com/integrations/cal_com/oauth_callback -
Select every scope in the user scopes table below. If you plan to turn on Admin access, also select every team and organization scope.
-
In Helios, choose Your own Cal.com OAuth app and enter the client's Client ID and Client Secret.
-
Optional: turn on Admin access to also ask for the team and organization scopes. For an organization admin, it also registers an organization webhook. See Triggers.
-
Save, then approve access in Cal.com.
Helios always asks for these user scopes:
| Scope | What it's for |
|---|---|
EVENT_TYPE_READ, EVENT_TYPE_WRITE | Read event types and list them for the event type filter, and create, change, and delete them |
BOOKING_READ, BOOKING_WRITE | Read bookings, recordings, and transcripts, and reschedule, cancel, confirm, decline, and reassign bookings |
SCHEDULE_READ, SCHEDULE_WRITE | Read and change availability schedules and out-of-office entries |
APPS_READ, APPS_WRITE | Read connected calendars and busy times, and connect or disconnect calendars |
PROFILE_READ, PROFILE_WRITE | Read the connected user to check the connection, and edit the user's profile |
WEBHOOK_READ, WEBHOOK_WRITE | Find, create, update, and remove the trigger webhook |
VERIFIED_RESOURCES_READ, VERIFIED_RESOURCES_WRITE | Read and verify email addresses and phone numbers |
CREDITS_READ, CREDITS_WRITE | Read the credit balance and charge credits |
INSIGHTS_READ | Read the user's insights |
EVENT_READ, EVENT_WRITE | Read and manage Cal.com Events, the fixed-date RSVP pages |
Admin access adds these team scopes:
| Scope | What it's for |
|---|---|
TEAM_EVENT_TYPE_READ, TEAM_EVENT_TYPE_WRITE | Team event types |
TEAM_BOOKING_READ, TEAM_BOOKING_WRITE | Team bookings |
TEAM_SCHEDULE_READ, TEAM_SCHEDULE_WRITE | Team members' schedules and out-of-office entries |
TEAM_PROFILE_READ, TEAM_PROFILE_WRITE | Read, edit, and delete teams |
TEAM_MEMBERSHIP_READ, TEAM_MEMBERSHIP_WRITE | Team memberships |
TEAM_APPS_READ, TEAM_APPS_WRITE | Team connected apps |
TEAM_ROUTING_FORM_READ, TEAM_ROUTING_FORM_WRITE | Team routing forms and their responses |
TEAM_WORKFLOW_READ, TEAM_WORKFLOW_WRITE | Team workflows |
TEAM_VERIFIED_RESOURCES_READ, TEAM_VERIFIED_RESOURCES_WRITE | Team email addresses and phone numbers |
TEAM_INSIGHTS_READ | Team insights |
TEAM_EVENT_READ, TEAM_EVENT_WRITE | Team Events |
And these organization scopes:
| Scope | What it's for |
|---|---|
ORG_EVENT_TYPE_READ, ORG_EVENT_TYPE_WRITE | Event types across the organization |
ORG_BOOKING_READ, ORG_BOOKING_WRITE | Bookings across the organization |
ORG_SCHEDULE_READ, ORG_SCHEDULE_WRITE | Schedules and out-of-office entries across the organization |
ORG_PROFILE_READ, ORG_PROFILE_WRITE | Organization teams |
ORG_MEMBERSHIP_READ, ORG_MEMBERSHIP_WRITE | Organization memberships and users |
ORG_ROUTING_FORM_READ, ORG_ROUTING_FORM_WRITE | Organization routing forms and their responses |
ORG_WEBHOOK_READ, ORG_WEBHOOK_WRITE | Organization webhooks |
ORG_INSIGHTS_READ | Organization insights |
ORG_ATTRIBUTES_READ, ORG_ATTRIBUTES_WRITE | Organization attributes and their values for users |
Cal.com lets an OAuth token call only public endpoints, such as creating a booking or reading slots, and the endpoints whose reference page names a scope. Endpoints that name no scope, such as organization roles and delegation credentials, need an API key.
Cal.com reviews every new OAuth client. Until it approves yours, only the Cal.com account that registered the client can authorize it, so connect with that account. Changing the client's name, logo, website, or redirect URIs, or adding scopes, sends it back for review. Removing scopes doesn't.
Access tokens last 30 minutes, and Helios renews them with the refresh token Cal.com issues. If the connection's status shows Error, connect again. To change Admin access later, change it through Manage and save, then click Re-connect on the connection.
Triggers
Cal.com can start a Workflow when something happens to your bookings, meetings, or routing forms. Helios registers a webhook on your Cal.com user when you save the connection and subscribes it to every Cal.com webhook trigger that a user webhook receives, so there is nothing to set up in Cal.com. Saving again updates the same webhook. Deleting the connection removes it.
The user webhook covers the connected user's own event types, including managed event types assigned to the user. Bookings of round-robin and collective team event types don't reach it.
When the connection has Admin access and the connected user is an admin of a Cal.com organization, Helios also registers an organization webhook with every Cal.com webhook trigger. It covers the team event types of every team in the organization, including round-robin and collective event types and instant meetings, and the organization's delegation credential events. Turning Admin access off on an API key connection removes the organization webhook when you save. An OAuth connection can't remove it without Admin access, and it keeps sending events. An organization admin can delete it in Cal.com under Settings → Developer → Webhooks. Cal.com's API has no webhook for a single team, so bookings of team event types in a team outside an organization don't start runs.
An event can reach both webhooks, such as an attendee declining a booking in their calendar. Helios starts one run for it.
| Event | Description | Filters |
|---|---|---|
booking.created | A booking was created and confirmed | event type, attendee email (pattern) |
booking.requested | Someone requested a booking for an event type that needs your confirmation | event type, attendee email (pattern) |
booking.rescheduled | A booking was moved to a new time | event type, attendee email (pattern) |
booking.cancelled | A booking was cancelled | event type, attendee email (pattern) |
booking.rejected | A booking request was declined | event type, attendee email (pattern) |
booking.seat_accepted | A host confirmed another seat on a seated booking that needs confirmation | event type, attendee email (pattern) |
booking.seat_rejected | A host declined a seat on a seated booking that needs confirmation | event type, attendee email (pattern) |
booking.payment_initiated | An attendee started paying for a booking | event type, attendee email (pattern) |
booking.paid | An attendee paid for a booking | event type, attendee email (pattern) |
booking.updated | A booking's location changed, or an attendee was marked or unmarked as a no-show | change, event type, attendee email (pattern) |
booking.reassigned | A round-robin booking was moved to another host | event type, attendee email (pattern) |
booking.wrong_assignment_reported | A team member reported that a routed booking went to the wrong person | event type, attendee email (pattern) |
meeting.started | A booked meeting reached its start time | event type, attendee email (pattern) |
meeting.ended | A booked meeting reached its end time | event type, attendee email (pattern) |
meeting.host_no_show_detected | No host joined a Cal Video meeting within 5 minutes of its start | event type, attendee email (pattern) |
meeting.guest_no_show_detected | No guest joined a Cal Video meeting within 5 minutes of its start | event type, attendee email (pattern) |
recording.completed | A Cal Video recording is ready to download | attendee email (pattern) |
recording.transcribed | A transcript of a Cal Video recording is ready | attendee email (pattern) |
instant_meeting.created | Someone requested an instant meeting with a team | event type, attendee email (pattern) |
instant_meeting.accepted | A host accepted an instant meeting | event type, attendee email (pattern) |
calendar_entry.rejected | An attendee declined a booking in Google Calendar or Microsoft 365 | attendee email (pattern) |
routing_form.submitted | Someone submitted a routing form | form name (pattern) |
routing_form.submitted_without_booking | Someone submitted a routing form and did not book within 15 minutes | form name (pattern) |
routing_form.fallback_hit | A routing form submission matched no rule and went to the fallback route | form name (pattern) |
out_of_office.created | An out-of-office entry was added | none |
delegation_credential.failed | A delegation credential could not reach a member's calendar | none |
delegation_credential.secret_rotated | A new secret for a Microsoft 365 delegation credential became active | none |
delegation_credential.secret_rotation_failed | Automatic secret rotation for a Microsoft 365 delegation credential kept failing for 48 hours | none |
delegation_credential.rotation_required | The secret of a Microsoft 365 delegation credential expires soon and needs a manual rotation | none |
Without an organization webhook, the trigger picker shows instant_meeting.created, instant_meeting.accepted, and the four delegation_credential events as unavailable. Cal.com offers instant meetings only on team event types in an organization, and sends the delegation credential events only to organization webhooks. The reason in the picker says what's missing: an organization, Admin access, or the organization admin role.
All filters are optional. Patterns use * as a wildcard, and case doesn't matter.
- Event type matches events of the event types you pick from the menu. With Admin access, the menu also lists the organization's team event types. Cal.com doesn't send the event type with a no-show change, so a
booking.updatedtrigger with an event type filter skips no-show changes. - Attendee email matches when an attendee's email matches the pattern, such as
*@acme.com. Forinstant_meeting.createdit matches the booker's email, forbooking.wrong_assignment_reportedthe guest's email, and forcalendar_entry.rejectedthe email of the attendee who declined. - Change matches
booking.updatedevents of the changes you pick: Location or No-show. - Form name matches the routing form's name, such as
Sales*.
For an event type that needs confirmation, Cal.com sends booking.requested when someone books, and booking.created once you confirm. On a seated event type that needs confirmation, the first confirmed seat sends booking.created. Each later seat sends booking.seat_accepted when a host confirms it, and booking.seat_rejected when a host declines it. Cal.com sends meeting.started and meeting.ended at the booking's scheduled start and end time, whether or not the meeting took place. It schedules them when the booking is made or confirmed, so they fire only for bookings made after you connected Cal.com. The no-show, recording, and transcript events need meetings held on Cal Video. Cal.com sends out_of_office.created for out-of-office entries added in the Cal.com app. Entries created through Cal.com's API don't send it.
Deliveries are verified with the HMAC-SHA256 X-Cal-Signature-256 header, and deliveries more than a day old are rejected. Cal.com sends no delivery ID, so Helios identifies repeat deliveries by their event type, content, and timestamp for one day.
An agent that changes a booking can start another run. Cancelling a booking sends booking.cancelled, rescheduling sends booking.rescheduled, declining a request sends booking.rejected, and confirming a request sends booking.created. Confirming or declining a seat sends booking.seat_accepted or booking.seat_rejected. Changing a booking's location or marking a no-show sends booking.updated, and reassigning a booking sends booking.reassigned. A booking the agent makes for the connected user sends booking.created too. Say in the prompt which events to leave alone. See Guarding against events you don't want.
Check that it works
- The connection: after you save, the connection's status shows Connected. Error means Cal.com rejected the key or token. See Common errors.
- The webhook: in Cal.com, open Settings → Developer → Webhooks. A webhook whose URL contains
/integrations/cal_com/webhooks/should be listed. - The organization webhook: with Admin access as an organization admin, the trigger picker in Helios shows no Cal.com events as unavailable.
- A trigger:
- Add
booking.createdto a workflow with no filters. - Book one of your own event types from its public booking page.
- Check that a run starts. Then open the connection in Helios and click Webhook events to see the event.
- Add
Common errors
| What you see | Cause | Fix |
|---|---|---|
| The connection's status shows Error | The API key expired or was deleted, or the OAuth app's access was removed | Create a new key and enter it through Manage, or connect the OAuth app again |
Cal.com shows Requested scope exceeds the client's registered scopes | The OAuth client is missing a scope that Helios asks for | Select every user scope on the client, and the team and organization scopes too if Admin access is on. Then connect again |
| Cal.com won't let you approve the OAuth app | Cal.com hasn't approved the client, and you're signed in with a different account | Connect with the account that registered the client, or wait for Cal.com's approval |
Access token not found. Please complete the OAuth flow first. | The OAuth approval wasn't finished | Open the connection and connect again |
| An agent gets an error from a team or organization endpoint | The connected user isn't a team admin or organization admin, or Admin access is off on an OAuth connection | Connect as an admin, and turn on Admin access for an OAuth app |
| An agent gets an error from an endpoint that names no OAuth scope | Cal.com doesn't allow OAuth tokens on that endpoint | Use a Cal.com API Key connection |
| No run starts after an event | The booking is for a team event type and the connection has no organization webhook, the team isn't in an organization, someone else is the organizer, the OAuth app lacks the webhook scopes, or the filters don't match | Fix the cause, then save the connection again. Test with no filters |
Limits
- Rate limits: Cal.com allows 120 API requests a minute by default. Cal.com support can raise it. See Cal.com's API introduction.
- Plans: the API key, the API, and webhooks work on Cal.com's free plan. Routing forms need Cal.com's Teams plan or an organization. Instant meetings and delegation credentials need a Cal.com organization.
Last updated on