Skip to main content
Calendar integrations allow Cal.com to check your availability across multiple calendars and automatically create events when bookings are made.

Overview

Cal.com supports integration with major calendar providers:
  • Google Calendar
  • Microsoft Outlook / Office 365
  • Apple Calendar (CalDAV)
  • CalDAV-compatible calendars
Calendar integrations serve two primary purposes:
  1. Availability checking: Cal.com reads your calendars to find free time slots
  2. Event creation: Bookings are written to your destination calendar
You can connect multiple calendars for availability checking but only one destination calendar for new bookings.

Connecting Calendars

1

Navigate to Calendar Settings

Go to Settings → Calendars from your dashboard
2

Connect Calendar Provider

Click “Connect” next to your calendar provider (Google, Outlook, etc.)
3

Authorize Access

Follow the OAuth flow to grant Cal.com permission to access your calendar
4

Select Calendars

Choose which calendars to check for conflicts (you can select multiple)
5

Set Destination Calendar

Choose which calendar will receive new booking events

Calendar Types

Selected Calendars (Check for Conflicts)

// From schema.prisma:1002
model SelectedCalendar {
  id           String  @id @default(uuid())
  userId       Int
  integration  String      // "google_calendar", "office365_calendar"
  externalId   String      // External calendar ID
  credentialId Int?
}
Selected calendars are checked when determining your availability. If you have an event in any selected calendar, that time slot will be marked as busy.
Make sure to select all calendars where you have commitments. If a calendar isn’t selected, Cal.com won’t see those events and may create booking conflicts.

Destination Calendar

// From schema.prisma:354
model DestinationCalendar {
  id           Int     @id
  integration  String      // Calendar provider
  externalId   String      // Which calendar to write to
  primaryEmail String?     // Email associated with calendar
  userId       Int?        // User-level destination
  eventTypeId  Int?        // Event type-level destination
}
The destination calendar is where new booking events are created. You can set:
  • User-level destination: Default calendar for all your bookings
  • Event type-level destination: Specific calendar for certain event types
All bookings go to the same calendar unless overridden by event type settings.
user: {
  destinationCalendar: {
    integration: "google_calendar",
    externalId: "primary"
  }
}

Calendar Sync

Cal.com maintains a sync with your connected calendars:
// From schema.prisma:1036-1042
{
  syncToken: "abc123...",           // Incremental sync token
  syncedAt: "2024-03-04T10:00:00Z",
  syncErrorCount: 0,
  syncSubscribedAt: "2024-03-01T00:00:00Z"
}

Calendar Watch (Push Notifications)

For Google Calendar, Cal.com can subscribe to push notifications:
// From schema.prisma:1029-1033
{
  channelId: "channel_abc123",           // Watch channel ID
  channelResourceId: "resource_xyz",     // Resource being watched
  channelExpiration: "2024-03-11T00:00:00Z"
}
Push notifications allow near-instant availability updates when your calendar changes, providing a better booking experience.

Calendar Cache

To improve performance, Cal.com caches calendar events:
// Calendar events are cached locally
model CalendarCache {
  credentialId Int
  key          String  // Cache key (usually date-based)
  value        Json    // Cached events
  expiresAt    DateTime
}

model CalendarCacheEvent {
  eventId           String
  calendarId        String
  startTime         DateTime
  endTime           DateTime
  status            String  // "confirmed", "cancelled"
  summary           String?
}

Availability Checking

When someone visits your booking page, Cal.com:
1

Fetch Events

Retrieves events from all selected calendars (or uses cached data)
2

Calculate Busy Times

Determines which time slots are occupied
3

Apply Schedule

Overlays your availability schedule
4

Apply Buffers

Adds before/after event buffers
5

Show Available Slots

Displays free time slots to the booker
// Availability checking considers:
{
  selectedCalendars: [/* all connected calendars */],
  schedule: {/* your working hours */},
  bufferTime: 15,        // User-level buffer
  beforeEventBuffer: 10, // Event type buffer before
  afterEventBuffer: 10   // Event type buffer after
}

Event Type Calendar Settings

Event types can override user calendar settings:
// From schema.prisma:187, 262
{
  useEventLevelSelectedCalendars: true,  // Use different calendars for this event type
  useEventTypeDestinationCalendarEmail: true,  // Use event type's destination email
  selectedCalendars: [/* event type specific calendars */]
}
Event type-level calendar settings override user-level settings. Make sure the correct calendars are selected.

Calendar Permissions

Different calendar operations require different permissions:

Read Permission

Required to check availability and view events

Write Permission

Required to create/update/delete booking events

Troubleshooting Calendar Sync

Calendar Not Syncing

1

Check Connection Status

Go to Settings → Calendars and verify the calendar shows as “Connected”
2

Review Permissions

Ensure Cal.com has both read and write permissions to your calendar
3

Reconnect Calendar

Disconnect and reconnect the calendar to refresh credentials
4

Check Sync Errors

{
  syncErrorCount: 3,
  syncErrorAt: "2024-03-04T10:30:00Z",
  error: "Invalid credentials"
}

Booking Conflicts

If bookings are being created during busy times:
  1. Verify selected calendars: Ensure all your calendars are selected for conflict checking
  2. Check calendar permissions: Cal.com needs read access to all selected calendars
  3. Review event status: Only “confirmed” events block time (tentative events don’t)
  4. Clear calendar cache: Force a fresh sync from Settings → Calendars

Calendar Settings by Priority

Calendar settings are applied in this order (higher priority overrides lower):
  1. Event type-level destination calendar
  2. User-level destination calendar
  3. Event type-level selected calendars (if useEventLevelSelectedCalendars: true)
  4. User-level selected calendars

Best Practices

Select All Calendars

Connect every calendar where you have commitments to prevent double-booking

Use Event Type Calendars

Send different event types to different calendars for organization

Monitor Sync Status

Regularly check that calendars are syncing without errors

Set Appropriate Buffers

Use buffer time to account for travel or preparation between meetings

Advanced: Calendar Watch

For Google Calendar, push notifications keep availability updated in real-time:
// From schema.prisma:1051-1054
{
  watchAttempts: 0,
  unwatchAttempts: 0,
  maxAttempts: 3,
  lastErrorAt: null
}
Watch channels automatically renew before expiration. If watch fails after maxAttempts, Cal.com falls back to polling.

Build docs developers (and LLMs) love