Claude API Integration with Notion Workspace: Setup Guide
Integrating the Claude API with a Notion workspace means connecting Notion's API (for reading and writing pages, databases, and blocks) to Claude's API (for generating and transforming text), then wiring the two together with your own code or an automation platform. There's no official "Claude for Notion" plugin — you build the bridge yourself, and it's simpler than it sounds.
This guide covers the three integration patterns that actually get used in production: syncing Notion content into Claude for summarization, writing Claude output back into Notion pages, and running a lightweight sync service that keeps both in sync on a schedule or webhook trigger.
Why Connect Claude to Notion
Teams use this integration for a handful of recurring jobs:
- Meeting notes → structured summaries. Pull a raw notes page, send it to Claude, write back a clean summary with action items.
- Database enrichment. Loop over rows in a Notion database (leads, tickets, content drafts) and have Claude fill in a status, tag, or draft field.
- Knowledge base drafting. Feed Claude a set of source pages and have it draft a new help-center article directly into a Notion page.
- Weekly digest generation. Aggregate updates across a workspace and produce a digest block at the top of a dashboard page.
All of these follow the same shape: read from Notion → send to Claude → write back to Notion.
Step 1: Set Up Your Notion Integration
Create an internal integration at notion.so/my-integrations, copy the secret token, and share the specific pages or databases you want it to access. Notion integrations only see content explicitly shared with them — this is a common gotcha when nothing comes back from the API.
const notionRes = await fetch(`https://api.notion.com/v1/blocks/${pageId}/children`, {
headers: {
"Authorization": `Bearer ${process.env.NOTION_TOKEN}`,
"Notion-Version": "2022-06-28"
}
});
const blocks = await notionRes.json();
Extract plain text from the returned blocks (paragraphs, headings, bullet items) and concatenate it into a single string — that's what you'll send to Claude.
Step 2: Call Claude with the Extracted Content
This is the part where SubToAPI simplifies things. Instead of managing a separate Anthropic billing relationship, API keys, and rate-limit tiers just for this one automation, you use the Claude access you already have through your subscription, exposed as a standard HTTPS API.
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "claude-sonnet-4-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: `Summarize this Notion page into a short overview and a bullet list of action items:\n\n${pageText}`
}
]
})
});
const data = await response.json();
const summary = data.content[0].text;
The request and response format follows the same structure as Anthropic's native Messages API, so if you've already built Claude integrations before, this drops in without a rewrite. Check /docs/messages for the full request shape.
Step 3: Write the Result Back into Notion
Append a new block to the page, or update a property on a database row, using Notion's PATCH endpoint:
await fetch(`https://api.notion.com/v1/blocks/${pageId}/children`, {
method: "PATCH",
headers: {
"Authorization": `Bearer ${process.env.NOTION_TOKEN}`,
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
},
body: JSON.stringify({
children: [
{
object: "block",
type: "callout",
callout: {
rich_text: [{ type: "text", text: { content: summary } }]
}
}
]
})
});
Wrap this in a small script, a scheduled job, or a serverless function triggered by a Notion webhook (via a third-party listener, since Notion doesn't push native webhooks) and the loop is fully automated.
Handling Database Rows at Scale
If you're enriching a Notion database rather than a single page, query the database first:
const rows = await fetch(`https://api.notion.com/v1/databases/${dbId}/query`, {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.NOTION_TOKEN}`,
"Notion-Version": "2022-06-28"
}
}).then(r => r.json());
Then loop through rows.results, build a prompt per row, and call Claude for each one. For anything beyond a few dozen rows, batch the requests and add a short delay between calls to avoid hitting rate limits on either side. If you're generating long-form content per row — drafts, descriptions, reports — switch to streaming so you're not holding a connection open waiting for a full response; see /docs/streaming for the pattern.
Where SubToAPI Fits
The Notion half of this integration is the same regardless of provider. The part that varies is how you access Claude itself. If you're already paying for a Claude plan, SubToAPI turns that access into an application API key (sub_live_...) with usage metadata, team seats, and the standard Messages/streaming/tools endpoints — so your Notion automation doesn't require a separate Anthropic developer account or a second invoice to track. Plans start at €9/month for solo use, with Team and Scale tiers for shared workspaces; see /pricing. You can test the setup above with a free trial at /signup, and the quickstart at /docs/quickstart walks through generating your first key.
A Few Practical Notes
- Respect Notion's rate limits (roughly 3 requests per second per integration) — batch and throttle accordingly.
- Keep prompts focused. Dumping an entire workspace into one Claude call produces vague output; summarize or enrich page-by-page or row-by-row.
- Use tool calling if you want Claude to decide which Notion page to update based on content — see /docs/tools for how function calling works against the API.
- Version your prompts. Notion content formatting changes over time (new block types, nested structures); keep your text-extraction logic and your Claude prompt templates separate so you can update one without breaking the other.
Questions
Does Notion have a built-in Claude integration? No official one. You connect them yourself using Notion's API to read/write content and Claude's API to generate text, glued together with a short script or automation.
Can I use my existing Claude subscription instead of a separate developer API key? Yes — tools like SubToAPI expose your existing Claude access as a standard HTTPS API, so you don't need a separate Anthropic developer account just for this automation.
How do I avoid hitting rate limits when processing a large Notion database? Query the database once, batch rows into small groups, add short delays between Claude calls, and use streaming for longer generations so connections don't sit idle.