* refactor: consolidate agent config folders into agents directory - Move .claude/skills and .claude/rules content to agents/ - Remove duplicate .cursor/ and .goose/ folders - Create symlinks from .claude/ and .cursor/ to agents/ - Convert review.mdc to quality-review-checklist.md with proper frontmatter Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * feat: add Cal.com APIv2 skills to agents directory Move the Cal.com API v2 skills from PR #27445 into the consolidated agents/skills/ directory structure. This includes: - SKILL.md - Main skill file with API overview - references/authentication.md - Authentication methods - references/bookings.md - Bookings API reference - references/calendars.md - Calendars API reference - references/event-types.md - Event types API reference - references/schedules.md - Schedules API reference - references/slots-availability.md - Slots and availability API reference - references/webhooks.md - Webhooks API reference Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: update calcom-api skill to use Claude Code frontmatter format Remove non-standard frontmatter fields (license, metadata) and keep only the Claude Code supported fields (name, description) as per the Claude Code skills specification. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: restructure calcom-api SKILL.md as index file Convert SKILL.md from a comprehensive API doc (317 lines) to a concise index file (108 lines) that references the detailed documentation in the references/ folder. This follows the Claude Code skills pattern of keeping SKILL.md focused with supporting files for detailed content. The SKILL.md now: - Provides a quick start guide with essential examples - References all 7 detailed reference docs in a table - Lists common workflows and best practices - Points to external resources Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * docs: preserve deleted content in reference files Move content that was removed from SKILL.md to appropriate reference files: - Add Error Handling and Pagination sections to authentication.md - Add Organization endpoints to event-types.md - Add Core Concepts section back to SKILL.md This ensures no useful API documentation is lost during the restructuring. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
7.0 KiB
7.0 KiB
Calendars API Reference
Detailed documentation for calendar integration endpoints in the Cal.com API v2.
Endpoints Overview
| Method | Endpoint | Description |
|---|---|---|
| GET | /v2/calendars | List connected calendars |
| GET | /v2/calendars/busy-times | Get busy times |
| GET | /v2/calendars/{calendar}/check | Check calendar connection |
| POST | /v2/calendars/{calendar}/connect | Connect a calendar |
| DELETE | /v2/calendars/{calendar}/disconnect | Disconnect a calendar |
| GET | /v2/calendars/{calendar}/credentials | Get calendar credentials |
| GET | /v2/destination-calendars | List destination calendars |
| GET | /v2/selected-calendars | List selected calendars |
List Connected Calendars
GET /v2/calendars
Response
{
"status": "success",
"data": {
"connectedCalendars": [
{
"integration": {
"type": "google_calendar",
"title": "Google Calendar",
"slug": "google-calendar"
},
"credentialId": 123,
"primary": {
"externalId": "primary",
"name": "john@gmail.com",
"email": "john@gmail.com",
"isSelected": true,
"readOnly": false
},
"calendars": [
{
"externalId": "primary",
"name": "john@gmail.com",
"email": "john@gmail.com",
"isSelected": true,
"readOnly": false
},
{
"externalId": "calendar-id-2",
"name": "Work Calendar",
"email": "john@gmail.com",
"isSelected": true,
"readOnly": false
}
]
}
],
"destinationCalendar": {
"id": 1,
"integration": "google_calendar",
"externalId": "primary",
"name": "john@gmail.com"
}
}
}
Get Busy Times
Check busy times from connected calendars to understand availability.
GET /v2/calendars/busy-times
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| startTime | string | Yes | ISO 8601 start of date range |
| endTime | string | Yes | ISO 8601 end of date range |
| loggedInUsersTz | string | No | User's timezone |
| credentialId | number | No | Specific calendar credential ID |
Example Request
GET /v2/calendars/busy-times?startTime=2024-01-15T00:00:00Z&endTime=2024-01-22T00:00:00Z&loggedInUsersTz=America/New_York
Response
{
"status": "success",
"data": [
{
"start": "2024-01-15T10:00:00.000Z",
"end": "2024-01-15T11:00:00.000Z",
"title": "Team Meeting",
"source": "google_calendar"
},
{
"start": "2024-01-16T14:00:00.000Z",
"end": "2024-01-16T15:00:00.000Z",
"title": "Client Call",
"source": "google_calendar"
}
]
}
Calendar Connection
Check Calendar Connection
GET /v2/calendars/{calendar}/check
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| calendar | string | Calendar type (e.g., google-calendar, office365-calendar) |
Connect a Calendar
POST /v2/calendars/{calendar}/connect
This initiates the OAuth flow for calendar connection.
Disconnect a Calendar
DELETE /v2/calendars/{calendar}/disconnect
Supported Calendar Types
| Type | Slug | Description |
|---|---|---|
| Google Calendar | google-calendar | Google Workspace calendars |
| Microsoft 365 | office365-calendar | Outlook/Microsoft 365 calendars |
| Apple Calendar | apple-calendar | iCloud calendars (CalDAV) |
| CalDAV | caldav-calendar | Generic CalDAV calendars |
Destination Calendars
The destination calendar is where new bookings are created.
List Destination Calendars
GET /v2/destination-calendars
Response
{
"status": "success",
"data": [
{
"id": 1,
"integration": "google_calendar",
"externalId": "primary",
"name": "john@gmail.com",
"userId": 123,
"eventTypeId": null,
"credentialId": 456
}
]
}
Selected Calendars
Selected calendars are checked for conflicts when calculating availability.
List Selected Calendars
GET /v2/selected-calendars
Response
{
"status": "success",
"data": [
{
"integration": "google_calendar",
"externalId": "primary",
"credentialId": 123
},
{
"integration": "google_calendar",
"externalId": "work-calendar-id",
"credentialId": 123
}
]
}
ICS Feed
Check ICS Feed
GET /v2/calendars/ics-feed/check
Save ICS Feed
POST /v2/calendars/ics-feed/save
{
"url": "https://calendar.example.com/feed.ics"
}
Calendar Events
Get Calendar Event
GET /v2/calendars/{calendar}/events/{eventUid}
Response
{
"status": "success",
"data": {
"id": "event-id-123",
"title": "Meeting",
"description": "Discussion",
"start": {
"time": "2024-01-15T10:00:00.000Z",
"timeZone": "America/New_York"
},
"end": {
"time": "2024-01-15T11:00:00.000Z",
"timeZone": "America/New_York"
},
"attendees": [
{
"email": "attendee@example.com",
"name": "Attendee Name",
"responseStatus": "accepted"
}
],
"status": "accepted",
"source": "google"
}
}
Understanding Calendar Integration
How Calendars Affect Availability
- Selected Calendars: Events from selected calendars block availability
- Destination Calendar: New bookings are created in this calendar
- Busy Times: The API aggregates busy times from all selected calendars
Calendar Sync Flow
1. User connects calendar (OAuth)
POST /v2/calendars/google-calendar/connect
2. User selects which calendars to check for conflicts
(Done via Cal.com dashboard)
3. User sets destination calendar for new bookings
(Done via Cal.com dashboard)
4. When checking slots:
- API fetches busy times from all selected calendars
- Busy times are excluded from available slots
5. When booking is created:
- Event is created in destination calendar
- Confirmation emails sent to attendees
Cal.com Event Identification
Cal.com events in external calendars can be identified by their iCalUID ending with @Cal.com (e.g., 2GBXSdEixretciJfKVmYN8@Cal.com).
Team Calendar Integration
For team-level calendar management:
Team Conferencing
GET /v2/organizations/{orgId}/teams/{teamId}/conferencing
Connect Team Calendar
POST /v2/organizations/{orgId}/teams/{teamId}/conferencing/{app}/connect
Best Practices
- Check connection status: Verify calendar is connected before operations
- Handle OAuth expiry: Calendar tokens may expire, handle re-authentication
- Respect rate limits: Calendar APIs have their own rate limits
- Cache busy times: Busy times don't change frequently, cache appropriately
- Use webhooks: Subscribe to booking events instead of polling calendars