Developer API
Get Database View
V2

Get Database View

Read one view's full stable projection, including the manual page_sort order.

GET /v2/databases/:database_id/views/:view_id

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" }]
}
  • property always uses the exact property id (schema key) returned by the database API; legacy databases may use a non-title id for the title property.
  • value is always a string. For select and multi_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 as today, last_7_days, or 2026/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 applies any semantics, so accepting it would let callers believe the quantifier took effect.
  • propertyType is 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); legacy select/multi_select option 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 / rollup conditions are not evaluated server-side: writing them through v2 is always rejected (including isEmpty/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 case query?view_id returns more rows than the UI shows, so filter those views through the query request body's own filter instead.
  • 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.