Update the rows matching a filter
A partial patch of every row matching filters: only the columns in values are written, the rest are left alone. Returns the updated rows as stored.
filters is required and must be non-empty. Paige does not run an unconstrained UPDATE over this API — an empty or missing filter is 400, not a whole-table write. Predicates are AND-joined; up to 20. Ops: eq, neq, gt, gte, lt, lte, is.
like and ilike are read-only and are rejected here (400 filter_op_not_allowed). A pattern match has no bounded row set — like with a % pattern can match the whole table and looks no different from a narrow one — so Paige will not write through one. Read the rows you mean from GET /v1/tables/{table}/rows, then update them by primary key.
values must set at least one column (400 empty_payload).
Primary-key columns cannot be changed (400 primary_key_immutable) — delete the row and insert a replacement instead. Every other column you name is checked against the table’s real columns (400 unknown_column).
A column whose name collides with a reserved database query parameter (select, order, limit, offset, columns, and, or, not, on_conflict) cannot be used as a filter column — the predicate would be silently discarded, so it is refused with 400 reserved_filter_column.
Defaults to the public (production) schema.
A Paige platform table is 403 platform_table_forbidden; an unknown table is 404 table_not_found.
Only base tables are addressable. A view (or any other non-table relation) answers the same 404 table_not_found an unknown name does — including a view defined over a Paige platform table, which would otherwise be a writable alias for it.
Required scope: tables:write
Authorizations
Project API key issued in Settings → API keys. Send it as Authorization: Bearer pk_live_….
Headers
Target project id, for an MCP OAuth bearer (mcp_at_…) attached to more than one project — get ids from GET /v1/projects. Matched case-insensitively.
Omit it and a READ falls back to the connection's default project; a mutation (any non-GET) on a connection with 2+ projects is rejected with 400 project_required — a write is never defaulted to a guessed project. A connection with exactly one project never needs the header.
Scopes are checked against the SELECTED project only, never a union across the connection.
For a pk_ API key the header selects nothing — one key is one project's context — but it IS validated: omit it and the key's own project is used, send it and it must name that project, otherwise the call is rejected with 403 project_not_attached (a blank value is 400 invalid_project_header, as above).
Path Parameters
Table name. Lowercase letters, digits and underscores only. Paige platform tables are rejected.
^[a-z_][a-z0-9_]{0,62}$Body
Columns to set on every matched row, at least one. A partial patch — columns you omit are left unchanged.
Which rows to affect. REQUIRED and non-empty: 1-20 AND-joined predicates. Ops: eq, neq, gt, gte, lt, lte, is — like/ilike are read-only. An unfiltered update or delete is rejected, never executed against the whole table.
Which database schema to target: "public" (production, the default) or "preview" (dev sandbox).
public, preview 