Skip to main content
runQuery fetches rows from the workspace’s managed Postgres database using a typed filter DSL. It is the in-page data-fetching primitive: blocks like Table and KanbanBoard use it to populate themselves from live data. You declare the filter in the page document and the runtime translates it to a parameterized Postgres query server-side — raw SQL is never accepted and never exposed. By the end of this page you can wire a Table block to a schema table with filters, sort order, and cursor pagination.

Invoke from a Table block

The canonical pattern is binding Table to a schema_table. The block calls runQuery automatically and surfaces sort, filter, and pagination through its UI.
leads-table.json
{
  "block": "Table",
  "props": {
    "schema_table": "leads",
    "sort": [{ "field": "created_at", "dir": "desc" }],
    "limit": 50,
    "filter": {
      "status": { "eq": "active" }
    }
  }
}
A KanbanBoard uses runQuery the same way, grouping rows by a status field:
deals-kanban.json
{
  "block": "KanbanBoard",
  "props": {
    "schema_table": "deals",
    "status_field": "stage",
    "sort": [{ "field": "updated_at", "dir": "desc" }]
  }
}
The runtime resolves the filter against the table’s column types, parameterizes the query, executes against Postgres, and returns the rows in a validated envelope.
You do not write SQL. The filter argument is a typed DSL validated against the page’s declared schema. The runtime translates it to a parameterized Postgres query server-side — raw SQL is not accepted as input.
runQuery runs in the security context of the calling page. The user’s session — read via authUser — gates which rows return. If the calling user does not have access to a row, that row is excluded. Multi-tenant isolation is enforced at this layer; changing the table name does not grant access to another workspace’s data.
For server-side scripts and integrations, prefer the public REST API (see the API reference). runQuery is designed for in-page data fetching where the user’s session should govern row-level access. Using it from a background job would require a user session, which is the wrong tool for the job.

Inputs

Outputs

Provisioning

The workspace’s managed Postgres database is auto-provisioned. Tables must be declared in the page document’s schema section before they can be queried. Schemas are managed in the Builder’s schema editor or via the pages API.

Error codes

Every error returns the standard envelope:

authUser

The session whose roles gate row-level access on every runQuery call.

Data queries guide

End-to-end: declare a schema, wire a Table, paginate with next_cursor.