Portal Community
Block tree structure: Notion content is organized as a tree of blocks. A page's body is its top-level children. Toggle blocks, callouts, and lists may contain nested children — check the has_children field on each returned block. To retrieve nested content, call block/getChildren again with the child block's ID.

When to Use

Configuration

Authentication

FieldRequiredDescription
AuthenticationMethodRequired"ApiToken" or "OAuth2".
ApiTokenRequiredNotion Internal Integration Token starting with secret_.
ClientIdOAuth2OAuth2 client ID.
ClientSecretOAuth2OAuth2 client secret.
AccessTokenOAuth2OAuth2 access token.

Operation Fields

FieldRequiredDescription
BlockIdRequiredUUID of the parent page or block. Pass a page UUID to get the top-level body blocks of that page.
ReturnAllOptionalWhen true, automatically pages through all children. Default: false.
LimitOptionalMax blocks to return (1–100). Default: 100.
StartCursorOptionalPagination cursor for fetching additional blocks beyond the initial set.

Sample Configuration

{
  "resource": "block",
  "operation": "getChildren",
  "AuthenticationMethod": "ApiToken",
  "ApiToken": "{{ $credentials.notionApiToken }}",
  "BlockId": "{{ $json.pageId }}",
  "ReturnAll": true
}

Validation Errors

Error CodeCause
NOTION_VALIDATION_FAILEDBlockId is empty or not a valid UUID.
NOTION_NOT_FOUNDNo page or block exists with the given UUID.
NOTION_PERMISSION_DENIEDIntegration not shared with the page containing this block.
NOTION_RATE_LIMITEDRate limit exceeded.
NOTION_INVALID_REQUESTStartCursor is invalid.

Output

Success Port

FieldTypeDescription
resultsarrayArray of block objects. Each block contains id, type, created_time, last_edited_time, has_children, and a type-specific content object (e.g., paragraph.rich_text, to_do.rich_text, to_do.checked).
has_morebooleanWhether additional sibling blocks exist beyond the current page.
next_cursorstringPagination cursor for the next set of siblings. Null when has_more is false.

Error Port

On failure the error port receives errorCode, message, and httpStatus.

Sample Output

{
  "results": [
    {
      "id": "d0e1f2a3-b4c5-6789-defa-890123456789",
      "type": "heading_2",
      "created_time": "2024-06-10T09:00:00.000Z",
      "last_edited_time": "2024-06-10T09:00:00.000Z",
      "has_children": false,
      "heading_2": {
        "rich_text": [{ "type": "text", "text": { "content": "Action Items" }, "plain_text": "Action Items" }]
      }
    },
    {
      "id": "e1f2a3b4-c5d6-7890-efab-901234567890",
      "type": "to_do",
      "has_children": false,
      "to_do": {
        "rich_text": [{ "plain_text": "Send follow-up email to client" }],
        "checked": false
      }
    },
    {
      "id": "f2a3b4c5-d6e7-8901-fabc-012345678901",
      "type": "paragraph",
      "has_children": false,
      "paragraph": {
        "rich_text": [{ "plain_text": "Deployment completed at 14:32 UTC" }]
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Expression Reference

ExpressionTypeUse
{{ $output.getBlockChildren.results.length }}numberCount total blocks on the page
{{ $output.getBlockChildren.results[0].type }}stringCheck block type to filter by type in a Function node
{{ $output.getBlockChildren.results[0].paragraph.rich_text[0].plain_text }}stringExtract plain text from a paragraph block
{{ $output.getBlockChildren.results[0].to_do.checked }}booleanCheck whether a to-do item is complete
{{ $output.getBlockChildren.results[0].has_children }}booleanDetermine if a block has nested children to retrieve recursively

Node Policies & GuardRails

PolicyDetail
One level at a timeThis operation retrieves only direct children. For deeply nested content (e.g., content inside a toggle inside a callout), call block/getChildren again with each child block's ID where has_children === true.
Extract text via plain_textEach rich_text array item has a plain_text field that provides the raw string without annotations. Use this for downstream text processing rather than reconstructing text from the nested text.content structure.
Filter by type in Function nodeUse a Function node after block/getChildren to filter for specific block types: results.filter(b => b.type === 'to_do'). This avoids processing irrelevant blocks in downstream loop iterations.
Page body vs block childrenA page's UUID can be used as BlockId — this returns the top-level body blocks of the page, not its subpage list. There is no separate "get page content" endpoint; blocks are the content model.
Credentials in Credentials ManagerAlways use {{ $credentials.notionApiToken }} — never hard-code the token.

Workflow Examples

Example 1 — AI Meeting Notes Summarization

After a meeting trigger fires, read the meeting notes page blocks and send the text to FlowAiAgent for summarization.

// Step 1: trigger/pageAdded (meeting notes DB)
// Step 2: block/getChildren { "BlockId": "{{ $trigger.pageId }}", "ReturnAll": true }
// Step 3: Function node — extract all plain text
const text = $output.getBlockChildren.results
  .filter(b => b.paragraph || b.heading_1 || b.heading_2 || b.bulleted_list_item)
  .map(b => {
    const key = b.type;
    return b[key].rich_text.map(r => r.plain_text).join('');
  }).join('\n');
return { pageText: text };
// Step 4: FlowAiAgent — summarize and extract action items
// Step 5: block/appendChildren — append summary back to the page

Example 2 — Incomplete To-Do Extraction

Read to-do blocks from a daily planning page and create Jira issues for any unchecked items.

// Step 1: block/getChildren (ReturnAll: true)
// Step 2: Function node — filter unchecked to-dos
const todos = $output.getBlockChildren.results
  .filter(b => b.type === 'to_do' && !b.to_do.checked)
  .map(b => b.to_do.rich_text[0]?.plain_text ?? '');
return { pendingTasks: todos };
// Step 3: Loop over pendingTasks → Jira issue/create

Example 3 — Recursive Deep Content Extraction

Extract all text from a page including nested blocks inside toggles.

// Step 1: block/getChildren (top level)
// Step 2: For each block where has_children === true:
//   block/getChildren with that block's ID (nested level)
// Step 3: Merge all plain_text from both levels for processing