A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Cal.com API is how an app or AI agent works with a Cal.com account: reading available times, booking a meeting, rescheduling or cancelling one, managing event types, and setting availability schedules. Access is granted through an API key or an OAuth access token, where a key is account-level with full access and an OAuth token is limited to the scopes it was granted. A booking, reschedule, or cancellation can be pushed to a registered webhook URL as a named trigger.
How an app or AI agent connects to Cal.com determines what it can reach. There is a route for making calls, a route for receiving events, and a hosted server that exposes Cal.com tools to agents, and each is governed by the key or token behind it.
The v2 REST API answers at https://api.cal.com/v2, takes and returns JSON, and wraps every response in an envelope with a status of success or error. Each request must send a cal-api-version header, a dated string the method documents, and authenticate with an API key or OAuth token over HTTPS.
Cal.com POSTs a JSON payload to a registered URL when a chosen trigger fires, like BOOKING_CREATED or BOOKING_RESCHEDULED. A webhook can carry a secret so the receiver can verify the delivery came from Cal.com, and subscriptions are managed through the webhooks endpoints.
Cal.com's first-party MCP server lets an AI agent call Cal.com through the Model Context Protocol. The hosted server at https://mcp.cal.com/mcp uses Streamable HTTP transport and OAuth 2.1, so a client handles authorization automatically, and it exposes 34 tools across user profile, event types, bookings, schedules, availability, conferencing, routing forms, and organizations. A local instance can run with an API key. The source is at github.com/calcom/cal-mcp.
Platform customers create managed users and call on their behalf using the x-cal-client-id and x-cal-secret-key headers, with short-lived access tokens minted per managed user. Cal.com stopped offering new Platform plan signups on 15 December 2025.
An API key authenticates as the account that created it and is sent as a Bearer token. A key is account-level: it carries no per-endpoint scopes, so it can call everything the account can. Test keys use the cal_ prefix and live keys use cal_live_.
An OAuth client uses the authorization-code flow, with PKCE for public clients, and is granted a scoped access token that expires after 30 minutes, refreshed with a refresh token. Scopes restrict the token to specific resources, like BOOKING_READ or EVENT_TYPE_WRITE. A new OAuth client starts pending until Cal.com approves it.
A platform OAuth client authenticates with the x-cal-client-id and x-cal-secret-key headers and mints short-lived access tokens for each managed user it creates. New Platform plan signups closed on 15 December 2025.
The Cal.com API is split into areas an agent can act on, like bookings, event types, available slots, schedules, calendars, and teams. Each area has its own methods, and a write to bookings or calendars changes a real meeting or someone's availability.
Create, read, and list bookings, and cancel, reschedule, confirm, decline, or mark a no-show.
List, read, create, update, and delete event types, the templates people book against.
Read available time slots and reserve, update, or release a held slot.
List, read, create, update, and delete availability schedules.
List connected calendars, read busy times, and start or end a calendar connection.
Read and update the authenticated user's profile.
List, read, create, update, and delete teams.
List, read, create, update, and delete webhook subscriptions.
Manage users within an organization, used by platform and enterprise customers.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
BookingsCreate, read, and list bookings, and cancel, reschedule, confirm, decline, or mark a no-show.8 | ||||||
| POST | /v2/bookings | Create a regular, recurring, or instant booking against an event type. | write | BOOKING_WRITE | Current | |
Sends cal-api-version 2026-02-25. Authentication is optional for public booking pages; an OAuth token needs BOOKING_WRITE. A plain API key (cal_) is account-level and carries no per-endpoint scope. Acts onbooking Permission (capability) BOOKING_WRITEVersionAvailable since the API’s base version Webhook event BOOKING_CREATEDRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/bookings/{uid} | Get a single booking by its uid. | read | BOOKING_READ | Current | |
An OAuth token needs BOOKING_READ. A plain API key is account-level full access. Acts onbooking Permission (capability) BOOKING_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/bookings | Get all bookings, filterable by status, attendee, event type, and date range. | read | BOOKING_READ | Current | |
An OAuth token needs BOOKING_READ. Returning another managed user's bookings needs that user's access token. Acts onbooking Permission (capability) BOOKING_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/bookings/{uid}/cancel | Cancel a booking, optionally with a cancellation reason. | write | BOOKING_WRITE | Current | |
An OAuth token needs BOOKING_WRITE. Cancelling fires the BOOKING_CANCELLED webhook. Acts onbooking Permission (capability) BOOKING_WRITEVersionAvailable since the API’s base version Webhook event BOOKING_CANCELLEDRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/bookings/{uid}/reschedule | Reschedule a booking to a new start time, creating a new booking linked to the old one. | write | BOOKING_WRITE | Current | |
An OAuth token needs BOOKING_WRITE. Rescheduling fires the BOOKING_RESCHEDULED webhook. Acts onbooking Permission (capability) BOOKING_WRITEVersionAvailable since the API’s base version Webhook event BOOKING_RESCHEDULEDRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/bookings/{uid}/confirm | Confirm a booking that requires confirmation, accepting the request. | write | BOOKING_WRITE | Current | |
An OAuth token needs BOOKING_WRITE. Only applies to event types set to require confirmation. Acts onbooking Permission (capability) BOOKING_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/bookings/{uid}/decline | Decline a booking that requires confirmation, rejecting the request. | write | BOOKING_WRITE | Current | |
An OAuth token needs BOOKING_WRITE. Declining fires the BOOKING_REJECTED webhook. Acts onbooking Permission (capability) BOOKING_WRITEVersionAvailable since the API’s base version Webhook event BOOKING_REJECTEDRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/bookings/{uid}/mark-absent | Mark a host or attendee as absent (a no-show) for a booking. | write | BOOKING_WRITE | Current | |
An OAuth token needs BOOKING_WRITE. Marking absence fires the BOOKING_NO_SHOW_UPDATED webhook. Acts onbooking Permission (capability) BOOKING_WRITEVersionAvailable since the API’s base version Webhook event BOOKING_NO_SHOW_UPDATEDRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Event typesList, read, create, update, and delete event types, the templates people book against.5 | ||||||
| GET | /v2/event-types | Get all event types for a user, the templates people book against. | read | EVENT_TYPE_READ | Current | |
Sends cal-api-version 2024-06-14. An OAuth token needs EVENT_TYPE_READ. Acts onevent type Permission (capability) EVENT_TYPE_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/event-types/{eventTypeId} | Get a single event type by id. | read | EVENT_TYPE_READ | Current | |
An OAuth token needs EVENT_TYPE_READ. Acts onevent type Permission (capability) EVENT_TYPE_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/event-types | Create an event type with length, location, and booking rules. | write | EVENT_TYPE_WRITE | Current | |
An OAuth token needs EVENT_TYPE_WRITE. Acts onevent type Permission (capability) EVENT_TYPE_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v2/event-types/{eventTypeId} | Update an event type's settings. | write | EVENT_TYPE_WRITE | Current | |
An OAuth token needs EVENT_TYPE_WRITE. Acts onevent type Permission (capability) EVENT_TYPE_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/event-types/{eventTypeId} | Delete an event type. | write | EVENT_TYPE_WRITE | Current | |
An OAuth token needs EVENT_TYPE_WRITE. Removes the booking page tied to it. Acts onevent type Permission (capability) EVENT_TYPE_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SlotsRead available time slots and reserve, update, or release a held slot.4 | ||||||
| GET | /v2/slots | Get available time slots for an event type over a date range. | read | — | Current | |
Sends cal-api-version 2024-09-04. Public for a booking page, so no scope is required; queryable by event type id, or by event type slug plus username. Acts onslot Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/slots/reservations | Reserve a slot so it is held while a booking is completed, returning a reservation uid. | write | — | Current | |
Sends cal-api-version 2024-09-04. Holds the slot for a limited window; the returned reservationUid is used to update or release it. Acts onslot Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v2/slots/reservations/{uid} | Update a reserved slot, such as extending the hold. | write | — | Current | |
Sends cal-api-version 2024-09-04. Identified by the reservationUid from reserve a slot. Acts onslot Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/slots/reservations/{uid} | Release a reserved slot so it becomes bookable again. | write | — | Current | |
Sends cal-api-version 2024-09-04. Frees a hold made by reserve a slot. Acts onslot Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Schedules & availabilityList, read, create, update, and delete availability schedules.5 | ||||||
| GET | /v2/schedules | Get all availability schedules for the authenticated user. | read | SCHEDULE_READ | Current | |
Sends cal-api-version 2024-06-11. An OAuth token needs SCHEDULE_READ. Acts onschedule Permission (capability) SCHEDULE_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/schedules/{scheduleId} | Get a single availability schedule by id. | read | SCHEDULE_READ | Current | |
An OAuth token needs SCHEDULE_READ. Acts onschedule Permission (capability) SCHEDULE_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/schedules | Create an availability schedule with working hours and overrides. | write | SCHEDULE_WRITE | Current | |
An OAuth token needs SCHEDULE_WRITE. Acts onschedule Permission (capability) SCHEDULE_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v2/schedules/{scheduleId} | Update an availability schedule's working hours or overrides. | write | SCHEDULE_WRITE | Current | |
An OAuth token needs SCHEDULE_WRITE. Changing availability affects which slots are offered. Acts onschedule Permission (capability) SCHEDULE_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/schedules/{scheduleId} | Delete an availability schedule. | write | SCHEDULE_WRITE | Current | |
An OAuth token needs SCHEDULE_WRITE. Acts onschedule Permission (capability) SCHEDULE_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CalendarsList connected calendars, read busy times, and start or end a calendar connection.4 | ||||||
| GET | /v2/calendars | List the calendars connected to the authenticated user. | read | APPS_READ | Current | |
An OAuth token needs APPS_READ, the scope that covers calendar and app integrations. Acts oncalendar Permission (capability) APPS_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/calendars/busy-times | Get busy times across the user's connected calendars. | read | APPS_READ | Current | |
An OAuth token needs APPS_READ. Returns when the user is unavailable, used to compute open slots. Acts oncalendar Permission (capability) APPS_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/calendars/{calendar}/connect | Get the OAuth connect URL to start connecting a Google or Outlook calendar. | read | APPS_READ | Current | |
An OAuth token needs APPS_READ. Returns a URL the user visits to grant calendar access. Acts oncalendar Permission (capability) APPS_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/calendars/{calendar}/disconnect | Disconnect a connected calendar from the user. | write | APPS_WRITE | Current | |
An OAuth token needs APPS_WRITE. Removes the calendar's availability and event syncing. Acts oncalendar Permission (capability) APPS_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Me (profile)Read and update the authenticated user's profile.2 | ||||||
| GET | /v2/me | Get the authenticated user's profile. | read | PROFILE_READ | Current | |
An OAuth token needs PROFILE_READ. A plain API key resolves to the key owner's account. Acts onprofile Permission (capability) PROFILE_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v2/me | Update the authenticated user's profile, such as name, time zone, or week start. | write | PROFILE_WRITE | Current | |
An OAuth token needs PROFILE_WRITE. Acts onprofile Permission (capability) PROFILE_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TeamsList, read, create, update, and delete teams.5 | ||||||
| GET | /v2/teams | Get the teams the authenticated user belongs to. | read | TEAM_READ | Current | |
An OAuth token needs the team-level read scope. A plain API key returns the key owner's teams. Acts onteam Permission (capability) TEAM_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v2/teams/{teamId} | Get a single team by id. | read | TEAM_READ | Current | |
An OAuth token needs the team-level read scope; membership in the team is also required. Acts onteam Permission (capability) TEAM_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/teams | Create a team. | write | TEAM_WRITE | Current | |
An OAuth token needs the team-level write scope. The creator becomes the team owner. Acts onteam Permission (capability) TEAM_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v2/teams/{teamId} | Update a team's settings. | write | TEAM_WRITE | Current | |
An OAuth token needs the team-level write scope, and an owner or admin role on the team. Acts onteam Permission (capability) TEAM_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/teams/{teamId} | Delete a team. | write | TEAM_WRITE | Current | |
An OAuth token needs the team-level write scope, and an owner role on the team. Acts onteam Permission (capability) TEAM_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
WebhooksList, read, create, update, and delete webhook subscriptions.4 | ||||||
| GET | /v2/webhooks | Get all webhook subscriptions for the account. | read | WEBHOOK_READ | Current | |
Sends cal-api-version 2021-10-20, the version the webhooks family documents. An OAuth token needs WEBHOOK_READ. Acts onwebhook Permission (capability) WEBHOOK_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/webhooks | Create a webhook subscription, choosing the triggers and the destination URL. | write | WEBHOOK_WRITE | Current | |
Sends cal-api-version 2021-10-20. An OAuth token needs WEBHOOK_WRITE. A secret can be set to sign deliveries. Acts onwebhook Permission (capability) WEBHOOK_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v2/webhooks/{webhookId} | Update a webhook subscription's triggers, URL, or active state. | write | WEBHOOK_WRITE | Current | |
Sends cal-api-version 2021-10-20. An OAuth token needs WEBHOOK_WRITE. Acts onwebhook Permission (capability) WEBHOOK_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/webhooks/{webhookId} | Delete a webhook subscription. | write | WEBHOOK_WRITE | Current | |
Sends cal-api-version 2021-10-20. An OAuth token needs WEBHOOK_WRITE. Acts onwebhook Permission (capability) WEBHOOK_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
OrganizationsManage users within an organization, used by platform and enterprise customers.4 | ||||||
| GET | /v2/organizations/{orgId}/users | Get all users in an organization (platform and enterprise). | read | ORG_USERS_READ | Current | |
An ORG_ scope automatically grants the matching TEAM_ scope. Organization endpoints are for platform and enterprise customers. Acts onorganization user Permission (capability) ORG_USERS_READVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v2/organizations/{orgId}/users | Create a user within an organization. | write | ORG_USERS_WRITE | Current | |
Needs an organization-level write scope and an owner or admin role on the organization. Acts onorganization user Permission (capability) ORG_USERS_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v2/organizations/{orgId}/users/{userId} | Update a user within an organization. | write | ORG_USERS_WRITE | Current | |
Needs an organization-level write scope. Acts onorganization user Permission (capability) ORG_USERS_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v2/organizations/{orgId}/users/{userId} | Delete a user from an organization. | write | ORG_USERS_WRITE | Current | |
Needs an organization-level write scope and an owner or admin role on the organization. Acts onorganization user Permission (capability) ORG_USERS_WRITEVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Cal.com can notify an app when something happens in an account, like a booking being created, rescheduled, or cancelled. It posts a payload describing the trigger to a registered URL, so an integration learns about activity without polling.
| Event | What it signals | Triggered by |
|---|---|---|
BOOKING_CREATED | A booking was created against an event type. | /v2/bookings |
BOOKING_RESCHEDULED | A booking was rescheduled to a new time. | /v2/bookings/{uid}/reschedule |
BOOKING_CANCELLED | A booking was cancelled. | /v2/bookings/{uid}/cancel |
BOOKING_REQUESTED | A booking was requested on an event type that requires confirmation, and is awaiting a decision. | /v2/bookings |
BOOKING_REJECTED | A booking that required confirmation was declined. | /v2/bookings/{uid}/decline |
BOOKING_NO_SHOW_UPDATED | A host or attendee was marked present or absent for a booking. | /v2/bookings/{uid}/mark-absent |
BOOKING_PAID | A paid booking was paid for. | In-app only |
MEETING_STARTED | A Cal Video meeting for a booking started. | In-app only |
MEETING_ENDED | A Cal Video meeting for a booking ended. | In-app only |
RECORDING_READY | A Cal Video recording for a booking finished processing and is available. | In-app only |
FORM_SUBMITTED | A routing form was submitted. | In-app only |
OOO_CREATED | An out-of-office entry was created. | In-app only |
Cal.com limits how fast an app or AI agent can call, by a request rate measured per minute against the API key or token making the call.
Cal.com meters requests by rate against the API key or token making the call, not by a per-method cost. The default is 120 requests per minute, and Cal.com can raise it on request to a higher ceiling such as 200 per minute, or further with potential charges. The same default applies to unauthenticated calls on public booking endpoints. Going over returns HTTP 429.
List endpoints page with take and skip query parameters, where take sets the page size and skip is the offset, and some organization list endpoints use cursor-based pagination instead. The response data carries the page of results inside the success envelope.
Requests and responses are JSON. Every response is wrapped in an envelope with a status of success or error, the payload in data, and, on failure, an error object with a code and message.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | BAD_REQUEST | The request was malformed or a required field is missing or invalid. The error object names the problem in its message. | Read the error message, fix the request body or parameters, and resend. |
| 401 | UNAUTHORIZED | Authentication is missing or invalid. Requests without authentication, and plain HTTP requests, fail. | Send a valid API key or OAuth access token as a Bearer token over HTTPS. |
| 403 | FORBIDDEN | The caller is authenticated but not permitted, for example an OAuth token without the required scope or a membership role too low for the action. | Grant the missing scope on the OAuth client, or use a key or role that holds the permission. |
| 404 | NOT_FOUND | The requested resource does not exist or is not visible to this caller. | Verify the id in the path and confirm the caller has access to it. |
| 429 | TOO_MANY_REQUESTS | The rate limit was exceeded, by default 120 requests per minute against the key or token. | Slow the request rate and retry with backoff, or request a higher limit from Cal.com. |
| 500 | INTERNAL_SERVER_ERROR | An error on Cal.com's side. It is uncommon. | Retry with backoff, and contact Cal.com support if it persists. |
Cal.com pins the v2 API by date through the cal-api-version header. The date is chosen per request, and different endpoint families settle on different dated versions, so an integration sends the version that each method documents.
The v2 API is pinned by date through the cal-api-version header on every request. There is no single global version string: each endpoint family documents its own dated version, and the introduction leads with 2024-08-13. An integration sends the version the method it calls documents.
The dated version the bookings endpoints document, used to create, get, list, cancel, reschedule, confirm, decline, and mark absence on bookings.
The dated version the slots endpoints document, used to read available times and to reserve, update, or release a held slot.
The dated version the event-types endpoints document.
The dated version the schedules endpoints document.
The dated version the webhooks endpoints document, the only version their schema accepts.
Send the dated version each method documents, and move up deliberately.
Cal.com API v2 reference ↗Bollard AI sits between a team's AI agents and Cal.com. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.