The Notes Nodes & Documents API lets you manage the tree structure of a notebook, read and write block-based document content, export pages to static formats, and track read interactions. Use these endpoints to build notebook navigation, sync editor content, and surface read receipts.
Returns a paginated list of nodes the user has access to. Filterable by type, parentId, and rootId.
Name In Type Required Description typequery string No Filter by node type. parentIdquery string No Filter by parent node ID. rootIdquery string No Filter by root node ID. limitquery integer No Page size. Default: 50. offsetquery integer No Pagination offset. Default: 0. notebookIdpath string Yes Notebook ID.
curl -X GET " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes?type=page&limit=25 " \
-H " Authorization: Bearer <token> "
const { nodes , total } = await client . notes . nodes . list ( {
"parentId" : " node_root01 " ,
"parentId" : " node_root01 " ,
"message" : " You do not have access to this node. " ,
{ "path" : " notebookId " , "message" : " Not a collaborator " }
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin
Returns the full details of a single node by ID.
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
curl -X GET " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b " \
-H " Authorization: Bearer <token> "
const node = await client . notes . nodes . get ( {
"parentId" : " node_root01 " ,
"createdAt" : " 2025-01-12T10:14:22Z "
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin
"message" : " Node not found. " ,
Error Code Title Description Resolution not_foundNode not found No node exists with the provided ID in this notebook Verify node ID using listNodes or listNodeChildren
Resolves a page node by its safe alias within the notebook scope.
Name In Type Required Description notebookIdpath string Yes Notebook ID. aliaspath string Yes Page alias.
curl -X GET " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/alias/onboarding " \
-H " Authorization: Bearer <token> "
const node = await client . notes . nodes . getByAlias ( {
"parentId" : " node_root01 "
"message" : " Invalid alias format. " ,
{ "path" : " alias " , "message" : " Alias must be lowercase alphanumeric with dashes " }
"message" : " You do not have access to this notebook. " ,
"message" : " No node found with that alias. " ,
Returns a paginated list of direct children of the specified node.
Name In Type Required Description limitquery integer No Page size. Default: 50. offsetquery integer No Pagination offset. Default: 0. notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Parent node ID.
curl -X GET " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_root01/children?limit=10 " \
-H " Authorization: Bearer <token> "
const { nodes , total } = await client . notes . nodes . listChildren ( {
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin
"message" : " Node not found. " ,
Error Code Title Description Resolution not_foundNode not found No node exists with the provided ID in this notebook Verify node ID using listNodes or listNodeChildren
Creates a new node (section, page, channel, message, database, or record) in the notebook.
Name In Type Required Description notebookIdpath string Yes Notebook ID.
Name Type Required Description idstring No Optional client-provided ID. typestring Yes Node type (e.g. page, section, channel). parentIdstring No Parent node ID. attributesobject Yes Type-specific attributes (name, icon, etc.).
curl -X POST " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
"parentId": "node_root01",
"attributes": { "name": "Onboarding", "icon": "🚀" }
const node = await client . notes . nodes . create ( {
attributes: { name: " Onboarding " , icon: " 🚀 " },
"parentId" : " node_root01 "
"message" : " Invalid node type. " ,
{ "path" : " type " , "message" : " Unsupported type 'folder' " }
Error Code Title Description Resolution bad_requestInvalid node data The request body is invalid — missing required fields or unsupported node type Check the node type is valid and all required attributes are provided
"message" : " You do not have permission to perform this action. " ,
Error Code Title Description Resolution forbiddenInsufficient permissions User role does not have permission for this action Request a higher role from the notebook or node admin
"message" : " Idempotency key conflict. " ,
Error Code Title Description Resolution bad_requestIdempotency conflict A different request was already made with the same idempotency key Use a new idempotency key for a different request
"message" : " An unexpected error occurred. " ,
Error Code Title Description Resolution unknownInternal server error An unexpected error occurred while processing the request Retry the request; if it persists, contact support
Updates node attributes (name, description, etc.). Type and parentId cannot be changed.
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
Name Type Required Description attributesobject Yes Partial attributes object to merge.
curl -X PATCH " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
"attributes": { "name": "Onboarding Guide", "icon": "📘" }
const node = await client . notes . nodes . update ( {
data: { attributes: { name: " Onboarding Guide " , icon: " 📘 " } },
"name" : " Onboarding Guide " ,
"message" : " Invalid attributes payload. " ,
{ "path" : " attributes " , "message" : " name must be a non-empty string " }
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin
"message" : " Node not found. " ,
Error Code Title Description Resolution not_foundNode not found No node exists with the provided ID in this notebook Verify node ID using listNodes or listNodeChildren
"message" : " Concurrent update conflict. " ,
"message" : " An unexpected error occurred. " ,
Error Code Title Description Resolution unknownInternal server error An unexpected error occurred while processing the request Retry the request; if it persists, contact support
Permanently deletes a node and its associated data (documents, files, reactions).
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
curl -X DELETE " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b " \
-H " Authorization: Bearer <token> "
const { success } = await client . notes . nodes . delete ( {
"message" : " You do not have permission to perform this action. " ,
Error Code Title Description Resolution forbiddenInsufficient permissions User role does not have permission for this action Request a higher role from the notebook or node admin
"message" : " Node not found. " ,
Error Code Title Description Resolution not_foundNode not found No node exists with the provided ID in this notebook Verify node ID using listNodes or listNodeChildren
"message" : " An unexpected error occurred. " ,
Error Code Title Description Resolution unknownInternal server error An unexpected error occurred while processing the request Retry the request; if it persists, contact support
Retrieves document content for a node. Supports block filtering via blockIds and line range queries.
Name In Type Required Description blockIdsquery string No Comma-separated list of block IDs to include. linesquery string No Line range in the form start-end (e.g. 1-50). outputquery string No Output format. One of json, md, html. includeCommentsquery string No Include comments. One of none, appendix. Default: "none". ticketquery string No Pre-issued export ticket (required when output=html). notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
curl -X GET " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b/document?output=md " \
-H " Authorization: Bearer <token> "
const doc = await client . notes . documents . get ( {
{ "type" : " heading " , "level" : 1 , "text" : " Onboarding " },
{ "type" : " paragraph " , "text" : " Welcome to the team. " }
"createdAt" : " 2025-01-12T10:14:22Z " ,
"createdBy" : " user_1a2b3c " ,
"updatedAt" : " 2025-02-04T08:31:05Z " ,
"updatedBy" : " user_4d5e6f "
"message" : " Invalid or missing authentication. " ,
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin
"message" : " Document not found. " ,
Error Code Title Description Resolution not_foundDocument not found No document content exists for this node, or the node type does not support documents Create document content with putDocument first
Creates a new document or fully replaces an existing document for a node.
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
Name Type Required Description contentobject Yes Full document content (block tree).
curl -X PUT " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b/document " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
{ "type": "heading", "level": 1, "text": "Onboarding" },
{ "type": "paragraph", "text": "Welcome to the team." }
const doc = await client . notes . documents . put ( {
{ type: " heading " , level: 1 , text: " Onboarding " },
{ type: " paragraph " , text: " Welcome to the team. " },
{ "type" : " heading " , "level" : 1 , "text" : " Onboarding " }
"createdAt" : " 2025-01-12T10:14:22Z " ,
"createdBy" : " user_1a2b3c " ,
"updatedAt" : " 2025-02-05T09:00:00Z " ,
"updatedBy" : " user_1a2b3c "
"message" : " Node type does not support documents. " ,
Error Code Title Description Resolution bad_requestUnsupported node type This node type does not support document content Only page, channel, and similar node types support documents
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin forbiddenInsufficient permissions User role does not have permission for this action Request a higher role from the notebook or node admin
"message" : " Node not found. " ,
Error Code Title Description Resolution not_foundNode not found No node exists with the provided ID in this notebook Verify node ID using listNodes or listNodeChildren
"message" : " An unexpected error occurred. " ,
Error Code Title Description Resolution unknownInternal server error An unexpected error occurred while processing the request Retry the request; if it persists, contact support
Merges content into an existing document at the top level. Existing blocks are preserved unless overwritten.
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
Name Type Required Description contentobject Yes Block-level content to merge.
curl -X PATCH " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b/document " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
{ "type": "paragraph", "text": "Added in patch." }
const doc = await client . notes . documents . patch ( {
content: [{ type: " paragraph " , text: " Added in patch. " }] ,
{ "type" : " heading " , "level" : 1 , "text" : " Onboarding " },
{ "type" : " paragraph " , "text" : " Added in patch. " }
"createdAt" : " 2025-01-12T10:14:22Z " ,
"createdBy" : " user_1a2b3c " ,
"updatedAt" : " 2025-02-05T11:22:18Z " ,
"updatedBy" : " user_1a2b3c "
"message" : " Node type does not support documents. " ,
Error Code Title Description Resolution bad_requestUnsupported node type This node type does not support document content Only page, channel, and similar node types support documents
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin forbiddenInsufficient permissions User role does not have permission for this action Request a higher role from the notebook or node admin
"message" : " Document not found. " ,
Error Code Title Description Resolution not_foundDocument not found No document exists for this node — create it with putDocument first Use putDocument to create the document before patching
"message" : " An unexpected error occurred. " ,
Error Code Title Description Resolution unknownInternal server error An unexpected error occurred while processing the request Retry the request; if it persists, contact support
Renders a drawing block as an SVG image. Supports optional background color and scale factor.
Name In Type Required Description bgquery string No CSS-compatible background color (e.g. #ffffff, transparent). scalequery number No Scale factor applied to the output dimensions. notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID. blockIdpath string Yes Drawing block ID.
curl -X GET " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b/blocks/block_d12/svg?bg=transparent&scale=2 " \
-H " Authorization: Bearer <token> " \
const svg = await client . notes . documents . exportBlockSvg ( {
< svg xmlns = " http://www.w3.org/2000/svg " viewBox = " 0 0 800 600 " >
< rect width = " 100% " height = " 100% " fill = " transparent " />
< path d = " M10 80 Q 95 10 180 80 T 350 80 " stroke = " #1f6feb " fill = " none " stroke-width = " 3 " />
Creates a short-lived export ticket for static HTML document delivery. Pass the returned ticket to getDocument with output=html.
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
Name Type Required Default Description outputstring No "html"Export format. Must be html. includeCommentsstring No "none"Whether to append comments. One of none, appendix. includeBackgroundboolean No trueWhether to render the page background. themeModestring No "dark"Theme mode. One of light, dark. themeIdstring | null No — Optional theme identifier (max 64 chars). themeVariablesobject No — Map of theme variable name to value. fileNamestring No — Suggested file name (max 128 chars).
curl -X POST " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b/export-ticket " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
"includeComments": "appendix",
"fileName": "Onboarding.html"
const { ticket , expiresAt , usesRemaining } = await client . notes . documents . createExportTicket ( {
includeComments: " appendix " ,
fileName: " Onboarding.html " ,
"ticket" : " tk_01HXY8K3B5QJZ9W3E0F2M7PR8V " ,
"expiresAt" : " 2025-02-05T11:30:00Z " ,
"message" : " You do not have access to this node. " ,
"message" : " Node not found. " ,
Records that the current user has opened the node. Tracks first and last opened timestamps.
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
Name Type Required Description openedAtstring No ISO-8601 timestamp; defaults to server time.
curl -X POST " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b/interactions/opened " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
const result = await client . notes . interactions . markOpened ( {
"collaboratorId" : " collab_7e1a " ,
"firstSeenAt" : " 2025-01-20T09:00:00Z " ,
"lastSeenAt" : " 2025-02-05T11:22:18Z " ,
"firstOpenedAt" : " 2025-02-05T11:22:18Z " ,
"lastOpenedAt" : " 2025-02-05T11:22:18Z "
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin
"message" : " Node not found. " ,
Error Code Title Description Resolution not_foundNode not found No node exists with the provided ID in this notebook Verify node ID using listNodes or listNodeChildren
"message" : " Idempotency key conflict. " ,
Error Code Title Description Resolution bad_requestIdempotency conflict A different request was already made with the same idempotency key Use a new idempotency key for a different request
"message" : " An unexpected error occurred. " ,
Error Code Title Description Resolution unknownInternal server error An unexpected error occurred while processing the request Retry the request; if it persists, contact support
Records that the current user has seen the node. Tracks first and last seen timestamps.
Name In Type Required Description notebookIdpath string Yes Notebook ID. nodeIdpath string Yes Node ID.
Name Type Required Description seenAtstring No ISO-8601 timestamp; defaults to server time.
curl -X POST " https://api.hoody.com/api/v1/notes/notebooks/nb_abc123/nodes/node_8f3a2b/interactions/seen " \
-H " Authorization: Bearer <token> " \
-H " Content-Type: application/json " \
const result = await client . notes . interactions . markSeen ( {
"collaboratorId" : " collab_7e1a " ,
"firstSeenAt" : " 2025-02-05T11:21:00Z " ,
"lastSeenAt" : " 2025-02-05T11:21:00Z " ,
"message" : " You do not have access to this node. " ,
Error Code Title Description Resolution forbiddenAccess denied User does not have permission to access this node Check collaborator list or request access from the node admin
"message" : " Node not found. " ,
Error Code Title Description Resolution not_foundNode not found No node exists with the provided ID in this notebook Verify node ID using listNodes or listNodeChildren
"message" : " Idempotency key conflict. " ,
Error Code Title Description Resolution bad_requestIdempotency conflict A different request was already made with the same idempotency key Use a new idempotency key for a different request
"message" : " An unexpected error occurred. " ,
Error Code Title Description Resolution unknownInternal server error An unexpected error occurred while processing the request Retry the request; if it persists, contact support