Skip to main content
Appointment scheduling is the classic voice-agent use case: the assistant checks open slots during the call, offers a few options, and books the one the caller picks. The platform supports this in two ways that can be combined freely:
  1. Calendar integrations — connect an external scheduling provider (Acuity Scheduling, Cal.com, Calendly, eTermin, HighLevel) once, assign it to an assistant, and the assistant automatically gets booking tools for every call. Google Calendar and Outlook connect in the same place, but they feed the built-in engine’s calendar sync rather than mid-call booking — see the note under the table.
  2. The built-in booking engine — define your own event types with weekly availability and get a public, embeddable booking page at /book/{workspace}/{slug}, ICS invitation emails, and a native integration your assistants can book against. No external account required. See Built-in calendar for the full picture.

Providers at a glance

Google Calendar and Outlook are sync targets, not mid-call booking providers. Connecting them makes their busy times and event creation available to the built-in booking engine; assistants cannot call them directly during a conversation yet. To book on those calendars mid-call, either put a Cal.com, Calendly, Acuity, or HighLevel event type in front of them, or use a built-in event type with calendar sync switched on.
Calendly link mode: Calendly’s Scheduling API requires a paid Calendly plan. If your plan cannot book directly, set the integration’s booking_mode to link — the assistant then agrees on a rough time with the caller and sends a single-use scheduling link by SMS or email (link_channel) instead of hard-booking. Integrations that hit the paid-plan restriction at call time are flagged with status link_mode.

Connecting an integration

Go to Booking → Integrations and pick a provider card:
Paste your API key (Cal.com → Settings → Developer → API Keys) and pick the API endpoint: US (default), EU, or Custom for a self-hosted Cal.com instance. Select Load event types to fetch your events by name and duration — no need to copy a numeric ID from the URL. The integration also reads the event type’s custom booking questions automatically; use Refresh fields if you change them later in Cal.com. Optional timezone override — make sure it matches the Cal.com event type.
Every integration is verified before it is saved. Invalid credentials or event settings are rejected with a clear error. Secret values are never displayed again after saving. Deleting the final integration that uses an Acuity account revokes its OAuth token through Acuity’s disconnect endpoint and removes the local connection. An unused account can also be removed with Disconnect account in the Acuity editor; shared accounts cannot be disconnected until their remaining integrations are removed. Existing personal-access-token integrations remain operational but appear as Legacy connection — reconnect with Calendly. Reconnecting upgrades them to OAuth and removes the PAT from the integration.

Assigning to an assistant

Open the assistant’s settings and tick the integrations it should use (or PUT /api/v1/assistants/{id}/integrations). Each assigned integration adds its own booking tools to every call: Every integration gets check_availability and book_appointment. The management tools are added only where the provider supports them: Calendly (find and cancel), Acuity (find, cancel, and reschedule, following the toggles you set), and the built-in engine, which adds a workspace-wide set that identifies the caller by phone number first and falls back to email plus full name. Cal.com, eTermin, and HighLevel calendars currently offer availability and booking only — the assistant can read slots and book on them, but not look up, cancel, or move an existing appointment during a call. If more than one integration is assigned, tool names get the integration name as a suffix (for example check_availability_sales). Slots are always spoken in the assistant timezone — set it in the assistant’s settings.
Calendly bookings can’t be rescheduled through its API — a caller who wants a different time gets a fresh cancel_appointment and book_appointment instead, or reschedules through the link in their Calendly confirmation email.
Tell the assistant when to book in its prompt, e.g.: “Before offering any time, call check_availability. Once the caller confirms a slot, call book_appointment with their name and email.”

Plan gating

Your plan must include Calendar integrations. If it is not included, you cannot create integrations.

Troubleshooting

Confirm the key is still active in Cal.com and that you pasted a live key (Cal.com’s live keys begin with cal_live_), then select Load event types again. If you get an authentication error instead of an empty list, you likely picked the wrong API endpoint — an EU Cal.com account needs the EU endpoint (or Custom for a self-hosted instance), not the US default.
book_appointment needs a valid email address, because Cal.com rejects a booking without one. Spoken addresses (“anna at example dot com”) and German umlauts are converted automatically before the request goes out, so most dictated addresses work; if what the assistant heard still isn’t usable, it is told to ask again rather than booking. Tell it in the prompt to collect and confirm the email before booking, and to reuse an address you already hold as a call variable instead of asking twice.
The event type’s only location in Calendly is a video-conferencing link (Google Meet, Zoom, Teams), and the voice agent can’t generate meeting links. In Calendly, edit the event type and add Custom or Phone Call → Inbound call as a location — Custom is the safest choice and works in every case. If the event type ends up with more than one location, pick the right one under Meeting location in the integration.
In a Calendly organization, admin and owner accounts see every member’s event types, including Round Robin and Collective events; a regular member account only sees its own.
A Web Call test runs without a phone number, so anything the booking flow derives from the caller’s number (sending a scheduling link by SMS, looking an appointment up by phone) can’t work the same way. Use Test → Call in the assistant header for a realistic run: the assistant dials a number you enter, or you dial its inbound number yourself.
Still stuck? Contact support with the integration’s name, the error shown in the assistant editor, and a transcript of the call that failed to book.

API & MCP

Everything above is available in the public REST API and as MCP tools at https://<your-domain>/mcp: Event types, connections, and booking records for the built-in engine are covered in Built-in calendar.