findFreeTime

Finds slots when every listed calendar is free, across providers.

Pass everyone's calendars, even on different providers, and set workingHours so slots land inside the working day of the person you're booking. Slots come back as UTC instants, ready to show in each viewer's own zone.

import { findFreeTime } from '@cal-sdk/core';

const { slots } = await findFreeTime({
  calendars: [{ calendar: google({ accessToken }) }, { calendar: microsoft({ accessToken }) }],
  timeMin: new Date(),
  timeMax: new Date(Date.now() + 7 * 86_400_000),
  duration: 30,
  workingHours: { start: '09:00', end: '18:00', timeZone: 'Asia/Kolkata' },
});

Options

calendars{ calendar; calendarIds?; headers?; providerOptions? }[]
Every calendar that must be free, grouped by provider. calendarIds defaults to ['primary']. headers and providerOptions apply to that provider's requests.
timeMinDate | string
timeMaxDate | string
durationnumber
Meeting length in minutes. A positive whole number.
workingHours?WorkingHours
Only return slots inside these hours. Leave out to search the whole window.
slotInterval?number= 15
Minutes between slot starts, lined up with the hour in workingHours.timeZone, or UTC.
maxRetries?number= 2
abortSignal?AbortSignal

WorkingHours

startstring
'HH:mm', such as '09:00'.
endstring
'HH:mm', after start. Slots end by this time.
timeZonestring
IANA time zone the hours are in.
days?number[]= [1, 2, 3, 4, 5]
0 (Sunday) to 6 (Saturday).

Result

slots{ start: string; end: string }[]
Free slots in order, as UTC ISO 8601 instants. Neighbouring slots overlap when slotInterval is less than duration.
warningsWarning[]
Warnings from every provider, such as the free/busy fallback.

Throws

  • FreeBusyUnavailableError when any calendar cannot be read, rather than return slots that might clash. It has provider and calendarId.
  • InvalidArgumentError when duration or slotInterval is not a positive whole number, or workingHours is invalid.

On this page