Google Calendar is organized around calendars and the events, access controls, and settings attached to them. Most operations act on a specific calendar and therefore require a calendarId (many client flows use the special keyword primary to mean the authenticated user’s main calendar). Understand that a calendar resource (the calendar itself) and a calendar list entry (what appears in a user’s list of calendars) are related but distinct: you typically read calendar IDs from the calendar list and then operate on those calendars.
Key entities and relationships
- Calendar: the main resource most operations target. Nearly every event, ACL, and watch call needs a
calendarId. Useprimaryfor the authenticated user’s primary calendar. - CalendarListEntry: the user-specific list of calendars (their subscriptions). Retrieve these to discover
calendarIdvalues and per-user settings (color, hidden, access role). Usecalendar.calendarList.listas the primary way to discover calendars you can operate on. - Event: belongs to a calendar and is identified by
eventId. Recurring events have a parenteventIdand individual occurrences (instances) are accessed viaevents.instancesor by listing withsingleEvents=true. - ACL (access rule): tied to a calendar and identified by
ruleId. Manage sharing using the ACL endpoints on a calendar. - Channel: represents a watch/notification subscription. Start with a watch endpoint and stop it with
channels.stop(pass the channel resource the API returned when the watch was created). - Settings and Colors: user settings are global (use
settings.get/list) and color palettes for calendars/events are available viacolors.get.
Entry points — what to call first
- To discover available calendars and the
calendarIdvalues other calls need, callcalendar.calendarList.list. That response is the canonical source of the IDs you will pass to almost every other operation. - To check availability across calendars (for scheduling), call
calendar.freebusy.querywith the request body specifying time ranges and the calendars to check. - To find events within a time window, call
calendar.events.listwithtimeMin/timeMax(and typicallysingleEvents=trueandorderBy=startTimefor an expanded, chronological list of instances).
Common tasks and the sequences to accomplish them
-
Create an event on a calendar
- Ensure you have the target
calendarId(fromcalendar.calendarList.listorprimary). - Use
calendar.events.insert. UsesendUpdatesto control guest notifications (all/externalOnly/none), setconferenceDataVersionif you need conference creation/copying, and setsupportsAttachmentswhen including attachments.
- Ensure you have the target
-
Update part of an event vs replace the whole event
- Use
calendar.events.patchto change only specific fields (partial update). Usecalendar.events.updateto replace the event object. - Both accept
sendUpdates(preferred) andconferenceDataVersionwhere applicable.
- Use
-
Move an event to another calendar
- Call
calendar.events.movewith the sourcecalendarIdandeventId, and set thedestinationquery parameter to the targetcalendarId. The returned object is the event as now stored on the destination calendar.
- Call
-
Expand recurring events into occurrences
- Use
calendar.events.instanceswith the recurring event’seventIdto list its instances, optionally filtered bytimeMin/timeMax. - Alternatively, call
calendar.events.listwithsingleEvents=trueand a time window to get expanded instances across the calendar.
- Use
-
Search or filter events
- Use
calendar.events.listwithqfor free text,iCalUIDto find by iCalendar ID,privateExtendedProperty/sharedExtendedPropertyfor extended properties, andtimeMin/timeMaxfor time range filtering. SetsingleEventswhen you want expanded instances.
- Use
-
Import events from an external source
- Use
calendar.events.import. Note thatimportdoes not expose notification controls the wayinsertdoes—useinsertwhen you need explicit notification behavior.
- Use
-
Manage calendar subscriptions (user’s list)
- Add a calendar to the user’s list with
calendar.calendarList.insert(usecolorRgbFormatwhen writing RGB colors). Update visibility or color withcalendar.calendarList.patch/update.
- Add a calendar to the user’s list with
-
Manage ACLs (sharing)
- List ACLs with
calendar.acl.list, add withcalendar.acl.insert, change withcalendar.acl.patchorcalendar.acl.update, and remove withcalendar.acl.delete. Many ACL write calls accept asendNotificationsflag (default True) to notify users of sharing changes.
- List ACLs with
-
Watch for changes and stop watches
- Start watches with
calendar.events.watch,calendar.calendarList.watch,calendar.acl.watch, orcalendar.settings.watchdepending on the resource. The watch response includes the channel resource you must supply tocalendar.channels.stopto stop notifications.
- Start watches with
-
Retrieve user-level preferences and available colors
- Use
calendar.settings.list/calendar.settings.getfor per-user settings. Usecalendar.colors.getto obtain the available palette for calendars and events.
- Use
Sync (incremental) behavior and gotchas
- Many list/watch endpoints support incremental synchronization via
syncToken(for examplecalendar.calendarList.list,calendar.acl.list,calendar.events.list). If you supply asyncTokenthe server returns only changes since the token. If the token has expired the server returns a 410 GONE response — you must then clear client state and perform a full list withoutsyncTokento re-sync. - Several query parameters cannot be combined with
syncTokenonevents.listbecause they change the shape of results. Notably:iCalUID,orderBy,privateExtendedProperty,q,sharedExtendedProperty,timeMin,timeMax, andupdatedMin. Keep initial synchronization parameters stable when you intend to usesyncToken. nextSyncTokenandsyncTokenare issued on list responses; always use the returned token for subsequent incremental requests.
Notifications and deprecations
- Prefer
sendUpdates(valuesall,externalOnly,none) to control guest notifications for event create/update/move/delete flows. Some endpoints still exposesendNotifications(deprecated);sendUpdatesoffers finer control. events.importdoes not providesendUpdates/sendNotificationsoptions; if you need control over invitations useevents.insert.
Event-specific quirks
- Recurring events vs instances: the parent recurring event has its own
eventId. Useevents.instanceswhen you need occurrences tied to that parent. When listing across a time window, usesingleEvents=trueto expand recurrences into separate instances. showDeletedandsingleEventsinteract: if bothshowDeletedandsingleEventsare True, the list returns only single instances of deleted events (not the underlying recurring masters). Deleted recurring instances may still appear depending on these flags.- Max page sizes and defaults:
events.listdefaults to 250 items per page and caps at 2500;calendarList.listand ACL lists default to 100 and cap at 250. Use pagination tokens to navigate larger sets. conferenceDataVersion: include a non-zero version when you want the API to accept or create conference data (copying or creating meetings). If you need to create conferencing information, set this parameter appropriately when inserting or updating events.supportsAttachments: set this to True when creating/updating events that include attachments; otherwise attachment-related fields may be ignored.quickAdd: theevents.quickAddendpoint parses natural-languagetextinto an event. Use it only when you accept the service’s interpretation; it gives less control than constructing an explicit event body.
ACLs and sharing
- ACLs are always scoped to a calendar. Use
calendar.acl.listto enumerate rules and getruleIdvalues for subsequentget/patch/update/deletecalls. - Adding or changing ACLs may send notifications (the write endpoints accept
sendNotifications, default True). Use this when you want users notified of sharing changes.
Scheduling and availability
- For multi-calendar availability checks, call
calendar.freebusy.querywith the time ranges and the set ofcalendarIdvalues or free/busy requests for users. This is the canonical way to gather cross-calendar busy/free information for scheduling.
Watches and channels
- Watches are created on specific resources (events, calendarList, ACLs, settings). The watch response includes a channel object; to terminate the subscription call
calendar.channels.stopwith the channel object provided. Do not assume the watch persists indefinitely — watch lifetimes and renewal behavior can vary.
Practical priorities when handling user requests
- If the user asks to operate on a calendar and no
calendarIdis given, start withcalendar.calendarList.listto find candidate calendars (look forprimaryor matching summary/email fields). - If the user asks to find or create events in a time range, prefer
calendar.events.listwithtimeMin/timeMax,singleEvents=true, andorderBy=startTimefor predictable chronological results. - If the user asks to move an event between calendars, use
calendar.events.move(sourcecalendarId,eventId, querydestination). - If the user asks to schedule across multiple people, use
calendar.freebusy.queryfirst to identify available slots, then propose times and create events withevents.insertwhen a slot is chosen.
Use these patterns as the mental model for requests: get calendar IDs from the calendar list, treat calendarId as the primary scoping parameter, prefer sendUpdates for notification control, respect syncToken semantics for incremental syncs, and choose patch for minimal updates or update for full replacements.