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

# Granola

> Technical reference for the Rippit Granola data integration: API key authorization, API endpoints, what a note becomes in Rippit, and sync behavior.

A read-only API key integration that syncs Granola meeting notes and transcripts into Rippit on a schedule. For what applies to every integration, see [how data integrations work](/plg/data-integrations). For the security model, see [Data integration security](/security/data-integrations).

## Connection summary

| | |
| - | - |
| Authorization | Granola API key, sent as `Authorization: Bearer <key>` |
| Key format | Starts with `grn_`. Any other value is rejected before it reaches Granola |
| Granola plan | Business or Enterprise, to create an API key |
| Scope parameter | None |
| Writes to Granola | None. Every call is a `GET` |
| Credentials shared with Rippit | The API key. Rippit stores it and uses it for every sync |
| Credential check | The key is tested against Granola before the connection is saved. A rejected key saves nothing |
| Connection identity | The workspace name you enter. Granola's API returns no workspace or account ID |
| Required Rippit role | Workspace admin |
| API base | `https://public-api.granola.ai` |
| API version | `v1`, in the path |
| Sync method | Scheduled polling |
| Attachments and audio | None requested. Only note text and transcript text |
| Maximum historical backfill | 90 days |
| Field selection limit | 150 columns |

## Data handling

| Question | Answer |
| - | - |
| Is note content ingested, or only metadata? | Full content: Granola's AI summary, the note's private notes, and the full transcript |
| Are private notes ingested? | Yes. They are stored as an internal comment, separate from the summary and the transcript |
| Are attachments or audio stored? | No. No file or audio endpoint is called |
| Can Rippit modify Granola? | No. No write code path exists |

### What a note becomes in Rippit

Each Granola note becomes one conversation in Rippit.

| Rippit record | Content |
| - | - |
| Subject | The note title |
| Agent | The note owner, by email. The owner is also added to your agent list |
| Fields | Owner name, attendee emails, folder names, the note's Granola URL, summary text, and private notes text |
| Default selected fields | Title, owner, attendee emails, and summary |
| Summary comment | Granola's AI summary, timestamped at the note's creation so it sits above the transcript |
| Internal comment | The note's private notes, when present, timestamped the same way |
| Transcript comments | The transcript, one comment per speaker turn |

Transcript lines are merged into speaker turns. Consecutive lines from one speaker join the same turn until there is a pause of more than 3 seconds or the turn reaches 1,000 characters.

Lines Granola attributes to the note owner carry the owner's name. Other speakers carry the name Granola identified. When Granola has no name and the note has exactly one attendee besides the owner, that attendee's name is used. Otherwise the line carries Granola's anonymous speaker label.

The "Chat with meeting transcript" link Granola appends to each summary is removed. Links from Rippit to a note open the note's own Granola URL.

## API endpoints

### Authentication

| Purpose | Endpoint | Method |
| - | - | - |
| Credential check when you connect | `/v1/notes?page_size=1` | GET |

### Notes

| Object | Endpoint | Method |
| - | - | - |
| Note discovery | `/v1/notes?updated_after=<window start>&created_before=<window end>&page_size=30` | GET |
| Note content and transcript | `/v1/notes/<id>?include=transcript` | GET |
| Note without transcript, when Granola answers `413` because the transcript is too large to inline | `/v1/notes/<id>` | GET |
| Transcript, paged, for those notes | `/v1/notes/<id>/transcript?page_size=100` | GET |
| Field discovery, a sample of 5 notes | `/v1/notes?page_size=5`, then `/v1/notes/<id>?include=transcript` for each | GET |

Notes are read in two phases, which is why `/v1/notes` and `/v1/notes/<id>` both appear.

**Discovery.** `/v1/notes` returns only each note's ID, title, owner, and timestamps. Granola has no `updated_before` filter, so each window is bounded by `created_before`, which keeps a backfill from listing the same notes in every window. `updated_after` still catches edits to older notes. Granola pages by cursor, and Rippit repeats the original filters on every page.

**Content.** Each listed note is then fetched individually at `/v1/notes/<id>?include=transcript`, 5 concurrent. This is the call that returns the summary, private notes, attendees, folders, and transcript. A note that returns `404`, because it was deleted after it was listed, is skipped.

No other Granola object is listed or swept. Owner, attendees, and folders come from the note record itself. No endpoint for deleted notes is called.

## Sync behavior

| | |
| - | - |
| Note discovery | Windowed on `updated_after`, bounded by `created_before`, 30 per page, cursor pagination |
| Window width | 24 hours, one window at a time |
| Trailing buffer | Each window closes 5 minutes behind the current time |
| Content fetch | Per note by ID, 5 concurrent |
| Daily re-sweep | The last 24 hours are listed again once a day, because a note appears in the list only after Granola generates its AI summary |
| Update handling | An edited note is listed again and refetched. A note version already fetched in the same run is not fetched twice |

## Rate limiting

* Every request, retries included, starts at least 250 ms after the previous one, so a sync sends at most 4 requests per second
* A backfill makes one content request per note, on top of the discovery pages
