The blocks.children namespace provides methods to work with child blocks - blocks nested inside other blocks or pages.
Methods
list() - Retrieve a list of child blocks
append() - Add new child blocks to a parent block or page
List Block Children
Retrieves a paginated list of child blocks for a given parent block or page.
Method Signature
client.blocks.children.list(args: ListBlockChildrenParameters): Promise<ListBlockChildrenResponse>
Source: Client.ts:645-656
Parameters
The ID of the parent block or page whose children you want to retrieve
Pagination cursor for the next page of results. If provided, the API returns results starting from this cursor.
Number of items to return per page. Maximum is 100 (default).
Optional authentication token to override the client-level auth
Response
Returns a paginated list of blocks.
results
Array<BlockObjectResponse>
Array of child block objects
Cursor for the next page of results, or null if there are no more results
Whether there are more results available
Examples
List All Children
import { Client } from "@notionhq/client"
const notion = new Client({ auth: process.env.NOTION_TOKEN })
const response = await notion.blocks.children.list({
block_id: "parent-block-id",
})
console.log(`Found ${response.results.length} child blocks`)
response.results.forEach(block => {
console.log(`- ${block.type} (${block.id})`)
})
Paginate Through Children
let cursor: string | undefined = undefined
const allBlocks: BlockObjectResponse[] = []
do {
const response = await notion.blocks.children.list({
block_id: "parent-block-id",
start_cursor: cursor,
page_size: 50,
})
allBlocks.push(...response.results)
cursor = response.next_cursor ?? undefined
} while (cursor)
console.log(`Total blocks: ${allBlocks.length}`)
import { iteratePaginatedAPI } from "@notionhq/client/build/src/helpers"
for await (const block of iteratePaginatedAPI(notion.blocks.children.list, {
block_id: "parent-block-id",
})) {
console.log(block.type, block.id)
}
Filter Children by Type
const response = await notion.blocks.children.list({
block_id: "parent-block-id",
})
const paragraphs = response.results.filter(block => block.type === "paragraph")
const headings = response.results.filter(block =>
block.type === "heading_1" ||
block.type === "heading_2" ||
block.type === "heading_3"
)
console.log(`${paragraphs.length} paragraphs, ${headings.length} headings`)
Append Block Children
Adds new child blocks to a parent block or page. You can append multiple blocks in a single request.
Method Signature
client.blocks.children.append(args: AppendBlockChildrenParameters): Promise<AppendBlockChildrenResponse>
Source: Client.ts:629-640
Parameters
The ID of the parent block or page to append children to
children
Array<BlockObjectRequest>
required
Array of block objects to append. Each block must include a type and type-specific content.
Deprecated. Use position instead. Block ID to insert after.
Position to insert the blocks:
{ type: "start" } - Insert at the beginning
{ type: "end" } - Insert at the end (default)
{ type: "after_block", after_block: { id: "block-id" } } - Insert after a specific block
Optional authentication token to override the client-level auth
Response
Returns a list containing the newly created blocks.
results
Array<BlockObjectResponse>
Array of newly created block objects with IDs assigned
Always null for append operations
Always false for append operations
Examples
Append a Single Paragraph
const response = await notion.blocks.children.append({
block_id: "parent-page-id",
children: [
{
object: "block",
type: "paragraph",
paragraph: {
rich_text: [
{
type: "text",
text: {
content: "This is a new paragraph",
},
},
],
},
},
],
})
console.log("Created block:", response.results[0].id)
Append Multiple Blocks
const response = await notion.blocks.children.append({
block_id: "parent-page-id",
children: [
{
type: "heading_2",
heading_2: {
rich_text: [{ type: "text", text: { content: "Section Title" } }],
},
},
{
type: "paragraph",
paragraph: {
rich_text: [{ type: "text", text: { content: "Section content" } }],
},
},
{
type: "bulleted_list_item",
bulleted_list_item: {
rich_text: [{ type: "text", text: { content: "First item" } }],
},
},
],
})
console.log(`Added ${response.results.length} blocks`)
Append a Code Block
await notion.blocks.children.append({
block_id: "parent-page-id",
children: [
{
type: "code",
code: {
rich_text: [
{
type: "text",
text: {
content: 'console.log("Hello, World!")\nconsole.log("Another line")',
},
},
],
language: "javascript",
caption: [
{
type: "text",
text: {
content: "Example JavaScript code",
},
},
],
},
},
],
})
Append To-Do Items
const todos = [
"Review documentation",
"Write tests",
"Deploy to production",
]
await notion.blocks.children.append({
block_id: "parent-page-id",
children: todos.map(text => ({
type: "to_do",
to_do: {
rich_text: [{ type: "text", text: { content: text } }],
checked: false,
},
})),
})
Append with Nested Children
await notion.blocks.children.append({
block_id: "parent-page-id",
children: [
{
type: "toggle",
toggle: {
rich_text: [{ type: "text", text: { content: "Click to expand" } }],
children: [
{
type: "paragraph",
paragraph: {
rich_text: [{ type: "text", text: { content: "Hidden content" } }],
},
},
],
},
},
],
})
Insert at Specific Position
// Insert at the beginning
await notion.blocks.children.append({
block_id: "parent-page-id",
children: [
{
type: "paragraph",
paragraph: {
rich_text: [{ type: "text", text: { content: "First paragraph" } }],
},
},
],
position: { type: "start" },
})
// Insert after a specific block
await notion.blocks.children.append({
block_id: "parent-page-id",
children: [
{
type: "paragraph",
paragraph: {
rich_text: [{ type: "text", text: { content: "Inserted content" } }],
},
},
],
position: {
type: "after_block",
after_block: { id: "existing-block-id" },
},
})
Append Callout with Emoji
await notion.blocks.children.append({
block_id: "parent-page-id",
children: [
{
type: "callout",
callout: {
rich_text: [
{
type: "text",
text: {
content: "Important information!",
},
},
],
icon: {
type: "emoji",
emoji: "⚠️",
},
color: "yellow_background",
},
},
],
})
Limitations
- Maximum of 100 blocks can be appended in a single request
- Nested children can only be one level deep (blocks with
children property cannot themselves have children in the request)
- Some block types cannot have children (e.g., dividers, images)
Error Handling
import { APIResponseError } from "@notionhq/client"
try {
const response = await notion.blocks.children.append({
block_id: "parent-id",
children: [
{
type: "paragraph",
paragraph: {
rich_text: [{ type: "text", text: { content: "Content" } }],
},
},
],
})
console.log("Blocks appended successfully")
} catch (error) {
if (APIResponseError.isAPIResponseError(error)) {
switch (error.code) {
case "object_not_found":
console.error("Parent block/page not found")
break
case "validation_error":
console.error("Invalid block structure:", error.message)
break
case "unauthorized":
console.error("Not authorized to append to this block")
break
default:
console.error("API error:", error.code, error.message)
}
}
}