Calendars: the user's calendar list (the calendars they see, with their colors and access roles), calendar metadata, creating secondary calendars, the color palette, and free/busy queries.
Scopes. Reads use calendar.readonly; create-calendar uses
calendar; query-free-busy uses calendar.freebusy
(calendar.readonly works too).
Functions
build-calendar
fn (summary: Str, opts: Map): Map
The calendars.insert body (pure): {summary} plus timeZone (IANA), description and location from opts when set.
build-free-busy
fn (time-min: Str, time-max: Str, calendar-ids: Vec, opts: Map): Map
The freeBusy body (pure): {timeMin, timeMax, items: [{id}]} plus timeZone, groupExpansionMax and calendarExpansionMax from opts when set. calendar-ids may name users' primary calendars by email, or groups.
busy-periods
fn (response: Map, calendar-id: Str): Vec
The busy periods ([{start, end}]) for one calendar in a query-free-busy response (pure), or an Err carrying Google's error reasons when that calendar could not be read.
create-calendar
fn (summary: Str): Map
fn (summary: Str, opts: Map): Map
POST /calendars - create a secondary calendar owned by the user. Options: timeZone, description, location. Returns the calendar with its new id. Scope: calendar.
get-calendar
fn (calendar-id: Str): Map
fn (calendar-id: Str, opts: Map): Map
GET /calendars/{calendarId} - calendar metadata: id, summary, description, timeZone, location. "primary" is the user's main calendar. Scope: calendar.readonly.
get-calendar-list-entry
fn (calendar-id: Str): Map
fn (calendar-id: Str, opts: Map): Map
GET /users/me/calendarList/{calendarId} - the user's entry for one calendar (summary, color, accessRole, notification settings). Scope: calendar.readonly.
get-colors
fn (): Map
fn (opts: Map): Map
GET /colors - the color palette: {calendar: {id: {background, foreground}}, event: {...}}. Use the ids as colorId on events and calendar-list entries. Scope: calendar.readonly.
list-all-calendars
fn (): Vec
fn (opts: Map): Vec
Every calendar on the user's list (all pages). Same options as list-calendars. Scope: calendar.readonly.
list-calendars
fn (): Map
fn (opts: Map): Map
GET /users/me/calendarList - one page of the user's calendars: {items: [{id, summary, timeZone, accessRole, primary?, ...}], nextPageToken?, nextSyncToken?}. Options: minAccessRole (freeBusyReader, reader, writer, owner), showHidden, showDeleted, maxResults (max 250), pageToken, syncToken. Scope: calendar.readonly.
query-free-busy
fn (time-min: Str, time-max: Str, calendar-ids: Vec): Map
fn (time-min: Str, time-max: Str, calendar-ids: Vec, opts: Map): Map
POST /freeBusy - busy periods for calendars between time-min and
time-max (RFC 3339). Returns {calendars: {id: {busy: [{start, end}], errors?}}, groups?, timeMin, timeMax}; a calendar you cannot
see has errors instead of busy. Scope: calendar.freebusy.
fb ::google::calendar::calendars/query-free-busy("2026-11-03T13:00:00Z", "2026-11-03T22:00:00Z", ["ada@example.com", "bob@example.com"])
::google::calendar::calendars/busy-periods(fb, "ada@example.com")