Skip to content
Skip to main content

How Google Calendar recurring events work

Last updated:

Google Calendar stores repeating meetings as a parent event plus generated instances. The parent carries the recurrence rule, while moved or cancelled occurrences become exceptions. That model is powerful, but the native Google Calendar API exposes several concepts you have to stitch together: recurrence, recurringEventId, originalStartTime, cancelled instances, and expanded date windows.

Nylas keeps the same calendar semantics but gives you one Events API shape across Google, Microsoft, iCloud, and Exchange. This recipe shows the Google behavior you need to understand, then maps it to the Nylas request pattern.

Create a recurring event by sending a Create Event request with a recurrence array. The array usually has one recurrence rule string. The when object sets the first occurrence and the time zone that anchors the whole series.

Use calendar_id=primary for the connected user’s default Google Calendar, or pass a specific calendar ID from the List Calendars endpoint.

Google Calendar follows the recurrence rule format used by major calendar providers. Nylas passes the recurrence string through the unified Events API, so the same rule works on other providers when they support the pattern.

ScheduleRecurrence rule
Every TuesdayRRULE:FREQ=WEEKLY;BYDAY=TU
Every weekdayRRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
Every other week on TuesdayRRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU
First Monday of each monthRRULE:FREQ=MONTHLY;BYDAY=1MO
Stop after 12 meetingsRRULE:FREQ=WEEKLY;BYDAY=TU;COUNT=12
Stop on a dateRRULE:FREQ=WEEKLY;BYDAY=TU;UNTIL=20261231T235959Z

To skip one occurrence when you create the series, include an EXDATE entry in the same array:

{
"recurrence": [
"RRULE:FREQ=WEEKLY;BYDAY=TU;COUNT=12",
"EXDATE:20260707T150000Z"
]
}

For the full recurrence reference, including provider differences, see Recurring events and recurrence rules.

When you list events without a date range, Google returns the parent recurring event and its recurrence rule. When you pass start and end, Nylas expands the series into the instances inside that window.

Expanded instances share a master_event_id that points back to the parent series. Store both IDs in your app. The instance id lets you move or cancel one meeting, while the parent id lets you edit the whole series.

To update one Google Calendar occurrence, send an Update Event request using the occurrence ID from the expanded list. Nylas updates only that instance, and the response includes original_start_time so you can tell which generated occurrence changed.

To update every future instance, update the parent series instead. Google keeps existing overrides that still fit the new rule. Microsoft can remove overrides when a recurrence pattern changes. If you support more than Google, test against the stricter Microsoft behavior before exposing broad recurrence editing in your UI.

Delete one expanded instance to cancel that date:

Google often represents a deleted occurrence as a cancelled event instead of only adding an EXDATE to the parent. Treat cancelled instances as tombstones in your sync table, not as events to show on the calendar.

Always pass a time zone. Without start_timezone and end_timezone, the series falls back to Coordinated Universal Time. A weekly 9:00 AM meeting can appear to drift around daylight saving time if you omit the time zone.

Bound every list request. Open-ended recurrence can generate years of instances. Pass start and end when you need expanded occurrences, and keep the window close to what your UI or sync job needs.

Invites can fan out. Updating a parent event sends participant updates for the whole series. Use instance-level updates when only one meeting changed.

Use webhooks for follow-up sync. Subscribe to event.created, event.updated, and event.deleted so moved or cancelled Google occurrences reach your app without polling. See Google Calendar webhooks.