Query tasks through the generated API
View as MarkdownThe generated screens from the previous page are clients of mounted table routes. This page uses those routes directly and explains their envelopes, strict query grammar, semantic values, and row boundary. You will discover the task operations, list open tasks, update one priority, and inspect a rejected filter. These calls support scripts, integrations, agent data work, and custom screens that still perform ordinary single-table CRUD.
Show me how to discover the generated tasks API, list open tasks, raise one task's priority, and confirm an invalid filter fails safely.Discover the mounted operations
Section titled “Discover the mounted operations”Generated table operations live under /api/tables/<table>. Inspect the live
contract before constructing a direct request:
pnpm exec sapporta endpoints show "GET /api/tables/tasks"pnpm exec sapporta endpoints show "PUT /api/tables/tasks/{id}"The output shows the actual method, mounted path, authentication boundary, query
or body shape, and declared responses. The discovery step also prevents a common
mistake: generated row updates use PUT, not PATCH.
For a protected local app, use the authenticated Sapporta CLI, an authenticated browser session, or a scoped API token. The examples below use the project-local CLI form for record operations and show the equivalent HTTP exchange.
List open tasks
Section titled “List open tasks”Use the generated row command for a routine filtered read:
pnpm exec sapporta rows list tasks \ --where '{"status":{"eq":"open"}}'The equivalent HTTP request uses the strict filter[column][operator]=value
grammar:
GET /api/tables/tasks?filter[status][eq]=open&page=1&limit=25curl --get keeps the bracketed query readable and URL-encodes it correctly:
curl --get 'http://localhost:3000/api/tables/tasks' \ -H 'Authorization: Bearer <token>' \ --data-urlencode 'filter[status][eq]=open' \ --data-urlencode 'page=1' \ --data-urlencode 'limit=25'List routes return rows and pagination metadata rather than a bare array:
{ "data": [ { "id": 1, "project_id": 1, "title": "Publish launch checklist", "description": "Prepare the release list", "status": "open", "priority": "medium", "due_date": "2026-08-01" } ], "meta": { "total": 1, "page": 1, "limit": 25, "pages": 1 }}Filters, search, sort, lookup, count, and export all run inside the same
row-visibility predicate. Product filters such as status=open narrow the rows
already visible to the request. Clients do not add a workspace filter or submit
workspace, owner, role, or scope fields.
Semantic values retain their JSON types. Select-backed status and priority are
strings. project_id remains a number because the target primary key is a
number. due_date is a canonical YYYY-MM-DD wire string; domain code parses
it into Temporal.PlainDate only at a declared application boundary.
Update one visible row
Section titled “Update one visible row”Update the task through the CLI:
pnpm exec sapporta rows update tasks 1 \ --values '{"priority":"high"}'The corresponding HTTP exchange is:
PUT /api/tables/tasks/1Content-Type: application/json
{ "priority": "high" }{ "data": { "id": 1, "project_id": 1, "title": "Publish launch checklist", "description": "Prepare the release list", "status": "open", "priority": "high", "due_date": "2026-08-01" }}The route applies the update to id = 1 and the request’s row predicate in the
same SQL write. A missing row and a row invisible to the caller both use the
same not-found result, so the endpoint does not disclose whether an inaccessible
identifier exists.
Refresh /tables/tasks after the command. The generated grid reads the same
route and shows the high priority immediately.
Treat rejected queries as caller errors
Section titled “Treat rejected queries as caller errors”The generated query parser rejects unknown columns, unsupported operators, malformed semantic values, invalid pagination, and incomplete filter shapes. For example, this request omits the operator bracket:
GET /api/tables/tasks?filter[status]=openIt returns HTTP 400 with a structured error body:
{ "error": "Filter \"filter[status]\" must use filter[col][op]=value syntax", "code": "unknown_filter_shape"}The caller must correct the query. Retrying after silently dropping the bad predicate can turn a bounded worklist or export into a much larger read.
Ordinary task reads and edits now have one programmatic surface shared with the generated UI. Its envelopes, semantic values, strict filters, and row boundary are predictable after endpoint discovery. A later tutorial step will use an app-owned endpoint when completing a task must update the task and append history atomically. First, continue to Use the task app to load a stable dataset and exercise the complete generated surface. The generated table API guide, table endpoint reference, and query syntax reference cover the remaining generated operations.