> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Calendar Ingestion

> Sync your primary Google Calendar into Cognee memory incrementally, with deleted events forgotten automatically

A minimal guide to turning your Google Calendar into Cognee memory. `google_calendar_source()` returns a dlt resource you pass straight to `remember()`. Each event becomes one document with its title, time, location, organizer, attendees and their responses, and description, so the same people are linked across meetings. Re-running the sync fetches only what changed, and deleted events are forgotten.

## Before You Start

* Complete [Quickstart](/getting-started/quickstart) to understand basic operations
* Ensure you have [LLM Providers](/setup-configuration/llm-providers) configured — the script calls `cognee.recall()`, which needs an LLM for the final completion
* Read [dlt Integration](/integrations/dlt-integration) for how structured sources flow through `remember()`
* Install the connector extra: `pip install "cognee[google-calendar]"`
* Set up a Google OAuth client and point the script at it — follow [Set Up Google Access](#set-up-google-access) below

> [!NOTE]
>
> The script syncs your primary calendar only. The first sync reads every event in it, past and future, and cognifies each one with your LLM, so it takes a while: a few hundred events can take 15 minutes or more. Later syncs are fast.

## Code in Action

```python theme={null}
import asyncio

import cognee
from cognee.tasks.ingestion.connectors import google_calendar_source

DATASET_NAME = "google_calendar_demo"
CALENDARS = ["primary"]

# "merge" is required: it makes re-runs incremental and propagates deleted
# events through orphan cleanup.
REMEMBER_KWARGS = {
    "dataset_name": DATASET_NAME,
    "primary_key": "id",
    "write_disposition": "merge",
}


async def main():
    print("=== Initial sync ===")
    # Your own calendar. Pass other ids, like "team@group.calendar.google.com",
    # to sync more; GOOGLE_CALENDAR_* env vars supply the credentials.
    source = google_calendar_source(CALENDARS)
    await cognee.remember(source, **REMEMBER_KWARGS)
    print("Sync stats:", source.cognee_sync_stats)

    answer = await cognee.recall(
        "Who do I meet with most often, and what are those meetings about?",
        datasets=[DATASET_NAME],
    )
    print("Recall:", answer[0].text if answer else "nothing found")

    print("\n=== Incremental re-sync (only new, changed or deleted events) ===")
    source = google_calendar_source(CALENDARS)
    await cognee.remember(source, **REMEMBER_KWARGS)
    print("Sync stats:", source.cognee_sync_stats)


if __name__ == "__main__":
    asyncio.run(main())
```

## What Just Happened

### Step 1: Configure the Sync

```python theme={null}
# "merge" is required: it makes re-runs incremental and propagates deleted
# events through orphan cleanup.
REMEMBER_KWARGS = {
    "dataset_name": DATASET_NAME,
    "primary_key": "id",
    "write_disposition": "merge",
}
```

These are the routing options for `remember()`, reused on every sync. `write_disposition="merge"` upserts events by their `id`, so a re-sync that returns only the changed events keeps all the others, and deleted events are forgotten through orphan cleanup. With the default `"replace"`, a re-sync would keep only the events it fetched and forget the rest.

### Step 2: Run the Initial Sync

```python theme={null}
    source = google_calendar_source(CALENDARS)
    await cognee.remember(source, **REMEMBER_KWARGS)
    print("Sync stats:", source.cognee_sync_stats)
```

`google_calendar_source(["primary"])` builds a dlt resource for your own calendar, reading credentials from the `GOOGLE_CALENDAR_*` environment variables. Pass other calendar ids to sync more. `remember()` loads every event into the `google_calendar_demo` dataset and builds the graph; `source.cognee_sync_stats` reports what the sync did.

### Step 3: Ask Your Calendar

```python theme={null}
    answer = await cognee.recall(
        "Who do I meet with most often, and what are those meetings about?",
        datasets=[DATASET_NAME],
    )
    print("Recall:", answer[0].text if answer else "nothing found")
```

[`recall()`](/core-concepts/main-operations/recall) queries the synced dataset. Because attendees are written into each event's text, the graph connects the same people across meetings.

### Step 4: Sync Again Incrementally

```python theme={null}
    source = google_calendar_source(CALENDARS)
    await cognee.remember(source, **REMEMBER_KWARGS)
    print("Sync stats:", source.cognee_sync_stats)
```

A fresh source with the same options fetches only new, changed or deleted events through Google's sync token. Deleted events are forgotten from memory. Run this on a schedule to keep the dataset in step with your calendar.

## Additional Information

> **Set Up Google Access**
>
> Do this once in the [Google Cloud Console](https://console.cloud.google.com/):
>
> 1. Create a project, or select an existing one.
> 2. Open the [Google Calendar API](https://console.cloud.google.com/apis/library/calendar-json.googleapis.com) page and click **Enable**.
> 3. Open [Google Auth Platform](https://console.cloud.google.com/auth/overview) and click **Get started**. Enter an app name and your email, choose **External** as the audience, and finish the wizard. Google Auth Platform isn't in the left menu by default; you can also reach it through **☰ → APIs & Services → OAuth consent screen**.
> 4. Open [Audience](https://console.cloud.google.com/auth/audience). If it shows **User type: External** and **Publishing status: Testing**, click **Add users** under **Test users** and add the Google account whose calendar you want to sync. If the user type is **Internal** (a Google Workspace organization) or the app is **In production**, there is no **Test users** section and you can skip this step.
> 5. Under [Data Access](https://console.cloud.google.com/auth/scopes), click **Add or remove scopes**, filter for `calendar.readonly`, tick `.../auth/calendar.readonly`, click **Update**, then **Save**.
> 6. Under [Clients](https://console.cloud.google.com/auth/clients), click **Create client**, choose **Desktop app**, and click **Create**. Click **Download JSON** in the dialog that follows. A **Web application** client, such as the one from the [Google Calendar integration](/integrations/google-calendar-integration), fails at sign-in with `Error 400: redirect_uri_mismatch`.
>
> Then point the script at the downloaded file, in your shell or in your `.env`:
>
> ```bash theme={null}
> export GOOGLE_CALENDAR_CREDENTIALS_PATH=~/Downloads/client_secret_XXXX.json
> # optional; defaults to ~/.cognee_google_calendar_token.json
> export GOOGLE_CALENDAR_TOKEN_PATH=~/.cognee_google_calendar_token.json
> ```
>
> Remove `GOOGLE_CALENDAR_ACCESS_TOKEN` and `GOOGLE_CALENDAR_REFRESH_TOKEN` from your shell and your `.env` if they are set. Either one takes precedence over the file above, and values in `.env` override the shell.

> **[Google Calendar](/integrations/google-calendar-integration)**
>
> Let users connect their calendars through Cognee's API instead of a local token

> **[Google Calendar Connector](/integrations/dlt-integration#google-calendar-connector)**
>
> Every connector parameter, the headless auth options, and how sync and forget-on-delete work

> **[Remember](/core-concepts/main-operations/remember)**
>
> All `remember()` parameters, including the dlt options

> **[Forget: Delete Agent Memory](/core-concepts/main-operations/forget)**
>
> Wipe the calendar dataset when you are done


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.