--- title: "Granola connector" sidebarTitle: "Granola" description: "Sync AI meeting notes and transcripts from Granola into your Supermemory knowledge base" icon: "/images/granola.svg" --- Connect Granola to sync AI meeting notes and transcripts into your Supermemory knowledge base. The connector uses a Granola API key, so there is no OAuth redirect flow. The Granola connector requires a **Pro Plan** or higher in Supermemory and a Granola plan that can create API keys. In Granola, create one from **Settings > Connectors > API keys**. ## Quick setup ### From the console 1. Open the [Supermemory Console](https://console.supermemory.ai). 2. Go to **Connectors**. 3. Find the **Granola** row and click **Connect**. 4. Paste your Granola API key. 5. Optionally set a document limit and namespace. 6. Click **Connect**. The console creates the connector and starts the initial sync automatically. The console limits connector setup to 500 documents. Use the API setup below for higher `documentLimit` values, up to 10,000. ### With the API ```typescript import { Supermemory } from "supermemory" const supermemory = new Supermemory({ apiKey: process.env.SUPERMEMORY_API_KEY }) const connector = await supermemory.connectors.create("org-123", { provider: "granola", config: { apiKey: process.env.GRANOLA_API_KEY!, }, documentLimit: 1000, }) // Granola doesn't require OAuth; authorization is null and the first sync starts now console.log("Granola connector:", connector.id) ``` ```python from supermemory import Supermemory import os client = Supermemory(api_key=os.environ["SUPERMEMORY_API_KEY"]) connector = client.connectors.create( "org-123", request={ "provider": "granola", "config": { "apiKey": os.environ["GRANOLA_API_KEY"], }, "documentLimit": 1000, }, ) # Granola doesn't require OAuth; authorization is None and the first sync starts now print(f"Granola connector: {connector.id}") ``` ```bash curl -X POST "https://api.supermemory.ai/ns/org-123/connectors" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "provider": "granola", "config": { "apiKey": "'"$GRANOLA_API_KEY"'" }, "documentLimit": 1000 }' # Response: {"id": "PTzGiUYei7pgzg5buzZHgA", "authorization": null} ``` Supermemory validates the Granola API key before creating the connector. The initial sync starts automatically after the connector is created. ## Configuration options For Granola, provider-specific fields go inside the `config` object. The namespace is in the URL, and `documentLimit` stays top-level in the body. | Parameter | Location | Required | Description | |-----------|----------|----------|-------------| | `apiKey` | `config.apiKey` | Yes | Granola API key from **Settings > Connectors > API keys** | | `documentLimit` | top-level | No | Maximum notes to sync per connector (default: 10,000) | The API key is stored encrypted and is never returned by `connectors.get` or `connectors.list`. ## What gets synced Granola notes are synced as markdown documents. Each document can include: - Note title - Meeting time, attendees, and meeting URL when Granola returns them - AI-generated summary when present - Full transcript when present ### Document metadata Each synced note includes searchable metadata: | Field | Description | |-------|-------------| | `type` | Always `granola` | | `title` | Granola note title | | `createdAt` | Granola note creation timestamp | | `updatedAt` | Granola note update timestamp | | `url` | Granola note URL, when available | | `attendees` | Attendee names or emails, when available | | `meetingStart` | Calendar event start time, when available | You can filter searches using these metadata fields: ```typescript const results = await supermemory.search("org-123", { query: "customer onboarding discussion", filter: { operator: "and", operands: [ { field: "type", operator: "eq", value: "granola" }, { field: "attendees", operator: "arrayContains", value: "alex@company.com" }, ], }, searchMode: "chunks", }) ``` ## Connector Management ### Check Sync Status ```typescript const connector = await supermemory.connectors.get("org-123", "PTzGiUYei7pgzg5buzZHgA", { include: "syncs", }) console.log("Last sync:", connector.latestRun?.system.status, connector.latestRun?.error) console.log("Notes synced:", connector.documentCount) ``` ```bash curl "https://api.supermemory.ai/ns/org-123/connectors/PTzGiUYei7pgzg5buzZHgA?include=syncs" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" ``` ### Delete Connector ```typescript await supermemory.connectors.delete("org-123", "PTzGiUYei7pgzg5buzZHgA") ``` ```python client.connectors.delete("org-123", "PTzGiUYei7pgzg5buzZHgA") ``` ```bash curl -X DELETE "https://api.supermemory.ai/ns/org-123/connectors/PTzGiUYei7pgzg5buzZHgA" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" ``` By default, deleting a connector removes all synced documents from Supermemory. To keep documents, pass `deleteDocuments: false` (`DELETE /ns/{namespace}/connectors/{id}?deleteDocuments=false`). ### Manual sync The call returns `409` while a sync for that connector is already running. ```typescript await supermemory.connectors.sync("org-123", "PTzGiUYei7pgzg5buzZHgA") ``` ```python client.connectors.sync("org-123", "PTzGiUYei7pgzg5buzZHgA") ``` ```bash curl -X POST "https://api.supermemory.ai/ns/org-123/connectors/PTzGiUYei7pgzg5buzZHgA/sync" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" # Response: {"id": "PTzGiUYei7pgzg5buzZHgA", "status": "queued"} ``` ## Sync behavior | Feature | Behavior | |---------|----------| | **Initial sync** | Fetches Granola notes up to `documentLimit` | | **Incremental sync** | Uses Granola `updated_at` timestamps to fetch notes changed since the previous sync | | **Transcript handling** | Fetches each note with transcript content included | | **Sync schedule** | Initial sync after connector creation + manual triggers | | **Document limit** | 10,000 notes per connector (default) | ## Troubleshooting | Error | Solution | |-------|----------| | `Granola API key is required` | Include a non-empty `config.apiKey` value when creating the connector | | `Granola API key is invalid` | Create a new key in Granola and reconnect | | `Could not reach Granola API` | Retry after checking Granola API availability and network access | | Missing notes | Check `documentLimit`; if the workspace has more notes than the limit, only notes up to the limit are imported |