Read events

List events in a time window, walk every page, fetch one event and search.

List a time window

A week view needs every event that touches the week, including the one that started Sunday night. listEvents returns the events that overlap [timeMin, timeMax), meaning events that end after timeMin and start before timeMax:

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

const { events, nextPageToken } = await listEvents({
  calendar,
  // The week of 9 November, in New York.
  timeMin: '2026-11-09T00:00:00-05:00',
  timeMax: '2026-11-16T00:00:00-05:00',
});

Because the end is exclusive, an event ending exactly on a boundary never shows up in two back-to-back windows. timeMin and timeMax take a Date or an ISO 8601 string. Watch out for strings without a time: '2026-11-01' means midnight UTC, so pass an offset when you mean midnight in Berlin or Kolkata.

Walk every page

listEvents returns one page. You can pass nextPageToken back as pageToken to get the next one, but it's usually easier to let iterateEvents do it:

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

for await (const event of iterateEvents({ calendar, timeMin, timeMax })) {
  console.log(event.title);
}

It fetches pages as you loop, so you can break early without reading the rest. Since it yields events rather than results, there's nowhere to return warnings, and they go to the warnings setting instead. Set pageSize to change how many events each request asks for; providers may return fewer.

Recurring events

By default each series is expanded into its instances, sorted by start. An instance that follows the series rule is an occurrence, and one that someone changed, like the Monday standup moved to 10:00, is an exception.

To show the rules themselves, such as "every Monday, Wednesday and Friday", pass expandRecurring: false to get one series event per recurring event, with its rule in recurrence:

const { events } = await listEvents({ calendar, timeMin, timeMax, expandRecurring: false });

const series = events.filter((event) => event.kind === 'series');
console.log(series[0]?.recurrence); // ['RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR']

Deleted instances are not events, so listings leave them out. Recurring events covers the rest.

Fetch one event

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

const { event } = await getEvent({ calendar, eventId });

eventId can be a single event, a series, an occurrence or an exception. A missing event throws NotFoundError.

const { events } = await listEvents({ calendar, timeMin, timeMax, query: 'design review' });

Search is the read most providers can't do. Only Google and the mock support query, and the others throw UnsupportedFunctionalityError rather than quietly ignoring it. If your app accepts any provider, check calendar.capabilities.events.search first.

Another calendar

Every read defaults to 'primary'. To read another calendar, pass the id you got from listCalendars:

const { events } = await listEvents({ calendar, calendarId: 'team@example.com', timeMin, timeMax });

On this page