> ## Documentation Index
> Fetch the complete documentation index at: https://developers.notion.com/llms.txt
> Use this file to discover all available pages before exploring further.

> Insert or replace content in a page using enhanced markdown.

# Update a page's content as markdown

export const developerConnectionsUrl = "https://www.notion.so/developers/connections";

### Use cases

#### Updating content with search-and-replace (recommended)

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.

#### Replacing all page content (recommended)

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 `position: { "type": "start" }` to prepend, `position: { "type": "end" }` to explicitly append, or omit `position` to append to the end of the page. You can also provide an `after` selection to insert at a specific point; `after` uses an **ellipsis-based selection** format: `"start text...end text"`.

<Note>
  We recommend using `update_content` or `replace_content` instead. The `insert_content` command is still supported but may be deprecated in a future version.
</Note>

#### 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`.

<Note>
  We recommend using `update_content` instead. The `replace_content_range` command is still supported but may be deprecated in a future version.
</Note>

### 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.

<Info>
  **Requirements**

  Your connection must have [update content capabilities](/reference/capabilities#content-capabilities) on the target page in order to call this endpoint. To update your connection's capabilities, navigate to the <a href={developerConnectionsUrl}>Developer portal</a>, select your connection, open the **Configuration** tab, and scroll to the Capabilities section.

  Attempting to call this endpoint without update content capabilities returns an HTTP response with a 403 status code.
</Info>

<Tip>
  **Newlines in content**

  The `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.
</Tip>

<Warning>
  **Protecting child pages and databases**

  By 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.
</Warning>

### Errors

| Error code         | Condition                                                                                                                          |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `validation_error` | The `content_range` or `after` selection does not match any content in the page, or an `old_str` in `update_content` is not found. |
| `validation_error` | Both `insert_content.after` and `insert_content.position` are provided. Use only one insertion target.                             |
| `validation_error` | The operation would delete child pages or databases and `allow_deleting_content` is not `true`.                                    |
| `validation_error` | An `old_str` in `update_content` matches multiple locations and `replace_all_matches` is not `true`.                               |
| `validation_error` | The provided ID is a database or non-page block.                                                                                   |
| `validation_error` | The target page is a synced page. Synced pages cannot be updated.                                                                  |
| `object_not_found` | The page does not exist or the connection does not have access to it.                                                              |

*Each Public API endpoint can return several possible error codes. See the [Error codes section](/reference/status-codes#error-codes) of the Status codes documentation for more information.*


## OpenAPI

````yaml patch /v1/pages/{page_id}/markdown
openapi: 3.1.0
info:
  title: Notion API
  version: 1.0.0
  termsOfService: >-
    https://notion.notion.site/Terms-and-Privacy-28ffdd083dc3473e9c2da6ec011b58ac
servers:
  - url: https://api.notion.com
security:
  - bearerAuth: []
tags:
  - name: Databases
    description: Database endpoints
  - name: Data sources
    description: Data source endpoints
  - name: Pages
    description: Page endpoints
  - name: Blocks
    description: Block endpoints
  - name: Comments
    description: Comment endpoints
  - name: File uploads
    description: File upload endpoints
  - name: OAuth
    description: OAuth endpoints (basic authentication)
  - name: Users
    description: User endpoints
  - name: Search
    description: Search endpoints
  - name: Views
    description: View endpoints
  - name: Custom emojis
    description: Custom emoji endpoints
  - name: Meeting notes
    description: Meeting notes endpoints
paths:
  /v1/pages/{page_id}/markdown:
    patch:
      tags:
        - Pages
      summary: Update a page's content as markdown
      operationId: update-page-markdown
      parameters:
        - name: page_id
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/idRequest'
            description: The ID of the page to update.
        - $ref: '#/components/parameters/notionVersion'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  properties:
                    type:
                      type: string
                      const: insert_content
                      description: Always `insert_content`
                    insert_content:
                      type: object
                      properties:
                        content:
                          type: string
                          examples:
                            - |-
                              ## New Section

                              Inserted content here.
                          description: >-
                            The enhanced markdown content to insert into the
                            page.
                        after:
                          type: string
                          description: >-
                            Selection of existing content to insert after, using
                            the ellipsis format ("start text...end text"). Omit
                            to append at the end of the page.
                        position:
                          oneOf:
                            - type: object
                              properties:
                                type:
                                  type: string
                                  const: start
                                  description: Insert the content at the start of the page.
                              required:
                                - type
                            - type: object
                              properties:
                                type:
                                  type: string
                                  const: end
                                  description: Insert the content at the end of the page.
                              required:
                                - type
                          description: >-
                            Explicit position for inserted content. Use
                            {"type":"start"} to prepend or {"type":"end"} to
                            append. Cannot be combined with after.
                      required:
                        - content
                      description: Insert new content into the page.
                  required:
                    - type
                    - insert_content
                  title: Insert Content
                  deprecated: true
                - type: object
                  properties:
                    type:
                      type: string
                      const: replace_content_range
                      description: Always `replace_content_range`
                    replace_content_range:
                      type: object
                      properties:
                        content:
                          type: string
                          examples:
                            - |-
                              ## Updated Section

                              New content replaces the old.
                          description: >-
                            The new enhanced markdown content to replace the
                            matched range.
                        content_range:
                          type: string
                          description: >-
                            Selection of existing content to replace, using the
                            ellipsis format ("start text...end text").
                        allow_deleting_content:
                          type: boolean
                          description: >-
                            Set to true to allow the operation to delete child
                            pages or databases. Defaults to false.
                      required:
                        - content
                        - content_range
                      description: Replace a range of content in the page.
                  required:
                    - type
                    - replace_content_range
                  title: Replace Content Range
                  deprecated: true
                - type: object
                  properties:
                    type:
                      type: string
                      const: update_content
                      description: Always `update_content`
                    update_content:
                      type: object
                      properties:
                        content_updates:
                          type: array
                          items:
                            type: object
                            properties:
                              old_str:
                                type: string
                                description: >-
                                  The existing content string to find and
                                  replace. Must exactly match the page content.
                              new_str:
                                type: string
                                description: >-
                                  The new content string to replace old_str
                                  with.
                              replace_all_matches:
                                type: boolean
                                description: >-
                                  If true, replaces all occurrences of old_str.
                                  If false (default), the operation fails if
                                  there are multiple matches.
                            required:
                              - old_str
                              - new_str
                          maxItems: 100
                          description: >-
                            An array of search-and-replace operations, each with
                            old_str (content to find) and new_str (replacement
                            content).
                        allow_deleting_content:
                          type: boolean
                          description: >-
                            Set to true to allow the operation to delete child
                            pages or databases. Defaults to false.
                      required:
                        - content_updates
                      description: >-
                        Update specific content using search-and-replace
                        operations.
                  required:
                    - type
                    - update_content
                  title: Update Content
                - type: object
                  properties:
                    type:
                      type: string
                      const: replace_content
                      description: Always `replace_content`
                    replace_content:
                      type: object
                      properties:
                        new_str:
                          type: string
                          examples:
                            - |-
                              # Updated Page

                              Completely new page content.
                          description: >-
                            The new enhanced markdown content to replace the
                            entire page content.
                        allow_deleting_content:
                          type: boolean
                          description: >-
                            Set to true to allow the operation to delete child
                            pages or databases. Defaults to false.
                      required:
                        - new_str
                      description: Replace the entire page content with new markdown.
                  required:
                    - type
                    - replace_content
                  title: Replace Content
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pageMarkdownResponse'
        '400':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_400'
        '401':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_401'
        '403':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_403'
        '404':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_404'
        '409':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_409'
        '429':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_429'
        '500':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_500'
        '503':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_503'
        '504':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error_api_504'
      x-codeSamples:
        - lang: javascript
          label: TypeScript SDK
          source: |-
            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"
                  }
                ]
              }
            })
components:
  schemas:
    idRequest:
      type: string
    pageMarkdownResponse:
      type: object
      properties:
        object:
          type: string
          const: page_markdown
          description: The type of object, always 'page_markdown'.
        id:
          $ref: '#/components/schemas/idResponse'
          description: The ID of the page or block.
        markdown:
          type: string
          description: The page content rendered as enhanced Markdown.
        truncated:
          type: boolean
          description: >-
            Whether the content was truncated due to exceeding the record count
            limit.
        unknown_block_ids:
          type: array
          items:
            $ref: '#/components/schemas/idResponse'
          maxItems: 100
          description: >-
            Block IDs that could not be loaded (appeared as <unknown> tags in
            the markdown). Pass these IDs back to this endpoint to fetch their
            content separately.
      additionalProperties: false
      required:
        - object
        - id
        - markdown
        - truncated
        - unknown_block_ids
    error_api_400:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - invalid_json
                - invalid_request_url
                - invalid_request
                - missing_version
                - validation_error
            status:
              const: 400
          required:
            - code
            - status
          additionalProperties: false
    error_api_401:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - unauthorized
            status:
              const: 401
          required:
            - code
            - status
          additionalProperties: false
    error_api_403:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - restricted_resource
            status:
              const: 403
          required:
            - code
            - status
          additionalProperties: false
    error_api_404:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - object_not_found
            status:
              const: 404
          required:
            - code
            - status
          additionalProperties: false
    error_api_409:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - conflict_error
            status:
              const: 409
          required:
            - code
            - status
          additionalProperties: false
    error_api_429:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - rate_limited
            status:
              const: 429
          required:
            - code
            - status
          additionalProperties: false
    error_api_500:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - internal_server_error
            status:
              const: 500
          required:
            - code
            - status
          additionalProperties: false
    error_api_503:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - service_unavailable
            status:
              const: 503
          required:
            - code
            - status
          additionalProperties: false
    error_api_504:
      allOf:
        - $ref: '#/components/schemas/publicApiCommonErrorResponse'
        - type: object
          properties:
            code:
              enum:
                - gateway_timeout
            status:
              const: 504
          required:
            - code
            - status
          additionalProperties: false
    idResponse:
      type: string
      format: uuid
    publicApiCommonErrorResponse:
      type: object
      properties:
        object:
          const: error
        message:
          type: string
        additional_data:
          type: object
          additionalProperties:
            oneOf:
              - type: string
              - type: array
                items:
                  type: string
      required:
        - object
        - message
  parameters:
    notionVersion:
      name: Notion-Version
      in: header
      required: true
      schema:
        enum:
          - '2026-03-11'
      description: >-
        The [API version](/reference/versioning) to use for this request. The
        latest version is `2026-03-11`.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````