Reference · Tools
Google Calendar integration
Create, retrieve, update, and delete calendar events and check availability for specific time windows.
The Google Calendar node lets you read and write to Google Calendar directly from a BusyBot workflow — creating events with attendees, reminders, and Google Meet links, querying free/busy windows, and managing recurring events. A common use case is automatically booking a calendar slot when a form is submitted, complete with a generated Meet conference link. It covers the full event lifecycle: create, get, list, update, and delete.
- Works as
- Action
- Tool name
google_calendar- Operations
- 6 — Calendar: Availability , Event: Create , Event: Delete , Event: Get , Event: Get Many and 1 more
- Parameters
- 77
- Outputs
- Output, Error
- Credentials
- Google Calendar OAuth2
- Official docs
- Google Calendar docs developers.google.com
What you can build with Google Calendar
- Create a new Google Calendar event with attendees.
- Delete an event from a calendar.
- Get a single event by ID.
- List all events in a date range.
- Update an event title or time.
- Check if a calendar is free during a time window.
- Create a recurring weekly meeting.
- Add a Google Meet link to an event.
- Get all events in the next 30 days.
Overview
Google Calendar tool manages calendars and events via the Google Calendar API. Calendar operations: check availability (POST /freeBusy with outputFormat options: availability, bookedSlots, raw). Event operations: create an event (POST /calendars/{calendarId}/events with start/end times, attendees, reminders, recurrence RRULE, conference data, color, visibility, transparency, location, guest permissions, allDay support), delete an event (DELETE /calendars/{calendarId}/events/{eventId}), get a single event (GET /calendars/{calendarId}/events/{eventId}), get many events (GET /calendars/{calendarId}/events with nextPageToken pagination, recurringEventHandling: expand/first/next), update an event (PATCH /calendars/{calendarId}/events/{eventId} with attendees mode: add/replace, modifyTarget: instance/event for recurring events). Calendar ID defaults to “primary”. Conference data uses hangoutsMeet with auto-generated UUID requestId. RRULE built from repeatFrequency/repeatCount/repeatUntil or raw rrule string. Output keys sorted: id, summary, start, end, attendees, creator, organizer, description, location, created, updated.
Node Type
Action — processes input items and produces output
Input / Output
| Direction | Port(s) |
|---|---|
| Input | Input |
| Output | Output, Error |
Credentials
This tool requires Google Calendar OAuth2 credentials. See the Credentials Guide for setup instructions.
Resources
| Resource | Value |
|---|---|
| Calendar | calendar |
| Event | event |
Operations
| Resource | Operation | Value | Description |
|---|---|---|---|
| Calendar | Availability | availability | Check when a calendar is free or busy during a time window. |
| Event | Create | create | Add an event to a calendar. |
| Event | Delete | delete | Delete an event from a calendar. |
| Event | Get | get | Retrieve a single event by ID. |
| Event | Get Many | getAll | Retrieve many events from a calendar. |
| Event | Update | update | Update an event in a calendar. |
Parameters
Calendar: Availability (availability)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Calendar ID | string | No | primary | The ID of the calendar to check availability for. Use “primary” for the primary calendar. Supports expressions like {{ $json.calendarId }}. |
| Time Min | string | Yes | — | Start of the time window, ISO 8601 with a UTC offset or Z, e.g. “2026-10-14T00:00:00-06:00” (midnight in Denver). A time without an offset is read as UTC. |
| Time Max | string | Yes | — | End of the time window (exclusive), ISO 8601 with a UTC offset or Z, e.g. “2026-10-15T00:00:00-06:00”. A time without an offset is read as UTC. |
| Output Format | options | No | availability | How to format the availability response. |
Options: availability (returns { available: true/false } — whether the calendar is free), bookedSlots (returns an array of busy time slots with start and end times), raw (returns the full raw freeBusy API response) | ||||
| Time Zone | string | No | — | IANA zone, e.g. “America/Denver”: the event’s zone on create/update (default UTC), else the zone of returned times. Here: the zone the busy slots are written in; it does not change how Time Min and Time Max are read. |
Event: Create (create)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Calendar ID | string | No | primary | The ID of the calendar to create the event in. Use “primary” for the primary calendar. |
| Title | string | No | — | Title of the event. Supports expressions like {{ $json.subject }}. |
| Start | string | Yes | — | Event start, ISO 8601 WITH the UTC offset in force on that date: “2026-10-14T06:30:00-06:00” is 6:30 AM in Denver (Denver is -07:00 in winter). A time without an offset is read as UTC, whatever Time Zone says. For all-day events use “YYYY-MM-DD”. |
| End | string | Yes | — | Event end, same form as start; with allDay, a date that is exclusive (the day after the last day). For example “2026-10-14T07:30:00-06:00”, or “2026-10-15” to end a one-day event on 2026-10-14. |
| All Day | boolean | No | false | Whether this is an all-day event. If true, start and end should be dates (YYYY-MM-DD). |
| Time Zone | string | No | — | IANA zone, e.g. “America/Denver”: the event’s zone on create/update (default UTC), else the zone of returned times. Google shows the event in this zone and repeats a series at the same local time in it. It never turns a Start or End without an offset into local time. |
| Description | string | No | — | Description of the event. Supports expressions. |
| Location | string | No | — | Geographic location of the event as free-form text. |
| Send Updates | options | No | none | Whether to send notifications about the event to guests. |
Options: all (notifications are sent to all guests), externalOnly (notifications are sent to non-Google Calendar guests only), none (no notifications are sent) | ||||
| Attendees | fixedCollection | No | {"values":[]} | List of attendees to invite. Add one entry per attendee. |
string | No | — | Attendee email address. | |
| — Optional | boolean | No | false | Whether this attendee is optional. |
| Use Default Reminders | boolean | No | true | Whether to use the calendar’s default reminders for this event. |
| Reminders | fixedCollection | No | {"values":[]} | Custom reminder overrides. Add one entry per reminder. (shown when Use Default Reminders is false) |
| — Method | options | No | email | Reminder notification method. |
Options: email, popup | ||||
| — Minutes Before | number | No | 30 | Minutes before the event to send the reminder. |
| Use Default Conference | boolean | No | false | Whether to automatically add a Google Meet conference link. |
| Repeat Frequency | options | No | — | How often the event repeats. |
Options: leave empty for a one-off event, DAILY, WEEKLY, MONTHLY, YEARLY | ||||
| Repeat Count | number | No | 0 | Total occurrences, the first included (do not combine with Repeat Until): DAILY with 7 is seven days in a row from the start date. |
| Repeat Until | string | No | — | Last start allowed, ISO 8601 with offset (a bare date is 00:00 UTC); do not combine with Repeat Count. Write “2026-10-20T23:59:59-06:00” to include 20 October in Denver. |
| RRULE (Raw) | string | No | — | Raw RRULE string (e.g. “FREQ=WEEKLY;COUNT=10”). Overrides Repeat Frequency/Count/Until. |
| Color ID | options | No | — | Color of the event. |
Options: leave empty for the calendar default, 1 (Lavender), 2 (Sage), 3 (Grape), 4 (Flamingo), 5 (Banana), 6 (Tangerine), 7 (Peacock), 8 (Graphite), 9 (Blueberry), 10 (Basil), 11 (Tomato) | ||||
| Visibility | options | No | — | Visibility of the event. |
Options: leave empty for the calendar default, default, public, private, confidential | ||||
| Show Me As | options | No | — | Whether this event blocks time on the calendar (busy vs free). |
Options: leave empty for the calendar default, opaque (busy), transparent (free) | ||||
| Guests Can Modify | boolean | No | false | Whether guests can modify the event. |
| Guests Can Invite Others | boolean | No | true | Whether guests can invite other people to the event. |
| Guests Can See Other Guests | boolean | No | true | Whether guests can see other guests in the event. |
Event: Delete (delete)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Calendar ID | string | No | primary | The ID of the calendar containing the event to delete. |
| Event ID | string | Yes | — | The ID of the event to delete. Supports expressions. |
| Send Updates | options | No | none | Whether to send cancellation notifications to guests. |
Options: all, externalOnly, none |
Event: Get (get)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Calendar ID | string | No | primary | The ID of the calendar containing the event to retrieve. |
| Event ID | string | Yes | — | The ID of the event to retrieve. Supports expressions. |
| Time Zone | string | No | — | IANA zone, e.g. “America/Denver”: the event’s zone on create/update (default UTC), else the zone of returned times. Here: the zone the event’s times are returned in. |
Event: Get Many (getAll)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Calendar ID | string | No | primary | The ID of the calendar to retrieve events from. |
| Time Min | string | No | — | Start of the time window, ISO 8601 with a UTC offset or Z (Google requires the offset), e.g. “2026-10-14T00:00:00-06:00”. Events still running at this moment are included. Leave blank for no lower bound. |
| Time Max | string | No | — | End of the time window (exclusive), ISO 8601 with a UTC offset or Z (Google requires the offset), e.g. “2026-10-15T00:00:00-06:00”. Only events that start before it are returned. Leave blank for no upper bound. |
| Time Zone | string | No | — | IANA zone, e.g. “America/Denver”: the event’s zone on create/update (default UTC), else the zone of returned times. Here: the zone the events’ times are returned in; it does not change how Time Min and Time Max are read. |
| Order By | options | No | — | The order of the events returned. startTime is only available when singleEvents is true. |
Options: leave empty for the API default, startTime, updated | ||||
| Query | string | No | — | Free text search terms to find events that match. Supports expressions. |
| Show Deleted | boolean | No | false | Whether to include deleted events in the results. |
| Recurring Event Handling | options | No | expand | How to handle recurring events in the results. |
Options: expand (expand recurring events into individual instances; recommended), first (return only events created within the Time Min–Time Max window), next (for each recurring event, make an extra API call to get only the next upcoming instance) | ||||
| Return All | boolean | No | false | Whether to return all results or only up to a given limit. |
| Limit | number | No | 20 | Maximum number of events to return. Between 1 and 2500. (shown when Return All is false) |
Event: Update (update)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Calendar ID | string | No | primary | The ID of the calendar containing the event to update. |
| Event ID | string | Yes | — | The ID of the event to update. For recurring event instances this is the instance ID (contains ”_”). |
| Title | string | No | — | New title for the event. Leave blank to keep existing. |
| Start | string | No | — | Event start, ISO 8601 WITH the UTC offset in force on that date: “2026-10-14T06:30:00-06:00” is 6:30 AM in Denver. A time without an offset is read as UTC. Leave blank to keep existing. |
| End | string | No | — | Event end, same form as start; with allDay, a date that is exclusive (the day after the last day). Leave blank to keep existing; to move an event, send Start, End and Time Zone together. |
| All Day | boolean | No | false | Whether this is an all-day event. If true, start and end should be dates (YYYY-MM-DD). |
| Time Zone | string | No | — | IANA zone, e.g. “America/Denver”: the event’s zone on create/update (default UTC), else the zone of returned times. It is set to UTC when left blank while Start or End is sent, so set it whenever you move an event. It never turns a time without an offset into local time. |
| Description | string | No | — | New description for the event. Leave blank to keep existing. |
| Location | string | No | — | New location for the event. Leave blank to keep existing. |
| Send Updates | options | No | none | Whether to send update notifications to guests. |
Options: all, externalOnly, none | ||||
| Attendees Mode | options | No | replace | How to handle attendees during update. |
Options: add (merge new attendees with existing list), replace (replace the entire attendees list) | ||||
| Attendees | fixedCollection | No | {"values":[]} | List of attendees. Behavior depends on Attendees Mode. |
string | No | — | Attendee email address. | |
| — Optional | boolean | No | false | Whether this attendee is optional. |
| Use Default Reminders | boolean | No | true | Whether to use the calendar’s default reminders for this event. |
| Reminders | fixedCollection | No | {"values":[]} | Custom reminder overrides. Add one entry per reminder. (shown when Use Default Reminders is false) |
| — Method | options | No | email | Reminder notification method. |
Options: email, popup | ||||
| — Minutes Before | number | No | 30 | Minutes before the event to send the reminder. |
| Repeat Frequency | options | No | — | How often the event repeats. |
Options: leave empty to keep the current recurrence, DAILY, WEEKLY, MONTHLY, YEARLY | ||||
| Repeat Count | number | No | 0 | Total occurrences, the first included (do not combine with Repeat Until): DAILY with 7 is seven days in a row from the start date. |
| Repeat Until | string | No | — | Last start allowed, ISO 8601 with offset (a bare date is 00:00 UTC); do not combine with Repeat Count. Write “2026-10-20T23:59:59-06:00” to include 20 October in Denver. |
| RRULE (Raw) | string | No | — | Raw RRULE string (e.g. “FREQ=WEEKLY;COUNT=10”). Overrides Repeat Frequency/Count/Until. |
| Color ID | options | No | — | Color of the event. |
Options: leave empty for no change, 1 (Lavender), 2 (Sage), 3 (Grape), 4 (Flamingo), 5 (Banana), 6 (Tangerine), 7 (Peacock), 8 (Graphite), 9 (Blueberry), 10 (Basil), 11 (Tomato) | ||||
| Visibility | options | No | — | Visibility of the event. |
Options: leave empty for no change, default, public, private, confidential | ||||
| Show Me As | options | No | — | Whether this event blocks time on the calendar (busy vs free). |
Options: leave empty for no change, opaque (busy), transparent (free) | ||||
| Guests Can Modify | boolean | No | false | Whether guests can modify the event. |
| Guests Can Invite Others | boolean | No | true | Whether guests can invite other people to the event. |
| Guests Can See Other Guests | boolean | No | true | Whether guests can see other guests in the event. |
| Modify Target | options | No | instance | For recurring event instances (event ID contains ”_”): whether to modify just this instance or the entire series. |
Options: instance (modify only this specific instance of the recurring event), event (modify the entire recurring event series) |
All Operations
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| Authentication | options | No | oAuth2 | Authentication method to use. |
Options: oAuth2 (OAuth2, recommended), serviceAccount (Service Account) | ||||
| Google Account | credential | No | — | Connect or select your Google account. (shown when Authentication is oAuth2) |
| Service Account Email | string | Yes | — | The email address of the Google service account, for example my-service-account@project.iam.gserviceaccount.com. (shown when Authentication is serviceAccount) |
| Private Key | string | Yes | — | The private key from the service account JSON key file. Paste the full PEM block, including the BEGIN and END lines. (shown when Authentication is serviceAccount) |
| Max Concurrency | number | No | 5 | Maximum number of items to process concurrently. Between 1 and 20. |
Output Data
The API result is merged into the item JSON, so the incoming fields pass through except where a result field uses the same name. Binary data on the input item is not carried to the output.
Most operations produce exactly one output item per input item. Two of them fan out:
| Operation | Output |
|---|---|
Calendar availability, Output Format availability | One item carrying available — true when nothing is booked in the window, false otherwise. |
Calendar availability, Output Format bookedSlots | Fans out — one item per busy slot, each with the slot’s start and end. A free window still emits one item, carrying the input JSON unchanged. |
Calendar availability, Output Format raw | One item carrying the full freeBusy response. |
Event create, get, update | One item carrying the event record. |
Event delete | One item carrying success: true. The API returns no body for a delete. |
Event getAll | Fans out — one item per event. A range with no events still emits one item, carrying the input JSON unchanged. |
Event records are returned with their most useful keys first: id, summary, start, end, attendees, creator, organizer, description, location, created, updated, followed by the remaining Google Calendar fields.
Because the fan-out operations already emit one item per record, you do not need a Split Out node after them. Reference the result downstream by expression, e.g. {{ $json.id }} or {{ $json.available }}.
Example Configuration
Create an event with two attendees, a Google Meet link and a custom reminder:
{
"type": "google_calendar",
"parameters": {
"authentication": "oAuth2",
"resource": "event",
"operation": "create",
"calendarId": "primary",
"summary": "{{ $json.title }}",
"start": "{{ $json.startsAt }}",
"end": "{{ $json.endsAt }}",
"timeZone": "America/New_York",
"description": "{{ $json.agenda }}",
"location": "Room 4B",
"sendUpdates": "all",
"attendees": {
"values": [
{ "email": "{{ $json.organizerEmail }}", "optional": false },
{ "email": "notes@example.com", "optional": true }
]
},
"useDefaultReminders": false,
"reminders": {
"values": [
{ "method": "popup", "minutes": 15 }
]
},
"useDefaultConference": true,
"colorId": "7",
"showMeAs": "opaque"
}
}
Create an all-day event that repeats weekly for 10 weeks:
{
"type": "google_calendar",
"parameters": {
"resource": "event",
"operation": "create",
"calendarId": "primary",
"summary": "Sprint planning",
"allDay": true,
"start": "2026-03-10",
"end": "2026-03-11",
"repeatFrequency": "WEEKLY",
"repeatCount": 10,
"visibility": "private"
}
}
List the events in a date range, one item per event:
{
"type": "google_calendar",
"parameters": {
"resource": "event",
"operation": "getAll",
"calendarId": "{{ $json.calendarId }}",
"timeMin": "{{ $json.from }}",
"timeMax": "{{ $json.to }}",
"orderBy": "startTime",
"recurringEventHandling": "expand",
"returnAll": false,
"limit": 100
}
}
Check whether a calendar is free in a window:
{
"type": "google_calendar",
"parameters": {
"resource": "calendar",
"operation": "availability",
"calendarId": "{{ $json.email }}",
"timeMin": "{{ $json.slotStart }}",
"timeMax": "{{ $json.slotEnd }}",
"outputFormat": "availability",
"timeZone": "Europe/London"
}
}
Move a single instance of a recurring event and notify the guests:
{
"type": "google_calendar",
"parameters": {
"resource": "event",
"operation": "update",
"calendarId": "primary",
"eventId": "{{ $json.id }}",
"start": "{{ $json.newStart }}",
"end": "{{ $json.newEnd }}",
"modifyTarget": "instance",
"attendeesMode": "add",
"sendUpdates": "all"
}
}
Error Handling
| Mode | Behavior |
|---|---|
| stop | Halts workflow on first error |
| continue | Skips failed items, passes successful ones through |
| errorPort | Routes failed items to Error output port |
Tips
This tool manages Google Calendar events and checks calendar availability. It schedules, changes and deletes events and finds free or busy times. Give every start, end, timeMin and timeMax the UTC offset in force on that date, such as 2026-10-14T06:30:00-06:00 for 6:30 AM in Denver, because a time without an offset is read as UTC and timeZone does not change that.
Frequently asked questions
What credentials do I need to connect this node to my Google account?
The node uses Google Calendar OAuth2 (credential type: googleCalendarOAuth2, the same credential the Google Calendar Trigger uses). You'll need to create OAuth2 credentials in Google Cloud Console with the Calendar API enabled, then authorize the connection through BusyBot's credential manager. The node will default to the 'primary' calendar of the authenticated account unless you specify a different Calendar ID.
How does checking availability work, and what formats does it return?
The availability check hits the /freeBusy endpoint and supports three output formats: 'availability' (a simple yes/no summary), 'bookedSlots' (a list of busy time ranges), or 'raw' (the full API response). Choose the format that suits your downstream logic — 'bookedSlots' is useful if you need to display conflicts, while 'availability' is enough for a simple gate check.
Can I create recurring events, and how do I define the recurrence rule?
Yes. You can define recurrence either by setting repeatFrequency, repeatCount, and repeatUntil fields — which the node assembles into an RRULE — or by supplying a raw RRULE string directly if you need full control. When listing or updating recurring events, the recurringEventHandling option lets you choose between expanding all instances, returning only the first, or returning the next upcoming one.
When I update a recurring event, does the change apply to all instances or just one?
You control this with the modifyTarget parameter, which accepts either 'instance' (only the specific occurrence) or 'event' (the entire recurring series). You can also control how attendees are handled on update: 'add' merges new attendees with existing ones, while 'replace' overwrites the attendee list entirely.
What does the node return, and how is the output structured?
The node has two outputs: Output (for successful responses) and Error (for failures, so you can route error-handling logic separately without stopping the workflow). Successful event responses return keys in a consistent sorted order: id, summary, start, end, attendees, creator, organizer, description, location, created, and updated. Conference data for Google Meet is generated automatically using a UUID-based requestId when you enable conference creation.
Build with Google Calendar
Drop it into a workflow, wire it to an agent, or call it on a schedule. You'll need Google Calendar OAuth2 credentials first.
Open BusyBotLast reviewed . Spotted something wrong? Tell us.