Notion
NOTION · FILES & DOCS
Connect Notion to your AI app with scoped access.
Let users connect Notion and make supported tools available to your agent. Document the provider’s sharing requirements alongside the permissions enforced by Fabriq.
Connect Notion with Fabriq Developer
Your user consents at Notion. The credential lands in a vault your agent cannot read, and the tool list it gets back is the intersection of that user’s grant and the agent’s own scopes.
Provider names are surfaces, not vendors, and the authoritative list is the capabilities endpoint rather than any page including this one — an unknown name returns 400 with the valid list. Fabriq Developer is free to start and needs no provider paperwork. Start free or read the quickstart.
Ship the Notion integration
Every route, header, field name and error string below is the gateway’s own, and every tool id and scope comes from the generated schema behind the action list further down this page.
Prerequisites
Before the redirect above can do anything, four things have to be in place on the Fabriq side and one or two on the Notion side.
- A Fabriq Developer app, and its AF_APP_ID and AF_APP_SECRET. They ride on every app-scoped call as X-App-Id and X-App-Secret.
- A Redirect URL saved on the agent’s Connect & webhooks page. It is checked before anything else, so leaving it empty fails every connect with “B2B2C OAuth callback URL not configured” and hides whatever else is wrong.
- An external user id of your own, one per real person, created with POST /api/v1/apps/{app_id}/external-users. The call is idempotent and a 409 means the id already exists.
- Grants on the agent itself. The tool list a user gets back is the intersection of that user’s grant and the agent’s own scopes, so an agent with no overlapping grant sees nothing even after a clean consent.
- At least one page or database shared with the connection. Notion is explicit that “before a connection can interact with your Notion workspace page(s), the page must be manually shared with the connection”, through the ••• menu at the top right of a page and Add connections.
- A plan for who does that sharing. Notion documents that after a user authorizes a public connection, only that user can interact or share pages and databases with it, so two people in one workspace can end up with different halves of the same integration.
Connect an account
The gateway provider id is notion. Post the initiate, redirect the user to oauth_url, and let them authorize and pick pages in Notion’s own picker. The capabilities the connector declares are read_content, insert_content, update_content and read_user_info.
Sharing is the half of this that happens outside your flow. The consent screen does not grant content access on its own: a connection reaches a page only once someone adds it there, and Notion notes that a connection added to a page can also reach that page’s children.
Make one tool call
notion_get_connection_info declares no scope at all and returns the workspace name and the connection status, which makes it the right first call: it separates “the connection is broken” from “nothing has been shared with it yet” before you spend a scope finding out.
Then run notion_search (POST /api/v1/tools/notion/search, read_content, no required arguments). An empty result from a healthy connection is the signature of the sharing step not having happened, not of a failure.
Inspect the result
Scope to action, as the connector declares it: read_content covers notion_search, notion_list_pages, notion_get_page, notion_list_databases, notion_get_database, notion_query_database, notion_get_block and notion_get_block_children. insert_content covers notion_create_page, notion_create_database and notion_append_block_children. update_content covers notion_update_page and notion_archive_page. read_user_info covers notion_list_users and notion_get_user.
Sixteen actions, and no scope in that list overrides Notion’s own sharing model. A user can grant read_content and still see nothing, because the grant and the sharing are two separate acts.
- tools/list has two gates: the connection has to exist, and the agent’s grants have to intersect the connection’s scopes. Connected with zero tools is a real state, so say “connected but no actions live” rather than showing the integration as on.
- A listed connection is not a working one. The initiate writes the row before the user ever reaches the provider: status “configured” means the row exists and nothing else does, and it yields zero tools. Key every user-facing state off status == "connected".
- Do not infer readiness from granted_scopes being non-empty. Some providers legitimately grant none.
- The callback query parameters — status, tool, connection_id, external_user_id — are not signed. Treat them as a UI hint, resolve the user from your own session, and confirm by re-reading the connections list. The signed channel is the connection.completed webhook.
The payload above shows the shape of a response using the field names the gateway documents. It is illustrative: it was not captured from a live Notion account, so treat the values as placeholders and read your own response.
Disconnect
Deleting the connection is one app-scoped call, and it is the only way to take Notion away from an agent without taking the agent down.
- The delete removes the stored credential and the connection row on the Fabriq side, so the user has to authorize again to reconnect.
- Whether the authorization is still listed in the provider’s own connected-apps screen is the provider’s state, not Fabriq’s. If your flow needs the grant gone there too, send the user to the provider and check.
- Drop any cached user token when you disconnect, and on a connection.needs_reauth webhook.
Troubleshooting
- notion_search returns nothing after a clean connect: nobody has shared a page with the connection yet. Notion requires the page to be shared manually through Add connections, and there is no error that reads as “you were never given this”.
- Coverage differs between two users in the same workspace: with a public connection the authorization and the sharing are both per user, so what the agent can reach depends on who onboarded it.
- A page appears but its sub-pages do not, or the reverse: a connection added to a page can access that page’s children, so where in the tree the connection was added decides what the agent sees.
- notion_archive_page is a soft delete of a page the user shared, and notion_update_page modifies an existing page in place. Both sit behind update_content, which is the grant worth naming explicitly on your consent copy.
- Consent completed but tools/list comes back empty: diff the authorize URL’s scope= parameter against the connection row’s granted_scopes before blaming the console. The URL tells you what was actually requested, and a scope never requested can never be granted.
- Every connect fails with “B2B2C OAuth callback URL not configured”: the Redirect URL on the agent’s Connect & webhooks page is empty. It is checked first, so it masks every other misconfiguration.
- Calls return 200 and nothing happens: an external-user token was posted to /mcp instead of /mcp/external. Both answer 200, so this one fails silently — pin the route with a test.
- An unknown provider name returns 400 with the list of valid names. Read that error; it is accurate. Provider names are surfaces rather than vendors.
Notion-side requirements checked against Notion authorization (pages must be shared with a connection) (2026-10-29), Notion integration capabilities (2026-10-29), Notion request limits (2026-09-29).
Connecting Notion in practice
Notion’s API cannot find anything nobody handed it: a page or database has to be shared with the connection by hand before it exists to the API, so "search my workspace" returns only what someone explicitly added. Throughput is 180 requests per minute on most plans and 600 on Business and Enterprise, and any array of blocks or rich text is capped at 100 elements per request.
Scopes that draw scrutiny
User information with email addressesThe widest of the three user capability tiers. The alternatives are "User information without email addresses", which returns name and profile image, and "No user information".Update contentModifies existing pages rather than appending, so an agent holding it can rewrite a document in place with no version the API exposes.Insert contentCreates new content in the shared pages, which is how an agent publishes into a workspace others read as authoritative.Read commentsComments are a separate capability from content, and they carry the discussion a page deliberately leaves out.
Rate limits
- 180 requests per minute, an average of 3 per second, on all plans other than Business and Enterprise.
- 600 requests per minute, an average of 10 per second, on Business and Enterprise.
- Payload caps: 1,000 block elements and 500 KB overall per request; 100 elements in any array of block types or rich text objects; 100 related pages and 100 users per request.
- Field caps: 2,000 characters of text content, 2,000 characters for any URL, 1,000 for an equation expression, 200 for an email address.
Who has to approve
Internal connections can only be created by a workspace owner in the developer portal, and on Business and Enterprise plans creating a personal access token is restricted by default until a workspace owner enables it in Settings → Connections. For a public connection each member authorizes separately, and only that user can share pages and databases with it.
Worth knowing
- Explicit sharing is the permission model: until someone uses "Add connections" on a page, the integration gets nothing, and there is no error that reads as "you were never given this".
- With a public connection the sharing is per user, so two people in the same workspace see different halves of it and the agent’s coverage depends on who onboarded.
- The 100-element array cap means a long page is many requests, which interacts badly with 3 requests per second on non-Business plans.
- Notion returns 429 with a Retry-After header and asks that you respect it with exponential backoff and jitter rather than assuming a fixed delay.
Checked against Request limits (2026-09-29), Integration capabilities (2026-09-29), Authorization (2026-09-29), Create a Notion integration (2026-09-29)
What an agent can do
Each action is granted on its own. An agent allowed to read is not thereby allowed to write, and the scope beside each row is what the acting user must have connected for it to run at all.
Often connected alongside
Put Notion behind one governed endpoint.
Same permissions, same audit trail, whatever else you connect next.