* feat: Cal.diy — community-driven MIT-licensed fork of Cal.com This squashed commit contains all Cal.diy changes applied on top of calcom/cal.com main: - Rebrand Cal.com to Cal.diy across the entire codebase - Remove Enterprise Edition (EE) features, license checks, and AGPL restrictions - Switch license from AGPL-3.0 to MIT - Remove docs/ directory (migrated to Nextra at cal.diy) - Remove dead code: org tests, EE tips, platform nav, premium username, SAML/SSO, etc. - Clean up .env.example for self-hosted Cal.diy - Update Docker image references to calcom/cal.diy - Update README, CONTRIBUTING.md, and issue templates for Cal.diy community fork - Add PR welcome bot for Cal.diy contributors - Fix API v2 breaking changes oasdiff ignore entries - Replace Blacksmith CI runners with default GitHub Actions 3893 files changed, 20789 insertions(+), 411020 deletions(-) Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * refactor: remove org-specific /organizations/:orgId endpoints from API v2 atoms controllers (#1701) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: revert Cal.diy Inc to Cal.com, Inc. in license files, copyright notices, and package metadata (#1702) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * rip out org related comments in api v2 --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
5.9 KiB
Slots and Availability API Reference
Detailed documentation for checking availability and managing slots in the Cal.diy API v2.
Endpoints Overview
| Method | Endpoint | Description |
|---|---|---|
| GET | /v2/slots | Get available time slots |
| POST | /v2/slots/reservations | Reserve a slot temporarily |
| DELETE | /v2/slots/reservations/{uid} | Release a reserved slot |
| GET | /v2/calendars/busy-times | Get busy times from calendars |
Get Available Slots
Check available time slots for booking an event type.
GET /v2/slots
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| startTime | string | Yes | ISO 8601 start of date range |
| endTime | string | Yes | ISO 8601 end of date range |
| eventTypeId | number | Conditional | Event type ID (required if no slug) |
| eventTypeSlug | string | Conditional | Event type slug (required if no ID) |
| usernameList | string | Conditional | Comma-separated usernames for team events |
| timeZone | string | No | Timezone for slot display (default: UTC) |
| duration | number | No | Override event duration in minutes |
| rescheduleUid | string | No | Booking UID if rescheduling |
Example Request
GET /v2/slots?startTime=2024-01-15T00:00:00Z&endTime=2024-01-22T00:00:00Z&eventTypeId=123&timeZone=America/New_York
Response
{
"status": "success",
"data": {
"slots": {
"2024-01-15": [
{
"time": "2024-01-15T09:00:00.000Z"
},
{
"time": "2024-01-15T09:30:00.000Z"
},
{
"time": "2024-01-15T10:00:00.000Z"
}
],
"2024-01-16": [
{
"time": "2024-01-16T09:00:00.000Z"
}
]
}
}
}
Response with Attendees (Seated Events)
For event types with seatsPerTimeSlot configured:
{
"status": "success",
"data": {
"slots": {
"2024-01-15": [
{
"time": "2024-01-15T09:00:00.000Z",
"attendees": 3,
"seatsAvailable": 7
}
]
}
}
}
Reserve a Slot
Temporarily reserve a slot while the user completes the booking form. This prevents double-booking.
POST /v2/slots/reservations
Request Body
{
"eventTypeId": 123,
"slotUtcStartDate": "2024-01-15T09:00:00.000Z",
"slotUtcEndDate": "2024-01-15T09:30:00.000Z"
}
Response
{
"status": "success",
"data": {
"uid": "reservation-uid-123",
"eventTypeId": 123,
"slotUtcStartDate": "2024-01-15T09:00:00.000Z",
"slotUtcEndDate": "2024-01-15T09:30:00.000Z",
"expiresAt": "2024-01-15T08:10:00.000Z"
}
}
Reservations automatically expire after a short period (typically 10 minutes).
Release a Reserved Slot
Release a slot reservation if the user abandons the booking flow.
DELETE /v2/slots/reservations/{uid}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| uid | string | Reservation UID |
Get Busy Times
Check busy times from connected calendars.
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 |
Response
{
"status": "success",
"data": [
{
"start": "2024-01-15T10:00:00.000Z",
"end": "2024-01-15T11:00:00.000Z",
"title": "Existing Meeting",
"source": "google_calendar"
}
]
}
Routing Form Slots
For routing forms that direct to different event types:
POST /v2/routing-forms/{routingFormId}/calculate-slots
Request Body
{
"startTime": "2024-01-15T00:00:00Z",
"endTime": "2024-01-22T00:00:00Z",
"timeZone": "America/New_York",
"responses": {
"field1": "value1",
"field2": "value2"
}
}
Understanding Slot Availability
Slots are calculated based on:
- User's Schedule: Working hours defined in their schedule
- Existing Bookings: Times already booked
- Calendar Busy Times: Events from connected calendars
- Buffer Times: Before/after event buffers
- Minimum Notice: Minimum booking notice period
- Booking Limits: Daily/weekly/monthly booking limits
Best Practices
Efficient Slot Fetching
- Limit date range: Request only the dates you need to display
- Cache results: Slots don't change frequently, cache for short periods
- Use timezone parameter: Request slots in user's timezone to avoid conversion
Preventing Double Bookings
- Reserve slots: Use slot reservations for multi-step booking flows
- Handle expiration: Reservations expire - handle gracefully
- Verify before booking: Always verify slot is still available before creating booking
Example Booking Flow
1. User selects date range
GET /v2/slots?startTime=...&endTime=...&eventTypeId=123
2. User selects a slot
POST /v2/slots/reservations
{
"eventTypeId": 123,
"slotUtcStartDate": "2024-01-15T09:00:00Z",
"slotUtcEndDate": "2024-01-15T09:30:00Z"
}
3. User fills booking form
4. Create booking
POST /v2/bookings
{
"start": "2024-01-15T09:00:00Z",
"eventTypeId": 123,
"attendee": {...}
}
5. If user abandons, release reservation
DELETE /v2/slots/reservations/{uid}
Timezone Handling
All times in the API are in UTC (ISO 8601 format). Use the timeZone parameter to receive slots in a specific timezone for display purposes.
GET /v2/slots?startTime=2024-01-15T00:00:00Z&endTime=2024-01-22T00:00:00Z&eventTypeId=123&timeZone=Europe/London
The response times will still be in UTC, but the slot calculation will respect the user's timezone for determining available hours.