Views

Views are admin-defined saved filters + sort for a table. Over the public API you can list views, fetch a single view, and query records through a view. Creating / updating / deleting views is session-only in v1.

All endpoints require an API key with read access to the workspace that contains the target table.

List views for a table

GET /api/table/<table_id>/views/list

Returns the synthesised Default view (id 0) first, then any saved views sorted alphabetically by name.

Response

[
  {
    "id": 0,
    "account_id": 1,
    "table_id": 101,
    "name": "Default",
    "type": "grid",
    "filters": [],
    "order_by": null,
    "order_dir": null,
    "created_by": 0,
    "created_at": "",
    "updated_at": "",
    "is_default": true,
    "is_table_default": false
  },
  {
    "id": 19,
    "account_id": 1,
    "table_id": 101,
    "name": "Open deals",
    "type": "grid",
    "config": {"columns": []},
    "filters": [
      {"column": "status", "compare": "=", "value": "open"}
    ],
    "order_by": "amount",
    "order_dir": "D",
    "created_by": 4,
    "created_at": "2026-04-22 12:00:00",
    "updated_at": "2026-04-22 12:00:00",
    "is_default": false,
    "is_table_default": true
  }
]

is_default is true only for the synthesised id-0 row. is_table_default is the admin-marked flag — at most one saved view per table has this set, and it controls which view auto-applies in the grid UI when the table is opened with no ?view= parameter. The public records-query endpoint ignores this flag (see below).

Layout types

type is one of grid, calendar, gallery, or kanban. The config field carries a layout-specific JSON object (it is null only for the synthesised Default view):

// grid — ordered list of visible columns
{"columns": ["title", "status", "amount"]}

// calendar
{"startField": "due", "endField": "until", "colorField": "status",
 "mode": "month", "weekStart": "monday"}

// gallery
{"imageField": "cover", "secondaryField": "client_name"}

// kanban
{"categoryField": "status", "secondaryField": "owner"}

For grid, columns is an ordered list of the visible column field ids; a field absent from the list is hidden and an empty list ({"columns": []}) means "show all". Unknown, deleted, or always-hidden field ids are dropped silently on save — grid config never raises a validation error.

For the others: startField/endField must be date fields, colorField must be a select field, imageField must be a file field, and categoryField must be a single-value select (multi-selects are rejected). Saving a calendar view also auto-creates an idx_layout_<startField> index on the underlying table for date-range scans.

Get a single view

GET /api/table/<table_id>/view/<view_id>/get

Pass 0 for <view_id> to get the synthesised Default view for that table. Cross-table ids return 404 View not found.

Query records through a view

POST /api/table/<table_id>/records/query

Request body

{
  "view_id": 19,
  "search": "acme",
  "limit": 100,
  "offset": 0
}
Field Type Notes
view_id int Optional. When present, the view's filters + sort fully replace request-supplied filters and order_by / order_dir. Pass 0 for Default (equivalent to omitting). The grid-UI marked default (is_table_default) is not auto-applied when view_id is omitted — call list views and pass the id explicitly if you want it.
append_filters bool Internal layout option. When true, request filters are added on top of the view filters.
search string Optional full-text search, applied on top of the view's filters.
limit int Default 100, max 1000. Values outside that range are clamped.
offset int Default 0.
fields array Optional column whitelist.

filters, order_by, and order_dir in the request body are ignored when view_id is set — the view is authoritative. Layout renderers are the exception: they pass append_filters: true for date-range or similar constraints. For normal API use, save filters into the view or drop view_id and send ad-hoc filters.

Errors

Status Message When
500 View not found view_id doesn't exist or belongs to a different table.
500 Not Authorized API key has no access to the table's workspace.

Response

Array of record objects, same shape as the non-view query.

Filter format

Stored view filters follow {column, compare, value, connector}. Supported compare values mirror the filter panel in the UI:

  • =, !=, >, <, >=, <=
  • contains, starts_with, ends_with
  • is_empty, is_not_empty (no value required)

connector is optional and joins each filter to the one before it — "AND" (default) or "OR". The first filter's connector is always treated as AND. See Query through a saved view for how combined AND/OR filters evaluate.

Date tokens like today, -7d, or start_of_month in value are resolved at query time against the server clock. User-field filters accept @me, which resolves to the authenticated user's email. For account API keys, it resolves to the account owner's email.

Mutation endpoints (session-only)

Creating, updating, and deleting views is available only to logged-in workspace admins via the session-authenticated UI API. These endpoints are not registered for API keys in v1:

POST /api/table/<table_id>/views/create
POST /api/table/<table_id>/view/<view_id>/update
POST /api/table/<table_id>/view/<view_id>/delete

Calling them with a bearer token returns 403 API endpoint not available to API keys.