JS/TS SDK
Calendar & Availability
Query calendars, events, and busy times.
Understanding Calendar Queries
The Calendar API provides read-only access to user calendars and availability information across multiple providers. Use these methods to list calendars, query events, and check busy times for scheduling applications.
List Calendars
Get all calendars connected to a user across their calendar providers.
// List all calendars
const calendars = await recal.calendar.list('user_id')
// Filter by provider
const googleCalendars = await recal.calendar.list('user_id', {
provider: 'google'
})
const microsoftCalendars = await recal.calendar.list('user_id', {
provider: 'microsoft'
})Each calendar includes:
id: Provider-specific calendar IDname: Calendar display nameprimary: Whether this is the user's primary calendarbackgroundColor: Calendar colortimeZone: Calendar timezone (e.g., "America/New_York")accessRole: User's access level (owner,writer,reader,freeBusyReader)
List Events
Retrieve events from a user's calendars within a date range.
// List all events in a date range
const events = await recal.calendar.listEvents('user_id', {
start: '2024-01-01T00:00:00Z',
end: '2024-01-31T23:59:59Z'
})
// Filter by provider
const googleEvents = await recal.calendar.listEvents('user_id', {
start: '2024-01-01T00:00:00Z',
end: '2024-01-31T23:59:59Z',
provider: 'google'
})
// Specify timezone for results
const eventsInET = await recal.calendar.listEvents('user_id', {
start: '2024-01-01T00:00:00Z',
end: '2024-01-31T23:59:59Z',
provider: ['google', 'microsoft'],
timeZone: 'America/New_York'
})Parameters:
start(required): ISO 8601 timestamp for range startend(required): ISO 8601 timestamp for range endprovider(optional): Filter by'google','microsoft', or array['google', 'microsoft']timeZone(optional): Return results in specific timezone
Get Busy Times
Query when a user is busy/unavailable based on their calendar events.
// Get busy times across all calendars
const busyTimes = await recal.calendar.getBusyTimes('user_id', {
start: '2024-01-15T00:00:00Z',
end: '2024-01-20T23:59:59Z'
})
// Filter by provider
const busyGoogle = await recal.calendar.getBusyTimes('user_id', {
start: '2024-01-15T00:00:00Z',
end: '2024-01-20T23:59:59Z',
provider: 'google'
})
// Check multiple providers
const busyAll = await recal.calendar.getBusyTimes('user_id', {
start: '2024-01-15T00:00:00Z',
end: '2024-01-20T23:59:59Z',
provider: ['google', 'microsoft'],
timeZone: 'America/Los_Angeles'
})Parameters:
start(required): ISO 8601 timestamp for range startend(required): ISO 8601 timestamp for range endprovider(optional): Filter by provider(s)timeZone(optional): Return results in specific timezone
Response Format:
[
{
start: '2024-01-15T10:00:00Z',
end: '2024-01-15T11:00:00Z'
},
{
start: '2024-01-15T14:00:00Z',
end: '2024-01-15T15:30:00Z'
}
]Use Cases
Check User Availability
async function isUserAvailable(userId: string, start: string, end: string) {
const busyTimes = await recal.calendar.getBusyTimes(userId, {
start,
end
})
// User is available if no busy times found
return busyTimes.length === 0
}Display User's Calendars
async function displayCalendars(userId: string) {
const calendars = await recal.calendar.list(userId)
for (const calendar of calendars) {
console.log(`${calendar.name} (${calendar.provider})`)
console.log(` Timezone: ${calendar.timeZone}`)
console.log(` Access: ${calendar.accessRole}`)
}
}Aggregate Events Across Providers
async function getAllUpcomingEvents(userId: string) {
const now = new Date()
const nextMonth = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000)
const events = await recal.calendar.listEvents(userId, {
start: now.toISOString(),
end: nextMonth.toISOString()
})
// Sort by start time
return events.sort((a, b) =>
new Date(a.start).getTime() - new Date(b.start).getTime()
)
}Best Practices
- Use Appropriate Date Ranges: Query only the time periods you need to minimize API load
- Filter by Provider: If you only need one provider's data, filter to reduce response size
- Handle Timezones: Always specify timezone when displaying times to users
- Cache Responses: Calendar data doesn't change frequently - consider caching results
- Use Busy Times for Scheduling: For scheduling, use
getBusyTimes()instead of fetching full events
Related
- See Events for creating, updating, and deleting events
- See Scheduling for finding available time slots
- See Organizations for team-wide availability queries