Appearance
Granola API
CurrentGranola API documentation. Programmatic access to meeting notes, transcripts, and AI summaries.
The Granola API provides programmatic access to your workspace's meeting notes and related data. This RESTful API enables you to integrate Granola with your existing tools, build custom workflows, and extract insights from your meeting documentation.
API key access scopes
API keys can include one or more access scopes. Any workspace member on a Business plan can create API keys. On Enterprise plans, workspace admins choose which access scopes members can use in Settings → Workspace → General → API access for members.
| Access scope | What can it access |
|---|---|
| Personal notes |
|
| Public notes |
|
Obtaining an API Key
- Open the Granola desktop app
- Navigate to Settings → Connectors → API keys
- Click Create new key
- Choose the note access scopes the key should include
- Click Generate API Key
TIP
On Enterprise plans, API key access scopes must be enabled by a workspace admin in Settings → Workspace → General → API access for members.
Revoking an API Key
To revoke an API key:
- Go to Settings → Connectors → API keys
- Find the key you want to revoke and click Revoke
- Confirm in the dialog
Once revoked, the key is permanently disabled and moves to the Revoked section of the table. This cannot be undone.
Updating an API Key
To update an API key's access scopes:
- Go to Settings → Connectors → API keys
- Find the key you want to update and click Edit
- Choose the note access scopes the key should include
- Click Save changes
Quick Start
bash
# List notes created this week
$ curl "https://public-api.granola.ai/v1/notes?created_after=$(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ)" \
-H "Authorization: Bearer grn_YOUR_API_KEY"
{
"notes": [ ... ],
"hasMore": true,
"cursor": "eyJjcmVkZW50aWFsfQ=="
}
# Get the next page using the cursor
$ curl "https://public-api.granola.ai/v1/notes?created_after=$(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ)&cursor=eyJjcmVkZW50aWFsfQ==" \
-H "Authorization: Bearer grn_YOUR_API_KEY"
{
"notes": [
{ "id": "not_1d3tmYTlCICgjy", "title": "Quarterly yoghurt budget review", ... },
...
],
"hasMore": false
}
# Get that note with its transcript
# (use the not_ ID from the list response, not a UUID)
$ curl "https://public-api.granola.ai/v1/notes/not_1d3tmYTlCICgjy?include=transcript" \
-H "Authorization: Bearer grn_YOUR_API_KEY"
{
"id": "not_1d3tmYTlCICgjy",
"title": "Quarterly yoghurt budget review",
"owner": { "name": "Oat Benson", "email": "oat@granola.ai" },
"summary": "The quarterly yoghurt budget review was a success. ...",
"transcript": [
{ "speaker": { "source": "microphone" }, "text": "I'm done pretending. Greek is the only yoghurt that deserves us." },
{ "speaker": { "source": "speaker" }, "text": "Finally. Regular yoghurt is just milk that gave up halfway." }
],
...
}INFO
This transcript example is from macOS. On macOS, transcript items can come from the local microphone or from other meeting audio, so you'll see speaker.source = "microphone" and speaker.source = "speaker".
For iOS transcripts, the shape is slightly different:
json
[
{
"speaker": { "source": "microphone", "diarization_label": "Speaker A" },
"text": "I'm done pretending. Greek is the only yoghurt that deserves us."
},
{
"speaker": { "source": "microphone", "diarization_label": "Speaker B" },
"text": "Finally. Regular yoghurt is just milk that gave up halfway."
}
]INFO
On iOS, Granola currently returns speaker.source = "microphone" because the app currently captures a single audio stream. Clients should not assume that will never expand in the future. When diarization is available, diarization_label carries the anonymous Speaker A/B/... bucket.
INFO
The API only returns notes that have a generated AI summary and transcript. Notes that are still being processed or were never summarized won't appear in responses - the List Notes endpoint excludes them, and the Get Note endpoint returns a 404.
Rate Limits
Rate limits are applied per user or workspace, depending on the key's access scope, to ensure fair usage and platform stability.
| Metric | Value |
|---|---|
| Burst capacity | 25 requests |
| Time window | 5 seconds |
| Sustained rate | 5 requests/second (300/minute) |
When rate limits are exceeded, the API returns a 429 Too Many Requests response.