supermemory/apps/docs/connectors/granola.mdx
MaheshtheDev 672defc08b docs: move SDK snippets to the shipped v5 call shape and finish the namespace rename (#1772)
Rewrites 339 TypeScript calls across 50 pages from the rc.5 `method({ namespace, body })` form to the shipped `method(namespace, { ... })` form, and aligns field names with the live v5 spec: `attach` to `include`, `authUrl` to `authorization`, `lastSync` to `latestRun`, `deletedCount` to `count`, and the paginated `namespaces.list()`.

Renames container tags to namespaces across concepts, connectors, integrations and snippets. The namespace pages keep container tag in the description, search keywords and a rename note so old searches still land, and the v3 reference page points at v5.

The migration guide's SDK table now covers both 5.0.0 SDKs, and the SDK integration page uses the real client options (`baseUrl`, `timeoutInSeconds`, `maxRetries`) and error classes.
2026-10-06 17:06:38 +00:00

236 lines
7.2 KiB
Text

---
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.
<Note>
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**.
</Note>
## 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.
<Note>
The console limits connector setup to 500 documents. Use the API setup below for higher `documentLimit` values, up to 10,000.
</Note>
### With the API
<Tabs>
<Tab title="TypeScript">
```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)
```
</Tab>
<Tab title="Python">
```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}")
```
</Tab>
<Tab title="cURL">
```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}
```
</Tab>
</Tabs>
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) |
<Note>
The API key is stored encrypted and is never returned by `connectors.get` or `connectors.list`.
</Note>
## 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
<Tabs>
<Tab title="TypeScript">
```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)
```
</Tab>
<Tab title="cURL">
```bash
curl "https://api.supermemory.ai/ns/org-123/connectors/PTzGiUYei7pgzg5buzZHgA?include=syncs" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY"
```
</Tab>
</Tabs>
### Delete Connector
<Tabs>
<Tab title="TypeScript">
```typescript
await supermemory.connectors.delete("org-123", "PTzGiUYei7pgzg5buzZHgA")
```
</Tab>
<Tab title="Python">
```python
client.connectors.delete("org-123", "PTzGiUYei7pgzg5buzZHgA")
```
</Tab>
<Tab title="cURL">
```bash
curl -X DELETE "https://api.supermemory.ai/ns/org-123/connectors/PTzGiUYei7pgzg5buzZHgA" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY"
```
</Tab>
</Tabs>
<Warning>
By default, deleting a connector removes all synced documents from Supermemory. To keep documents, pass `deleteDocuments: false` (`DELETE /ns/{namespace}/connectors/{id}?deleteDocuments=false`).
</Warning>
### Manual sync
The call returns `409` while a sync for that connector is already running.
<Tabs>
<Tab title="TypeScript">
```typescript
await supermemory.connectors.sync("org-123", "PTzGiUYei7pgzg5buzZHgA")
```
</Tab>
<Tab title="Python">
```python
client.connectors.sync("org-123", "PTzGiUYei7pgzg5buzZHgA")
```
</Tab>
<Tab title="cURL">
```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"}
```
</Tab>
</Tabs>
## 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 |