Every table you create is served as a REST API at /rest/v1/<table>. The TypeScript and Python clients build these requests for you; this page is the reference for the HTTP underneath, for other languages, scripts, curl, and anyone who wants to know exactly what goes over the wire. Your environment’s own, generated reference (with your actual tables, fields and rules) is in Studio’s API Explorer.

Headers

Without a signed-in person, requests are evaluated as anonymous against your access rules. A secret key passes every rule. See Keys and security.

Endpoints

For a table named orders: Each operation can be switched off for a table, or given its own access rule, in the table’s Access tab. A switched-off operation isn’t served.

List records

Query parameters

Filter operators

Write a filter as filter[<field>]=<operator>.<value>. A value with no operator means eq: filter[status]=paid. Filtering, sorting or selecting a field the table doesn’t have is refused with 400 bad_request, naming the field. URL-encode values that contain &, #, + or spaces.

The response

With paginate=false, more than 5,000 matches is refused with 400: narrow the filters, or page through. q searches the fields the table lists as search fields (its list operation’s settings). A table without search fields refuses q with a message saying how to turn it on. See Filter.

Relations

expand includes related records by relation name. Each related record is read under its own table’s rules: if the caller may read the order but not its customer, customer comes back null. See Relations.

Fields that aren’t returned

Write-only fields are never returned. Vector fields are left out unless you ask for them with select=embedding (or vectors=true when reading one record), because they’re thousands of numbers.

Read one record

select, expand and vectors work as for lists. A record that doesn’t exist, or that the caller may not read, is 404, so the API never reveals that a hidden record exists.

Create

Answers 201 with the record as stored, including its id and timestamps. If the table has an owner field and the caller is signed in, it’s filled with their user id. Validation failures are 422, with one entry per field; a duplicate unique value is 409 unique_violation.

Change a record

PATCH changes only the fields you send and answers with the record after the change. PUT is accepted too and does the same: it does not clear fields you leave out. A required field can’t be set to null. The update rule is checked against the record as it is now. And for anyone but a secret key, the fields your update rule reads can’t be changed: if the rule is “the owner may update”, the owner_id field can’t be changed, so nobody can hand a record to someone else (403, naming the field). Change such fields from your server with a secret key, or from a flow.

Delete

DELETE answers 204 with no body. If the rule refuses, a signed-in caller gets 403 and an anonymous caller gets 404.

Find by meaning

POST /rest/v1/<table>/similar takes a text (or a vector), and optionally field, metric, limit and max_distance, and returns the closest records with a distance. It follows the table’s list rule and accepts the same filter[…] parameters. See Vector search.

Events and caching

Successful writes emit <table>.created, .updated and .deleted events and invalidate the table’s cached lists. Lists can be cached when the table’s caching is on.

Errors

All error bodies and codes are on Errors.

Versions

/rest/v1 is always your live API. Other API versions are served side by side at /rest/v2 and so on, with the same endpoints and parameters.