> ## Documentation Index
> Fetch the complete documentation index at: https://raveculture-mintlify-api-calendar-invite-security-1774475202.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Calendar API

> Google Calendar integration endpoints for OAuth, event management, and availability checks

# Calendar API

Connect a Google Calendar account and manage events, check availability, and schedule directly through the API.

<Note>All calendar endpoints require an authenticated session. The user is identified from the session automatically — you do not pass a `userId` parameter.</Note>

<Note>Most calendar endpoints also require a connected Google Calendar account. Use the [connect flow](#connect-calendar) to authorize access before calling event endpoints.</Note>

## Base URL

```
https://agentbot.raveculture.xyz/api/calendar
```

## Authentication

All calendar endpoints require a valid NextAuth session. Requests without an active session receive a `401 Unauthorized` response (or a redirect to `/login` for browser-based flows).

The authenticated user's identity is derived from the session. You do not need to include a `userId` parameter in any request.

## Token storage

Calendar tokens (access and refresh tokens) are encrypted at rest using AES-256-GCM before being persisted to the database. Tokens are never stored in plaintext.

## Connect calendar

```http theme={"dark"}
POST /api/calendar
```

Initiates the Google Calendar OAuth flow. Returns an authorization URL that the user must visit to grant calendar access.

### Request body

| Field    | Type   | Required | Description       |
| -------- | ------ | -------- | ----------------- |
| `action` | string | Yes      | Must be `connect` |

### Response

```json theme={"dark"}
{
  "authUrl": "https://accounts.google.com/o/oauth2/v2/auth?..."
}
```

Redirect the user to `authUrl` to begin the OAuth consent flow. After granting access, Google redirects to the callback endpoint below.

### Errors

| Code | Description                           |
| ---- | ------------------------------------- |
| 401  | Not authenticated (no active session) |
| 400  | Invalid action                        |

## OAuth callback

```http theme={"dark"}
GET /api/calendar/callback
```

Handles the OAuth authorization code exchange after Google redirects the user back from the consent screen. You do not call this endpoint directly — Google redirects to it automatically.

### Query parameters

| Parameter | Type   | Description                                                                                                                                      |
| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `code`    | string | Authorization code provided by Google                                                                                                            |
| `state`   | string | HMAC-signed state token generated during the connect flow. Contains the user ID and a timestamp, verified on callback. Expires after 10 minutes. |
| `error`   | string | Error code if the user denied access or an error occurred                                                                                        |

### Behavior

On success, this endpoint:

1. Verifies the HMAC-signed state parameter and checks it has not expired.
2. Exchanges the authorization code for access and refresh tokens.
3. Retrieves the user's primary calendar ID and timezone.
4. Encrypts and persists the tokens to the database (AES-256-GCM).
5. Redirects to `/dashboard/calendar?connected=true`.

### Error redirects

If an error occurs, the endpoint redirects to `/dashboard/calendar` with an `error` query parameter:

| Redirect query         | Description                                              |
| ---------------------- | -------------------------------------------------------- |
| `error=<google_error>` | The user denied access or Google returned an error       |
| `error=no_code`        | No authorization code was present in the callback        |
| `error=token_failed`   | The authorization code could not be exchanged for tokens |
| `error=unknown`        | An unexpected error occurred during the callback         |

## Start OAuth (redirect)

```http theme={"dark"}
GET /api/calendar?action=auth
```

Redirects the browser directly to the Google OAuth consent screen. This is an alternative to the POST-based connect flow — use it when you want a simple link-based authorization.

Requires an active session. If the user is not authenticated, this endpoint redirects to `/login`.

### Query parameters

| Parameter | Type   | Required | Description    |
| --------- | ------ | -------- | -------------- |
| `action`  | string | Yes      | Must be `auth` |

## List events

```http theme={"dark"}
GET /api/calendar?action=list
```

Returns calendar events within a date range. The user is identified from the session.

### Query parameters

| Parameter | Type   | Required | Description                                      |
| --------- | ------ | -------- | ------------------------------------------------ |
| `action`  | string | Yes      | Must be `list`                                   |
| `start`   | string | No       | ISO 8601 start date. Defaults to now.            |
| `end`     | string | No       | ISO 8601 end date. Defaults to 30 days from now. |

### Response

```json theme={"dark"}
{
  "events": [
    {
      "id": "event_abc123",
      "summary": "Team standup",
      "start": { "dateTime": "2026-03-24T10:00:00Z" },
      "end": { "dateTime": "2026-03-24T10:30:00Z" },
      "location": "Zoom"
    }
  ],
  "timezone": "America/New_York"
}
```

### Errors

| Code | Description                                 |
| ---- | ------------------------------------------- |
| 401  | Not authenticated or calendar not connected |

## Check availability

```http theme={"dark"}
GET /api/calendar?action=availability
```

Returns available and busy time slots for a given date. Slots are one hour each, from 09:00 to 23:00. The user is identified from the session.

### Query parameters

| Parameter | Type   | Required | Description                                     |
| --------- | ------ | -------- | ----------------------------------------------- |
| `action`  | string | Yes      | Must be `availability`                          |
| `date`    | string | No       | Date in `YYYY-MM-DD` format. Defaults to today. |

### Response

```json theme={"dark"}
{
  "availableSlots": [
    { "start": "2026-03-24T09:00:00", "end": "2026-03-24T10:00:00" },
    { "start": "2026-03-24T11:00:00", "end": "2026-03-24T12:00:00" }
  ],
  "busySlots": [
    { "start": "2026-03-24T10:00:00Z", "end": "2026-03-24T11:00:00Z" }
  ],
  "date": "2026-03-24"
}
```

### Errors

| Code | Description                                 |
| ---- | ------------------------------------------- |
| 401  | Not authenticated or calendar not connected |

## Create event

```http theme={"dark"}
POST /api/calendar
```

Creates a new calendar event. The user is identified from the session.

### Request body

| Field         | Type      | Required | Description                      |
| ------------- | --------- | -------- | -------------------------------- |
| `action`      | string    | Yes      | Must be `create-event`           |
| `title`       | string    | Yes      | Event title                      |
| `start`       | string    | Yes      | ISO 8601 start time              |
| `end`         | string    | Yes      | ISO 8601 end time                |
| `description` | string    | No       | Event description                |
| `location`    | string    | No       | Event location                   |
| `attendees`   | string\[] | No       | List of attendee email addresses |

### Example request

```json theme={"dark"}
{
  "action": "create-event",
  "title": "DJ Set @ Warehouse",
  "start": "2026-03-28T22:00:00Z",
  "end": "2026-03-29T02:00:00Z",
  "location": "Warehouse 42, London",
  "attendees": ["promoter@example.com"]
}
```

### Response

```json theme={"dark"}
{
  "success": true,
  "eventId": "event_abc123",
  "event": {
    "id": "event_abc123",
    "summary": "DJ Set @ Warehouse",
    "start": { "dateTime": "2026-03-28T22:00:00Z" },
    "end": { "dateTime": "2026-03-29T02:00:00Z" }
  }
}
```

### Errors

| Code | Description                                 |
| ---- | ------------------------------------------- |
| 401  | Not authenticated or calendar not connected |
| 500  | Internal error                              |

## Update event

```http theme={"dark"}
POST /api/calendar
```

Updates an existing calendar event. Only the fields you include are changed. The user is identified from the session.

### Request body

| Field         | Type   | Required | Description                   |
| ------------- | ------ | -------- | ----------------------------- |
| `action`      | string | Yes      | Must be `update-event`        |
| `eventId`     | string | Yes      | ID of the event to update     |
| `title`       | string | No       | Updated event title           |
| `description` | string | No       | Updated description           |
| `start`       | string | No       | Updated start time (ISO 8601) |
| `end`         | string | No       | Updated end time (ISO 8601)   |
| `location`    | string | No       | Updated location              |

### Response

```json theme={"dark"}
{
  "success": true,
  "event": { "id": "event_abc123", "summary": "Updated title" }
}
```

### Errors

| Code | Description                                 |
| ---- | ------------------------------------------- |
| 401  | Not authenticated or calendar not connected |
| 500  | Internal error                              |

## Delete event

```http theme={"dark"}
POST /api/calendar
```

Deletes a calendar event. The user is identified from the session.

### Request body

| Field     | Type   | Required | Description               |
| --------- | ------ | -------- | ------------------------- |
| `action`  | string | Yes      | Must be `delete-event`    |
| `eventId` | string | Yes      | ID of the event to delete |

### Response

```json theme={"dark"}
{
  "success": true
}
```

### Errors

| Code | Description                                 |
| ---- | ------------------------------------------- |
| 401  | Not authenticated or calendar not connected |
| 500  | Internal error                              |

## Quick add

```http theme={"dark"}
POST /api/calendar
```

Creates an event from a natural language string using Google Calendar's quick-add feature. The user is identified from the session.

### Request body

| Field    | Type   | Required | Description                                                                              |
| -------- | ------ | -------- | ---------------------------------------------------------------------------------------- |
| `action` | string | Yes      | Must be `quick-add`                                                                      |
| `text`   | string | Yes      | Natural language event description (for example, `"Meeting with Sarah tomorrow at 3pm"`) |

### Response

```json theme={"dark"}
{
  "success": true,
  "eventId": "event_abc123"
}
```

### Errors

| Code | Description                                 |
| ---- | ------------------------------------------- |
| 401  | Not authenticated or calendar not connected |
| 500  | Internal error                              |
