Skip to content

Manage notebook nodes (sections, pages, channels, databases, records) and their associated rich-text documents. These endpoints cover node CRUD, alias resolution, child traversal, document read/write, idempotent block append, HTML export tickets, drawing-block SVG rendering, and user interaction tracking (open/seen events).

Use these endpoints when building editor surfaces, content importers, automated doc pipelines, or analytics dashboards that need to read or mutate notebook content.


GET /api/v1/notes/notebooks/{notebookId}/nodes

Section titled “GET /api/v1/notes/notebooks/{notebookId}/nodes”

Returns a paginated list of nodes the user has access to. Filterable by type, parentId, and rootId.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
typequerystringNoFilter by node type
parentIdquerystringNoFilter by parent node ID
rootIdquerystringNoFilter by root node ID
limitqueryintegerNoPage size (default 50)
offsetqueryintegerNoPage offset (default 0)
await client.notes.nodes.list("nb_abc123", { type: "page", limit: 25 });
{
"nodes": [
{
"id": "node_8f3a2b",
"type": "page",
"parentId": "node_root01",
"attributes": {
"name": "Onboarding checklist",
"alias": "onboarding",
"icon": "📋"
},
"createdAt": "2025-01-12T09:21:00.000Z",
"updatedAt": "2025-03-04T14:08:00.000Z"
},
{
"id": "node_4c91de",
"type": "section",
"parentId": "node_root01",
"attributes": {
"name": "Engineering"
},
"createdAt": "2025-01-10T11:02:00.000Z",
"updatedAt": "2025-01-10T11:02:00.000Z"
}
],
"total": 2
}

GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}

Section titled “GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}”

Returns the full details of a single node by ID.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
await client.notes.nodes.get("nb_abc123", "node_8f3a2b");
{
"id": "node_8f3a2b",
"type": "page",
"parentId": "node_root01",
"attributes": {
"name": "Onboarding checklist",
"alias": "onboarding",
"icon": "📋",
"description": "First-day steps for new hires"
},
"createdAt": "2025-01-12T09:21:00.000Z",
"createdBy": "user_alice",
"updatedAt": "2025-03-04T14:08:00.000Z",
"updatedBy": "user_bob"
}

GET /api/v1/notes/notebooks/{notebookId}/nodes/alias/{alias}

Section titled “GET /api/v1/notes/notebooks/{notebookId}/nodes/alias/{alias}”

Resolves a page node by its safe alias within the notebook scope.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
aliaspathstringYesNode alias
await client.notes.nodes.getByAlias("nb_abc123", "onboarding");
{
"id": "node_8f3a2b",
"type": "page",
"parentId": "node_root01",
"attributes": {
"name": "Onboarding checklist",
"alias": "onboarding"
},
"createdAt": "2025-01-12T09:21:00.000Z",
"updatedAt": "2025-03-04T14:08:00.000Z"
}

GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/children

Section titled “GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/children”

Returns a paginated list of direct children of the specified node.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesParent node identifier
limitqueryintegerNoPage size (default 50)
offsetqueryintegerNoPage offset (default 0)
await client.notes.nodes.listChildren("nb_abc123", "node_root01", { limit: 10 });
{
"nodes": [
{
"id": "node_8f3a2b",
"type": "page",
"parentId": "node_root01",
"attributes": { "name": "Onboarding checklist" },
"createdAt": "2025-01-12T09:21:00.000Z"
},
{
"id": "node_4c91de",
"type": "section",
"parentId": "node_root01",
"attributes": { "name": "Engineering" },
"createdAt": "2025-01-10T11:02:00.000Z"
}
],
"total": 2
}

POST /api/v1/notes/notebooks/{notebookId}/nodes

Section titled “POST /api/v1/notes/notebooks/{notebookId}/nodes”

Creates a new node (section, page, channel, message, database, or record) in the notebook.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
NameTypeRequiredDescription
idstringNoOptional client-supplied node ID
typestringYesNode type (e.g. page, section, channel, database, record, message)
parentIdstringNoParent node ID
attributesobjectYesType-specific attributes (e.g. name, description, alias, icon)
{
"type": "page",
"parentId": "node_root01",
"attributes": {
"name": "Release notes",
"alias": "release-notes",
"icon": "🚀",
"description": "Track weekly product releases"
}
}
await client.notes.nodes.create("nb_abc123", {
type: "page",
parentId: "node_root01",
attributes: { name: "Release notes", alias: "release-notes" }
});
{
"id": "node_77ab2e",
"type": "page",
"parentId": "node_root01",
"attributes": {
"name": "Release notes",
"alias": "release-notes",
"icon": "🚀"
},
"createdAt": "2025-04-01T08:00:00.000Z",
"createdBy": "user_alice"
}

PATCH /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}

Section titled “PATCH /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}”

Updates node attributes (name, description, etc.). Type and parentId cannot be changed.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
NameTypeRequiredDescription
attributesobjectYesPartial attribute map to merge (e.g. name, description, icon)
{
"attributes": {
"name": "Release notes (Q2)",
"description": "Weekly product release notes for Q2 2025"
}
}
await client.notes.nodes.update("nb_abc123", "node_8f3a2b", {
attributes: { name: "Release notes (Q2)", description: "Weekly product release notes for Q2 2025" }
});
{
"id": "node_8f3a2b",
"type": "page",
"parentId": "node_root01",
"attributes": {
"name": "Release notes (Q2)",
"description": "Weekly product release notes for Q2 2025"
},
"createdAt": "2025-01-12T09:21:00.000Z",
"updatedAt": "2025-04-01T08:42:00.000Z",
"updatedBy": "user_alice"
}

DELETE /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}

Section titled “DELETE /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}”

Permanently deletes a node and its associated data (documents, files, reactions).

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
await client.notes.nodes.delete("nb_abc123", "node_8f3a2b");
{
"success": true
}

GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document

Section titled “GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document”

Retrieves document content for a node. Supports block filtering via blockIds and line range queries.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
blockIdsquerystringNoComma-separated list of block IDs to fetch
linesquerystringNoLine range, e.g. 0-50
outputquerystringNoOutput format: json, md, or html
includeCommentsquerystringNonone (default) or appendix
ticketquerystringNoExport ticket (required when output=html)
await client.notes.documents.get("nb_abc123", "node_8f3a2b", {
output: "md",
includeComments: "none"
});
{
"id": "doc_77ab2e",
"content": {
"type": "doc",
"content": [
{
"type": "heading1",
"content": [{ "type": "text", "text": "Onboarding checklist" }]
},
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Welcome to the team — start here." }
]
}
]
},
"createdAt": "2025-01-12T09:21:00.000Z",
"createdBy": "user_alice",
"updatedAt": "2025-03-04T14:08:00.000Z",
"updatedBy": "user_bob"
}

PUT /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document

Section titled “PUT /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document”

Creates a new document or fully replaces an existing document for a node.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
NameTypeRequiredDescription
contentobjectYesFull document content tree (block tree)
{
"content": {
"type": "doc",
"content": [
{
"type": "heading1",
"content": [{ "type": "text", "text": "Release notes" }]
},
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Initial cut." }]
}
]
}
}
await client.notes.documents.put("nb_abc123", "node_8f3a2b", {
content: {
type: "doc",
content: [
{ type: "heading1", content: [{ type: "text", text: "Release notes" }] }
]
}
});
{
"id": "doc_77ab2e",
"content": {
"type": "doc",
"content": [
{
"type": "heading1",
"content": [{ "type": "text", "text": "Release notes" }]
}
]
},
"createdAt": "2025-04-01T08:00:00.000Z",
"createdBy": "user_alice",
"updatedAt": "2025-04-01T08:00:00.000Z",
"updatedBy": "user_alice"
}

PATCH /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document

Section titled “PATCH /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document”

Merges content into an existing document at the top level. Existing blocks are preserved unless overwritten.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
NameTypeRequiredDescription
contentobjectYesPartial content to merge into the top-level document
{
"content": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Added a new paragraph on 2025-04-02." }]
}
]
}
}
await client.notes.documents.patch("nb_abc123", "node_8f3a2b", {
content: {
type: "doc",
content: [
{ type: "paragraph", content: [{ type: "text", text: "Added a new paragraph." }] }
]
}
});
{
"id": "doc_77ab2e",
"content": {
"type": "doc",
"content": [
{ "type": "heading1", "content": [{ "type": "text", "text": "Release notes" }] },
{ "type": "paragraph", "content": [{ "type": "text", "text": "Added a new paragraph." }] }
]
},
"createdAt": "2025-04-01T08:00:00.000Z",
"createdBy": "user_alice",
"updatedAt": "2025-04-02T10:14:00.000Z",
"updatedBy": "user_bob"
}

POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document/append

Section titled “POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/document/append”

Appends one or more blocks to the END of a node’s rich-text document. The server assigns each block id, parentId, and index — any client-supplied values (including attrs.id) are rejected.

You must send exactly one of:

  • text — a single block from plain text. Newlines are not split; the text is stored as one literal block.
  • blocks — an array of 1–100 flat root blocks.

If the document does not exist yet, it is created. Pass X-Idempotency-Key to make retries safe: a repeated key + identical body replays the original response; a different body with the same key returns 409.

Allowed block types: paragraph, heading1, heading2, heading3, codeBlock, horizontalRule.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
X-Idempotency-KeyheaderstringNoOptional idempotency key (max 256 chars). Reusing the same key with an identical request body and node replays the original response; reusing it with a different body or node returns 409.

You must provide one of these two shapes:

Shape A — plain text block:

NameTypeRequiredDescription
textstringYesNon-empty plain text for a single block
typestringNoBlock type — paragraph (default), heading1, heading2, heading3, or codeBlock
attrsobject | nullNoBlock-level attributes (e.g. language for codeBlock)
{
"text": "This change went live on April 2nd.",
"type": "paragraph"
}

Shape B — array of blocks:

NameTypeRequiredDescription
blocksarrayYes1–100 flat root blocks. Each block has type (paragraph, heading1, heading2, heading3, codeBlock, horizontalRule), content (array of { type: "text", text, marks }), and optional attrs.
{
"blocks": [
{
"type": "heading2",
"content": [{ "type": "text", "text": "April 2nd updates" }]
},
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Shipped the new export pipeline." }
]
},
{ "type": "horizontalRule" }
]
}
await client.notes.documents.appendDocument(
"nb_abc123",
"node_8f3a2b",
{
text: "This change went live on April 2nd.",
type: "paragraph"
},
{ XIdempotencyKey: "key_123" }
);
{
"id": "doc_77ab2e",
"content": {
"type": "doc",
"content": [
{ "type": "heading1", "content": [{ "type": "text", "text": "Release notes" }] },
{ "type": "paragraph", "content": [{ "type": "text", "text": "Initial cut." }] },
{ "type": "paragraph", "content": [{ "type": "text", "text": "This change went live on April 2nd." }] }
]
},
"createdAt": "2025-04-01T08:00:00.000Z",
"createdBy": "user_alice",
"updatedAt": "2025-04-02T10:14:00.000Z",
"updatedBy": "user_alice",
"appendedBlockIds": ["block_d12", "block_d13"]
}

POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/export-ticket

Section titled “POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/export-ticket”

Creates a short-lived export ticket for static HTML document delivery. Ticket is required to fetch output=html.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
NameTypeRequiredDescription
outputstringNoOutput format (default "html")
includeCommentsstringNonone (default) or appendix
includeBackgroundbooleanNoInclude page background in export (default true)
themeModestringNolight or dark (default "dark")
themeIdstring | nullNoTheme identifier (max 64 chars)
themeVariablesobjectNoMap of theme variable name to string value
fileNamestringNoSuggested download filename (max 128 chars)
{
"output": "html",
"includeComments": "appendix",
"themeMode": "light",
"fileName": "Onboarding.html"
}
await client.notes.documents.createExportTicket("nb_abc123", "node_8f3a2b", {
output: "html",
includeComments: "appendix",
themeMode: "light",
fileName: "Onboarding.html"
});
{
"ticket": "tkt_8f4a2c91",
"expiresAt": "2025-04-02T09:30:00.000Z",
"usesRemaining": 3
}

GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/blocks/{blockId}/svg

Section titled “GET /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/blocks/{blockId}/svg”

Renders a drawing block as an SVG image. Supports optional background color and scale factor.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
blockIdpathstringYesDrawing block identifier
bgquerystringNoBackground color (e.g. transparent, #ffffff)
scalequerynumberNoScale factor (e.g. 2 for 2× resolution)
await client.notes.documents.exportBlockSvg("nb_abc123", "node_8f3a2b", "block_d12", {
bg: "transparent",
scale: 2
});

Returns an image/svg+xml body containing the rendered drawing.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
<!-- Drawing strokes and shapes rendered here -->
</svg>

POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/interactions/opened

Section titled “POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/interactions/opened”

Records that the current user has opened the node. Tracks first and last opened timestamps.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
NameTypeRequiredDescription
openedAtstringNoISO timestamp of the open event (defaults to server time)
{
"openedAt": "2025-04-02T10:14:00.000Z"
}
await client.notes.interactions.markOpened("nb_abc123", "node_8f3a2b", {
openedAt: "2025-04-02T10:14:00.000Z"
});
{
"nodeId": "node_8f3a2b",
"collaboratorId": "user_bob",
"firstSeenAt": "2025-03-28T08:00:00.000Z",
"lastSeenAt": "2025-04-02T10:14:00.000Z",
"firstOpenedAt": "2025-03-28T08:01:12.000Z",
"lastOpenedAt": "2025-04-02T10:14:00.000Z"
}

POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/interactions/seen

Section titled “POST /api/v1/notes/notebooks/{notebookId}/nodes/{nodeId}/interactions/seen”

Records that the current user has seen the node. Tracks first and last seen timestamps.

NameInTypeRequiredDescription
notebookIdpathstringYesNotebook identifier
nodeIdpathstringYesNode identifier
NameTypeRequiredDescription
seenAtstringNoISO timestamp of the seen event (defaults to server time)
{
"seenAt": "2025-04-02T10:14:00.000Z"
}
await client.notes.interactions.markSeen("nb_abc123", "node_8f3a2b", {
seenAt: "2025-04-02T10:14:00.000Z"
});
{
"nodeId": "node_8f3a2b",
"collaboratorId": "user_bob",
"firstSeenAt": "2025-03-28T08:00:00.000Z",
"lastSeenAt": "2025-04-02T10:14:00.000Z",
"firstOpenedAt": "2025-03-28T08:01:12.000Z",
"lastOpenedAt": "2025-04-02T10:14:00.000Z"
}