> For the complete documentation index, see [llms.txt](https://docs.planetcrust.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.planetcrust.com/human-connections/google/google-calendar-individual.md).

# Google Calendar

<p align="center"><a class="button primary" data-icon="circle-caret-right">Try @Human</a><a class="button primary" data-icon="check">Buy @Human Subscription</a><a class="button primary" data-icon="comments">Join @Human Community</a></p>

<figure><img src="/files/XTIXuRodkVx2AJQ6LF4T" alt="" width="188"><figcaption></figcaption></figure>

<h3 align="center">Put Google Calendar to Work with @Human Automations and @Human Agents</h3>

<p align="center">The Google Calendar Connection documents all Triggers, Actions and Query Operations available for creating automations via the Google Calendar API.</p>

{% embed url="<https://www.youtube.com/watch?v=CyuUuaBSZzA>" %}

#### What can you do with the Google Calendar Connection?

* Connect to the Google Calendar API in a few clicks
* Use the related Google Calendar Operations (see below) in @Human Automations or @Human Agents

### Related Operations

#### Trigger Operations

**Event Created**

Triggers on: events/eventCreated

Triggered when a new event is created in the connected Google Calendar.

**Event Updated**

Triggers on: events/eventUpdated

Triggered when an existing event is updated in the connected Google Calendar.

**Event Deleted**

Triggers on: events/eventDeleted

Triggered when an event is deleted from the connected Google Calendar.

#### Action Operations

[https://github.com/crusttech/human-docs/blob/main/google/google-calendar-individual/action-add-attendees-to-event.md](https://github.com/crusttech/human-docs/blob/main/google/google-calendar-individual/action-add-attendees-to-event.md "mention")

[Action: Delete Event](/human-connections/google/google-calendar-individual/action-delete-event.md)

[Action: Quick Add Event](/human-connections/google/google-calendar-individual/action-quick-add-event.md)

[Action: Update Event](/human-connections/google/google-calendar-individual/action-update-event.md)

[Action: Create Detailed Event](/human-connections/google/google-calendar-individual/action-create-detailed-event.md)

[Action: Move Event to Another Calendar](/human-connections/google/google-calendar-individual/action-move-event-to-another-calendar.md)

[Action: API Request](/human-connections/google/google-calendar-individual/action-api-request.md)

#### Query Operations

Example link

### Related Automations

Example link

### Obtaining Access Credentials

> **Note:** @Human can access all Calendars the service account has access to. Use Domain-Wide Delegation to grant access to calendars across your Google Workspace organization.

**1. Create a Google Cloud project**

* Go to [Google Cloud Console](https://console.cloud.google.com/) and create a new project (or select an existing one).

**2. Enable required APIs**

* Navigate to **APIs & Services → Library**.
* Enable the **Google Calendar API**.

**3. Create a Service Account**

* Under **Google Calendar API**, go to the **Credentials** tab and add a new **Service Account**.

**4. Configure Domain-Wide Delegation (DWD)**

* Go to [Google Admin Console](https://admin.google.com/) → **Security → Access and data control → API controls**.
* Click **Manage domain-wide delegation** → **Add new**.
* Enter the **Client ID** (Service Account ID) and set the scope to `https://www.googleapis.com/auth/calendar`.
* Click **Authorize**.

**5. Download the JSON key**

* Open the newly created service account and go to the **Keys** tab.
* Click **Create new key**, select **JSON**, and click **Create**.

### Configuring Webhooks

1. **Verify Domain Ownership**
   * Navigate to the [Google Search Console](https://search.google.com/search-console/welcome).
   * Add the domain where your webhook endpoint is hosted and complete the verification process.
2. **Register the Domain in Google Cloud**
   * Open the [Google Cloud Console](https://console.cloud.google.com/) and select your project.
   * Navigate to **APIs & Services > Domain Verification**.
   * Click **Add domain**, enter your verified domain, and confirm the addition.
3. **Set Up an HTTPS Endpoint**
   * Deploy a publicly accessible server that uses a valid SSL certificate (self-signed certificates are not supported).
   * Ensure your endpoint can receive `POST` notifications and responds with a `200 OK` status code.
4. **Subscribe to Notification Channels**
   * Send a `POST` request to the `watch` endpoint for the resource you want to monitor (e.g., `https://www.googleapis.com/calendar/v3/calendars/primary/events/watch`).
   * In the request body, include a unique `id` for the channel, set `type` to `web_hook`, and provide your endpoint URL in the `address` field.

### Code (Apache v2.0): Service Connectivity and Metadata

```
{
  "handle": "google-calendar-individual-v3",
  "status": "active",
  "meta": {
    "short": "Google Calendar",
    "description": "Connects to Google Calendar API to manage events, calendars, and reminders.",
    "icon": "google-calendar-individual",
    "tags": [
      "calendar",
      "google",
      "events",
      "scheduling"
    ]
  },
  "service": {
    "baseURL": {
      "value": "https://www.googleapis.com/calendar/v3/calendars"
    },
    "protocol": "https",
    "contentType": "application/json",
    "auth": {
      "method": "oauth2_client_credentials",
      "params": {
        "oauth2ClientCredentials": {
          "value": "{{serviceAccountJSON}}",
          "placeholders": [
            {
              "name": "serviceAccountJSON",
              "type": "password",
              "description": "Google Service Account key JSON (downloaded from Google Cloud Console → IAM → Service Accounts → Keys).",
              "required": true,
              "default": ""
            }
          ]
        }
      }
    },
    "params": [
      {
        "name": "dwdSubject",
        "label": "Impersonated User",
        "type": "String",
        "description": "Email of the Google Workspace user to impersonate via Domain-Wide Delegation (e.g. user@yourdomain.com). Required for calendar discovery.",
        "required": true,
        "default": ""
      }
    ]
  }
}
```

> **Note on discovery**: At connection enable time the server fetches the impersonated user's calendar list (`calendarList`) and injects the calendars as dropdown options on the `calendarId` parameter of every registered operation. Requires Domain-Wide Delegation with `dwdSubject` set to the target user's email. To refresh, call `POST /api/system/configured-connections/{id}/refresh-discovery`.

### Code (Apache v2.0): List of External Resources and Internal Mapping

```
[
  {
    "handle": "events",
    "meta": {
      "short": "Events",
      "description": "Manage and retrieve events from Google Calendar."
    },
    "endpoint": {
      "value": ""
    },
    "operations": {
      "list": {
        "method": "GET",
        "path": {
          "value": "/{{calendarId}}/events",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            }
          ]
        },
        "queryParams": {
          "maxResults": {
            "value": "{{maxResults}}"
          },
          "timeMax": {
            "value": "{{timeMax}}"
          },
          "timeMin": {
            "value": "{{timeMin}}"
          }
        },
        "bodyTemplate": {
          "value": ""
        }
      },
      "read": {
        "method": "GET",
        "path": {
          "value": "/{{calendarId}}/events/{{eventId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            },
            {
              "name": "eventId",
              "type": "String",
              "description": "The event identifier.",
              "required": true,
              "default": ""
            }
          ]
        },
        "bodyTemplate": {
          "value": ""
        }
      },
      "create": {
        "method": "POST",
        "path": {
          "value": "/{{calendarId}}/events",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            }
          ]
        },
        "headers": {
          "Content-Type": {
            "value": "application/json"
          }
        },
        "bodyTemplate": {
          "value": "{\"summary\": \"{{summary}}\", \"description\": \"{{description}}\", \"location\": \"{{location}}\", \"start\": {\"dateTime\": \"{{startDateTime}}\", \"timeZone\": \"{{timeZone}}\"}, \"end\": {\"dateTime\": \"{{endDateTime}}\", \"timeZone\": \"{{timeZone}}\"}}",
          "placeholders": [
            {
              "name": "summary",
              "type": "String",
              "description": "The event title.",
              "required": true,
              "default": ""
            },
            {
              "name": "description",
              "type": "String",
              "description": "The event description.",
              "required": false,
              "default": ""
            },
            {
              "name": "location",
              "type": "String",
              "description": "Location of the event.",
              "required": false,
              "default": ""
            },
            {
              "name": "startDateTime",
              "type": "String",
              "description": "The start date and time of the event in RFC3339 format.",
              "required": true,
              "default": ""
            },
            {
              "name": "endDateTime",
              "type": "String",
              "description": "The end date and time of the event in RFC3339 format.",
              "required": true,
              "default": ""
            },
            {
              "name": "timeZone",
              "type": "String",
              "description": "The time zone for both start and end times (e.g. 'Europe/Paris', optional).",
              "required": false,
              "default": ""
            }
          ]
        }
      },
      "update": {
        "method": "PUT",
        "path": {
          "value": "/{{calendarId}}/events/{{eventId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            },
            {
              "name": "eventId",
              "type": "String",
              "description": "The event identifier.",
              "required": true,
              "default": ""
            }
          ]
        },
        "headers": {
          "Content-Type": {
            "value": "application/json"
          }
        },
        "bodyTemplate": {
          "value": "{\"summary\": \"{{summary}}\", \"description\": \"{{description}}\", \"location\": \"{{location}}\", \"start\": {\"dateTime\": \"{{startDateTime}}\", \"timeZone\": \"{{timeZone}}\"}, \"end\": {\"dateTime\": \"{{endDateTime}}\", \"timeZone\": \"{{timeZone}}\"}}",
          "placeholders": [
            {
              "name": "summary",
              "type": "String",
              "description": "The event title.",
              "required": false,
              "default": ""
            },
            {
              "name": "description",
              "type": "String",
              "description": "The event description.",
              "required": false,
              "default": ""
            },
            {
              "name": "location",
              "type": "String",
              "description": "Location of the event.",
              "required": false,
              "default": ""
            },
            {
              "name": "startDateTime",
              "type": "String",
              "description": "The start date and time of the event in RFC3339 format.",
              "required": false,
              "default": ""
            },
            {
              "name": "endDateTime",
              "type": "String",
              "description": "The end date and time of the event in RFC3339 format.",
              "required": false,
              "default": ""
            },
            {
              "name": "timeZone",
              "type": "String",
              "description": "The time zone for both start and end times (e.g. 'Europe/Paris', optional).",
              "required": false,
              "default": ""
            }
          ]
        }
      },
      "delete": {
        "method": "DELETE",
        "path": {
          "value": "/{{calendarId}}/events/{{eventId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            },
            {
              "name": "eventId",
              "type": "String",
              "description": "The event identifier.",
              "required": true,
              "default": ""
            }
          ]
        },
        "bodyTemplate": {
          "value": ""
        }
      }
    },
    "fields": [
      {
        "name": "id",
        "type": "String",
        "selector": [
          "id"
        ],
        "meta": {
          "description": "The event ID."
        }
      },
      {
        "name": "status",
        "type": "String",
        "selector": [
          "status"
        ],
        "meta": {
          "description": "Status of the event (e.g., confirmed, tentative, cancelled)."
        }
      },
      {
        "name": "htmlLink",
        "type": "String",
        "selector": [
          "htmlLink"
        ],
        "meta": {
          "description": "An absolute link to this event in the Google Calendar Web UI."
        }
      },
      {
        "name": "created",
        "type": "String",
        "selector": [
          "created"
        ],
        "meta": {
          "description": "Creation time of the event (RFC3339)."
        }
      },
      {
        "name": "updated",
        "type": "String",
        "selector": [
          "updated"
        ],
        "meta": {
          "description": "Last modification time of the event (RFC3339)."
        }
      },
      {
        "name": "summary",
        "type": "String",
        "selector": [
          "summary"
        ],
        "meta": {
          "description": "The event title."
        }
      },
      {
        "name": "description",
        "type": "String",
        "selector": [
          "description"
        ],
        "meta": {
          "description": "The event description."
        }
      },
      {
        "name": "location",
        "type": "String",
        "selector": [
          "location"
        ],
        "meta": {
          "description": "Geographic location of the event as free-form text."
        }
      },
      {
        "name": "startDateTime",
        "type": "String",
        "selector": [
          "start",
          "dateTime"
        ],
        "meta": {
          "description": "The start time of the event (for timed events)."
        }
      },
      {
        "name": "startDate",
        "type": "String",
        "selector": [
          "start",
          "date"
        ],
        "meta": {
          "description": "The start date of the event (for all-day events)."
        }
      },
      {
        "name": "startTimeZone",
        "type": "String",
        "selector": [
          "start",
          "timeZone"
        ],
        "meta": {
          "description": "The time zone in which the start time is specified."
        }
      },
      {
        "name": "endDateTime",
        "type": "String",
        "selector": [
          "end",
          "dateTime"
        ],
        "meta": {
          "description": "The end time of the event (for timed events)."
        }
      },
      {
        "name": "endDate",
        "type": "String",
        "selector": [
          "end",
          "date"
        ],
        "meta": {
          "description": "The end date of the event (for all-day events)."
        }
      },
      {
        "name": "endTimeZone",
        "type": "String",
        "selector": [
          "end",
          "timeZone"
        ],
        "meta": {
          "description": "The time zone in which the end time is specified."
        }
      },
      {
        "name": "organizerEmail",
        "type": "String",
        "selector": [
          "organizer",
          "email"
        ],
        "meta": {
          "description": "Email address of the organizer."
        }
      },
      {
        "name": "creatorEmail",
        "type": "String",
        "selector": [
          "creator",
          "email"
        ],
        "meta": {
          "description": "Email address of the creator."
        }
      }
    ],
    "webhooks": [
      {
        "event": "eventCreated",
        "path": "/webhooks/google-calendar-individual/events/created",
        "payload": [
          {
            "name": "eventId",
            "type": "String",
            "selector": [
              "id"
            ],
            "meta": {
              "description": "The ID of the created event."
            }
          },
          {
            "name": "summary",
            "type": "String",
            "selector": [
              "summary"
            ],
            "meta": {
              "description": "The title of the created event."
            }
          }
        ]
      },
      {
        "event": "eventUpdated",
        "path": "/webhooks/google-calendar-individual/events/updated",
        "payload": [
          {
            "name": "eventId",
            "type": "String",
            "selector": [
              "id"
            ],
            "meta": {
              "description": "The ID of the updated event."
            }
          },
          {
            "name": "summary",
            "type": "String",
            "selector": [
              "summary"
            ],
            "meta": {
              "description": "The updated title of the event."
            }
          }
        ]
      },
      {
        "event": "eventDeleted",
        "path": "/webhooks/google-calendar-individual/events/deleted",
        "payload": [
          {
            "name": "eventId",
            "type": "String",
            "selector": [
              "id"
            ],
            "meta": {
              "description": "The ID of the deleted event."
            }
          }
        ]
      }
    ]
  },
  {
    "handle": "acl",
    "meta": {
      "short": "ACL",
      "description": "Manage access control rules for the specific Google Calendar configured for this connection."
    },
    "endpoint": {
      "value": ""
    },
    "operations": {
      "list": {
        "method": "GET",
        "path": {
          "value": "/{{calendarId}}/acl",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            }
          ]
        },
        "bodyTemplate": {
          "value": ""
        }
      },
      "read": {
        "method": "GET",
        "path": {
          "value": "/{{calendarId}}/acl/{{ruleId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            },
            {
              "name": "ruleId",
              "type": "String",
              "description": "ACL rule identifier.",
              "required": true,
              "default": ""
            }
          ]
        },
        "bodyTemplate": {
          "value": ""
        }
      },
      "create": {
        "method": "POST",
        "path": {
          "value": "/{{calendarId}}/acl",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            }
          ]
        },
        "headers": {
          "Content-Type": {
            "value": "application/json"
          }
        },
        "bodyTemplate": {
          "value": "{\"role\": \"{{role}}\", \"scope\": {\"type\": \"{{scopeType}}\", \"value\": \"{{scopeValue}}\"}}",
          "placeholders": [
            {
              "name": "role",
              "type": "String",
              "description": "The role to assign (none, freeBusyReader, reader, writer, owner).",
              "required": true,
              "default": ""
            },
            {
              "name": "scopeType",
              "type": "String",
              "description": "The type of the scope (default, user, group, domain).",
              "required": true,
              "default": ""
            },
            {
              "name": "scopeValue",
              "type": "String",
              "description": "The email or domain for the scope.",
              "required": false,
              "default": ""
            }
          ]
        }
      },
      "update": {
        "method": "PUT",
        "path": {
          "value": "/{{calendarId}}/acl/{{ruleId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            },
            {
              "name": "ruleId",
              "type": "String",
              "description": "ACL rule identifier.",
              "required": true,
              "default": ""
            }
          ]
        },
        "headers": {
          "Content-Type": {
            "value": "application/json"
          }
        },
        "bodyTemplate": {
          "value": "{\"role\": \"{{role}}\"}",
          "placeholders": [
            {
              "name": "role",
              "type": "String",
              "description": "The new role to assign.",
              "required": true,
              "default": ""
            }
          ]
        }
      },
      "delete": {
        "method": "DELETE",
        "path": {
          "value": "/{{calendarId}}/acl/{{ruleId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            },
            {
              "name": "ruleId",
              "type": "String",
              "description": "ACL rule identifier.",
              "required": true,
              "default": ""
            }
          ]
        },
        "bodyTemplate": {
          "value": ""
        }
      }
    },
    "fields": [
      {
        "name": "id",
        "type": "String",
        "selector": [
          "id"
        ],
        "meta": {
          "description": "Identifier of the ACL rule."
        }
      },
      {
        "name": "role",
        "type": "String",
        "selector": [
          "role"
        ],
        "meta": {
          "description": "The role assigned to the scope. Allowed values: none, freeBusyReader, reader, writer, owner."
        }
      },
      {
        "name": "scopeType",
        "type": "String",
        "selector": [
          "scope",
          "type"
        ],
        "meta": {
          "description": "The type of the ACL scope. Allowed values: default, user, group, domain."
        }
      },
      {
        "name": "scopeValue",
        "type": "String",
        "selector": [
          "scope",
          "value"
        ],
        "meta": {
          "description": "The email address of a user or group, or the name of a domain, depending on the scope type."
        }
      }
    ]
  },
  {
    "handle": "calendar",
    "meta": {
      "short": "Calendar",
      "description": "Manage the specific Google Calendar configured for this connection."
    },
    "endpoint": {
      "value": ""
    },
    "operations": {
      "read": {
        "method": "GET",
        "path": {
          "value": "/{{calendarId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            }
          ]
        },
        "bodyTemplate": {
          "value": ""
        }
      },
      "update": {
        "method": "PUT",
        "path": {
          "value": "/{{calendarId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            }
          ]
        },
        "headers": {
          "Content-Type": {
            "value": "application/json"
          }
        },
        "bodyTemplate": {
          "value": "{\"summary\": \"{{summary}}\", \"description\": \"{{description}}\", \"timeZone\": \"{{timeZone}}\"}",
          "placeholders": [
            {
              "name": "summary",
              "type": "String",
              "description": "The calendar title.",
              "required": false,
              "default": ""
            },
            {
              "name": "description",
              "type": "String",
              "description": "The calendar description.",
              "required": false,
              "default": ""
            },
            {
              "name": "timeZone",
              "type": "String",
              "description": "The time zone of the calendar.",
              "required": false,
              "default": ""
            }
          ]
        }
      },
      "delete": {
        "method": "DELETE",
        "path": {
          "value": "/{{calendarId}}",
          "placeholders": [
            {
              "name": "calendarId",
              "type": "String",
              "description": "The calendar identifier. Populated from discovered calendars.",
              "required": true,
              "default": ""
            }
          ]
        },
        "bodyTemplate": {
          "value": ""
        }
      }
    },
    "fields": [
      {
        "name": "id",
        "type": "String",
        "selector": [
          "id"
        ],
        "meta": {
          "description": "The calendar ID."
        }
      },
      {
        "name": "summary",
        "type": "String",
        "selector": [
          "summary"
        ],
        "meta": {
          "description": "The calendar title."
        }
      },
      {
        "name": "description",
        "type": "String",
        "selector": [
          "description"
        ],
        "meta": {
          "description": "The calendar description."
        }
      },
      {
        "name": "timeZone",
        "type": "String",
        "selector": [
          "timeZone"
        ],
        "meta": {
          "description": "The time zone of the calendar."
        }
      }
    ]
  }
]
```

<p align="center"><a class="button primary" data-icon="square-caret-right">Try @Human</a><a class="button primary" data-icon="check">Buy @Human Subscription</a><a class="button primary" data-icon="comments">Join @Human Community</a></p>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.planetcrust.com/human-connections/google/google-calendar-individual.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
