Docs API
Databases
Create and change databases, read their properties and data sources, and query rows with filters and sorts.
Base URLhttps://docs.polder.work
The database object
{
"object": "database",
"id": "01k8x2p3q5r7s9t1v3w5x7y9za",
"title": [ { "plain_text": "Tasks" } ],
"description": [],
"icon": null,
"cover": null,
"parent": { "type": "page_id", "page_id": "01k8x2k…" },
"url": "https://docs.polder.work/pages/01k8x2k…",
"public_url": null,
"is_inline": false,
"archived": false,
"in_trash": false,
"properties": {
"Name": { "id": "title", "name": "Name", "type": "title", "description": "", "title": {} },
"Status": { "id": "k3f9a1", "name": "Status", "type": "status", "description": "", "status": { "options": [ { "id": "…", "name": "In progress", "color": "blue" } ], "groups": [ … ] } },
"Points": { "id": "p0x2bb", "name": "Points", "type": "number", "description": "", "number": { "format": "number" } }
},
"data_sources": [ { "id": "01k8x2p3q5r7s9t1v3w5x7y9za", "name": "Tasks", "kind": "default" } ],
"created_time": "…", "last_edited_time": "…", "created_by": { "object": "user", "id": "3" }, "last_edited_by": { "object": "user", "id": "3" }
}
A database's id is the id of its database block: the child_database block on a page, which is also the database_id in its rows' parent. For a full-page database, the id of its page works wherever a database id is expected.
A database can hold several data sources, each with its own rows and properties. data_sources lists the ones the integration can reach (kind is Polder only). A data source is the same shape as a database with object: "data_source"; a database with one source is its own data source.
properties is keyed by name. Property types are the ones in the page object, plus formula, rollup and the like, which can be read here but not created.
Create a database
/api/v1/databasesCreates a database on a page the integration is connected to, and returns it.
Body
| Field | Type | Required | Description |
|---|---|---|---|
parent |
object | yes | {"type": "page_id", "page_id": "…"}. A normal page, not a database; not locked |
title |
array | no | Rich text |
icon |
object | no | Emoji or external icon, as on pages |
cover |
object | no | External cover; for a full-page database only |
is_inline |
boolean | no | false (default) creates a new full-page database under the parent page. true adds a database at the end of the parent page's body |
properties |
object | no | Properties by name, in Notion's shape: {"Severity": {"select": {"options": [ {"name": "High", "color": "red"} ]}}} |
- There is exactly one
titleproperty (a second returns400). If you send none, it is called "Name". - The types you can create are
rich_text,number(withformat),select,multi_select,status,date,people,files,checkbox,url,email,phone_number,created_time,created_by,last_edited_time,last_edited_byandunique_id(withprefix). Formulas, relations and rollups have to be set up in the app; asking for them returns400 validation_error. descriptionon a property is kept.
curl https://docs.polder.work/api/v1/databases \
-H "Authorization: Bearer $POLDER_DOCS_KEY" \
-H "Content-Type: application/json" \
-d '{
"parent": { "type": "page_id", "page_id": "01k8x2k5r1m3a7z9w2e4t6y8ui" },
"title": [ { "text": { "content": "Bugs" } } ],
"properties": {
"Bug": { "title": {} },
"Severity": { "select": { "options": [ { "name": "High", "color": "red" }, { "name": "Low" } ] } },
"Estimate": { "number": { "format": "number_with_commas" } },
"Reported": { "date": {} }
}
}'
Retrieve a database
/api/v1/databases/{id}Returns the database object.
curl https://docs.polder.work/api/v1/databases/01k8x2p3q5r7s9t1v3w5x7y9za \
-H "Authorization: Bearer $POLDER_DOCS_KEY"
Update a database
/api/v1/databases/{id}Changes the title, icon and properties, or moves the database to the trash. Returns the database.
{
"title": [ { "text": { "content": "Team tasks" } } ],
"properties": {
"Points": { "name": "Estimate" },
"Urgent": null,
"Status": { "select": { "options": [ { "name": "Blocked", "color": "red" } ] } },
"Owner": { "people": {} }
}
}
- A property name that does not exist yet adds a property, from its type.
{"name": "…"}renames a property;descriptionsets its description.nullremoves a property. The title property cannot be removed, and a name that does not exist returns400.- Options in a
select,multi_selectorstatusconfig are added when they are new. Existing options are never removed through the API (Notion replaces the list). New status options go in the "to-do" group. - Changing a property's type returns
400. iconchanges the icon of a full-page database.in_trash: true(orarchived) moves the whole database to the trash.
Query a database
/api/v1/databases/{id}/queryReturns the rows of a database as a list of page objects (type: "page_or_database"). Templates are not included, nor are rows the integration's admin may not see.
Body
| Field | Type | Description |
|---|---|---|
filter |
object | One condition, or and / or with a list of conditions |
sorts |
array | Sorts, applied in order |
data_source_id |
string | Query one of the database's other data sources |
start_cursor, page_size |
Pagination |
curl https://docs.polder.work/api/v1/databases/01k8x2p3q5r7s9t1v3w5x7y9za/query \
-H "Authorization: Bearer $POLDER_DOCS_KEY" \
-H "Content-Type: application/json" \
-d '{
"filter": { "or": [
{ "property": "Status", "status": { "equals": "In progress" } },
{ "and": [
{ "property": "Points", "number": { "greater_than": 3 } },
{ "property": "Due", "date": { "next_week": {} } }
] }
] },
"sorts": [
{ "property": "Due", "direction": "ascending" },
{ "timestamp": "created_time", "direction": "descending" }
],
"page_size": 50
}'
Filters
A condition names a property (by name or id) and puts exactly one operator under the property type's name: {"property": "Points", "number": {"greater_than": 3}}. and / or groups can nest two levels deep. A filter that does not fit returns 400 validation_error.
{"timestamp": "created_time", "created_time": {"after": "2026-10-01"}} filters on a row's creation or last edit time (last_edited_time).
| Type | Operators |
|---|---|
title, rich_text, url, email, phone_number |
equals, does_not_equal, contains, does_not_contain, starts_with, ends_with, is_empty, is_not_empty |
number, unique_id |
equals, does_not_equal, greater_than, less_than, greater_than_or_equal_to, less_than_or_equal_to, is_empty, is_not_empty |
checkbox |
equals, does_not_equal |
select, status |
equals, does_not_equal (option name or id; an unknown option matches nothing), is_empty, is_not_empty |
multi_select, people, relation |
contains, does_not_contain (option name or id, user id or "me", page id), is_empty, is_not_empty |
date, created_time, last_edited_time |
equals, before, after, on_or_before, on_or_after (an ISO date; only the day counts), past_week, past_month, past_year, next_week, next_month, next_year, this_week, is_empty, is_not_empty |
created_by, last_edited_by |
contains, does_not_contain (user id or "me") |
Filters are evaluated by the same code that applies a view's filters in the app, so the API and a view with the same filter show the same rows. Filtering on a formula, rollup or verification property returns 400.
Sorts
Each sort is {"property": "Due", "direction": "ascending"} or {"timestamp": "created_time" | "last_edited_time", "direction": …}. direction defaults to ascending. The first sort decides, the next ones break ties. Select and status options sort in their option order. Empty values come last in either direction. Without sorts, rows come in the database's own order.
Retrieve a data source
/api/v1/data_sources/{id}Returns one data source of a database: the same fields as the database object, with object: "data_source". {id} is the id from the database's data_sources list.
curl https://docs.polder.work/api/v1/data_sources/01k8x2p3q5r7s9t1v3w5x7y9za \
-H "Authorization: Bearer $POLDER_DOCS_KEY"
Query a data source
/api/v1/data_sources/{id}/queryQueries the rows of one data source. The body, filters, sorts and response are those of querying a database.
curl https://docs.polder.work/api/v1/data_sources/01k8x2p3q5r7s9t1v3w5x7y9za/query \
-H "Authorization: Bearer $POLDER_DOCS_KEY" \
-H "Content-Type: application/json" \
-d '{"filter": {"property": "Name", "title": {"contains": "launch"}}}'