# API Reference

> ServerBee REST API overview, authentication, WebSocket endpoints, and Swagger UI interactive docs.

URL: https://docs.serverbee.app/en/docs/api-reference

ServerBee exposes the same capabilities the web dashboard uses through REST and WebSocket APIs. The authoritative, schema-level reference is generated from OpenAPI annotations in the server binary.

## Swagger UI [#swagger-ui]

Open the built-in interactive documentation at:

```text
https://your-server/swagger-ui/
```

Swagger UI lets you inspect request/response schemas and authentication requirements, and send test requests against your own deployment. The raw OpenAPI document is available at:

```text
https://your-server/api-docs/openapi.json
```

## Response Format [#response-format]

Successful REST responses are wrapped as:

```json
{
  "data": {}
}
```

Application errors use an error code and message, with optional `details`:

```json
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Bad request: description of what went wrong"
  }
}
```

## Authentication [#authentication]

### Session Cookie [#session-cookie]

Used by the web dashboard after login:

```bash
curl -X POST https://your-server/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"your-password"}' \
  -c cookies.txt

curl https://your-server/api/servers -b cookies.txt
```

### API Key [#api-key]

Use API keys for automation. Admin users can create them in Settings → API Keys.

```bash
curl https://your-server/api/servers \
  -H "X-API-Key: serverbee_your-api-key-here"
```

API keys use the `serverbee_` prefix and are shown only once when created. An API key authenticates as its owning user; it is a credential, not a separate role. Requests inherit the owner's current Admin or Member permissions. Only Admin users can create new API keys.

### Bearer Session Token [#bearer-session-token]

Mobile flows use Bearer tokens for selected REST and WebSocket endpoints:

```bash
curl https://your-server/api/auth/me \
  -H "Authorization: Bearer <session-token>"
```

## Public Endpoints [#public-endpoints]

| Method | Path                                                | Description                                                                                                       |
| ------ | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| POST   | `/api/auth/login`                                   | Web login                                                                                                         |
| GET    | `/api/auth/oauth/providers`                         | List enabled OAuth providers                                                                                      |
| GET    | `/api/auth/oauth/{provider}`                        | OAuth authorization redirect                                                                                      |
| GET    | `/api/auth/oauth/{provider}/callback`               | OAuth callback                                                                                                    |
| POST   | `/api/mobile/auth/login`                            | Mobile login                                                                                                      |
| POST   | `/api/mobile/auth/refresh`                          | Refresh a mobile session                                                                                          |
| POST   | `/api/mobile/auth/revoke`                           | Revoke one original mobile session using an installation-scoped deletion-only proof                               |
| POST   | `/api/mobile/auth/recover`                          | Reauthenticate the original account to delete one captured session or confirm its absence, without issuing tokens |
| POST   | `/api/mobile/auth/pair`                             | Redeem a mobile pairing code                                                                                      |
| POST   | `/api/agent/register`                               | Claim a bound enrollment offer with an Agent-proposed run token                                                   |
| GET    | `/api/status/config`                                | Public status page configuration                                                                                  |
| GET    | `/api/status`                                       | Servers included on the public status page                                                                        |
| GET    | `/api/status/servers/{id}`                          | Public detail for an included server                                                                              |
| GET    | `/api/status/servers/{id}/metrics`                  | Public metrics for an included server                                                                             |
| GET    | `/api/status/servers/{id}/uptime-daily`             | Public daily uptime for an included server                                                                        |
| GET    | `/api/status/network`, `/api/status/network/{id}`   | Public network overview and per-server detail                                                                     |
| GET    | `/api/status/ip-quality`                            | Public IP quality overview                                                                                        |
| GET    | `/api/status/incidents`, `/api/status/maintenances` | Public incidents and maintenance windows                                                                          |
| GET    | `/api/settings/brand`                               | Public brand settings                                                                                             |
| GET    | `/api/brand/logo`                                   | Serve uploaded logo                                                                                               |
| GET    | `/api/brand/favicon`                                | Serve uploaded favicon                                                                                            |

Ordinary mobile refresh preserves the installation registration and invalidates the previous access and refresh credentials. Login returns a stable `revocation_token`; the client retains it across refreshes and sends it with `installation_id` to `/api/mobile/auth/revoke` when signing out or discarding permanently rejected credentials. Cleanup uses the original login context even if a replacement login starts while the request is pending. This proof can only delete its original session, credentials, and registration; it cannot authenticate other APIs or refresh a session. Cleanup captures both the saved proof and the original login's current refresh secret before rotation. The saved proof can be absent or stale when an older Server replaced sessions during an iOS-first upgrade. If the saved proof is rejected, the client tries only the captured refresh secret at the deletion endpoint, without adopting a replacement login's credentials. An absent proof is saved before networking. Revocation can verify that secret before consumption; every successful rotation also retains the consumed secret's hash in the same transaction. Verification and deletion are serialized with rotation, so cleanup remains possible whether it reaches the Server before consumption or after a committed response is lost. These retained hashes grant deletion of only the original session and are removed with that session. They never grant ordinary API access or allow reuse of a consumed refresh token. Other installations, users, and replacement logins remain independent.

Recovery through `/api/mobile/auth/recover` uses the same login rate limit and accepts exactly one authentication mode: `username` plus `password` (with `totp_code` when enabled), `pairing_code` from the authenticated web QR pairing flow, or a previously returned `recovery_token`. Password fields are optional for QR/grant mode; mixing modes or supplying TOTP with QR/grant is rejected. The QR code is consumed once by recovery and cannot also be redeemed for a normal login. Account security changes after code generation or grant creation invalidate that authority; password onboarding remains enforced. Every request includes `expected_user_id`, `installation_id`, optional `expected_session_id`, and captured original access/refresh/revocation material. Recovery issues no login tokens. Expired material may identify an original session, but cannot authenticate ordinary requests.

A response contains `outcome`, `user_id`, `installation_id`, nullable `mobile_session_id`, and `candidates`. Outcomes `ok` and `already_absent` confirm cleanup and return no candidates. Without a known ID or matching material, remaining scoped sessions produce `selection_required` with device names, session IDs, creation dates and last-use dates, including expired sessions. No session is selected or removed automatically. The user chooses the original session, and another reauthenticated request uses that exact `expected_session_id`. Absence without an ID is confirmed only when the original account and installation have no remaining operational state. Unattributed state or more than 64 candidates returns 409 without discarding records. Recovery never chooses the newest session or deletes all sessions for an installation.

QR/grant responses also contain a cleanup-only `recovery_token`; password responses omit it. This random grant expires five minutes after creation, is kept only in client memory, and is lost on Server restart. The Server retains at most 128 grants, cleans expired entries, and returns 429 at capacity. It is bound to the original account, installation, and exact captured access/refresh/revocation material, and cannot authorize ordinary login, pairing, refresh or API calls. Reuse it with unchanged captured material for session selection and retries. Selection is restricted to the initially offered candidates and pinned before deletion; retries cannot change the target or broaden the list. A terminal grant retains the exact resolved target until expiry, so lost-response retries confirm only that target’s absence. An ID-less absence grant cannot acknowledge or clean up later replacement state. After restart, expiry, or new state following an ID-less absence, scan a fresh web QR code.

## Authenticated Read Endpoints [#authenticated-read-endpoints]

These endpoints require a user credential. Admin and Member users can use the listed read operations, plus operations that apply only to the signed-in account. API keys receive the same access as their owning users. Admin-only management endpoints are listed separately below.

| Family                       | Representative endpoints                                                                                                                                                                                                                                                                                   |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Current user and credentials | `GET /api/auth/me`, `PUT /api/auth/password`, `GET /api/auth/api-keys`, `DELETE /api/auth/api-keys/{id}`                                                                                                                                                                                                   |
| 2FA and OAuth accounts       | `/api/auth/2fa/*`, `GET/DELETE /api/auth/oauth/accounts/*`                                                                                                                                                                                                                                                 |
| Mobile sessions and devices  | `POST /api/mobile/auth/logout`, `GET /api/mobile/auth/devices`, `DELETE /api/mobile/auth/devices/{id}`, `POST /api/mobile/pair`, `POST /api/mobile/push/register`, `POST /api/mobile/push/unregister`                                                                                                      |
| Servers                      | `GET /api/servers`, `GET /api/servers/{id}`, `GET /api/servers/{id}/records`, `GET /api/servers/{id}/gpu-records`                                                                                                                                                                                          |
| Agent Authority              | `GET /api/servers/{id}/agent-authority`, `GET /api/agent-authority/events?server_id={id}`                                                                                                                                                                                                                  |
| Groups and tags              | `GET /api/server-groups`, `GET /api/servers/{id}/tags`                                                                                                                                                                                                                                                     |
| Uptime and traffic           | `GET /api/servers/{id}/uptime-daily`, `GET /api/servers/{id}/traffic`                                                                                                                                                                                                                                      |
| GeoIP                        | `GET /api/geoip/status`                                                                                                                                                                                                                                                                                    |
| Ping tasks                   | `GET /api/ping-tasks`, `GET /api/ping-tasks/{id}/records`                                                                                                                                                                                                                                                  |
| Network probes               | `GET /api/network-probes/targets`, `GET /api/network-probes/setting`, `GET /api/network-probes/overview`, `GET /api/servers/{id}/network-probes/targets`, `GET /api/servers/{id}/network-probes/records`, `GET /api/servers/{id}/network-probes/summary`, `GET /api/servers/{id}/network-probes/anomalies` |
| Traceroute results           | `GET /api/servers/{id}/traceroute/{request_id}`                                                                                                                                                                                                                                                            |
| Docker, read-only            | `GET /api/servers/{id}/docker/containers`, `stats`, `info`, `events`, `networks`, `volumes`                                                                                                                                                                                                                |
| Service monitors             | `GET /api/service-monitors`, `GET /api/service-monitors/{id}`, `GET /api/service-monitors/{id}/records`                                                                                                                                                                                                    |
| Status page config           | `GET /api/status-page`                                                                                                                                                                                                                                                                                     |
| Dashboards                   | `GET /api/dashboards`, `GET /api/dashboards/default`, `GET /api/dashboards/{id}`                                                                                                                                                                                                                           |
| Cost insights                | `GET /api/cost/overview`, `GET /api/servers/{id}/cost-insights`                                                                                                                                                                                                                                            |
| Alert events                 | `GET /api/alert-events`, `GET /api/alert-events/{alert_key}`                                                                                                                                                                                                                                               |

## Admin Write and Management Endpoints [#admin-write-and-management-endpoints]

The following management and host-control operations require Admin. Operations listed above that apply only to the signed-in account remain available to authenticated Member users.

| Family                   | Representative endpoints                                                                                                                                                                                                        |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API key creation         | `POST /api/auth/api-keys`                                                                                                                                                                                                       |
| Server management        | `POST /api/servers` (idempotent onboarding), `PUT/DELETE /api/servers/{id}`, `POST /api/servers/{id}/upgrade`                                                                                                                   |
| Agent Authority          | re-enrollment, offer issue/replace/revoke, and authority revocation under `/api/servers/{id}/agent-authority/*`                                                                                                                 |
| Groups and tags          | `POST /api/server-groups`, `PUT/DELETE /api/server-groups/{id}`, `PUT /api/servers/{id}/tags`                                                                                                                                   |
| Ping and network probes  | `POST /api/ping-tasks`, `PUT/DELETE /api/ping-tasks/{id}`, `POST /api/network-probes/targets`, `PUT/DELETE /api/network-probes/targets/{id}`, `PUT /api/network-probes/setting`, `PUT /api/servers/{id}/network-probes/targets` |
| Traceroute               | `POST /api/servers/{id}/traceroute`                                                                                                                                                                                             |
| Files                    | All `/api/files/*` endpoints, including list, stat, read, download, transfer management, and file changes                                                                                                                       |
| Docker actions           | `POST /api/servers/{id}/docker/containers/{cid}/action`                                                                                                                                                                         |
| Service monitors         | `POST /api/service-monitors`, `PUT/DELETE /api/service-monitors/{id}`, `POST /api/service-monitors/{id}/check`                                                                                                                  |
| Dashboards               | `POST /api/dashboards`, `PUT/DELETE /api/dashboards/{id}`                                                                                                                                                                       |
| Brand appearance         | `PUT /api/settings/brand`, `POST /api/settings/brand/logo`, `POST /api/settings/brand/favicon`                                                                                                                                  |
| Status page              | `PUT /api/status-page`                                                                                                                                                                                                          |
| Incidents                | `GET/POST /api/incidents`, `PUT/DELETE /api/incidents/{id}`, `POST /api/incidents/{id}/updates`                                                                                                                                 |
| Maintenance windows      | `GET/POST /api/maintenances`, `PUT/DELETE /api/maintenances/{id}`                                                                                                                                                               |
| Alerts and notifications | Manage `/api/alert-rules`, `/api/notifications`, `/api/notification-groups`, and their `/{id}` routes                                                                                                                           |
| Tasks                    | `GET/POST /api/tasks`, `GET/PUT/DELETE /api/tasks/{id}`, `GET /api/tasks/{id}/results`, `POST /api/tasks/{id}/run`                                                                                                              |
| Users                    | `GET/POST /api/users`, `GET/PUT/DELETE /api/users/{id}`                                                                                                                                                                         |
| Audit and settings       | `GET/DELETE /api/audit-logs`, `GET/PUT /api/settings`, `POST /api/settings/backup`, `POST /api/settings/restore`                                                                                                                |
| GeoIP                    | `POST /api/geoip/download`                                                                                                                                                                                                      |

The backup endpoint returns a raw SQLite download. Restore accepts a raw SQLite body with `Content-Type: application/octet-stream` and requires a Server restart. Both are Admin-only, high-risk operations; see [Backup and Restore](/en/docs/deployment#backup-and-restore) for verified commands and safeguards.

## Agent Authority and Enrollment [#agent-authority-and-enrollment]

Responses follow the standard `{ "data": ... }` envelope. Agent Authority management requires Admin; state and event history are authenticated read endpoints.

### `POST /api/servers` -- Onboard a Server [#post-apiservers----onboard-a-server]

Creates the Server profile and its initial bound offer atomically. `onboarding_request_id` is required and is scoped to the authenticated actor. Retrying the same ID with identical normalized input returns the same `server_id`; reusing it with different input returns `409 ONBOARDING_IDEMPOTENCY_CONFLICT`.

```json
{
  "onboarding_request_id": "019f...",
  "name": "edge-tpe-1",
  "tags": ["production"],
  "ttl_secs": 600
}
```

A new operation returns `replayed: false` and `enrollment: { id, code, code_prefix, expires_at }`. A replay returns `replayed: true`, never returns plaintext `code`, and may return `outstanding_offer` metadata.

### `POST /api/agent/register` -- Claim an offer [#post-apiagentregister----claim-an-offer]

This public Agent endpoint authenticates with `Authorization: Bearer <enrollment_code>` and requires an Agent-generated token:

```json
{ "proposed_run_token": "<32-or-more non-whitespace characters>" }
```

On success it consumes the offer, stores only the run-token hash, and returns `{ "data": { "server_id": "..." } }`. The Server never returns the plaintext run token.

### Agent Authority state and history [#agent-authority-state-and-history]

* `GET /api/servers/{id}/agent-authority` returns `status` (`claimed` or `unclaimed`) and the current `outstanding_offer`, if any.
* `GET /api/agent-authority/events?server_id={id}&limit=100` returns secret-free transition history. Events survive Server deletion.

### Offer and authority actions [#offer-and-authority-actions]

* `POST /api/servers/{id}/agent-authority/re-enrollment` with `{ "mode": "graceful" | "emergency", "ttl_secs": 600 }` starts re-enrollment for a claimed authority. Graceful keeps the old authority valid; emergency revokes and fences it immediately.
* `POST /api/servers/{id}/agent-authority/offers` with optional `{ "ttl_secs": 600 }` issues an offer only when authority is unclaimed.
* `POST /api/servers/{id}/agent-authority/offers/{offer_id}/replace` replaces exactly the current outstanding offer and returns new plaintext once.
* `DELETE /api/servers/{id}/agent-authority/offers/{offer_id}` revokes exactly that offer.
* `DELETE /api/servers/{id}/agent-authority` revokes the current authority and disconnects its Agent without issuing an offer.

Only one offer may be outstanding per Server. Its terminal outcome is exactly one of `consumed`, `revoked`, `replaced`, or `expired`. Exact-ID replacement is compare-and-swap: stale or terminal offers return `409` and cannot overwrite newer state.

## WebSocket Endpoints [#websocket-endpoints]

| Path                              | Auth                                                      | Description                                                              |
| --------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------ |
| `/api/agent/ws`                   | Agent Bearer token (`?token=` accepted for legacy Agents) | Agent metrics, commands, pings, files, Docker, traceroute                |
| `/api/ws/servers`                 | Session cookie, API key, or Bearer token                  | Browser/mobile real-time server updates                                  |
| `/api/ws/terminal/{server_id}`    | Authenticated Admin + `CAP_TERMINAL`                      | Web terminal proxy; JSON text messages with terminal data base64-encoded |
| `/api/ws/docker/logs/{server_id}` | Authenticated Admin + `CAP_DOCKER`                        | Per-container Docker log streaming                                       |

## Common Status Codes [#common-status-codes]

| Code | Meaning                                                                 |
| ---- | ----------------------------------------------------------------------- |
| 400  | Bad request or invalid operation                                        |
| 401  | Not authenticated                                                       |
| 403  | Forbidden: role, capability, or local agent policy blocks the operation |
| 404  | Resource not found, server offline, or disabled public page             |
| 409  | Conflict, such as duplicate slug/name                                   |
| 422  | Validation error                                                        |
| 429  | Rate limited                                                            |
| 500  | Internal server error                                                   |

<Cards>
  <Card title="Capabilities" href="/en/docs/capabilities" />

  <Card title="Admin Guide" href="/en/docs/admin" />

  <Card title="Architecture" href="/en/docs/architecture" />
</Cards>
