---
summary: Endpoints, authentication, asynchronous operations, pagination and errors
  of the Scuttle v1 API.
title: API
path: reference/api
status: published
---

# API

The Scuttle API manages realms, databases, accounts and grants. Base URL: `https://scuttle.scailabs.ai/api/v1`. Requests and responses are JSON.

## Authentication

Send `Authorization: Bearer <token>`. Automation uses Scuttle API tokens (`sct_...`), created under *API tokens* in the console and scoped to a tenant or a single realm with a role. Tokens are shown once and stored hashed. Console users authenticate through ScaiKey.

## Asynchronous operations

Every change to a database or account answers `202 Accepted` with an `operation` object. Poll `GET /operations/{id}`; `state` moves from `queued` to `running` to `succeeded` or `failed`. A failed operation carries the exact difference between the requested and the observed state in `error`.

## Errors

Errors are RFC 9457 problem documents (`application/problem+json`) with `type`, `title`, `status`, `detail` and a `request_id` to quote in support requests. A resource you have no role on answers `404`, not `403`.

## Pagination

List endpoints take `limit` (default 50, maximum 200) and `cursor`, and return `{items, next_cursor}`.

## Endpoints

| Method and path | Purpose |
|---|---|
| `GET /me` | your principal, tenant and realm roles |
| `GET /myip` | the address Scuttle sees you connecting from, and the `allowed_networks` entry for it (no authentication; `?format=text` for the bare address) |
| `GET /clusters` | clusters with region, service level and endpoint |
| `GET /tenants/{tenant}` | tenant and its quotas |
| `GET /tenants/{tenant}/usage?from=&to=` | daily usage per cluster |
| `GET, POST /tenants/{tenant}/realms` | list, create (`slug`, `display_name`) |
| `GET, PATCH, DELETE /tenants/{tenant}/realms/{realm}` | read, update, delete (only when empty) |
| `GET /tenants/{tenant}/realms/{realm}/members` | list members |
| `PUT, DELETE .../members/{principal}` | set role (`admin`, `operator`, `viewer`), remove |
| `GET, POST .../realms/{realm}/databases` | list, create (`name`, `cluster`, `charset?`, `collation?`) |
| `GET, DELETE .../databases/{name}` | read with connection info; delete (purged after 14 days) |
| `GET, POST .../realms/{realm}/accounts` | list, create (`name`, `cluster`, `grants`, `allowed_networks?` — IPv4 CIDRs and single IPv6 addresses `/128` —, `max_user_connections?`) |
| `GET, PATCH, DELETE .../accounts/{name}` | read; change attributes and grants (full replace); delete |
| `POST .../accounts/{name}:rotate-password` | returns the new password once |
| `GET /operations/{id}`, `GET /tenants/{tenant}/operations` | operation status and history |
| `GET, POST, DELETE /tenants/{tenant}/api-tokens` | list, create (`name`, `role`: `viewer` \| `operator` \| `admin` \| `tenant_admin`, `realm?` to limit it to one realm, `expires_at?`), revoke; the token itself is returned once, on creation |
| `GET /tenants/{tenant}/directory?q=`, `GET .../realms/{realm}/directory?q=` | find users and groups of your tenant by name, e-mail or group name, to grant a role to (tenant admins / realm admins) |
| `GET /tenants/{tenant}/admins`, `PUT, DELETE .../admins/{principal}` | tenant admins (users or groups; `{"principal_type": "user" \| "group"}`) |
| `GET .../databases/{name}/backups` | restorable window and backups |
| `POST .../databases/{name}:restore` | restore into a new database: `{"target": "...", "point_in_time": "..."}` (time optional: latest) |
| `POST .../databases/{name}:export` | build a `.sql.gz` of the database at a point in time (`{"point_in_time": ...}`, optional) |
| `GET .../databases/{name}/exports/{operation_id}` | the export's download link, valid 24 hours (operators) |
| `POST .../databases/{name}:purge-backups` | erase a deleted database's backups now (tenant admins) |

## Grants

A grant is `{"scope": "realm" | "database", "database": "<name>", "profile": "dba" | "readwrite" | "readonly"}`. `PATCH` with `grants` replaces the complete set.

## Quotas

Defaults for `std`: 20 realms per tenant, 50 databases and 50 accounts per realm, 100 connections per account (up to 500), 14 days before a deleted database is purged, 14 days of point-in-time backups.
