Search + K

Command Palette

Search for a command to run...

Sign In

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. Use primary for the authenticated user’s primary calendar.
  • CalendarListEntry: the user-specific list of calendars (their subscriptions). Retrieve these to discover calendarId values and per-user settings (color, hidden, access role). Use calendar.calendarList.list as the primary way to discover calendars you can operate on.
  • Event: belongs to a calendar and is identified by eventId. Recurring events have a parent eventId and individual occurrences (instances) are accessed via events.instances or by listing with singleEvents=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 via colors.get.

Entry points — what to call first

  • To discover available calendars and the calendarId values other calls need, call calendar.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.query with the request body specifying time ranges and the calendars to check.
  • To find events within a time window, call calendar.events.list with timeMin/timeMax (and typically singleEvents=true and orderBy=startTime for 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 (from calendar.calendarList.list or primary).
    • Use calendar.events.insert. Use sendUpdates to control guest notifications (all / externalOnly / none), set conferenceDataVersion if you need conference creation/copying, and set supportsAttachments when including attachments.
  • Update part of an event vs replace the whole event

    • Use calendar.events.patch to change only specific fields (partial update). Use calendar.events.update to replace the event object.
    • Both accept sendUpdates (preferred) and conferenceDataVersion where applicable.
  • Move an event to another calendar

    • Call calendar.events.move with the source calendarId and eventId, and set the destination query parameter to the target calendarId. The returned object is the event as now stored on the destination calendar.
  • Expand recurring events into occurrences

    • Use calendar.events.instances with the recurring event’s eventId to list its instances, optionally filtered by timeMin/timeMax.
    • Alternatively, call calendar.events.list with singleEvents=true and a time window to get expanded instances across the calendar.
  • Search or filter events

    • Use calendar.events.list with q for free text, iCalUID to find by iCalendar ID, privateExtendedProperty / sharedExtendedProperty for extended properties, and timeMin/timeMax for time range filtering. Set singleEvents when you want expanded instances.
  • Import events from an external source

    • Use calendar.events.import. Note that import does not expose notification controls the way insert does—use insert when you need explicit notification behavior.
  • Manage calendar subscriptions (user’s list)

    • Add a calendar to the user’s list with calendar.calendarList.insert (use colorRgbFormat when writing RGB colors). Update visibility or color with calendar.calendarList.patch / update.
  • Manage ACLs (sharing)

    • List ACLs with calendar.acl.list, add with calendar.acl.insert, change with calendar.acl.patch or calendar.acl.update, and remove with calendar.acl.delete. Many ACL write calls accept a sendNotifications flag (default True) to notify users of sharing changes.
  • Watch for changes and stop watches

    • Start watches with calendar.events.watch, calendar.calendarList.watch, calendar.acl.watch, or calendar.settings.watch depending on the resource. The watch response includes the channel resource you must supply to calendar.channels.stop to stop notifications.
  • Retrieve user-level preferences and available colors

    • Use calendar.settings.list / calendar.settings.get for per-user settings. Use calendar.colors.get to obtain the available palette for calendars and events.

Sync (incremental) behavior and gotchas

  • Many list/watch endpoints support incremental synchronization via syncToken (for example calendar.calendarList.list, calendar.acl.list, calendar.events.list). If you supply a syncToken the 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 without syncToken to re-sync.
  • Several query parameters cannot be combined with syncToken on events.list because they change the shape of results. Notably: iCalUID, orderBy, privateExtendedProperty, q, sharedExtendedProperty, timeMin, timeMax, and updatedMin. Keep initial synchronization parameters stable when you intend to use syncToken.
  • nextSyncToken and syncToken are issued on list responses; always use the returned token for subsequent incremental requests.

Notifications and deprecations

  • Prefer sendUpdates (values all, externalOnly, none) to control guest notifications for event create/update/move/delete flows. Some endpoints still expose sendNotifications (deprecated); sendUpdates offers finer control.
  • events.import does not provide sendUpdates/sendNotifications options; if you need control over invitations use events.insert.

Event-specific quirks

  • Recurring events vs instances: the parent recurring event has its own eventId. Use events.instances when you need occurrences tied to that parent. When listing across a time window, use singleEvents=true to expand recurrences into separate instances.
  • showDeleted and singleEvents interact: if both showDeleted and singleEvents are 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.list defaults to 250 items per page and caps at 2500; calendarList.list and 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: the events.quickAdd endpoint parses natural-language text into 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.list to enumerate rules and get ruleId values for subsequent get/patch/update/delete calls.
  • 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.query with the time ranges and the set of calendarId values 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.stop with 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 calendarId is given, start with calendar.calendarList.list to find candidate calendars (look for primary or matching summary/email fields).
  • If the user asks to find or create events in a time range, prefer calendar.events.list with timeMin/timeMax, singleEvents=true, and orderBy=startTime for predictable chronological results.
  • If the user asks to move an event between calendars, use calendar.events.move (source calendarId, eventId, query destination).
  • If the user asks to schedule across multiple people, use calendar.freebusy.query first to identify available slots, then propose times and create events with events.insert when 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.