Filtering, Sorting & Pagination
GET /api/tables/:tableId/records returns a paginated envelope and accepts a rich set of query parameters to paginate, sort, filter, select fields, group, and aggregate records — so you can shape large datasets without writing custom endpoints. Every parameter is optional; combine them freely.
GET /api/tables/tasks/records?limit=10&offset=0&sort=priority:desc,name:asc&fields=id,name,status
The response is always the list envelope (never a bare array):
{
"records": [{ "id": "1", "fields": {} }],
"pagination": { "total": 128, "limit": 10, "offset": 0 }
}
Query parameter reference
| Parameter | Description | Example |
|---|---|---|
limit |
Maximum records to return | ?limit=20 |
offset |
Number of records to skip | ?offset=40 |
page |
Page number (1-indexed) — alternative to offset |
?page=3 |
sort |
Sort field(s) and direction | ?sort=name:asc,created_at:desc |
order |
Sort order (asc/desc) for a single-field sort |
?sort=name&order=desc |
fields |
Comma-separated field names to include | ?fields=id,name,status |
filter |
Filter expression (JSON) | ?filter={"status":"active"} |
view |
Apply a saved view configuration | ?view=2 |
groupBy |
Group records by a field | ?groupBy=status |
aggregate |
Aggregation functions | ?aggregate=sum:amount,count:id |
q |
Free-text search query | ?q=invoice |
format |
raw (default) or display field values |
?format=display |
timezone |
IANA timezone for date display formatting | ?timezone=Europe/Paris |
includeDeleted |
true to include soft-deleted rows; only for trash-only |
?includeDeleted=true |
Pagination
Two equivalent paging styles are supported. Use limit + offset for cursor-style scanning, or limit + page for page-numbered UIs. pagination.total is the count of all matching rows (independent of the page), so a client can compute the page count as ceil(total / limit).
GET /api/tables/tasks/records?limit=20&offset=40 # rows 41–60
GET /api/tables/tasks/records?limit=20&page=3 # rows 41–60 (1-indexed)
Sorting
Sort by one or more fields, each with a direction, using field:direction segments separated by commas. The leftmost field is the primary sort key.
GET /api/tables/tasks/records?sort=priority:desc,name:asc
For a single sort field you may instead split the field and direction across sort and order (?sort=name&order=desc). The field:direction form is preferred because it composes cleanly for multi-key sorts.
Field selection
Request a subset of columns with fields. This trims the response payload — useful for list views that only render a few columns. Fields the caller cannot read are omitted regardless of whether they appear in the fields list.
GET /api/tables/contacts/records?fields=id,name,status
Filtering
Pass a JSON filter expression in the filter parameter. A flat object filters by equality on each key:
GET /api/tables/tasks/records?filter={"status":"active"}
For richer conditions, filters use the same structured form as saved views — a tree of and/or groups whose leaves are { field, operator, value } conditions:
filters:
and:
- field: status
operator: in
value: [todo, in_progress]
- field: priority
operator: equals
value: high
Conditions name a field, an operator (e.g. equals, in, greaterThan), and a value. Operators are resolved per field type.
Prefer saved views for recurring queries. A view bundles a filter tree, sort order, and field selection under a stable id. Reference it with ?view=2 rather than re-encoding the same filter on every request. See Table Views.
Grouping & aggregation
groupBy partitions records by a field's value; aggregate computes summary functions. Combine them to produce grouped roll-ups (e.g. total amount per status).
GET /api/tables/orders/records?groupBy=status
GET /api/tables/orders/records?aggregate=sum:amount,count:id,avg:quantity
Each aggregate entry is function:field — supported functions include sum, count, avg, min, and max. When paired with groupBy, aggregates are computed per group.
Saved views
A view (?view=2) applies its stored filter, sort, and field configuration server-side. Explicit query parameters layer on top of the view, letting a client further narrow a base view without redefining it.
tables:
- id: 1
name: tasks
views:
- id: 2
name: Active Tasks
filters:
and:
- field: status
operator: in
value: [todo, in_progress]
sorts:
- field: priority
direction: desc
Including deleted records
By default, soft-deleted rows are excluded. Use includeDeleted=true to merge active and deleted rows, or includeDeleted=only for a trash-only view. See Soft Delete & Restore for the full recovery workflow.
Related pages
- Records Overview — list envelope and cross-cutting rules
- CRUD & Upsert — single-record operations and formatting
- Table Views — saved filter/sort/field configurations
- Soft Delete & Restore — trash queries