Events: list (every filter) and list-all, get, create, full update, patch, delete, quick add from text, move to another calendar, recurring-event instances, and pure builders for event bodies and Google Meet links.
Write options (create, update, patch, delete, quick-add, move):
sendUpdates (all, externalOnly, none; who gets email about
the change, none when unset), and for create/update/patch
conferenceDataVersion (set to 1 automatically when the body has
conferenceData, which creating a Meet link needs),
supportsAttachments (set automatically when the body has
attachments), maxAttendees.
Scopes. Reads use calendar.events.readonly, writes
calendar.events; calendar and calendar.readonly also work, and
calendar.events.owned covers calendars the user owns.
Values
BUILD_KEYS
BUILD_KEYS: Vec [
"start",
"end",
"time-zone",
"attendees",
"meet",
"meet-request-id",
"reminders-minutes"
]
DATE_PATTERN
DATE_PATTERN: Str "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
MAX_PAGE_SIZE
MAX_PAGE_SIZE: Int 2500
SEND_UPDATES
SEND_UPDATES: Vec [
"all",
"externalOnly",
"none"
]
Functions
attendee
fn (value: Any): Map
An attendee from an email Str or a Map ({email, displayName?, optional?, responseStatus?}) (pure).
build-event
fn (fields: Map): Map
An event body from friendlier fields (pure). Shorthands:
start,end- Str (date or RFC 3339) or EventDateTime Map; seeevent-time.time-zone(IANA) is applied to both.attendees- emails or attendee Maps (a single Str is one email)meet: true- request a Google Meet link (meet-request-idto set its request id)reminders-minutes- popup reminders, e.g.[10, 60], instead of the calendar's defaults
Every other field is passed through as the API's own (summary,
description, location, recurrence like
["RRULE:FREQ=WEEKLY;COUNT=10"], visibility, transparency,
colorId, guestsCanModify, extendedProperties, ...). Null
fields are dropped.
::google::calendar::events/build-event({
summary: "Standup",
start: "2026-11-02T09:00:00",
end: "2026-11-02T09:15:00",
time-zone: "America/Chicago",
recurrence: ["RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"],
attendees: ["ada@example.com", {email: "bob@example.com", optional: true}],
meet: true,
reminders-minutes: [5]
})
create-event
fn (calendar-id: Str, event: Map): Map
fn (calendar-id: Str, event: Map, opts: Map): Map
POST /calendars/{id}/events - create an event from an Event body
(build-event makes one): summary, start/end, attendees,
conferenceData, recurrence, reminders, ... Null fields are
dropped. Returns the event (with id, htmlLink, and hangoutLink
for Meet). Attendees are not emailed unless sendUpdates: "all".
Scope: calendar.events.
::google::calendar::events/create-event("primary", ::google::calendar::events/with-meet({
summary: "Kickoff",
start: {dateTime: "2026-11-05T10:00:00-05:00"},
end: {dateTime: "2026-11-05T10:45:00-05:00"},
attendees: [{email: "ada@example.com"}]
}), {sendUpdates: "all"})
delete-event
fn (calendar-id: Str, event-id: Str): Bool
fn (calendar-id: Str, event-id: Str, opts: Map): Bool
DELETE /calendars/{id}/events/{eventId} - cancel and remove an event (deleting one instance of a recurring event cancels just that occurrence). Options: sendUpdates. Returns true. Scope: calendar.events.
event-time
fn (value: Any): Map
fn (value: Any, time-zone: Str?): Map
An EventDateTime from a Str (pure): a YYYY-MM-DD date gives
{date} (all day); anything else is an RFC 3339 {dateTime}, with
timeZone when time-zone is given. A Map passes through.
::google::calendar::events/event-time("2026-11-03") // {date: "2026-11-03"}
::google::calendar::events/event-time("2026-11-03T09:00:00-06:00", "America/Chicago") // {dateTime, timeZone}
get-event
fn (calendar-id: Str, event-id: Str): Map
fn (calendar-id: Str, event-id: Str, opts: Map): Map
GET /calendars/{id}/events/{eventId} - one event. Options: timeZone, maxAttendees, alwaysIncludeEmail. Scope: calendar.events.readonly.
list-all-events
fn (calendar-id: Str, opts: Map): Vec
fn (calendar-id: Str, opts: Map, limit: Int?): Vec
Follow nextPageToken and return every matching event, or at most
limit. Same options as list-events; uses maxResults: 2500 (or
limit when smaller) unless set. Scope: calendar.events.readonly.
today ::google::calendar::events/list-all-events("primary", {
timeMin: "2026-11-03T00:00:00-06:00", timeMax: "2026-11-04T00:00:00-06:00",
singleEvents: true, orderBy: "startTime"
})
list-all-instances
fn (calendar-id: Str, event-id: Str, opts: Map): Vec
fn (calendar-id: Str, event-id: Str, opts: Map, limit: Int?): Vec
Every occurrence of a recurring event (all pages), or at most limit; bound it with timeMin/timeMax for endless series. Scope: calendar.events.readonly.
list-events
fn (calendar-id: Str): Map
fn (calendar-id: Str, opts: Map): Map
GET /calendars/{id}/events - one page of events: {items, nextPageToken?, nextSyncToken?, timeZone, updated, ...}.
Options (all of the API's): timeMin, timeMax (RFC 3339 with an
offset), q (text search), singleEvents (expand recurring events
into instances; required for orderBy: "startTime"), orderBy
(startTime, updated), maxResults (default 250, max 2500),
pageToken, showDeleted, showHiddenInvitations, updatedMin,
iCalUID, eventTypes (a Vec, e.g. ["default", "outOfOffice"]),
privateExtendedProperty / sharedExtendedProperty
("key=value", Vec for several), timeZone, maxAttendees,
alwaysIncludeEmail, syncToken (see ::google::calendar::sync).
Scope: calendar.events.readonly.
list-instances
fn (calendar-id: Str, event-id: Str): Map
fn (calendar-id: Str, event-id: Str, opts: Map): Map
GET /calendars/{id}/events/{eventId}/instances - one page of a recurring event's occurrences. Options: timeMin, timeMax, originalStart, showDeleted, maxResults, pageToken, timeZone, maxAttendees. Scope: calendar.events.readonly.
meet-link
fn (event: Map): Str?
The Google Meet URL of an event: hangoutLink, else the first video entry point; null when there is none (or the conference is still pending).
meet-request
fn (): Map
fn (request-id: Str): Map
conferenceData asking Google to create a Google Meet link (pure):
{createRequest: {requestId, conferenceSolutionKey: {type: "hangoutsMeet"}}}. request-id makes retries idempotent (default
a new UUID). Needs conferenceDataVersion=1, which create-event,
update-event and patch-event add when they see conferenceData.
The link appears as hangoutLink once the request succeeds.
move-event
fn (calendar-id: Str, event-id: Str, destination: Str): Map
fn (calendar-id: Str, event-id: Str, destination: Str, opts: Map): Map
POST /calendars/{id}/events/{eventId}/move - move an event to the calendar destination (changes its organizer; only default events can move). Options: sendUpdates. Scope: calendar.events.
notify-params
fn (opts: Map): Map
The query parameters of a delete, quick-add or move (pure): your options, with sendUpdates checked.
patch-event
fn (calendar-id: Str, event-id: Str, changes: Map): Map
fn (calendar-id: Str, event-id: Str, changes: Map, opts: Map): Map
PATCH /calendars/{id}/events/{eventId} - change only the given fields (a Vec such as attendees is replaced whole). Scope: calendar.events.
quick-add
fn (calendar-id: Str, text: Str): Map
fn (calendar-id: Str, text: Str, opts: Map): Map
POST /calendars/{id}/events/quickAdd - create an event from text, e.g. "Lunch with Sam tomorrow at noon" (parsed in the calendar's time zone; English works best). Options: sendUpdates. Scope: calendar.events.
update-event
fn (calendar-id: Str, event-id: Str, event: Map): Map
fn (calendar-id: Str, event-id: Str, event: Map, opts: Map): Map
PUT /calendars/{id}/events/{eventId} - replace an event: fields you leave out are cleared, so start from get-event. Prefer patch-event to change a few fields. Scope: calendar.events.
with-meet
fn (event: Map): Map
fn (event: Map, request-id: Str): Map
An event body with a Meet conferenceData request added (pure).
write
fn (method: Str, path: Str, event: Map, opts: Map): Map
write-params
fn (event: Map, opts: Map): Map
The query parameters a create/update/patch sends for event (pure):
conferenceDataVersion: 1 when the body has conferenceData,
supportsAttachments: true when it has attachments, then your
options (sendUpdates, conferenceDataVersion, supportsAttachments,
maxAttendees, ...). Unset options are omitted. An unknown
sendUpdates value is an Err.