Developer API
Append Block Children
V2

Append Block Children

Append direct child blocks under a block and optionally choose the insertion point.

PATCH /v2/blocks/:block_id/children

Append Block Children

Use Case

Use this endpoint to append new direct children under a block. You can optionally insert them before or after an existing child block.

Endpoint

Item Value
Method PATCH
Path /v2/blocks/:block_id/children
Request body JSON
Returns list of appended block objects
Scope blocks.write

Permissions

Requires blocks.write and write access to the parent block.

Parameters

Parameter Type Required Description
block_id string Yes Parent block ID.
children block input[] Yes Blocks to append.
after string No Existing direct child block ID to insert after. Cannot be used with before.
before string No Existing direct child block ID to insert before. Cannot be used with after.

Request Example

{
  "children": [
    {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": [
          {
            "type": "text",
            "text": {
              "content": "Follow-up notes"
            }
          }
        ]
      }
    },
    {
      "object": "block",
      "type": "to_do",
      "to_do": {
        "rich_text": [
          {
            "type": "text",
            "text": {
              "content": "Confirm launch date"
            },
            "annotations": {
              "text_color": "black",
              "background_color": "light_green"
            }
          }
        ],
        "checked": false,
        "text_color": "purple",
        "background_color": "blue_purple"
      }
    }
  ],
  "after": null
}

To insert before an existing direct child block, pass before instead:

{
  "children": [
    {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": [
          {
            "type": "text",
            "text": {
              "content": "Notes inserted before the target block"
            }
          }
        ]
      }
    }
  ],
  "before": "12121212-1212-4212-8212-121212121212"
}

Nested Children

To append a subtree, put children on each block input, alongside type and its content object, not inside paragraph or toggle:

{
  "children": [
    {
      "type": "toggle",
      "toggle": {
        "rich_text": [{ "type": "text", "text": { "content": "Topic" } }]
      },
      "children": [
        {
          "type": "bulleted_list_item",
          "bulleted_list_item": {
            "rich_text": [{ "type": "text", "text": { "content": "Item" } }]
          },
          "children": [
            {
              "type": "paragraph",
              "paragraph": {
                "rich_text": [{ "type": "text", "text": { "content": "Details" } }]
              }
            }
          ]
        }
      ]
    }
  ]
}

The entire subtree is validated before writing and submitted in one transaction. Each children array allows up to 100 blocks; only the request's root array must be nonempty. Sibling order is preserved at every level. before and after apply only to the root array, not to descendants. Invalid descendants reject the entire request, with a field path such as children.0.children.0.paragraph.text_color.

The response still lists only the directly appended blocks. A block with descendants has has_children: true; use Get Block Children to read each level. Native table rows must be nested under their table and have exactly table_width cells. Update Block cannot replace a subtree.

Response Example

{
  "object": "list",
  "results": [
    {
      "object": "block",
      "id": "44444444-4444-4444-8444-444444444444",
      "parent": {
        "type": "page_id",
        "page_id": "11111111-1111-4111-8111-111111111111"
      },
      "created_time": "2026-04-09T08:00:00.000Z",
      "last_edited_time": "2026-04-09T09:30:00.000Z",
      "created_by": {
        "object": "user",
        "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
      },
      "last_edited_by": {
        "object": "user",
        "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
      },
      "has_children": false,
      "in_trash": false,
      "type": "paragraph",
      "paragraph": {
        "rich_text": [
          {
            "type": "text",
            "text": {
              "content": "Project kickoff notes",
              "link": null
            },
            "plain_text": "Project kickoff notes",
            "href": null
          }
        ],
        "text_color": "default",
        "background_color": "default"
      }
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Behavior

  • children is required and can contain up to 100 blocks; the same limit applies to every nested children array.
  • Only writable block types are accepted.
  • Nested child blocks are supported for block types that can contain children.
  • Page and inline mind maps use their type-specific nodes field for the initial node tree. Use the mind map endpoint for later node edits.
  • Existing databases, mind maps, and file blocks reject generic child appends. Create database records through the database API and edit mind-map nodes through the mind-map API.
  • An existing column_list accepts only direct column children and cannot exceed 100 active columns after the append.
  • If neither after nor before is provided, new children are appended to the end of the parent block.
  • If after is provided, it must refer to an existing direct child of the parent block, and new children are inserted after it.
  • If before is provided, it must refer to an existing direct child of the parent block, and new children are inserted before it.
  • after and before are mutually exclusive. If both are provided, the request returns 400 validation_error.
  • When multiple children are provided, their array order is preserved at the insertion point.
  • Paragraphs, headings, list items, to-do items, quotes, toggles, and callouts can set text_color and background_color together. Their rich_text[].annotations objects use the same two-channel format.
  • The legacy color field remains accepted, but new integrations should use the explicit color fields.

Errors

  • 400 validation_error: invalid children, both after and before are provided, or the after / before value is not a direct child of the parent block.
  • 400 unsupported_block_type: child block type cannot be written.
  • 401 unauthorized: invalid or expired token.
  • 403 forbidden: missing blocks.write or no access.
  • 404 not_found: parent block does not exist.

Prerequisites

Next Steps

References