Skip to main content
PATCH
/
v1
/
pages
/
{page_id}
/
markdown
TypeScript SDK
import { Client } from "@notionhq/client"

const notion = new Client({ auth: process.env.NOTION_API_KEY })

const response = await notion.pages.updateMarkdown({
  page_id: "b55c9c91-384d-452b-81db-d1ef79372b75",
  type: "update_content",
  update_content: {
    content_updates: [
      {
        old_str: "existing text to find",
        new_str: "replacement text"
      }
    ]
  }
})
{
  "object": "<string>",
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "markdown": "<string>",
  "truncated": true,
  "unknown_block_ids": [
    "3c90c3cc-0d44-4b50-8888-8dd25736052a"
  ]
}

Use cases

Use the update_content command to make targeted edits using an array of search-and-replace operations. Each operation specifies an old_str to find and a new_str to replace it with. This is the recommended approach for making precise edits without rewriting the full page. Use the replace_content command to replace the entire page content with new markdown. Provide the full replacement content in new_str.

Inserting content (legacy)

Use the insert_content command to add new markdown content to a page. Provide an after selection to insert at a specific point, or omit it to append to the end of the page. The after parameter uses an ellipsis-based selection format: "start text...end text".
We recommend using update_content or replace_content instead. The insert_content command is still supported but may be deprecated in a future version.

Replacing a content range (legacy)

Use the replace_content_range command to replace a matched range of existing content with new markdown. The content_range parameter uses the same ellipsis-based selection format as after.
We recommend using update_content instead. The replace_content_range command is still supported but may be deprecated in a future version.

General behavior

Returns a page_markdown object containing the full page content as enhanced markdown after the update, including truncated and unknown_block_ids fields for large pages.
RequirementsYour integration must have update content capabilities on the target page in order to call this endpoint. To update your integration’s capabilities, navigate to the My integrations dashboard, select your integration, go to the Capabilities tab, and update your settings as needed.Attempting to call this endpoint without update content capabilities returns an HTTP response with a 403 status code.
Newlines in contentThe content field expects standard markdown with actual newline characters. In JSON, \n is the escape sequence for a newline — for example, "## Heading\n\nParagraph" creates a heading followed by a paragraph.When using cURL, wrap the --data body in single quotes ('...') so that \n is passed through to the JSON parser. Avoid $'...' quoting, which converts \n into a literal newline and produces invalid JSON.Note that the interactive API explorer on this page does not support multiline input. To test with newlines, use cURL, an SDK, or any HTTP client that sends properly encoded JSON.
Protecting child pages and databasesBy default, this endpoint refuses to delete child pages or databases. If an operation would remove them, a validation_error is returned listing the affected items. Set allow_deleting_content to true in the command body (replace_content_range, update_content, or replace_content) to permit deletion.

Errors

Error codeCondition
validation_errorThe content_range or after selection does not match any content in the page, or an old_str in update_content is not found.
validation_errorThe operation would delete child pages or databases and allow_deleting_content is not true.
validation_errorAn old_str in update_content matches multiple locations and replace_all_matches is not true.
validation_errorThe provided ID is a database or non-page block.
validation_errorThe target page is a synced page. Synced pages cannot be updated.
object_not_foundThe page does not exist or the integration does not have access to it.
Each Public API endpoint can return several possible error codes. See the Error codes section of the Status codes documentation for more information.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

Notion-Version
enum<string>
required

The API version to use for this request. The latest version is 2026-03-11.

Available options:
2026-03-11

Path Parameters

page_id
string
required

The ID of the page to update.

Body

application/json
type
string
required

Always insert_content

Allowed value: "insert_content"
insert_content
object
required

Insert new content into the page.

Response

object
string
required

The type of object, always 'page_markdown'.

Allowed value: "page_markdown"
id
string<uuid>
required

The ID of the page or block.

markdown
string
required

The page content rendered as enhanced Markdown.

truncated
boolean
required

Whether the content was truncated due to exceeding the record count limit.

unknown_block_ids
string<uuid>[]
required

Block IDs that could not be loaded (appeared as tags in the markdown). Pass these IDs back to this endpoint to fetch their content separately.

Maximum array length: 100