> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/calcom/cal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Calendars

> Connect external calendars to check availability and sync events automatically

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

<Note>
  You can connect multiple calendars for availability checking but only one destination calendar for new bookings.
</Note>

## Connecting Calendars

<Steps>
  <Step title="Navigate to Calendar Settings">
    Go to Settings → Calendars from your dashboard
  </Step>

  <Step title="Connect Calendar Provider">
    Click "Connect" next to your calendar provider (Google, Outlook, etc.)
  </Step>

  <Step title="Authorize Access">
    Follow the OAuth flow to grant Cal.com permission to access your calendar
  </Step>

  <Step title="Select Calendars">
    Choose which calendars to check for conflicts (you can select multiple)
  </Step>

  <Step title="Set Destination Calendar">
    Choose which calendar will receive new booking events
  </Step>
</Steps>

## Calendar Types

### Selected Calendars (Check for Conflicts)

```typescript theme={null}
// 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.

<Warning>
  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.
</Warning>

### Destination Calendar

```typescript theme={null}
// 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

<Tabs>
  <Tab title="User-Level">
    All bookings go to the same calendar unless overridden by event type settings.

    ```typescript theme={null}
    user: {
      destinationCalendar: {
        integration: "google_calendar",
        externalId: "primary"
      }
    }
    ```
  </Tab>

  <Tab title="Event Type-Level">
    Specific event types can use different destination calendars.

    ```typescript theme={null}
    eventType: {
      useEventLevelSelectedCalendars: true,
      destinationCalendar: {
        integration: "office365_calendar",
        externalId: "sales@company.com"
      }
    }
    ```
  </Tab>
</Tabs>

## Calendar Sync

Cal.com maintains a sync with your connected calendars:

```typescript theme={null}
// 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:

```typescript theme={null}
// From schema.prisma:1029-1033
{
  channelId: "channel_abc123",           // Watch channel ID
  channelResourceId: "resource_xyz",     // Resource being watched
  channelExpiration: "2024-03-11T00:00:00Z"
}
```

<Note>
  Push notifications allow near-instant availability updates when your calendar changes, providing a better booking experience.
</Note>

## Calendar Cache

To improve performance, Cal.com caches calendar events:

```typescript theme={null}
// 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:

<Steps>
  <Step title="Fetch Events">
    Retrieves events from all selected calendars (or uses cached data)
  </Step>

  <Step title="Calculate Busy Times">
    Determines which time slots are occupied
  </Step>

  <Step title="Apply Schedule">
    Overlays your availability schedule
  </Step>

  <Step title="Apply Buffers">
    Adds before/after event buffers
  </Step>

  <Step title="Show Available Slots">
    Displays free time slots to the booker
  </Step>
</Steps>

```typescript theme={null}
// 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:

```typescript theme={null}
// 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 */]
}
```

<Warning>
  Event type-level calendar settings override user-level settings. Make sure the correct calendars are selected.
</Warning>

## Calendar Permissions

Different calendar operations require different permissions:

<CardGroup cols={2}>
  <Card title="Read Permission" icon="eye">
    Required to check availability and view events
  </Card>

  <Card title="Write Permission" icon="pen">
    Required to create/update/delete booking events
  </Card>
</CardGroup>

## Troubleshooting Calendar Sync

### Calendar Not Syncing

<Steps>
  <Step title="Check Connection Status">
    Go to Settings → Calendars and verify the calendar shows as "Connected"
  </Step>

  <Step title="Review Permissions">
    Ensure Cal.com has both read and write permissions to your calendar
  </Step>

  <Step title="Reconnect Calendar">
    Disconnect and reconnect the calendar to refresh credentials
  </Step>

  <Step title="Check Sync Errors">
    ```typescript theme={null}
    {
      syncErrorCount: 3,
      syncErrorAt: "2024-03-04T10:30:00Z",
      error: "Invalid credentials"
    }
    ```
  </Step>
</Steps>

### 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

<Note>
  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
</Note>

## Best Practices

<CardGroup cols={2}>
  <Card title="Select All Calendars" icon="calendar-check">
    Connect every calendar where you have commitments to prevent double-booking
  </Card>

  <Card title="Use Event Type Calendars" icon="layer-group">
    Send different event types to different calendars for organization
  </Card>

  <Card title="Monitor Sync Status" icon="rotate">
    Regularly check that calendars are syncing without errors
  </Card>

  <Card title="Set Appropriate Buffers" icon="clock">
    Use buffer time to account for travel or preparation between meetings
  </Card>
</CardGroup>

## Advanced: Calendar Watch

For Google Calendar, push notifications keep availability updated in real-time:

```typescript theme={null}
// 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.

## Related Features

* [Availability](/features/availability) - Configure your working hours
* [Event Types](/features/event-types) - Set event-specific calendar settings
* [Bookings](/features/bookings) - View events created in your calendar
