Docs API
Blocks
Read, append, change and delete the blocks that make up a page.
Base URLhttps://docs.polder.work
The block object
{
"object": "block",
"id": "01k8x2n7b4c6d8f0g2h4j6k8lm",
"parent": { "type": "page_id", "page_id": "01k8x2m4t7q9b3n5v6c8d0f2gh" },
"created_time": "2026-10-02T09:30:00.000Z",
"last_edited_time": "2026-10-02T09:30:00.000Z",
"created_by": { "object": "user", "id": "3" },
"last_edited_by": { "object": "user", "id": "3" },
"has_children": false,
"archived": false,
"in_trash": false,
"type": "to_do",
"to_do": { "rich_text": [ { "plain_text": "Ship it" } ], "checked": false }
}
A page is a block too (child_page), and so is a database (child_database), as in Notion. Their ids work in every block endpoint that reads.
Block types that can be created and changed through the API:
| Type | Fields in its body |
|---|---|
paragraph, heading_1, heading_2, heading_3, heading_4 (Polder only), quote, bulleted_list_item, numbered_list_item, toggle |
rich_text |
to_do |
rich_text, checked |
code |
rich_text, language |
callout |
rich_text, icon ({"emoji": "💡"} or a string), color |
equation |
expression |
bookmark, embed |
url |
image, video, audio, file |
external.url, caption, name. Only external files: uploads are refused with 400 |
divider, table_of_contents, breadcrumb |
none |
column_list, column |
none; they hold children |
Other block types (tables, synced blocks, buttons, form embeds…) are returned with their Polder content under their own type name but cannot be created or changed. child_page and child_database are created with POST /pages and POST /databases.
Retrieve a block
/api/v1/blocks/{id}Returns the block object. 404 object_not_found when the block does not exist or is not shared with the integration.
curl https://docs.polder.work/api/v1/blocks/01k8x2n7b4c6d8f0g2h4j6k8lm \
-H "Authorization: Bearer $POLDER_DOCS_KEY"
List block children
/api/v1/blocks/{id}/childrenThe blocks directly inside a page or block, in order, as a paginated list (?page_size=…&start_cursor=…). has_children on each one tells you whether to fetch deeper. A database has no children here: its rows come from a query.
curl "https://docs.polder.work/api/v1/blocks/01k8x2m4t7q9b3n5v6c8d0f2gh/children?page_size=50" \
-H "Authorization: Bearer $POLDER_DOCS_KEY"
Append block children
/api/v1/blocks/{id}/childrenAdds blocks inside a page or block. Returns a list of the new top-level blocks.
Body
| Field | Type | Required | Description |
|---|---|---|---|
children |
array | yes | 1 to 100 blocks, nested ones included, at most two levels of nesting. Each is {"type": "to_do", "to_do": {…}}; type may be left out when the body key names it |
after |
string | no | Id of a child of this block. The new blocks go after it instead of at the end |
- A database refuses blocks (
400): add rows by creating pages with the database as parent. - A locked page refuses the request (
400). A block that cannot hold children refuseschildrenof its own. - A type that cannot be created returns
400 validation_errorand lists the types that can.
curl -X PATCH https://docs.polder.work/api/v1/blocks/01k8x2m4t7q9b3n5v6c8d0f2gh/children \
-H "Authorization: Bearer $POLDER_DOCS_KEY" \
-H "Content-Type: application/json" \
-d '{
"children": [
{ "type": "bulleted_list_item", "bulleted_list_item": {
"rich_text": [ { "text": { "content": "Parent" } } ],
"children": [ { "type": "bulleted_list_item", "bulleted_list_item": { "rich_text": [ { "text": { "content": "Child" } } ] } } ]
} },
{ "type": "code", "code": { "rich_text": [ { "text": { "content": "echo 1;" } } ], "language": "php" } }
]
}'
Update a block
/api/v1/blocks/{id}Send the block's own type with the fields to change; fields you leave out stay as they are. Returns the block.
{ "to_do": { "checked": true } }
- A block's type cannot be changed: sending another type's body returns
400 validation_error. {"child_page": {"title": …}}renames a sub-page. A database is renamed withPATCH /databases/{id}.in_trash(orarchived) works as on pages:truemoves the block and everything in it to the trash,falserestores it. A block in the trash accepts only{"in_trash": false}.- A block on a locked page cannot be changed.
curl -X PATCH https://docs.polder.work/api/v1/blocks/01k8x2n7b4c6d8f0g2h4j6k8lm \
-H "Authorization: Bearer $POLDER_DOCS_KEY" \
-H "Content-Type: application/json" \
-d '{"to_do": {"checked": true}}'
Delete a block
/api/v1/blocks/{id}Moves the block, and everything inside it, to the trash. Returns the block with in_trash: true. Restore it with PATCH and {"in_trash": false}. Needs delete permission on the block, and fails on a locked page.
curl -X DELETE https://docs.polder.work/api/v1/blocks/01k8x2n7b4c6d8f0g2h4j6k8lm \
-H "Authorization: Bearer $POLDER_DOCS_KEY"