Give your assistant a calendar and the power to book.
Personal AI assistants need two things to be useful in the real world: to know when their user is free, and to actually book the dentist, the barber or the table. Cal.com gives your agent both: scheduling primitives over one API, a hosted MCP server, drop-in React components, a CLI and voice agents. Or hand the whole task to our agent through api.cal.com/v2/agents.
What does my user's week look like?
Free slots across every connected calendar, never the events behind them.
curl "https://api.cal.com/v2/slots?eventTypeId=123\ &start=2026-10-05&end=2026-10-09&timeZone=Europe/Berlin" \ -H "Authorization: Bearer $CAL_API_KEY" \ -H "cal-api-version: 2024-09-04"
Book the dentist on their behalf
One call creates the booking and puts it on the user's calendar.
curl -X POST https://api.cal.com/v2/bookings \ -H "Authorization: Bearer $CAL_API_KEY" \ -H "cal-api-version: 2024-08-13" \ -d '{ "eventTypeId": 123, "start": "2026-10-06T08:30:00Z", "attendee": { "name": "Ada", "email": "ada@example.com", "timeZone": "Europe/Berlin" } }'
You bring the user, we bring the data.
Building a personal agent means owning the relationship with your end user. Owning a scheduling stack does not have to come with it. Cal.com is the data layer underneath: the calendars, the availability, the events and the bookings your assistant acts on, so you ship the product instead of the plumbing.
You bring
The user
- The relationship, the conversation, the trust
- Your assistant, your brand, your product surface
- The intent: “find me a dentist next week”
We bring
The data
- Calendar access across Google, Outlook, iCloud and more
- Availability, computed against every connected calendar
- Event creation, rescheduling and cancellation
- Real-world bookings with businesses that run on Cal.com
Every scheduling primitive your agent needs, as REST
Read availability, find or create event types, create bookings, reschedule and cancel. Everything a personal assistant does to a calendar maps to one versioned endpoint.
Availability
The slots a user, or the business they want to book, has open.
const res = await fetch( "https://api.cal.com/v2/slots?eventTypeId=123" + "&start=2026-10-05&end=2026-10-09&timeZone=Europe/Berlin", { headers: { Authorization: `Bearer ${process.env.CAL_API_KEY}`, "cal-api-version": "2024-09-04", }, });const { data } = await res.json();// { "2026-10-05": [{ start: "2026-10-05T08:00:00Z" }, ...], ... }
Event types
Find the right thing to book, or create it on the fly.
// Find an existing event typeGET /v2/event-types?username=dr-lee-dental// Or create one for the occasionPOST /v2/event-types{ "title": "Dentist check-up", "slug": "checkup", "lengthInMinutes": 30, "locations": [{ "type": "address", "address": "Friedrichstr. 12, Berlin" }]}
Create a booking
Book on the user's behalf; the confirmation lands on their calendar.
POST /v2/bookingscal-api-version: 2024-08-13{ "eventTypeId": 123, "start": "2026-10-06T08:30:00Z", "attendee": { "name": "Ada", "email": "ada@example.com", "timeZone": "Europe/Berlin" }, "metadata": { "source": "my-assistant" }}
Reschedule and cancel
Plans change. Your agent handles that too.
// Move it to WednesdayPOST /v2/bookings/{uid}/reschedule{ "start": "2026-10-07T14:00:00Z", "reschedulingReason": "User asked to move it"}// Or call it offPOST /v2/bookings/{uid}/cancel{ "cancellationReason": "No longer needed" }
Or skip the primitives and talk to our agent
Send a message to api.cal.com/v2/agents and Cal.com's scheduling agent does the rest: it checks availability, picks or creates the event type, books, reschedules or cancels, and streams every step back to you. It is the same agent behind Cal.ai in the web app and Slack, now a channel your assistant can call with the API key or OAuth token it already has.
One message in, a booking out
Natural language in, a streamed turn out. The first message opens a session.
curl -N -X POST https://api.cal.com/v2/agents/chat \ -H "Authorization: Bearer $CAL_API_KEY" \ -d '{ "message": "Book me a 30 min check-up with dr-lee-dental next week, mornings only" }'# server-sent events as the agent worksevent: session { "uid": "ses_9k2" }event: tool { "name": "slots.list", "eventTypeId": 123 }event: approval { "uid": "apr_8f2", "action": "bookings.create", "start": "2026-10-06T08:30:00Z" }event: message { "text": "Tuesday 08:30 is free. Book it?" }
Approve before it acts
Anything that writes to a calendar pauses for a yes. Your assistant relays the question and the answer.
POST /v2/agents/sessions/{uid}/approvals{ "approvalUid": "apr_8f2", "decision": "approve" }// or deny, with a reason the agent takes into account{ "approvalUid": "apr_8f2", "decision": "deny", "reason": "Try Wednesday" }// stop a running turn at any pointPOST /v2/agents/sessions/{uid}/stop
Sessions that remember
Follow-ups land in the same session, so "move it an hour later" needs no context from you.
// continue the conversationPOST /v2/agents/chat{ "sessionUid": "ses_9k2", "message": "Actually, an hour later" }// list and replay sessions for this userGET /v2/agents/sessionsGET /v2/agents/sessions/{uid}// { messages: [...], toolCalls: [...], approvals: [...] }
Same auth, same limits
No new credential. Whatever the caller may do in Cal.com is exactly what the agent may do.
// Personal API keyAuthorization: Bearer cal_live_xxxx// Platform OAuth access token, on behalf of a managed userAuthorization: Bearer <access_token>// Tools are filtered to the caller's permissions.// Rate limits and per-turn token budgets apply.// Usage is billed as credits, like every other call.
Bookings
Availability
Event types
Insights
Teams
Routing
Point your model at mcp.cal.com and it can schedule
The hosted Model Context Protocol server exposes bookings, event types, schedules and availability as tools. Your agent authenticates with OAuth, so each user grants access to their own calendar, and starts calling them. No SDK, no glue code.
Connect any MCP client
Streamable HTTP with OAuth 2.1. Works with Claude, ChatGPT, Cursor and your own runtime.
{ "mcpServers": { "calcom": { "type": "http", "url": "https://mcp.cal.com/mcp" } }}
Or run it locally with an API key
The same tools over stdio, for self-hosted Cal.com or server-side agents.
# Claude Codeclaude mcp add --transport http calcom https://mcp.cal.com/mcp# stdio, with a Cal.com API keyCAL_API_KEY=cal_live_xxxx npx @calcom/cal-mcp@latest
The scheduling UI your assistant hands back to the user
When the agent needs a human in the loop, drop in React components that already work: a full Booker, availability settings, event type management, calendar connect and a payment form.
Connect the user's calendars
Google, Outlook and Apple, connected once inside your app.
import { CalProvider, Connect } from "@calcom/atoms";import "@calcom/atoms/globals.min.css";export function Calendars({ accessToken }) { return ( <CalProvider clientId={process.env.NEXT_PUBLIC_X_CAL_ID} accessToken={accessToken} options={{ apiUrl: "https://api.cal.com/v2", refreshUrl: "/api/refresh" }} > <Connect.GoogleCalendar /> <Connect.OutlookCalendar /> </CalProvider> );}
Availability and event types
Let the user tune what their assistant is allowed to book.
import { AvailabilitySettings, EventTypeSettings } from "@calcom/atoms";<AvailabilitySettings enableOverrides /><EventTypeSettings id={eventTypeId} allowDelete={false} />
Confirm the slot the agent found
The Booker handles slot picking, the form and the confirmation.
import { Booker } from "@calcom/atoms";<Booker username="dr-lee-dental" eventSlug="checkup" onCreateBookingSuccess={(booking) => assistant.confirm(booking)}/>
Take payment
Paid services settle inside the same flow.
import { PaymentForm } from "@calcom/atoms";<PaymentForm paymentUid={paymentUid} onPaymentSuccess={() => assistant.say("Booked and paid.")}/>
A command line your agent can run
Agents that already operate a shell get every API v2 operation as a command with --json output. Ideal for coding agents, cron-driven assistants and anything that executes tools locally.
npm install -g @calcom/clicurl -fsSL https://cal.com/install.sh | bashThree commands from question to booking
Log in once, then read the user's agenda, find an opening and book it.
Read the schedule
What is on the user's plate, and where is there room?
calcom login# Today, as JSON the agent can reason overcalcom agenda --json# Find an opening with the barbercalcom slots available --event-type-id 123 \ --timezone Europe/Berlin --json
Book it
Same flags as the API, same booking on the calendar.
calcom bookings create --event-type-id 123 \ --start 2026-10-06T08:30:00Z \ --attendee-name "Ada" \ --attendee-email ada@example.com \ --attendee-timezone Europe/Berlin --json
When the booking has to happen over the phone
Not every business has an API. Cal.ai voice agents make and take calls: they book appointments over the phone, send reminders and run follow-ups, so your assistant can close the loop with the real world.
+1 (415) 873-1159
Cal.ai Agent
Cal.ai Agent
Hi, Alex. This is Sally from Deel. How are you doing today?
I’m doing great Sally, thanks for asking. How are you?
Cal.ai Agent
I’m great! I’m just calling to see if you can still make the call tomorrow?
Phone booking
Your assistant asks for a dentist next week; Cal.ai calls the practice, agrees on a time against the user's real availability and creates the booking.
Reminders and follow-ups
Built on Cal.com Workflows, so the reminder the evening before and the no-show follow-up run on the booking without extra code.
- Trigger calls on bookings, cancellations and no-shows
- Combine with email and SMS automations
Cal.ai Agent
Hi, Alex. This is Sally from Deel. How are you doing today?
I’m doing great Sally, thanks for asking. How are you?
Cal.ai Agent
I’m great! I’m just calling to see if you can still make the call tomorrow?
Transcripts your agent can read
Every call is transcribed onto the booking, so your assistant knows what was agreed and can tell the user.
Your agent sees available slots. Not the calendar.
Calendar credentials and event data stay encrypted inside Cal.com. When your assistant asks what is free, it gets free times: not meeting titles, attendees or notes.
Encrypted calendar data
Per-user consent
Usage-based credits
Exactly what a personal assistant's user expects
Access anyone's time, create or find the right event, book a service nearby. Three steps, one infrastructure layer, whichever interface your agent speaks: API, MCP, Atoms, CLI or a phone call.
Access anyone's time
Create or find events
Book a service nearby
Ship the assistant. We handle the scheduling.
Start with whichever interface is closest to how your agent already works. Everything is free to try.