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

# Quickstart

> Get from signup to your first booking in 5 minutes

Get Cal.com up and running and receive your first booking in minutes. This guide covers both Cal.com Cloud and self-hosted deployments.

<Note>
  **New to Cal.com?** This quickstart focuses on getting you productive quickly. For detailed installation options, see the [Installation guide](/installation).
</Note>

## Choose your path

<Tabs>
  <Tab title="Cal.com Cloud">
    Fastest way to get started with zero setup
  </Tab>

  <Tab title="Self-hosted">
    Deploy Cal.com on your own infrastructure
  </Tab>
</Tabs>

## Cal.com Cloud

<Steps>
  <Step title="Sign up for an account">
    Visit [cal.com/signup](https://cal.com/signup) and create your account with email or OAuth.

    ```typescript theme={null}
    // Authentication uses NextAuth.js with multiple providers
    // From apps/web/pages/api/auth/[...nextauth].tsx
    providers: [
      EmailProvider,
      GoogleProvider,
      GitHubProvider,
      // ... more providers
    ]
    ```

    <Tip>
      Use **Continue with Google** for faster setup - it will automatically connect your Google Calendar.
    </Tip>
  </Step>

  <Step title="Complete your profile">
    Set your:

    * **Username**: Your booking URL will be `cal.com/your-username`
    * **Name**: Displayed on your booking page
    * **Time zone**: Ensures accurate availability
    * **Bio** (optional): Introduce yourself to bookers

    ```typescript theme={null}
    // User profile structure from packages/prisma/schema.prisma:77
    model User {
      username      String?  @unique
      name          String?
      bio           String?
      timeZone      String   @default("Europe/London")
      weekStart     String   @default("Sunday")
    }
    ```
  </Step>

  <Step title="Create your first event type">
    Cal.com creates a default "30 Minute Meeting" for you, but let's customize it:

    1. Go to **Event Types** in the sidebar
    2. Click your "30 Minute Meeting" event
    3. Customize the settings:
       * **Title**: What people see (e.g., "Quick Chat")
       * **URL**: Your booking link slug (e.g., `cal.com/you/quick-chat`)
       * **Duration**: Meeting length (15, 30, 60 minutes, or custom)
       * **Location**: Where you'll meet

    <Accordion title="Event type configuration options" icon="gear">
      ```typescript theme={null}
      // Core event type fields from packages/platform/types/event-types
      {
        title: "30 Minute Meeting",
        slug: "30min",
        lengthInMinutes: 30,
        
        // Choose meeting location
        locations: [
          { type: "zoom" },                    // Zoom (requires integration)
          { type: "phone" },                   // Phone call
          { type: "userPhone" },               // Booker provides phone
          { type: "integrations:google:meet" }, // Google Meet
          { type: "link", link: "https://..." } // Custom link
        ],
        
        // Booking rules
        minimumBookingNotice: 120,      // 2 hours minimum notice
        beforeEventBuffer: 15,          // 15 min buffer before
        afterEventBuffer: 10,           // 10 min buffer after
        
        // Advanced options
        requiresConfirmation: false,    // Auto-confirm or manual approval
        disableGuests: false,           // Allow/disallow additional guests
      }
      ```
    </Accordion>

    4. Click **Save** when done
  </Step>

  <Step title="Connect your calendar">
    Prevent double-bookings by connecting your calendar:

    <Tabs>
      <Tab title="Google Calendar">
        1. Click **Apps** in the sidebar
        2. Find "Google Calendar" and click **Connect**
        3. Sign in and grant permissions
        4. Select which calendars to check for conflicts

        ```typescript theme={null}
        // Google Calendar integration from apps/api/v2/src/ee/calendars
        // Requires Google OAuth 2.0 credentials configured
        {
          GOOGLE_API_CREDENTIALS: {
            web: {
              client_id: "...",
              client_secret: "...",
              redirect_uris: ["https://cal.com/api/integrations/googlecalendar/callback"]
            }
          }
        }
        ```
      </Tab>

      <Tab title="Outlook/Office 365">
        1. Click **Apps** in the sidebar
        2. Find "Office 365 Calendar" and click **Connect**
        3. Sign in with your Microsoft account
        4. Grant calendar permissions
      </Tab>

      <Tab title="Apple Calendar">
        1. Click **Apps** in the sidebar
        2. Find "Apple Calendar" and click **Connect**
        3. Enter your Apple ID email
        4. Use an [app-specific password](https://support.apple.com/en-us/HT204397)

        <Note>
          Apple Calendar uses CalDAV. No API credentials needed - users connect individually.
        </Note>
      </Tab>
    </Tabs>

    <Warning>
      **Important**: Connected calendars are checked for conflicts. Any busy events will block those time slots from being booked.
    </Warning>
  </Step>

  <Step title="Set your availability">
    Define when you're available for bookings:

    1. Go to **Availability** in the sidebar
    2. Edit your "Working Hours" schedule
    3. Set your typical availability:
       * **Days**: Select working days
       * **Time ranges**: Add multiple time blocks per day
       * **Time zone**: Already set from your profile

    ```typescript theme={null}
    // Schedule structure from packages/prisma/schema.prisma:534
    model Schedule {
      name      String
      timeZone  String?
      
      availability: [
        {
          days: [1, 2, 3, 4, 5],  // Monday-Friday (0=Sunday)
          startTime: "09:00",      // 9 AM
          endTime: "17:00"         // 5 PM
        }
      ]
    }
    ```

    <Accordion title="Advanced availability options" icon="calendar">
      * **Multiple schedules**: Create different schedules for different event types
      * **Date overrides**: Block specific dates or add special availability
      * **Minimum notice**: Set how far in advance people can book
      * **Booking window**: Limit how far into the future bookings can be made

      ```typescript theme={null}
      // From packages/platform/types/event-types
      {
        minimumBookingNotice: 1440,    // 24 hours (in minutes)
        bookingWindow: {
          type: "rolling",
          value: 30,                   // Book up to 30 days ahead
          unit: "days"
        }
      }
      ```
    </Accordion>
  </Step>

  <Step title="Share your booking link">
    Your booking page is ready! Share it:

    ```
    https://cal.com/your-username
    https://cal.com/your-username/30min
    ```

    <CardGroup cols={2}>
      <Card title="Direct link" icon="link">
        Share your booking URL via email, social media, or messaging
      </Card>

      <Card title="Website embed" icon="code">
        Embed Cal.com on your website with our embed components
      </Card>

      <Card title="Email signature" icon="envelope">
        Add your booking link to your email signature
      </Card>

      <Card title="Social profiles" icon="user">
        Add to Twitter bio, LinkedIn profile, etc.
      </Card>
    </CardGroup>

    <Tip>
      Preview your booking page by visiting your link or clicking **Preview** on the event type.
    </Tip>
  </Step>

  <Step title="Get your first booking">
    When someone books time with you:

    1. **You'll receive an email** with booking details
    2. **Event appears in your calendar** automatically
    3. **Booker gets confirmation** with meeting details
    4. **Automatic reminders** are sent before the meeting

    ```typescript theme={null}
    // Booking creation flow from apps/web/pages/api/book/event.ts
    // 1. Validate booking against availability
    // 2. Create booking in database
    // 3. Add to connected calendars
    // 4. Send confirmation emails
    // 5. Trigger workflows (reminders, webhooks)

    const regularBookingService = getRegularBookingService();
    const booking = await regularBookingService.createBooking({
      eventTypeId,
      start: selectedSlot,
      responses: bookerInfo,
      // ... more parameters
    });
    ```

    <Note>
      Bookings are managed in the **Bookings** tab where you can view, reschedule, or cancel meetings.
    </Note>
  </Step>
</Steps>

## Self-hosted deployment

<Steps>
  <Step title="Deploy Cal.com">
    Choose your deployment method:

    <Tabs>
      <Tab title="Docker (Recommended)">
        ```bash theme={null}
        # Clone repository
        git clone https://github.com/calcom/cal.com.git
        cd cal.com

        # Configure environment
        cp .env.example .env

        # Generate secrets
        openssl rand -base64 32  # NEXTAUTH_SECRET
        openssl rand -base64 24  # CALENDSO_ENCRYPTION_KEY

        # Start services
        docker compose up -d
        ```

        <Accordion title="Required environment variables" icon="key">
          ```bash .env theme={null}
          # Database (included in docker-compose)
          DATABASE_URL="postgresql://unicorn_user:magical_password@database:5432/calendso"

          # Application URL
          NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000"
          NEXTAUTH_URL="http://localhost:3000"

          # Secrets (generate with openssl)
          NEXTAUTH_SECRET="your-32-byte-secret"
          CALENDSO_ENCRYPTION_KEY="your-24-byte-encryption-key"

          # Cron jobs
          CRON_API_KEY="random-string-for-cron-endpoints"
          ```
        </Accordion>

        Access at: `http://localhost:3000`
      </Tab>

      <Tab title="Railway">
        One-click deploy with automatic database:

        [![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/cal)

        Railway automatically:

        * Forks the repository
        * Provisions PostgreSQL database
        * Sets up environment variables
        * Deploys the application
      </Tab>

      <Tab title="Vercel">
        [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com)

        <Warning>
          **Vercel Pro required**: Free plan doesn't support Cal.com's serverless function requirements.
        </Warning>

        You'll need to provide:

        * PostgreSQL database (Neon, Supabase, or Railway)
        * Environment variables (see Docker tab)
      </Tab>
    </Tabs>

    [See all deployment options →](/installation)
  </Step>

  <Step title="Complete initial setup">
    1. Visit your Cal.com instance
    2. Create your admin account
    3. Set up your profile (username, name, timezone)

    ```typescript theme={null}
    // First user becomes admin automatically
    // From packages/prisma/schema.prisma:77
    model User {
      role          UserRole  @default(USER)  // First user gets ADMIN
      username      String?   @unique
      email         String    @unique
    }
    ```
  </Step>

  <Step title="Configure integrations">
    <Warning>
      Self-hosted instances require your own OAuth credentials for third-party integrations.
    </Warning>

    <Accordion title="Google Calendar setup" icon="google">
      1. Go to [Google Cloud Console](https://console.cloud.google.com/)
      2. Create a new project
      3. Enable Google Calendar API
      4. Create OAuth 2.0 credentials
      5. Add authorized redirect URIs:
         ```
         https://your-domain.com/api/integrations/googlecalendar/callback
         https://your-domain.com/api/auth/callback/google
         ```
      6. Add to `.env`:
         ```bash theme={null}
         GOOGLE_API_CREDENTIALS='{"web":{"client_id":"...","client_secret":"..."}}'
         GOOGLE_LOGIN_ENABLED=true
         ```

      [Detailed Google setup guide →](https://github.com/calcom/cal.com#obtaining-the-google-api-credentials)
    </Accordion>

    <Accordion title="Zoom integration" icon="video">
      1. Create app on [Zoom Marketplace](https://marketplace.zoom.us/)
      2. Choose "General App" → "User-managed"
      3. Set redirect URL: `https://your-domain.com/api/integrations/zoomvideo/callback`
      4. Add scopes:
         * `meeting:write:meeting`
         * `user:read:settings`
      5. Add to `.env`:
         ```bash theme={null}
         ZOOM_CLIENT_ID="your-client-id"
         ZOOM_CLIENT_SECRET="your-client-secret"
         ```
    </Accordion>

    <Accordion title="Email configuration" icon="envelope">
      Configure SMTP for sending booking confirmations:

      ```bash .env theme={null}
      # SendGrid (recommended)
      SENDGRID_API_KEY="your-api-key"
      SENDGRID_EMAIL="verified@yourdomain.com"

      # Or use SMTP
      EMAIL_SERVER_HOST="smtp.gmail.com"
      EMAIL_SERVER_PORT=465
      EMAIL_SERVER_USER="your-email@gmail.com"
      EMAIL_SERVER_PASSWORD="your-app-password"
      EMAIL_FROM="your-email@gmail.com"
      ```

      <Warning>
        Without email configuration, booking confirmations won't be sent. This is required for production use.
      </Warning>
    </Accordion>
  </Step>

  <Step title="Create your first event type">
    Follow the same steps as Cal.com Cloud (Steps 3-6 above):

    1. Create/customize an event type
    2. Connect your calendar (requires OAuth setup)
    3. Set your availability
    4. Share your booking link
    5. Get your first booking!
  </Step>
</Steps>

## Understanding the booking flow

Here's what happens when someone books with you:

<Steps>
  <Step title="Booker selects a time">
    ```typescript theme={null}
    // Available slots are calculated based on:
    // - Your schedule/availability
    // - Connected calendar busy times
    // - Existing Cal.com bookings
    // - Buffer times and booking limits

    // From packages/features/bookings/lib/handleNewBooking
    const availableSlots = await getAvailableSlots({
      eventTypeId,
      startTime,
      endTime,
      timeZone: booker.timeZone
    });
    ```
  </Step>

  <Step title="Booker fills out form">
    Required information:

    * Name
    * Email
    * Custom fields (if configured)
    * Guest emails (if allowed)

    ```typescript theme={null}
    // Booking fields from packages/platform/types/event-types
    bookingFields: [
      { type: "name", required: true },
      { type: "email", required: true },
      { type: "phone", required: false },
      // Custom fields
      { type: "text", label: "Company", required: true }
    ]
    ```
  </Step>

  <Step title="Booking is created">
    ```typescript theme={null}
    // From apps/web/pages/api/book/event.ts
    const booking = await regularBookingService.createBooking({
      eventTypeId: 1,
      start: "2024-03-15T10:00:00Z",
      end: "2024-03-15T10:30:00Z",
      responses: {
        name: "John Doe",
        email: "john@example.com"
      },
      timeZone: "America/New_York",
      language: "en"
    });
    ```

    The booking is:

    * Saved to database
    * Added to your connected calendars
    * Status set to `ACCEPTED` (or `PENDING` if approval required)
  </Step>

  <Step title="Notifications sent">
    Both you and the booker receive:

    * Email confirmation
    * Calendar invitation (.ics file)
    * Meeting location details

    ```typescript theme={null}
    // Email templates from packages/emails
    // - booking-confirmation (to booker)
    // - organizer-booking-notification (to you)
    // - calendar-event (ICS attachment)
    ```
  </Step>

  <Step title="Reminders (optional)">
    If you have workflows configured:

    * Email/SMS reminders before the meeting
    * Follow-up emails after the meeting
    * Custom webhooks for integrations

    See [Workflows documentation](/features/workflows) for setup.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="Customize your booking page" icon="palette" href="/features/event-types">
    Add your brand colors, logo, and custom questions
  </Card>

  <Card title="Set up team scheduling" icon="users" href="/features/teams">
    Create round-robin or collective team event types
  </Card>

  <Card title="Add workflows" icon="robot" href="/features/workflows">
    Automate reminders, follow-ups, and notifications
  </Card>

  <Card title="Integrate with your tools" icon="plug" href="/integrations/overview">
    Connect CRM, payment processing, and more
  </Card>

  <Card title="Embed on your website" icon="code" href="/embed/overview">
    Add Cal.com directly to your website
  </Card>

  <Card title="Use the API" icon="brackets-curly" href="/api/introduction">
    Build custom scheduling experiences
  </Card>
</CardGroup>

## Common questions

<AccordionGroup>
  <Accordion title="How do I change my booking URL?" icon="link">
    Go to **Settings** → **Profile** and update your username. Your booking URL is:

    ```
    https://cal.com/your-username
    https://cal.com/your-username/event-slug
    ```

    For custom domains, see [self-hosting configuration](/self-hosting/configuration).
  </Accordion>

  <Accordion title="Can I require approval for bookings?" icon="shield-check">
    Yes! In your event type settings:

    1. Enable **Requires confirmation**
    2. Choose whether to block the time slot while pending
    3. Approve or reject bookings from the **Bookings** tab

    ```typescript theme={null}
    {
      requiresConfirmation: true,
      requiresConfirmationWillBlockSlot: true  // Optional
    }
    ```
  </Accordion>

  <Accordion title="How do I prevent back-to-back meetings?" icon="clock">
    Add buffer time in your event type settings:

    * **Before event buffer**: Time before meetings
    * **After event buffer**: Time after meetings

    Example: 15 minutes before, 10 minutes after

    ```typescript theme={null}
    {
      beforeEventBuffer: 15,  // 15 minutes before
      afterEventBuffer: 10    // 10 minutes after
    }
    ```
  </Accordion>

  <Accordion title="Can I limit bookings per day/week?" icon="calendar-check">
    Yes! Set booking limits in your event type:

    ```typescript theme={null}
    {
      bookingLimits: {
        day: 3,     // Max 3 bookings per day
        week: 10,   // Max 10 per week
        month: 30   // Max 30 per month
      }
    }
    ```

    Or limit total duration:

    ```typescript theme={null}
    {
      durationLimits: {
        day: 180,   // Max 3 hours of meetings per day
        week: 600   // Max 10 hours per week
      }
    }
    ```
  </Accordion>

  <Accordion title="What if someone needs to reschedule?" icon="calendar-days">
    Bookers can reschedule using the link in their confirmation email. You can also:

    1. Go to **Bookings** tab
    2. Click the booking
    3. Click **Reschedule**

    Rescheduling respects your availability and sends updated notifications.

    To disable rescheduling:

    ```typescript theme={null}
    {
      disableRescheduling: {
        disabled: true,
        // Or only disable within X minutes before meeting:
        minutesBefore: 60
      }
    }
    ```
  </Accordion>

  <Accordion title="How do I handle different time zones?" icon="earth">
    Cal.com automatically handles time zones:

    * Your availability is set in **your** time zone
    * Bookers see slots in **their** time zone
    * Calendar events show correct times for both parties

    ```typescript theme={null}
    // Time zone handling from packages/lib/date-fns
    // All times stored in UTC, displayed in user's timezone
    import { formatInTimeZone } from "date-fns-tz";

    formatInTimeZone(
      booking.startTime,
      userTimeZone,
      "PPpp"  // Format: Jan 1, 2024, 10:00 AM
    );
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="No available times showing" icon="calendar-xmark">
    **Common causes:**

    1. **Availability not set**: Check your schedule in **Availability**
    2. **Calendar conflicts**: Review connected calendars for busy events
    3. **Booking notice**: Reduce `minimumBookingNotice` in event type settings
    4. **Booking window**: Extend how far ahead bookings can be made
    5. **Booking limits reached**: Check if you've hit daily/weekly limits

    **Debug steps:**

    ```typescript theme={null}
    // Check availability calculation
    // From apps/web/test/lib/getSchedule
    const schedule = await getSchedule({
      eventTypeId,
      startDate,
      endDate,
      timeZone: "America/New_York"
    });
    ```
  </Accordion>

  <Accordion title="Calendar integration not working" icon="calendar-slash">
    **Google Calendar:**

    1. Disconnect and reconnect in **Apps**
    2. Ensure you granted all permissions
    3. Check that calendars are selected in integration settings
    4. Verify OAuth redirect URIs are correct (self-hosted)

    **Outlook/Office 365:**

    1. Verify calendar permissions in Azure AD
    2. Check that API permissions include `Calendars.Read` and `Calendars.ReadWrite`
    3. Ensure consent was granted by admin (if required)
  </Accordion>

  <Accordion title="Emails not sending" icon="envelope-open-text">
    **Self-hosted only:**

    1. Verify email configuration in `.env`:
       ```bash theme={null}
       EMAIL_SERVER_HOST="smtp.gmail.com"
       EMAIL_SERVER_PORT=465
       EMAIL_FROM="your-email@gmail.com"
       ```

    2. Test SMTP connection:
       ```bash theme={null}
       # Check if SMTP server is reachable
       telnet smtp.gmail.com 465
       ```

    3. For Gmail, use an [app password](https://support.google.com/accounts/answer/185833)

    4. Check application logs for email errors

    **Cal.com Cloud:** Email issues should be rare. Contact support if emails aren't being delivered.
  </Accordion>

  <Accordion title="Time zone showing incorrectly" icon="clock">
    1. Update your time zone in **Settings** → **Profile**
    2. Clear browser cache and reload
    3. Check that system time zone is correct
    4. For event types, verify schedule time zone matches your preference

    ```typescript theme={null}
    // Time zone priority:
    // 1. Event type schedule timezone
    // 2. User profile timezone
    // 3. Browser timezone (fallback)
    ```
  </Accordion>
</AccordionGroup>

## Getting help

<CardGroup cols={2}>
  <Card title="Documentation" icon="book" href="/introduction">
    Comprehensive guides and API reference
  </Card>

  <Card title="GitHub Discussions" icon="github" href="https://github.com/calcom/cal.com/discussions">
    Ask questions and share with the community
  </Card>

  <Card title="Discord" icon="discord" href="https://cal.com/discord">
    Chat with other Cal.com users
  </Card>

  <Card title="Enterprise support" icon="headset" href="https://cal.com/sales">
    Commercial support and consulting
  </Card>
</CardGroup>

<Note>
  **Now scheduling!** You're ready to start taking bookings. Share your booking link and watch your calendar fill up.
</Note>
