Get Database View
Read one view's full stable projection, including the manual page_sort order.
Get Database View
Use Case
Use this endpoint to read one view's complete configuration (manual order page_sort, filter, sorts, grouping, and type-specific config). The response carries a weak ETag that can be used as the If-Match precondition of a later PATCH.
Endpoint
| Item | Value |
|---|---|
| Method | GET |
| Path | /v2/databases/:database_id/views/:view_id |
| Request body | None |
| Returns | database_view |
| Scope | databases.read |
Permissions
Requires databases.read. The view must belong to the database and must not be archived, otherwise the endpoint returns 404.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
database_id |
string | Yes | Database ID. |
view_id |
string | Yes | View ID. |
Response Example
{
"object": "database_view",
"id": "34343434-3434-4343-8343-343434343434",
"database_id": "66666666-6666-4666-8666-666666666666",
"title": "In progress",
"type": "table",
"property_layout": [
{ "property_id": "title", "property_name": "Name", "visible": true, "width": 260 },
{
"property_id": "88888888-8888-4888-8888-888888888888",
"property_name": "Status",
"visible": true
}
],
"filter": {
"type": "group",
"operator": "and",
"filters": [
{
"type": "filter",
"property": "88888888-8888-4888-8888-888888888888",
"operator": "eq",
"value": "In progress",
"propertyType": "select"
}
]
},
"sorts": null,
"page_sort": ["77777777-7777-4777-8777-777777777777"],
"group_by": null,
"config": { "wrap": true, "freeze_column_index": 1 },
"created_time": "2026-04-09T08:00:00.000Z",
"last_edited_time": "2026-04-09T09:30:00.000Z"
}
Field Notes
filter / sorts (the web-client structure is the contract)
filter and sorts match exactly what the web client stores on the view. They are not converted to or from the Notion-style dialect of the query request body:
{
"filter": {
"type": "group",
"operator": "and",
"filters": [
{ "type": "filter", "property": "<property_id>", "operator": "eq", "value": "<option_id>" },
{ "type": "group", "operator": "or", "filters": ["..."] }
]
},
"sorts": [{ "property": "<property_id>", "direction": "asc" }]
}
propertyalways uses the exact property id (schema key) returned by the database API; legacy databases may use a non-titleid for the title property.valueis always a string. Forselectandmulti_select, responses use the option id exposed by Retrieve a database. Writes accept either that id or a unique option name and store the id; unknown or ambiguous names return 400. Other multi-value operands are comma-joined (including"me"for person conditions).- Operator set:
eq,neq,gt,gte,lt,lte,in,nin,startsWith,endsWith,isEmpty,isNotEmpty,checked,unChecked. Date conditions also accept relative operands such astoday,last_7_days, or2026/01/01,2026/01/31. mode(the multi-value quantifier) is read-only: it is returned as stored by the web client, but rejected on write. The server-side evaluator always appliesanysemantics, so accepting it would let callers believe the quantifier took effect.propertyTypeis a type hint: when provided it must match the schema; the server backfills it from the schema on write.- On read, conditions and sorters referencing deleted properties are pruned (same as the web client's
pruneFilter); legacyselect/multi_selectoption names are returned as ids when they resolve uniquely.
page_sort
The view's manual record order (an array of record ids). Queries with view_id use it as the ordering tie-break.
config (per view type)
| type | Fields |
|---|---|
table |
wrap, freeze_column_index (-1 for none), aggregations (property_id → {action}) |
board / gallery |
card_size, cover_type, cover_property_id, show_property_name |
calendar |
date_property_id, end_date_property_id (date properties), mode, show_lunar_calendar |
timeline |
start_property_id, end_property_id (date properties), show_table, zoom |
form |
show_description, serial_number, only_one_submit |
list |
none |
property_layout is always an empty array for timeline / form views (their internal layouts are dual-list/form structures and are not exposed yet).
cover_type accepts none, page_cover, page_content, and file_property (with file_property, cover_property_id must reference a file property). Read responses always stay within this enum: unrecognized legacy values are reported as none.
Known differences from the web client
- Page-link and person segments inside text conditions render as
@<uuid>(the web client renders page titles and user display names). formula/rollupconditions are not evaluated server-side: writing them through v2 is always rejected (includingisEmpty/isNotEmpty). However, a view created in the web client that carries such a condition is returned as stored and the condition is skipped as invalid during query evaluation — in that casequery?view_idreturns more rows than the UI shows, so filter those views through the query request body's ownfilterinstead.- The
"me"operand on person conditions resolves to the owner of the bot behind the credential, not the view's author; a "assignee = me" condition saved in the web client therefore evaluates differently through this endpoint.
Errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error |
Invalid path parameter. |
| 403 | forbidden |
Missing scope or no access to the database. |
| 404 | not_found |
Database or view does not exist, or the view belongs to another database. |