Notion integration
Turn explicitly shared Notion pages and blocks into retrievable team knowledge. Retrieve supported content from pages explicitly shared with the connection, including recursively discovered page and block content.
The shared-page mental model
What content works best
Pages explicitly shared with the connection.
Supported content extracted from shared pages and blocks.
Supported nested content discovered beneath shared pages.
Share pages before connecting
- A Notion workspace where you can share the intended pages with a connection.
- A clear list of pages that are appropriate to import.
- A MemorySync project for the imported workspace knowledge.
Check items for your own planning. Nothing here changes a live connection.
0 of 4 planning steps complete
Recursive discovery and resynchronization
- 1Share pages
Explicitly share only the pages intended for import.
- 2Discover recursively
Find supported page and block content beneath that boundary.
- 3Extract and resynchronize
Extract supported content and refresh it through resynchronization.
- 4Retrieve
Query the imported workspace knowledge.
Verify workspace knowledge
Query a distinctive phrase from a known shared page or supported block. Confirm the result comes from the intended shared-page tree before adding more roots.
Missing or incomplete page troubleshooting
Why is a page missing?
Confirm the page was explicitly shared with the connection and remains inside the shared page boundary.
Why is part of a page not searchable?
The missing material may not be supported content. Verify with text from a supported page or block.
Why are edits not visible yet?
Confirm the page remains shared and allow its resynchronization to complete before verifying again.
Related sources
Operations on this page
| Operation | Method and path | Python | Node.js |
|---|---|---|---|
| Read Notion capabilities | GET /api/v2/integrations/providers/notion | providers.get | providers.get |
| Start Notion OAuth | POST /api/v2/integrations/oauth/initiate | connections.oauth.initiate | connections.oauth.initiate |
| Confirm the connection | GET /api/v2/integrations/connections/{connection_id} | connections.get | connections.get |
| Start synchronization | POST /api/v2/integrations/connections/{connection_id}/sync | connections.trigger_sync | connections.triggerSync |
Authentication and scope
| Requirement | Contract |
|---|---|
| Credential | An API key sent as X-API-Key. Connector operations are not end-user scoped. |
| Read scope | integrations:read for every GET. |
| Write scope | integrations:write for every POST, PUT, PATCH and DELETE. |
| Tenant | Derived from the authenticated key. There is no tenant parameter to pass or to get wrong. |
X-End-User-ID | Not used. A connection belongs to the organization, not to one end user. |
1. Check Notion availability
Read the provider record before offering setup so your UI follows the deployed catalog instead of a hard-coded provider list.
import osfrom memorysync import MemorySyncClientclient = MemorySyncClient(api_key=os.environ["MEMORYSYNC_API_KEY"],base_url="https://api.memorysync.io",)provider = client.providers.get("notion")print(provider["is_available"], provider["capabilities"])
2. Authorize Notion
Start OAuth and send the browser to the returned URL. During consent, choose the workspace content that the integration may access.
import osfrom memorysync import MemorySyncClientclient = MemorySyncClient(api_key=os.environ["MEMORYSYNC_API_KEY"],base_url="https://api.memorysync.io",)result = client.connections.oauth.initiate("notion",redirect_url="https://app.example.com/connections/callback",)print(result["authorization_url"], result["connection_id"])
3. Confirm and sync
Wait for a connected status before starting an incremental sync. Sharing another Notion page later makes it available to a later sync.
import osfrom memorysync import MemorySyncClientclient = MemorySyncClient(api_key=os.environ["MEMORYSYNC_API_KEY"],base_url="https://api.memorysync.io",)connection = client.connections.get("conn_8f21a4")if connection["status"] == "connected":job = client.connections.trigger_sync("conn_8f21a4", job_type="incremental")print(job["id"], job["status"])
Errors and next action
| Status | Meaning | Next action |
|---|---|---|
401 | Missing, malformed or inactive API key. | Check server configuration without printing the key. |
403 | The key lacks integrations:read or integrations:write. | Grant the scope on the key, or use a key that has it. |
404 | The connection, object or job is not visible to this tenant. | Confirm the identifier belongs to this organization. |
409 | The connection is in a state that forbids the operation. | Read the connection status first and act on it. |
429 | Rate limited, either by MemorySync or by the upstream provider. | Back off; do not tighten a polling loop in response. |
5xx | Service failure. | Treat a write outcome as uncertain and reconcile by reading the connection back. |