The Notion API supports reading, writing, and updating page content using enhanced markdown (also called “Notion-flavored Markdown”) as an alternative to the block-based API. This is especially useful for agentic systems and developer tools that work natively with markdown.Three API surfaces are available:
Operation
Endpoint
Description
Create
POST /v1/pages
Create a page with markdown content (via markdown body param)
This endpoint is restricted to public integrations only. Internal integrations (workspace-level bots) will receive a restricted_resource error. Use the block-based API instead for internal integrations.
Key behaviors:
Requires read_content capability.
File URIs in the content are automatically converted to pre-signed URLs.
Use PATCH /v1/pages/:page_id/markdown to insert or replace content in an existing page using markdown.The request body uses a discriminated union with two command variants: insert_content and replace_content_range.
curl -X PATCH 'https://api.notion.com/v1/pages/YOUR_PAGE_ID/markdown' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H "Content-Type: application/json" \ -H "Notion-Version: 2025-09-03" \ --data '{ "type": "insert_content", "insert_content": { "content": "## Appendix\n\nAdded at the end of the page." } }'
The after parameter uses an ellipsis-based selection format: "start text...end text". This matches a range from the first occurrence of the start text to the end text. When after is omitted, content is appended to the end of the page.
By default, the update endpoint refuses to delete child pages or databases. If an operation would delete them, a validation_error is returned listing the affected items.To allow deletion, set allow_deleting_content: true:
The update endpoint always skips meeting note transcript content, matching the default behavior of the GET endpoint. If you retrieve a page with include_transcript=true, the transcript text will appear in the response but cannot be used in content_range or after selections — the update endpoint does not see transcript content during matching and will return a validation_error for selections that span transcript text.