Something quietly significant happened to Notion this year, and most of the people running Notion workspaces have not noticed yet. An AI agent can now hold a seat in your workspace. Not a background integration writing rows through a token, an actual named participant that shows up in @-mentions, gets assigned to database items, and can be handed a card on a board like any other member of the team.
Notion shipped it in stages between February and September. Custom Agents went to public beta, then general availability with usage pricing. The Developer Platform arrived with an External Agents API in alpha. By July, Claude and Cursor were live inside workspaces. By August there were public endpoints for driving agents programmatically and an Admin API for governing them.
That is a lot of platform in seven months, and platforms that move that fast leave sharp edges. This is what actually shipped, what it costs, what governs it, and the one failure mode that will catch people who treat an agent as just another automation.
What actually shipped, and when
Worth laying out properly, because the announcements landed close enough together that they blur, and because a few of them carry dates you need to care about.
- 25 February. Custom Agents enter public beta.
- 4 May. Custom Agents reach general availability and move onto Notion Credits, a usage-based add-on for Business and Enterprise at $10 per 1,000 credits. The pool is shared across the workspace and resets monthly. Unused credits do not roll over.
- 5 May. Admin controls for Custom Agents: workspace-level credit limits, alerts at 80% and 100%, and the ability to pause everything.
- 13 May. Notion 3.5, the Developer Platform. The External Agents API lands in alpha behind a waitlist, alongside Notion Workers, a CLI, Database Sync, and an Agent SDK.
- 1 July. Notion 3.6 ships External Agents properly, with Claude and Cursor as the first two.
- 11 August. Workers stop being free and start consuming Notion credits.
- 12 August. The Admin API gains agent endpoints: credit usage, limits, permissions, status, creation policy, workflow metadata.
- 20 August. The Notion Agent APIs reach public beta. Anything still on the private alpha routes has to migrate by 30 September.
- 24 August. The Admin API adds user and permission group management, Enterprise only.
If you skim one line in that list, make it 20 August. A deprecation with a date on it is the only item here that can break something you already built.
Custom Agents and External Agents are not the same product
This is the confusion I keep running into, and it matters because the two behave differently on every axis you would care about: who builds them, what model they run, who pays, and what you can govern.
A Custom Agent is built inside Notion. You configure it in the workspace, it runs on Notion AI, it burns Notion credits, and the Admin API can see and control it. It is Notion's own thing, end to end.
An External Agent is somebody else's agent, given a seat. Claude Code from Anthropic and Cursor from Anysphere were the first two, with Codex and Decagon also named at the platform launch, and the same API is open to agents you built yourself. The agent runs on the vendor's infrastructure and the vendor's model. Notion provides the identity, the permissions, and the surface it acts on.
The practical consequence: advice about one does not transfer to the other. A guide to capping Custom Agent credits tells you nothing about what a Cursor agent is doing in your workspace, because that one is not spending Notion credits at all.
How an external agent actually behaves
You add one from your agent library, picking the vendor when you create it. That choice is permanent, so a blank agent cannot be converted into a Claude agent later. Claude authenticates with a GitHub personal access token under advanced settings. Cursor authenticates with a Cursor API key and lets you pick from several models.
Once it exists, you grant it access to specific Notion databases, exactly like sharing with a person. Then it can be triggered two ways: @-mention it on a page, or wire a database automation so a status change hands it work. Moving an issue to "Ready for pickup" and having an agent start on it is the flagship demo, and it works.
The differences between the two vendors are sharper than the marketing suggests. Claude runs in an isolated sandbox with no access to your local files or personal skills, so any capability you want it to have must be injected through a GitHub repository or shared as a Notion page. That isolation is good security and awkward ergonomics. It also means you cannot start a run in Notion and continue it in your local Claude Code session. Cursor stays connected to your wider Cursor setup, which makes handoffs between the workspace and your editor much smoother.
One more constraint worth knowing before you commit: a Claude agent is locked to Anthropic models. If model choice matters to you, that decision is made at creation time and you live with it.
The billing split nobody puts in the announcement
Here is the detail that should shape your decision more than any feature comparison. Claude external agents consume Notion credits. Cursor agents bill your existing Cursor plan and never touch the Notion pool at all.
Read that again with a budget in mind. The Notion credit pool is shared across the entire workspace and resets monthly with no rollover. Every Claude agent run competes for the same credits as every Custom Agent your ops team built, and as of 11 August, as every Notion Worker you deployed. A team already paying for Cursor can route agent work through Cursor and leave the Notion pool entirely for the workspace automations that have no alternative.
That is not a small optimisation. For a team running agents at any volume it is the difference between one line item and two, and it is decided by a dropdown at agent creation time that nothing in the interface flags as a financial choice.
The failure mode: an agent out of credits does not error
Everything above is setup. This is the part that will actually cost somebody a quarter.
When a workspace reaches its credit limit, agents pause. They do not throw. They do not return a 429 you can catch, or a 402 you can branch on. Notion emails an admin at 80% and again at 100%, and the agents stop.
Think about where that lands. Your n8n workflow triggers a Notion automation, which assigns a card to an agent, which was supposed to draft the response and move the status. The agent is paused. The card sits there. n8n's execution log is green, because n8n did its job perfectly: it moved the card. Every error handler you built is watching for exceptions that will never arrive.
This is the exact shape I wrote about in automation drift, with a new cause. The workflow still runs, still reports success, and the output has silently stopped being produced. What is new is that the trigger is financial. Your automation now has a funding dependency, and the alert for it goes to a workspace admin's inbox rather than to whoever owns the workflow.
The two roles are almost never the same person. The admin who gets the 80% email is in finance or IT. The person who needs to know is the ops lead whose board just stopped moving. Nothing connects them.
Poll the usage yourself
The fix is unglamorous and takes about twenty minutes. Do not wait for Notion's alert, because by the time the 100% email arrives the work has already stopped. Poll the agent insights endpoint on a schedule and alert on the trend.
// POST /v1/agents/query
// Find every Custom Agent the current token can actually reach.
// Run this first. It is the only honest inventory you will get.
const res = await fetch("https://api.notion.com/v1/agents/query", {
method: "POST",
headers: {
"Authorization": "Bearer " + token,
"Notion-Version": "2026-03-11",
"Content-Type": "application/json"
},
body: JSON.stringify({ page_size: 100 })
});
const data = await res.json();
// Same list shape as every other Notion endpoint:
// results, has_more, next_cursor.
// Loop on has_more or you will inventory the first 100 agents
// and quietly miss the rest.Note the list shape. results, has_more, next_cursor, the same cursor pagination as every other Notion list endpoint. An inventory that reads the first response and stops will miss agents past the hundredth, which is the same failure I covered in the 100-row wall wearing different clothes.
// GET /v1/agents/{agent_id}/insights
// Per-agent usage: credits burned, run counts, current status.
// This is the endpoint that turns "the agent stopped" into a number
// you could have seen coming.
async function getAgentUsage(agentId) {
const res = await fetch(
"https://api.notion.com/v1/agents/" + agentId + "/insights",
{
headers: {
"Authorization": "Bearer " + token,
"Notion-Version": "2026-03-11"
}
}
);
return res.json();
}
// Poll this on a schedule. Do not wait for a human to notice
// that the board stopped moving.Then the tripwire. The point is to fire well before the ceiling and to send the warning to the person who owns the work, not only to the admin who owns the budget.
// The guard that costs four nodes.
// An agent that runs out of credits does not error. It pauses.
// So poll usage yourself and alert on the trend, not the wall.
// n8n Code node, running on a schedule trigger:
const agents = $input.all();
const alerts = [];
for (const item of agents) {
const a = item.json;
const used = a.credits_used || 0;
const limit = a.credit_limit || 0;
if (!limit) continue; // no cap set, nothing to trip
const pct = (used / limit) * 100;
// Notion alerts an admin at 80 and at 100. By 100 the agent
// has already stopped. Fire your own warning earlier, and send
// it to the person who owns the workflow, not just the admin.
if (pct >= 60) {
alerts.push({
agent: a.name,
percent: Math.round(pct),
severity: pct >= 85 ? "critical" : "warning"
});
}
}
return alerts.map(a => ({ json: a }));Sixty percent is not a magic number. Pick a threshold that gives whoever has to act on it enough runway to either raise the cap or turn something off before the month ends. The principle is that a limit you discover by hitting it is not a limit, it is an outage.
The 30 September migration, if you built early
If you got waitlist access and built against the private alpha routes for agents, threads, messages, or chat, those routes retire on 30 September 2026. This is worth its own section because the word "migration" undersells it.
// The alpha to beta migration is not a rename. The shape changed.
// If you built against the private alpha routes, both halves of
// every call are different.
// BEFORE (alpha): parameters rode in the query string,
// and the model was threads containing messages.
//
// GET /v1/.../chat?thread_id=abc&message=hello
// -> { "thread": { "messages": [ ... ] } }
// AFTER (public beta): parameters ride in a JSON body,
// and the model is sessions containing events.
//
// POST /v1/... with Content-Type: application/json
// { "session_id": "abc", "input": "hello" }
// -> { "session": { "events": [ ... ] } }
// Renaming your variables is not the migration. Anything that
// read thread.messages needs to read session.events, and every
// call that built a query string needs to build a body instead.Two things changed at once. The replacements take JSON request bodies where the alpha took query parameters, and the domain model moved from threads containing messages to sessions containing events. Either change alone would be a find and replace. Together they mean every call site needs its request rebuilt and its response re-read, and a compiler will not help you because the old code still compiles perfectly and just talks to an endpoint that is about to stop existing.
The public beta gives you sessions with streaming replies, action submission, retrievable session state, queryable sessions, paged event history, and cancellation of a run in progress. Alongside that sit the management endpoints: POST /v1/agents/query to find agents, GET /v1/agents/{agent_id}/insights for usage, and POST /v1/agents/batch for setting credit limits or enabling, disabling and deleting agents in one asynchronous call.
Authentication is either a personal access token, which acts as the user and inherits whatever Custom Agent access that user already has, or a connection token carrying the "Interact with agents" capability. Permissions follow the ordinary Notion model: read lets you view agents and sessions, edit lets you change status or delete, and full access is what you need to manage credit limits. That last tier is the one to be careful with, because the ability to raise a credit limit is the ability to spend money.
What you can actually govern
The Admin API is where an agent programme stops being a pilot and becomes something you can run. It shows every Custom Agent in the workspace, who created it, whether it is active, which model it uses, when it last ran, and what it can reach. It sets who is allowed to create agents at all, tracks and caps credits per agent or across the whole workspace, updates sharing permissions, and can pause everything at once.
Two constraints on that, and both are load-bearing. It is Enterprise only. And it does not accept personal integration tokens: it needs an org-owned admin token, with changes attributed to your organisation's admin access rather than to a person.
That second constraint is the right design and it catches teams out. If your plan for governing agents was a script running under somebody's personal token, that plan does not work. Someone has to own an organisation-level credential, and that is a conversation with whoever runs security, not a task you finish on a Friday afternoon.
Below Enterprise, you do not have programmatic governance. You have the interface, workspace credit limits, and a shared understanding of who is allowed to build what. For a small team that is genuinely fine. It stops being fine at roughly the point where you cannot name every agent in the workspace from memory.
Before you let one into a client workspace
This is what I run through, and most of it is permissions thinking rather than AI thinking. An agent with a seat in your workspace is a member with credentials, and the interesting questions are the ones you would ask about any new member with unusual access.
- Which databases can it actually reach? Grant it the ones it needs and nothing adjacent. Access granted for one task tends to outlive the task.
- Who created it, and does that person still work here? The Admin API answers this. Without Enterprise, you need to write it down somewhere.
- Does it consume Notion credits or the vendor's plan? Decide this deliberately at creation, because you cannot change vendor afterwards.
- What is the credit limit, and who gets the alert? If the answer is "an admin", add a second alert routed to whoever owns the work.
- Is anything downstream assuming the agent completed? If a workflow depends on the agent moving a status, add a staleness check: a card sitting in the same state past a threshold should page someone.
- For Claude specifically, what is in the GitHub repository you pointed it at? That token and that repo are the agent's entire capability surface.
- If you built on the alpha routes, is the migration done? After 30 September the question stops being hypothetical.
None of this is a reason to avoid external agents. Assigning a card to Claude and having a reviewed pull request come back is genuinely useful, and the multi-agent patterns people are building on top of it, a planner handing to a builder handing to a reviewer, are the first agent workflows I have seen that survive contact with a real team.
The point is narrower. Notion added a member type that spends money, holds permissions, and stops working without raising an error. Every one of those three properties needs something watching it, and none of them are watched by the error handling you already built.
Frequently asked questions
What is the Notion External Agents API?
It is the interface that lets an AI agent built outside Notion hold a seat inside a Notion workspace as a named participant with its own identity and permissions. The agent appears in @-mentions, can be assigned to database items, and can be triggered by database automations. Claude and Cursor were the first two supported, with Codex and Decagon also named at launch, and the same API accepts agents you built yourself.
What is the difference between a Notion Custom Agent and an External Agent?
A Custom Agent is built inside Notion, runs on Notion AI, consumes Notion credits, and is governed by the Admin API. An External Agent is built elsewhere and runs on the vendor's model and infrastructure, with Notion supplying only the identity, permissions, and workspace surface. Billing and governance differ by vendor, so guidance about one does not apply to the other.
Do Notion External Agents use Notion credits?
It depends on the vendor. Claude external agents consume Notion credits from the shared workspace pool, which is priced at $10 per 1,000 credits for Business and Enterprise and resets monthly with no rollover. Cursor agents bill your existing Cursor plan and do not draw on the Notion pool at all. The choice is made when you create the agent and cannot be changed afterwards.
What happens when a Notion agent runs out of credits?
It pauses rather than failing. No error is returned to anything calling it, so upstream automations continue reporting success while the agent's work silently stops. Notion emails a workspace admin at 80% and 100% of the limit. Poll the agent insights endpoint on your own schedule and alert at a lower threshold, routed to whoever owns the workflow rather than only to the admin who owns the budget.
When do the Notion Agent API alpha routes stop working?
30 September 2026. Anything built against the private alpha routes for agents, threads, messages, or chat must move to the public beta by then. The replacements take JSON request bodies instead of query parameters and return sessions containing events instead of threads containing messages, so both the request and the response handling have to change.
Do I need Enterprise to manage Notion agents through the API?
For the Admin API, yes. Managing agent creation policy, credit limits across the workspace, permissions, and status programmatically requires the Enterprise plan and an organisation-owned admin token. Personal integration tokens are not accepted, and changes are attributed to the organisation's admin access. The Agent APIs for driving a specific agent work with a personal access token or a connection token carrying the "Interact with agents" capability.