Calendly

Read, book and cancel Calendly meetings as calendar events.

Calendly is a scheduling tool, so its events are the meetings people have booked with your user. You can list them, sync them, book a new one on an event type and cancel one. Two limits shape everything else: Calendly can't change a scheduled meeting at all, and booking through its API needs a paid plan.

npm install @cal-sdk/core @cal-sdk/calendly
import { createEvent, listEvents } from '@cal-sdk/core';
import { calendly } from '@cal-sdk/calendly';

const calendar = calendly({ accessToken: process.env.CALENDLY_TOKEN! });

const { events } = await listEvents({
  calendar,
  timeMin: '2026-11-01T00:00:00Z',
  timeMax: '2026-12-01T00:00:00Z',
});

// Book a 30 minute event type for a guest.
await createEvent({
  calendar,
  event: {
    start: { dateTime: '2026-11-03T10:00:00', timeZone: 'Europe/Berlin' },
    end: { dateTime: '2026-11-03T10:30:00', timeZone: 'Europe/Berlin' },
    attendees: [{ email: 'guest@example.com', name: 'Guest' }],
  },
  providerOptions: {
    calendly: { eventType: 'https://api.calendly.com/event_types/<uuid>' },
  },
});

Credentials

accessToken is a personal access token or OAuth access token with the scopes users:read and scheduled_events:read, plus event_types:read and scheduled_events:write to book.

Settings

accessTokenstring | (() => string | PromiseLike<string>)
Personal access token or OAuth access token, or a function that returns one.
headers?Record<string, string | undefined>
Headers sent with every request.
fetch?typeof fetch
A custom fetch, for example to log or record requests.

Not supported

Updating, all-day and recurring events, ifMatch and search aren't supported. Free/busy is computed from meetings. See the comparison for every provider.

How it behaves

Calendars, ids and times

'primary' holds every meeting the user hosts. Calendly can't list meetings by event type, so there are no other calendars. An event id is the scheduled event's uuid, and times are shown in the user's Calendly time zone.

Booking

Creating an event books an event type through Calendly's Scheduling API, which needs a paid Calendly plan. The meeting lasts as long as the event type, and other lengths throw InvalidArgumentError. Calendly only books times the event type has free. The first attendee books the meeting and the others are added as guests (Calendly accepts up to 10). Without attendees, the user books it for themselves. Fields the event type sets (title, description, location, createConference, reminders, color, visibility) are ignored with a warning.

Changing and cancelling

Updating throws UnsupportedFunctionalityError, since Calendly can't change a scheduled meeting. To reschedule, delete it and book a new one. Deleting cancels the meeting, and cancelled meetings read as deleted events. Calendly always emails invitees, so sendUpdates values other than 'all' return a warning.

Listing and sync

Listing finds meetings by their start. Calendly meetings last at most 12 hours, so calsdk looks back a day to catch meetings that started before timeMin and end inside the window.

getEvent and createEvent return the hosts, the invitees and the guests they added. Listing and sync leave attendees out, because Calendly needs a request per meeting for its invitees, and a month of meetings would mean a request for each. Hosts are in organizer.

Calendly can't list meetings by when they changed, so each sync reads every active meeting and compares it with the last sync. All changes come on one page, and the cursor grows with the number of meetings.

Provider options

await createEvent({
  calendar,
  event,
  providerOptions: {
    calendly: { eventType: '<uuid>', location: { kind: 'physical', location: 'Office' } },
  },
});

await deleteEvent({
  calendar,
  eventId,
  providerOptions: { calendly: { reason: 'No longer needed' } },
});

createEvent

eventTypestring
The event type's URI or uuid.
location?{ kind: string; location?: string }
Passed to Calendly as is, such as { kind: 'zoom_conference' }.

deleteEvent

reason?string
Shown in the cancellation email.

Metadata

Events carry providerMetadata.calendly:

FieldType and notes
uristring, the scheduled event's URI
eventTypestring, the URI of the event type it was booked on

On this page