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/callback

Set 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:

  1. Authorize its Notion workspace.
  2. Choose or reuse a shared connector context repository.
  3. Select the Notion pages and databases to mirror.
  4. Review and merge the generated notion/config.yaml pull 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.