Notion Integration
Sync Notion pages into governed memory — read-only.
The Notion connector pulls your Notion pages into Cortex as governed, searchable memories. It is read-only: the Notion integration is configured with the Read content capability only, so Cortex can never edit or create pages in your workspace.
How it works
Notion has no webhook for page edits, so Cortex uses a scheduled pull:
Connect (OAuth)
Authorize Notion from Connectors (or onboarding). Cortex stores the workspace bot token.
Periodic sync
The cron job (POST /api/cron/connectors) searches for pages edited since
the connector's last cursor, newest first.
Ingest → memory
Each page's block text is extracted and routed through the governed pipeline (scope + clearance, embedding, vector + knowledge graph, audit), becoming recallable memory with a citation back to the page.
Setup
1. Create a public Notion integration
- Go to notion.so/my-integrations → New integration → type Public.
- Under Capabilities, enable Read content only. Leave Update and Insert off — this is what enforces read-only.
- Add the OAuth redirect URI:
https://<your-app>/api/connectors/notion/callback
2. Set environment variables
NOTION_CLIENT_ID=...
NOTION_CLIENT_SECRET=...
3. Connect
From Connectors (or onboarding step 1), click Connect on Notion and authorize the workspace + pages you want Cortex to read.
Notion OAuth has no per-request scope parameter — read-only is enforced entirely by the integration's capabilities setting in the Notion developer portal. Make sure only Read content is enabled.
What gets ingested
| Source | Becomes | Default scope | Category |
|---|---|---|---|
| Notion page | One memory per page (block text) | public-docs | Knowledge Base |
Scheduling the sync
curl -X POST https://<your-app>/api/cron/connectors \
-H "x-cron-secret: $CRON_SECRET"
Immediate sync for the workspace owner:
POST /api/connectors/notion/sync # CEO-only
Troubleshooting
"This connection can't be installed on <workspace> — The developer has
restricted this connection to specific workspaces."
This is a Notion integration setting, not a Cortex bug — the OAuth request
is well-formed. The integration behind NOTION_CLIENT_ID is configured in
Notion as internal (or restricted to an allow-list of workspaces) that doesn't
include the workspace you're installing into. Fix it in the Notion developer
portal (notion.so/my-integrations → your integration):
- Set the integration's distribution to Public, or
- Add the target workspace to the allowed workspaces, or
- If it's an internal integration meant for one workspace, install into that workspace instead.
No redeploy is needed — the change takes effect on the next authorize attempt.
Disabling
Disconnect from Connectors in the dashboard to clear the token and stop syncs.