# HTTP API

> Resta's HTTP API for creating and deleting databases, issuing database tokens, managing API keys, and taking and restoring backups.

Source: https://resta.dev/docs/api · Updated 2026-11-01

**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](https://resta.dev/docs/clients).

All examples use `https://db.example.com` and `$RESTA_API_KEY`.

## Authentication

```http
Authorization: Bearer blk_...
```

Errors are JSON with a stable code:

```json
{"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`.

```sh
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](https://resta.dev/docs/backups) 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. |
