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

  1. Go to notion.so/my-integrationsNew integration → type Public.
  2. Under Capabilities, enable Read content only. Leave Update and Insert off — this is what enforces read-only.
  3. 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

SourceBecomesDefault scopeCategory
Notion pageOne memory per page (block text)public-docsKnowledge 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.