---
title: sherbase
description: The v1 reference for provisioning and managing databases.
---

# sherbase

Base path `/api/sherbase/v1`. See [API reference](/api) for
authentication and the `api.shebang.pro` rewrite.

Every route requires an `shb_...` key or bearer with `base` in scope
(master keys always qualify). `project` behaves exactly as described in
[platform](/api/platform#projects) — provisioning a database, and every
`{slug}` route below, is treated as a write for grant purposes (a `read`
grant on another project can list/fetch its databases but not touch
one).

The **Database** envelope below is what list and create return (each
other route's response shape is documented in its own section):

```json
{
  "slug": "string",
  "ref": "string (= slug)",
  "status": "ACTIVE_HEALTHY",
  "database": { "host": "string", "port": "number", "version": "string" },
  "api_url": "string | null",
  "publishable_key": "string | null",
  "api_enabled": "boolean"
}
```

`api_url` and `publishable_key` are `null` together, exactly when
`api_enabled` is `false`.

### GET /api/sherbase/v1/databases

Lists databases.

- **Auth** — `base` scope.
- **Query params** — `project` (slug, optional).
- **Response** — `200 { "databases": [Database, ...], "project": "slug" }`.
- **Errors** — `403 insufficient_scope`.

### POST /api/sherbase/v1/databases

Provisions a new database, then mints its Data API keys and pushes them
to the gateway. A Data API key-minting or gateway-push failure never
fails the whole call — it's folded into `data_api_error` on the response
and `api_enabled` is flipped back to `false`; the database itself is kept
and retrying via `enable` repairs it.

- **Auth** — `base` scope, write access to the target project.
- **Request body** — `slug` (string, 3–30 lowercase letters/numbers/
  underscores, required), `project` (slug, optional).
- **Response** — `201 { "project": { ...Database, "secret_key"?, "data_api_error"? }, "project_slug": "string" }`.
  `secret_key` is shown exactly once, at creation.
- **Errors** — `400 invalid slug`, `403 insufficient_scope`, plus
  whatever `mapCreateDatabaseError` maps a provisioning failure to (slug
  already taken, quota reached).

### DELETE /api/sherbase/v1/databases/{slug}

Drops a database. Confirm-guarded.

- **Auth** — `base` scope, write access to the database's project.
- **Path params** — `slug`.
- **Request body** — `confirm` (string, required, must equal `slug`).
- **Response** — `200 { "ok": true }`.
- **Errors** — `400` (missing/invalid body, or `confirm` mismatch), `404
  not_found`, `403 insufficient_scope`.

### POST /api/sherbase/v1/databases/{slug}/enable

Opts an existing database into the Data API. Idempotent — a second call
against an already-enabled, already-keyed database returns the existing
publishable key and no `secret_key`.

- **Auth** — `base` scope, write access to the database's project.
- **Path params** — `slug`.
- **Response** — `200 { "slug", "api_url", "publishable_key",
  "api_enabled", "secret_key"?, "data_api_error"? }`.
- **Errors** — `404 not_found`, `403 insufficient_scope`.

### POST /api/sherbase/v1/databases/{slug}/password

Resets the database's connection password.

- **Auth** — `base` scope, write access to the database's project.
- **Path params** — `slug`.
- **Response** — `200` (the new connection details).
- **Errors** — `404 not_found`, `403 insufficient_scope`.

### POST /api/sherbase/v1/databases/{slug}/query

Runs arbitrary SQL against the database (not restricted to `SELECT`, so
this is a write for grant purposes).

- **Auth** — `base` scope, write access to the database's project.
- **Path params** — `slug`.
- **Request body** — `sql` (string, 1–100,000 chars, required — a single
  statement; multi-statement bodies are rejected).
- **Response** — `200` (the query result).
- **Errors** — `400` (empty/oversized `sql`, a Postgres error, or the
  multi-statement guard rejecting the body — surfaced with the
  underlying message), `404 not_found`, `403 insufficient_scope`, `500`
  (a server misconfiguration, e.g. a required environment variable
  unset).

### POST /api/sherbase/v1/databases/{slug}/reload

Reloads the gateway's PostgREST instance for this database, so a schema
change made over a direct Postgres connection becomes visible to the Data
API without a full restart. A no-op `200` where no gateway is configured.

- **Auth** — `base` scope, write access to the database's project.
- **Path params** — `slug`.
- **Response** — `200 { "ok": true }`.
- **Errors** — `404 not_found`, `403 insufficient_scope`, `409
  data_api_disabled` (the gateway has no instance registered for this
  slug — Data API never enabled, or since disabled).

### POST /api/sherbase/v1/databases/{slug}/secret

Rotates the database's Data API secret key — the old one stops working
immediately.

- **Auth** — `base` scope, write access to the database's project.
- **Path params** — `slug`.
- **Request body** — `confirm` (string, required, must equal `slug`).
- **Response** — `200 { "secret_key", "data_api_error"? }`. `secret_key`
  is shown exactly once.
- **Errors** — `400` (missing/invalid body, or `confirm` mismatch), `404
  not_found`, `400 data_api_not_enabled`, `403 insufficient_scope`.

## Next

[agent-login](/api/agent-login) — the device-authorization flow.
