HTTP API
Resta’s management API lives under /v1 on your server and takes a bearer API key (or a dashboard session); it creates databases, issues tokens for them, and manages API keys and backups. Queries do not go through it: clients send SQL to each database’s URL with a database token. See Connecting from code.
All examples use https://db.example.com and $RESTA_API_KEY.
Authentication
Authorization: Bearer blk_...
Errors are JSON with a stable code:
{"error": {"code": "not_found", "message": "database not found"}}
Databases
| Method and path | Purpose |
|---|---|
POST /v1/databases | Create. Body: {"name": "user-42"}. |
GET /v1/databases?limit=100&after=<name> | List, ordered by name. next in the response is the after for the next page. |
GET /v1/databases/{name} | Details, including size_bytes. |
DELETE /v1/databases/{name} | Delete the database and all its snapshots. Existing tokens stop working. |
Names: 1–40 characters of a-z, 0-9 and -, starting with a letter or digit. Creating an existing name returns 409 already_exists.
curl -X POST https://db.example.com/v1/databases \
-H "Authorization: Bearer $RESTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "user-42"}'
Database tokens
| Method and path | Purpose |
|---|---|
POST /v1/databases/{name}/tokens | Token for one database. |
POST /v1/tokens | Token for every database on the server. |
Body: {"access": "rw" | "ro", "ttl_secs": 3600}. Both fields are optional; the defaults are rw and the longest allowed lifetime (30 days). Response: {"token": "eyJ...", "expires_at": <unix seconds>}.
Tokens are Ed25519-signed JWTs. Resta does not store them, so they cannot be listed or revoked one by one; keep lifetimes short. Deleting a database makes its tokens useless.
API keys
| Method and path | Purpose |
|---|---|
GET /v1/api-keys | List, with last_used_at. Never includes the key itself. |
POST /v1/api-keys | Create. Body: {"name": "production backend"}. The response’s key is shown once. |
DELETE /v1/api-keys/{id} | Revoke. |
Backups
| Method and path | Purpose |
|---|---|
GET /v1/databases/{name}/snapshots | List, newest first: {"snapshots": [{"id": <unix ms>, "size_bytes": n}]}. |
POST /v1/databases/{name}/snapshots | Snapshot now. 409 if the database has never been written. |
POST /v1/databases/{name}/restore | Body: {"snapshot": <id>}; omit to restore the latest. |
See Backups and restore for what restore does.
Account
| Method and path | Purpose |
|---|---|
GET /v1/setup | {"mode": "single", "needs_setup": true} until the account exists. No auth. |
POST /v1/auth/login | Body: {"email", "password"}. Returns a session for the dashboard. Rate limited. |
GET /v1/me | The account and server limits. |
GET /health | ok when the API is up. No auth. |
Common error codes
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Bad name, body or parameter. The message says which. |
| 401 | unauthorized | Missing, unknown or revoked key; expired session. |
| 404 | not_found | No such database or key. |
| 409 | already_exists, conflict | Name taken; nothing to snapshot yet. |
| 429 | rate_limited | Too many login attempts. Wait a minute. |
| 503 | node_unavailable | The data node did not respond. |