Skip to content

REST API (preview)

View Markdown

The REST surface exposes tables as small CRUD resources, without requiring clients to write SQL. Routes are derived from table names and live under /api/.

Preview: The endpoints are available, but the console does not yet expose the full REST_API key and per-table configuration flow. A DB_ACCESS key can use these routes today and is governed by its read and write scopes. Treat this surface as beta.

GET /{org}/{db}/api/{table} list rows
POST /{org}/{db}/api/{table} insert a row
GET /{org}/{db}/api/{table}/{id} fetch one row
PATCH /{org}/{db}/api/{table}/{id} update one row
DELETE /{org}/{db}/api/{table}/{id} delete one row

For org acme and database production, the users table is at https://db.database.pizza/acme/production/api/users.

Per-table method settings can restrict REST_API keys to selected tables and verbs. DB_ACCESS keys bypass those method settings because they already grant SQL access. The console configuration flow for dedicated REST_API keys is not yet available.

Single-row routes (GET/PATCH/DELETE …/{id}) look up rows by an id column, so a table intended for REST access should define id INTEGER PRIMARY KEY.

REST requests use a Bearer API key, exactly like the HTTP query API:

Authorization: Bearer pz_live_REPLACE_ME

Two key types work here:

  • REST_API keys are purpose-built for these endpoints. They are scoped to read and/or write, bound to one database, and further restricted by each table’s method settings.
  • DB_ACCESS keys also work and bypass the per-table method check, since they already carry full SQL scopes.

See API keys & permissions for how to create each.

Terminal window
curl -s "https://db.database.pizza/acme/production/api/users?limit=20&offset=0" \
-H "Authorization: Bearer pz_live_REPLACE_ME"
{
"data": [
{ "id": 1, "name": "Ada Lovelace", "email": "ada@acme.example" }
],
"limit": 20,
"offset": 0
}

Query parameters:

Param Default Notes
limit 100 Max 1000
offset 0
{column} Any other parameter filters by equality, e.g. ?plan=pro

Only column names that exist on the table are accepted as filters; unknown parameters are ignored.

Terminal window
curl -s "https://db.database.pizza/acme/production/api/users/1" \
-H "Authorization: Bearer pz_live_REPLACE_ME"
{ "data": { "id": 1, "name": "Ada Lovelace", "email": "ada@acme.example" } }

Returns 404 when no row matches.

Terminal window
curl -s -X POST "https://db.database.pizza/acme/production/api/users" \
-H "Authorization: Bearer pz_live_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{"name": "Grace Hopper", "email": "grace@acme.example"}'
{ "last_insert_id": 0, "rows_affected": 1 }

Only known columns are accepted; an unknown column is rejected with 400. Omit the id column and it is assigned automatically. last_insert_id is currently always 0, so do not use it to discover the generated value.

Terminal window
curl -s -X PATCH "https://db.database.pizza/acme/production/api/users/2" \
-H "Authorization: Bearer pz_live_REPLACE_ME" \
-H "Content-Type: application/json" \
-d '{"plan": "pro"}'
{ "rows_affected": 1 }

Sends a partial update — only the columns you provide are changed.

Terminal window
curl -s -X DELETE "https://db.database.pizza/acme/production/api/users/2" \
-H "Authorization: Bearer pz_live_REPLACE_ME"
{ "rows_affected": 1 }
Status Meaning
401 Missing or invalid API key
403 Key type doesn’t permit REST access, lacks the read/write scope, or the method isn’t enabled for this table
404 Organization, database, table, or row not found
400 Invalid table name, unknown column, or empty body

The error body is {"error": "…"}. Full troubleshooting is in Errors & troubleshooting.

Use the REST API when you want predictable, single-table CRUD with minimal attack surface (it only ever touches the tables you enable). Use the HTTP query API or PostgreSQL protocol when you need joins, arbitrary SQL, or transactions.