Granola
Connect Granola with an API key so summarised meeting notes become signals, with transcripts available on demand.
Connecting Granola makes your meeting notes a signal source. Every Granola note that has a generated summary arrives in nima as one signal, so what a customer said on a call reaches the pipeline without anyone retyping it.
On for every workspace. An owner or admin pastes a Granola API key on the Integrations screen. nima only reads Granola: it never creates or edits notes.
Connect Granola with an API key
An owner or admin connects Granola by pasting a Granola API key into the Granola card on Integrations, the home screen of the admin panel. Granola has no consent screen: the key is the whole grant, and there is one key per workspace. Which notes the key can see (one person's notes or the whole workspace's) is decided on the Granola side.
- Create an API key in Granola.
- In nima, open Integrations and the Granola card.
- Paste the key into the API key field and click Connect Granola.
nima checks the key against Granola before it stores anything, so a bad key fails in the form. The stored key is encrypted at rest and never shown again.
You can replace the key at any time with POST /v1/granola/connect and a body of { "apiKey": "..." }, whether or not the current key still works. The key must be 8 to 500 characters. A new key clears the invalid state (connectionInvalid becomes false) and restarts the poll from the newest note.
All four Granola routes are session-only: an API key or OAuth token gets a 403. Connect, replace and disconnect need a signed-in owner or admin, and a plain member cannot connect. Any signed-in member can read GET /v1/granola/status, which returns connected, connectedAt, connectedByEmail, lastSyncedAt and connectionInvalid.
| Error | When |
|---|---|
400 VALIDATION_ERROR, details.field is apiKey | Granola rejected the key: it was copied in part or has been revoked. The key is never echoed back. |
429 INTEGRATION_RATE_LIMITED, details.retryAfterMs | Granola is rate limiting nima. Try again in a moment. |
If Granola later rejects the stored key during a sync, nima marks the connection invalid and stops polling it. The Granola card still shows as connected. Open the card to see the notice "Granola rejected the stored API key." The key field only appears on a card that is not connected, so to recover in the admin panel click Disconnect, then paste a new key and click Connect Granola. Signals already created stay, and notes already ingested are not ingested again. A signed-in owner or admin can also send the new key straight to POST /v1/granola/connect without disconnecting.
What arrives from Granola
Each summarised Granola note becomes one signal: its title and summary become the signal's content, and the note is ingested once.
- Summaries only. A note without a generated summary is skipped, then picked up on a later sync once the summary exists.
- Redacted summary. Before the summary is stored, nima removes private-key blocks, URLs (query strings, fragments and credentials stripped), email addresses (replaced with
[redacted email]), bearer and basic tokens, credential assignments such aspassword,secret,token,access_token,api_key,authorizationandcookie, and phone numbers (replaced with[redacted phone]). This always runs on the stored summary and cannot be turned off. The note title is stored as written, andget_signal_sourcereturns the summary live from Granola, unredacted. - Attendees and calendar event. Names, emails, the event title and its start and end times are kept as signal metadata, along with the note's share link.
- Customer or internal. If any attendee has an email domain different from the email domain of the person who connected the key, the signal's origin is
customer. Otherwise it isinternal. Attendees without an email are ignored. nima does not special-case free-mail domains, so a key connected with a free-mail address treats every other domain as outside. - Attendees replace guessed stakeholders. During extraction, the structured attendee list is used as the signal's stakeholders instead of the model's guess. People the model found in the text who are not attendees are kept as "mentioned".
- Beacon weight 0.5. Granola has no producer weight of its own, so its signals rank with the default 0.5 in beacon rank scoring, the same as Slack, below Sentry, PostHog and webhook signals at 0.8 and HubSpot at 0.7.
Transcripts are never stored.
Granola transcripts on demand
The get_signal_source tool returns the full Granola transcript live when called with part set to full. The default part of summary returns the note header and summary. Transcripts are fetched from Granola at request time, in pages of 100 transcript entries, and are not stored in nima.
The tool needs the sources:read scope and an owner or admin caller; its parameters, paging and the reasons a source can come back unavailable are on get_signal_source.
Granola sync timing and limits
nima polls Granola every 15 minutes, so in steady state a note with a finished summary becomes a signal (status pending, then classified) at the next poll.
| Limit | Value |
|---|---|
| Poll interval | Every 15 minutes |
| New notes ingested per run | 150 |
| Notes walked per run | About 1,800 (60 pages of 30) |
| Date cap | None: the whole history is eligible |
| Filters by folder, attendee or title | None |
| Keys per workspace | One |
A long history backfills gradually, at up to 150 notes per 15 minutes. Because each run re-walks from the newest note and stops after roughly 1,800, notes deeper than that in a very long history are not reached. Notes already ingested are skipped.
Every summarised note the key can see becomes a signal. If your team records many calls, decide which key to connect before you do. Granola's own rate limits apply, requests are retried with backoff, and nothing is written back to Granola.
The On / Paused switch on the card is a label only. It does not stop syncing.
Disconnect Granola
An owner or admin disconnects Granola with Disconnect on the Granola card, or with DELETE /v1/granola/connection (204) or DELETE /v1/integrations/granola. Both stop nima from using the stored key and stop polling. The encrypted key is marked deleted rather than erased, so to revoke access on Granola's side, delete the key in Granola. Signals already created stay, with their evidence and links.