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

# Granola setup

ConfigView reads your Granola workspace through Granola's public API, using a **workspace API key** and, on Enterprise plans, an **Audit API key**. You create both in the Granola desktop app.

You will end up with **1 required secret** (`GRANOLA_API_KEY`) and **1 optional secret** (`GRANOLA_AUDIT_API_KEY`) in ConfigView when setup is complete.

> **Scope of this integration today.** ConfigView reads who is in your Granola workspace and with what role, which integrations (Slack, HubSpot, Salesforce, Notion, Attio, Pipedrive, Zapier) and which AI tools over MCP read your meeting notes, notes and folders shared with outside email addresses, data exports, webhooks, and who owns which notes. It never collects note titles, note text, AI summaries, transcripts or attendees. ConfigView only reads. It never creates, changes or deletes anything.

***

## Plan requirements

| What | Plan | Secret |
| - | - | - |
| Notes (owner and dates only), folders, spaces, webhooks | Business or Enterprise | `GRANOLA_API_KEY` |
| Audit log, and the full member list built from it | Enterprise | `GRANOLA_AUDIT_API_KEY` |

On a Business plan, leave `GRANOLA_AUDIT_API_KEY` empty. The audit log collector skips itself and the health check reports it as skipped, not failed.

***

## Step 1: Open the Granola page in ConfigView

Open ConfigView in a second browser tab and leave it open:

`https://{companyname}.configview.com/admin/integrations/granola`

Granola shows each key once, when you create it, so paste it straight into ConfigView instead of keeping it in a notes file.

***

## Step 2: Create a workspace API key

You need to be a **workspace admin**.

1. Open the **Granola desktop app**
2. Click your workspace name in the bottom-left corner, then **Settings**
3. Open **Connectors → Workspace API keys** and click **Create new key**
4. Copy the key. It starts with `grn_`
5. Switch to the ConfigView tab, paste it into `GRANOLA_API_KEY` under **Credentials**, and click the save icon

Use a **workspace** key, not a personal one from **Connectors → API keys**. A workspace key belongs to the workspace, never expires, and keeps working after the admin who made it leaves. A personal key stops when its owner leaves.

### What a workspace key can see

A workspace API key reads **public notes** (notes in folders everyone in the workspace can see, such as the Team space) and **notes in spaces that have Granola API access switched on**. It never sees private notes. That is the right amount of access for ConfigView, which only records who owns a note and when it changed. If `granola_notes` is smaller than you expect, that's why: switch on **Allow access with a workspace API key** under a space's **Integrations → Granola API** to include it.

***

## Step 3 (Enterprise only): Create an Audit API key

1. In the Granola desktop app, open **Settings → Connectors → Audit API keys** and click **Create new key**
2. Name it `ConfigView`
3. Copy the key and paste it into `GRANOLA_AUDIT_API_KEY` in ConfigView, then click the save icon

An audit key reads the audit log and nothing else. A workspace can have up to five; give ConfigView its own so you can revoke it without affecting anything else. To rotate it, create the new key, save it in ConfigView, then revoke the old one.

Don't swap the two keys. The workspace key can't read the audit log, and the audit key gets a "not found" answer from every other endpoint.

***

## Step 4: Connect and verify

1. Back on `https://{companyname}.configview.com/admin/integrations/granola`, confirm the credentials show as saved
2. Click **Connect**. ConfigView creates its tables and schedules every collector at your default run time. Stop any you don't want under **Collectors**:

| Script | Notes |
| - | - |
| **Spaces** | Shared spaces the workspace key can see: id and name. |
| **Folders** | Folders the workspace key can see, the folder each sits in, and its space. |
| **Notes** | Which notes exist and who owns them: owner name and email, the spaces each note is in, and when it was created, last changed or deleted. No titles or content. |
| **Webhook Endpoints** | Webhooks that send note events out of Granola: the receiving host, which events and note scopes, folder restrictions, who created it and whether it's on. |
| **Audit Log** | The workspace audit log (Enterprise). Kept in ConfigView beyond Granola's one-year limit. |
| **Members** | Who is in the workspace, rebuilt from the audit log and note owners. It makes no API calls and runs after Audit Log and Notes. |

3. Click **Verify now**. The health check confirms the workspace key can read notes, reads one record each of folders, spaces and webhooks, and then checks the audit key if you added one.

If a check fails:

* **Auth fails with 401.** The key is wrong or was revoked. Create a new one and paste it again.
* **Auth fails with 404 on /v1/notes.** An Audit API key was pasted into `GRANOLA_API_KEY`. Put it in `GRANOLA_AUDIT_API_KEY` instead and create a workspace key for `GRANOLA_API_KEY`.
* **Webhook endpoints is skipped.** The webhooks API isn't available on your plan. Nothing to fix.
* **Audit log is skipped.** No audit key is saved, or the plan isn't Enterprise.

***

## Data Tables

Once the scripts run, these tables are created in your database. Each includes a `run_at` column and a `raw_json` column holding the record as Granola returned it, minus the fields listed under *What isn't collected*. The snapshot tables keep only the newest run. `granola_audit_events` keeps every event it has ever collected.

| Table | Source | Key Columns |
| - | - | - |
| `granola_spaces` | `GET /v1/spaces` | space\_id, name |
| `granola_folders` | `GET /v1/folders` | folder\_id, name, parent\_folder\_id, space\_id |
| `granola_notes` | `GET /v1/notes`, and again per space | note\_id, owner\_name, owner\_email, space\_ids, created\_at, updated\_at, deleted\_at |
| `granola_webhook_endpoints` | `GET /v1/webhook-endpoints` | webhook\_id, url\_host, url\_redacted, events, scopes, folder\_ids, created\_by\_name, created\_by\_email, enabled, created\_at |
| `granola_audit_events` | `GET /v1/audit` | event\_id, action, action\_group, occurred\_at, collected\_at, actor\_type, actor\_user\_id, actor\_email, actor\_api\_key\_suffix, ip\_address, user\_agent, client\_version, document\_id, document\_list\_id, subject\_user\_id, subject\_email, role, integration, granted\_emails, mcp\_client\_name, mcp\_client\_version, mcp\_tool\_name, mcp\_outcome, api\_key\_name |
| `granola_members` | built from the two tables above | user\_id, email, name, role, status, status\_source, joined\_at, left\_at, first\_seen\_at, last\_activity\_at, last\_login\_at, mcp\_tool\_calls, mcp\_last\_used\_at, note\_count |

***

## Things worth knowing

**Granola has no member list.** Its API has no users endpoint. `granola_members` is assembled from three places, and `status_source` says which one each row came from:

* `audit`: a member added, joined, invited, removed, left or role-changed event set the role and status
* `activity`: the person appears acting in the audit log, which only covers people while they are members, so they were a member then. They joined before the log's first event
* `notes`: the person owns a note the workspace key can see. Their role and status are unknown

Without an audit key, every row is a `notes` row, and anyone who owns no visible note is missing.

**The audit log becomes your archive.** Granola serves one year of audit events and never backfills older ones. ConfigView stores every event it collects and never deletes them, so history builds up from the day you connect. The first run backfills the year Granola still holds. A busy workspace can take a few runs to finish, because each run stops after 25 minutes and the next one carries on.

**`action` is an open list.** Granola adds new audit actions over time. ConfigView stores every action it receives, including ones it doesn't know about yet. The `integration`, `granted_emails`, `subject_email` and `mcp_*` columns are filled in for the actions that carry them. Everything else is in `raw_json`.

**MCP client names are self-reported.** `mcp_client_name` is what the connecting AI tool says it is, for example "Claude" or "ChatGPT". Granola doesn't verify it, and older events have it empty.

**ConfigView's own requests show up in the audit log.** Granola writes a `workspace.public_api_key_used` summary every five minutes a key is in use, so ConfigView's workspace key appears there under the name you gave it.

**Rate limit.** Granola allows 5 requests a second, shared by every API key in the workspace. ConfigView paces itself at 2 a second so it doesn't slow down anything else using the API.

## What isn't collected

* Note titles. Meeting subjects can be sensitive, so the title is removed before anything is stored
* Note text, AI summaries, private notes, transcripts, attendees and calendar event details. ConfigView never calls the endpoint that returns a single note
* Titles, descriptions and other free text inside audit events, such as a renamed folder's title or an automation's description. Ids, roles, counts and email addresses are kept
* Webhook URLs beyond the host name, because the rest of the URL can contain a password or token. Webhook signing secrets
* Legal holds. They need a separate Legal hold API key and name the matters under investigation


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.