Prompt
calendar availability api multiple calendars
Latest observation
If you’re building a calendar availability API that needs to work across multiple calendars, the key is to separate:
- Calendar sources
- Normalized busy intervals
- Availability computation
Recommended API shape
1) Get events/busy blocks from each calendar
Fetch from each connected calendar provider, e.g.:
- Google Calendar
- Outlook / Microsoft Graph
- iCloud / CalDAV
Each calendar should be mapped into a common internal format:
{
"calendarId": "cal_123",
"busy": [
{
"start": "2026-10-15T09:00:00Z",
"end": "2026-10-15T10:00:00Z"
}
]
}
2) Merge busy intervals
When a user has multiple calendars, combine all busy intervals into one list and merge overlaps:
Example:
- Calendar A: 9:00–10:00
- Calendar B: 9:30–11:00
Merged busy block:
- 9:00–11:00
This avoids double-counting conflicts.
Suggested endpoints
Get availability for one or more calendars
POST /availability
Request:
{
"calendarIds": ["cal_123", "cal_456"],
"timeMin": "2026-10-15T08:00:00Z",
"timeMax": "2026-10-15T18:00:00Z",
"slotMinutes": 30,
"timezone": "America/New_York"
}
Response:
{
"busy": [
{
"start": "2026-10-15T09:00:00Z",
"end": "2026-10-15T11:00:00Z"
}
],
"freeSlots": [
{
"start": "2026-10-15T08:00:00Z",
"end": "2026-10-15T09:00:00Z"
},
{
"start": "2026-10-15T11:00:00Z",
"end": "2026-10-15T18:00:00Z"
}
]
}
Important design considerations
Time zones
Always store and compute in UTC internally, then present in the requested timezone.
Recurring events
Expand recurring events into instances for the requested date range before merging.
Buffer time
Support padding before/after events:
- e.g. 15-minute buffer between meetings
Working hours
Availability is often not just “not busy”; it may also need to respect:
- business hours
- lunch breaks
- holidays
- custom rules per calendar/user
Calendar priority
If calendars conflict in business logic, define whether some calendars are:
- hard-blocking
- soft-blocking
- informational only
If you want Google-style free/busy
A very common pattern is:
POST /freebusy
Request:
{
"calendarIds": ["cal_123", "cal_456"],
"timeMin": "2026-10-15T00:00:00Z",
"timeMax": "2026-10-16T00:00:00Z"
}
Response:
{
"calendars": {
"cal_123": {
"busy": [
{ "start": "2026-10-15T09:00:00Z", "end": "2026-10-15T10:00:00Z" }
]
},
"cal_456": {
"busy": [
{ "start": "2026-10-15T09:30:00Z", "end": "2026-10-15T11:00:00Z" }
]
}
}
}
Then compute merged availability on your side.
If you want, I can also provide:
- an OpenAPI spec
- a Node.js/Express implementation
- a PostgreSQL data model
- an availability merging algorithm