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

# Authentication

> Authenticate with the Cal.com Platform API using API keys or OAuth 2.0

The Cal.com Platform API supports two authentication methods: API keys for server-to-server communication and OAuth 2.0 for third-party applications.

## Authentication Methods

<CardGroup cols={2}>
  <Card title="API Keys" icon="key">
    Simple authentication for server-to-server integrations
  </Card>

  <Card title="OAuth 2.0" icon="shield-check">
    Secure authentication for third-party applications
  </Card>
</CardGroup>

## API Key Authentication

API keys are the simplest way to authenticate with the Platform API. They're ideal for:

* Server-to-server integrations
* Internal tools and scripts
* Testing and development

### Creating an API Key

1. Log in to your Cal.com account
2. Navigate to **Settings** > **Security** > **API Keys**
3. Click **Create New API Key**
4. Give your key a descriptive name
5. Copy the key immediately (it won't be shown again)

### Using API Keys

Include your API key in the `Authorization` header as a Bearer token:

```bash theme={null}
curl -X GET https://api.cal.com/v2/bookings \
  -H "Authorization: Bearer cal_live_xxxxxxxxxxxxxxxx"
```

<Note>
  API keys start with `cal_live_` for production and `cal_test_` for development environments.
</Note>

### API Key Formats

```
cal_live_xxxxxxxxxxxxxxxx  # Production key
cal_test_xxxxxxxxxxxxxxxx  # Test/development key
```

### Example Request with API Key

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.cal.com/v2/bookings \
    -H "Authorization: Bearer cal_live_sk_xxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "eventTypeId": 123,
      "start": "2024-03-15T10:00:00Z",
      "responses": {
        "name": "John Doe",
        "email": "john@example.com"
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.cal.com/v2/bookings', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer cal_live_sk_xxxxx',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      eventTypeId: 123,
      start: '2024-03-15T10:00:00Z',
      responses: {
        name: 'John Doe',
        email: 'john@example.com'
      }
    })
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.cal.com/v2/bookings',
      headers={
          'Authorization': 'Bearer cal_live_sk_xxxxx',
          'Content-Type': 'application/json'
      },
      json={
          'eventTypeId': 123,
          'start': '2024-03-15T10:00:00Z',
          'responses': {
              'name': 'John Doe',
              'email': 'john@example.com'
          }
      }
  )
  ```
</CodeGroup>

### Refreshing API Keys

You can refresh an API key to generate a new one and invalidate the old one:

```bash theme={null}
POST /v2/api-keys/refresh
```

**Request:**

```bash theme={null}
curl -X POST https://api.cal.com/v2/api-keys/refresh \
  -H "Authorization: Bearer cal_live_old_key" \
  -H "Content-Type: application/json" \
  -d '{
    "expiresAt": "2025-12-31T23:59:59Z"
  }'
```

**Response:**

```json theme={null}
{
  "status": "success",
  "data": {
    "apiKey": "cal_live_new_xxxxxxxxxxxxxxxx"
  }
}
```

<Warning>
  The old API key will be immediately invalidated. Update all systems using the old key before refreshing.
</Warning>

## OAuth 2.0 Authentication

OAuth 2.0 is recommended for third-party applications that need to access Cal.com data on behalf of users. It provides:

* Secure delegated access
* User authorization
* Token-based authentication
* Scope-based permissions

See the [OAuth 2.0 Guide](/api/oauth) for detailed implementation instructions.

### OAuth Flow Overview

<Steps>
  <Step title="Register OAuth Client">
    Create an OAuth client in your Cal.com settings
  </Step>

  <Step title="Redirect User to Authorization">
    Send users to the authorization endpoint
  </Step>

  <Step title="Receive Authorization Code">
    User authorizes and you receive a code
  </Step>

  <Step title="Exchange Code for Tokens">
    Exchange the authorization code for access and refresh tokens
  </Step>

  <Step title="Make API Requests">
    Use the access token to make authenticated requests
  </Step>
</Steps>

### Using Access Tokens

Access tokens are used the same way as API keys:

```bash theme={null}
curl -X GET https://api.cal.com/v2/bookings \
  -H "Authorization: Bearer <access_token>"
```

## Authentication Guard Types

The Platform API uses different authentication guards for different endpoints:

### ApiAuthGuard

Requires valid authentication (API key or OAuth token):

```typescript theme={null}
@UseGuards(ApiAuthGuard)
@Get('/bookings')
async getBookings(@GetUser() user: UserWithProfile) {
  // User is authenticated
}
```

### OptionalApiAuthGuard

Authentication is optional but will extract user info if provided:

```typescript theme={null}
@UseGuards(OptionalApiAuthGuard)
@Get('/public-data')
async getPublicData(@GetOptionalUser() user?: AuthOptionalUser) {
  // User may or may not be authenticated
}
```

## Authentication Methods Comparison

| Feature                     | API Keys              | OAuth 2.0           |
| --------------------------- | --------------------- | ------------------- |
| **Use Case**                | Server-to-server      | Third-party apps    |
| **Setup Complexity**        | Simple                | Moderate            |
| **User Authorization**      | Not required          | Required            |
| **Token Expiration**        | Optional              | Automatic           |
| **Scope-based Permissions** | No                    | Yes                 |
| **Best For**                | Internal integrations | Public applications |

## Security Best Practices

<AccordionGroup>
  <Accordion title="Store Credentials Securely">
    * Never commit API keys to version control
    * Use environment variables or secure vaults
    * Rotate keys regularly
    * Use different keys for different environments
  </Accordion>

  <Accordion title="Use HTTPS Only">
    * Always use HTTPS for API requests
    * Never send credentials over unencrypted connections
    * Verify SSL certificates
  </Accordion>

  <Accordion title="Implement Token Refresh">
    * Refresh OAuth tokens before they expire
    * Handle token expiration gracefully
    * Store refresh tokens securely
  </Accordion>

  <Accordion title="Limit Scope and Permissions">
    * Request only the scopes you need
    * Use read-only scopes when possible
    * Review permissions regularly
  </Accordion>
</AccordionGroup>

## Error Handling

### 401 Unauthorized

Returned when authentication credentials are missing or invalid:

```json theme={null}
{
  "status": "error",
  "error": {
    "message": "Invalid API key",
    "code": "UNAUTHORIZED"
  }
}
```

**Common causes:**

* Missing `Authorization` header
* Invalid API key format
* Expired access token
* Revoked credentials

### 403 Forbidden

Returned when the authenticated user lacks permissions:

```json theme={null}
{
  "status": "error",
  "error": {
    "message": "Insufficient permissions",
    "code": "FORBIDDEN"
  }
}
```

**Common causes:**

* Insufficient OAuth scopes
* Attempting to access another user's resources
* Organization/team permission restrictions

## Testing Authentication

Test your authentication setup with a simple request:

```bash theme={null}
curl -X GET https://api.cal.com/v2/bookings \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -v
```

Successful authentication returns a 200 status code and your bookings data.

## Rate Limits by Authentication Type

| Authentication Method | Default Limit | Time Window |
| --------------------- | ------------- | ----------- |
| API Key               | 120 requests  | 60 seconds  |
| OAuth Client          | 500 requests  | 60 seconds  |
| Access Token          | 500 requests  | 60 seconds  |
| Unauthenticated (IP)  | 120 requests  | 60 seconds  |

See [Rate Limits](/api/rate-limits) for more details.

## Migration from v1 to v2

If you're migrating from API v1:

* API keys remain the same
* Base URL changes from `/api/v1` to `/v2`
* Add `cal-api-version` header for version control
* OAuth 2.0 implementation is new in v2

## Next Steps

<CardGroup cols={2}>
  <Card title="OAuth 2.0 Guide" icon="shield" href="/api/oauth">
    Learn how to implement OAuth 2.0
  </Card>

  <Card title="Rate Limits" icon="gauge" href="/api/rate-limits">
    Understand rate limiting policies
  </Card>

  <Card title="Webhooks" icon="webhook" href="/api/webhooks">
    Set up webhook authentication
  </Card>

  <Card title="API Reference" icon="book" href="/api/reference">
    Browse all available endpoints
  </Card>
</CardGroup>
