Notion
Configure Notion OAuth and webhook delivery for self-hosted ctxpipe.
Overview
Self-hosted Notion uses the same connector flow as hosted ctxpipe, but your deployment owns one public Notion integration. Individual users authorize that integration with OAuth; they do not create integrations or configure webhooks.
1. Create the public integration
Create a public integration in the Notion integrations portal and enable the content capabilities needed by ctxpipe.
Register this OAuth callback URL:
{AUTH_BASE_URL}/api/v1/connectors/notion/oauth/callbackSet NOTION_CLIENT_ID and NOTION_CLIENT_SECRET on the backend. Set
NOTION_REDIRECT_URI only when the public callback differs from the URL
derived from AUTH_BASE_URL.
2. Register the webhook once
Notion webhook subscriptions belong to the integration, not to each customer workspace. Configure one subscription for the deployment. ctxpipe then routes signed events to the matching Notion connection by workspace or integration.
Notion's first verification request is unsigned. To prevent another caller from claiming the signing token, ctxpipe requires a provisioning token derived from your Notion client secret. Generate it from the repository root:
NOTION_CLIENT_SECRET='your-client-secret' bun -e 'import { createHmac } from "node:crypto"; process.stdout.write(createHmac("sha256", process.env.NOTION_CLIENT_SECRET ?? "").update("ctxpipe:notion-webhook-provisioning:v1").digest("base64url"))'Use the result in the webhook URL:
{AUTH_BASE_URL}/api/v1/webhook/notion?provisioningToken={generated-token}Create the subscription in Notion. ctxpipe answers Notion's verification
request with 200 so the subscription activates, but it does not store the
signing token — the token is a deployment secret you set in the environment.
Copy the verification token from Notion's developer UI (shown after the
first delivery) and set it as NOTION_WEBHOOK_SECRET on the backend, then
restart:
NOTION_WEBHOOK_SECRET={verification-token-from-notion}Once set, ctxpipe validates every event's X-Notion-Signature against
NOTION_WEBHOOK_SECRET. Until it is set, signed events are rejected with 503
(Notion retries), so configure it before relying on live sync. This mirrors
GITHUB_WEBHOOK_SECRET.
The webhook is operator-level setup. Do not ask each ctxpipe organization to repeat it, and do not put the OAuth client secret itself in the webhook URL.
3. Complete connector setup
After the deployment integration is ready, each organization can:
- Authorize its Notion workspace.
- Choose or reuse a shared connector context repository.
- Select the Notion pages and databases to mirror.
- Review and merge the generated
notion/config.yamlpull request.
Pages are written as Markdown under notion/pages/. Databases are written
under notion/databases/, with one table.csv snapshot per database and one
Markdown file per row for task- and knowledge-oriented retrieval.
User guide
See Notion connector for scope, repository layout, review workflow, and user-facing recovery steps.