Calendar API¶
This document describes the endpoints for integrating external calendars (Google, Outlook) with the user's workspace. All endpoints require authentication.
Google Integration¶
Initiate Google Connection¶
Generates a Google OAuth authorization URL wrapped by WorkOS. The frontend should redirect the user to the returned redirectUrl to begin the consent flow.
Endpoint: POST /api/v1/calendar/google/connect
Request Body:
{
"state": "random_string_xyz",
"codeChallenge": "pkce_challenge_string"
}
Parameters:
state(required): A random string generated by the client to prevent CSRF attacks.codeChallenge(required): The PKCE code challenge generated by the client.
Success Response: 200 OK
{
"authData": {
"redirectUrl": "https://api.workos.com/oauth/authorize?response_type=code&client_id=...&provider=Google..."
}
}
Finalize Connection¶
Completes the OAuth flow by exchanging the authorization code for access and refresh tokens. This endpoint is called after the user is redirected back from Google/WorkOS.
Endpoint: POST /api/v1/calendar/google/finalize-connection
Request Body:
{
"code": "0192e...",
"codeVerifier": "pkce_verifier_string..."
}
Parameters:
code(required): The authorization code received in the query parameters from the WorkOS redirect.codeVerifier(required): The original PKCE verifier used to generate the codeChallenge in the initiate step.
Success Response: 200 OK
List Calendars¶
Retrieves the list of all calendars associated with the user's Google account (e.g., Primary, Birthdays, Shared Calendars).
Endpoint: GET /api/v1/calendar/google/calendars
Request Body: None
Success Response: 200 OK
[
{
"id": "primary",
"name": "john.doe@example.com",
"color": "#123456"
},
{
"id": "addressbook#contacts@group.v.calendar.google.com",
"name": "Birthdays",
"color": "#92e1c0"
}
]
Batch List Events¶
Retrieves events for multiple calendars or time ranges in a single request. This endpoint is optimized to reduce payload size by returning instances for recurring events (expanded) but stripping unused metadata.
Endpoint: POST /api/v1/calendar/google/events
Request Body:
{
"calendars": [
{
"calendarId": "primary",
"timeMin": "2025-12-01T00:00:00Z",
"timeMax": "2026-01-31T23:59:59Z"
},
{
"calendarId": "team@example.com",
"timeMin": "2025-12-01T00:00:00Z",
"timeMax": "2026-01-31T23:59:59Z"
}
]
}
Parameters:
calendarId(required): The ID of the calendar to fetch (use"primary"for the main calendar).timeMin(required): Start of the time range (RFC3339 format).timeMax(required): End of the time range (RFC3339 format).
Success Response: 200 OK
Returns an array of objects, each representing a calendar's result
[
{
"calendarId": "primary",
"events": [
{
"id": "73qusdveu121_20260119T110000Z",
"calendarId": "primary",
"title": "Weekly Standup",
"start": "2026-01-19T12:00:00+01:00",
"startTimezone": "Europe/Rome",
"end": "2026-01-19T12:30:00+01:00",
"endTimezone": "Europe/Rome",
"recurringEventId": "73qusdveu121",
"organizer": {
"email": "boss@example.com"
},
"attendees": [
{
"email": "me@example.com",
"status": "accepted"
}
]
}
]
},
{
"calendarId": "anothercalendar@example.com",
"events": [
{
"id": "73qusdv42dd121_20260319T110000Z",
"calendarId": "anotherone",
"title": "Hello World",
"start": "2026-01-19T12:00:00+01:00",
"startTimezone": "Europe/Rome",
"end": "2026-01-19T12:30:00+01:00",
"endTimezone": "Europe/Rome",
"recurringEventId": "3qusdv42dd121",
"organizer": {
"email": "team@example.com"
},
"attendees": [
{
"email": "me@example.com",
"status": "pending"
}
]
}
],
}
]
Batch Get Event Details ¶
Retrieves full details for specific events given a list of IDs.
Primary Use Case: Fetching the "Master" event for a recurring series to obtain the recurrence rule (RRULE), which is usually missing from the expanded instances returned by the List endpoint.
Endpoint: POST /api/v1/calendar/google/events/details
Request Body:
{
"events": [
{
"calendarId": "primary",
"eventId": "73qusdveu121"
}
]
}
events (required): An array of objects containing:
- calendarId: The ID of the calendar where the event exists.
- eventId: The ID of the event to fetch.
Tip: Pass the recurringEventId (e.g., "73qusdveu121") found in the List endpoint response, not the instance ID (e.g., "73qusdveu121_2026..."), if you want to get the recurrence rules.
Success Response: 200 OK
Returns a flat array of the requested events.
[
{
"id": "73qusdveu121",
"calendarId": "primary",
"title": "Weekly Standup",
"description": "Full agenda in the doc...",
"start": "2026-01-19T12:00:00+01:00",
"startTimezone": "Europe/Rome",
"end": "2026-01-19T12:30:00+01:00",
"endTimezone": "Europe/Rome",
"recurrence": "RRULE:FREQ=WEEKLY;BYDAY=MO",
"organizer": {
"email": "boss@example.com",
"name": "The Boss"
},
"attendees": [
{
"email": "me@example.com",
"status": "accepted"
}
]
}
]
<!-- ### Get Connection Status Checks if the Google calendar integration is currently enabled for the authenticated user.
Endpoint: GET /api/v1/calendar/google/status
Request Body: None
Success Response: 200 OK
{
"isCalendarEnabled": true
}
Update Connection Status¶
Toggles the active state of the calendar integration (soft disable/enable) without deleting the stored tokens.
Endpoint: POST /api/v1/calendar/google/status/update
Request Body:
{
"enabled": false
}
enabled (required): A bool value that set display user preferences.
Success Response: 200 OK
Returns the updated state.
{
"isCalendarEnabled": false
}
``` -->
### <span style="color: #2196F3;">Disconnect Google Calendar</span>
Disconnects the Google Calendar integration by deleting the stored refresh token, without revoking the token on the provider side.
**Endpoint:** `POST /api/v1/calendar/google/disconnect`
**Request Body:** None
**Success Response:** `200 OK`
---
## <span style="color: #2196F3;">Microsoft Integration (FUTURE)</span>
### <span style="color: #2196F3;">Initiate Outlook Connection (FUTURE)</span>
Generates a Microsoft OAuth authorization URL.
**Endpoint:** `POST /api/v1/calendar/microsoft/connect`
**Request Body:**
```json
{
"state": "random_string_xyz",
"codeChallenge": "pkce_challenge_string"
}
Parameters:
state(required): A random string generated by the client to prevent CSRF attacks.codeChallenge(required): The PKCE code challenge generated by the client.
Success Response: 200 OK
{
"redirectUrl": "https://api.workos.com/oauth/authorize?..."
}
Disconnect Calendar (FUTURE)¶
Revokes the integration with the microsoft calendar provider and deletes the stored tokens. This stops all background synchronization.
Endpoint: POST /api/v1/calendar/microsoft/disconnect
Request Body: None
Success Response: 200 OK