API Reference
ServerBee REST API overview, authentication, WebSocket endpoints, and Swagger UI interactive docs.
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
Open the built-in interactive documentation at:
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:
https://your-server/api-docs/openapi.jsonResponse Format
Successful REST responses are wrapped as:
{
"data": {}
}Application errors use an error code and message, with optional details:
{
"error": {
"code": "BAD_REQUEST",
"message": "Bad request: description of what went wrong"
}
}Authentication
Session Cookie
Used by the web dashboard after login:
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.txtAPI Key
Use API keys for automation. Admin users can create them in Settings → API Keys.
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
Mobile flows use Bearer tokens for selected REST and WebSocket endpoints:
curl https://your-server/api/auth/me \
-H "Authorization: Bearer <session-token>"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
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
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 for verified commands and safeguards.
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
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.
{
"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
This public Agent endpoint authenticates with Authorization: Bearer <enrollment_code> and requires an Agent-generated token:
{ "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
GET /api/servers/{id}/agent-authorityreturnsstatus(claimedorunclaimed) and the currentoutstanding_offer, if any.GET /api/agent-authority/events?server_id={id}&limit=100returns secret-free transition history. Events survive Server deletion.
Offer and authority actions
POST /api/servers/{id}/agent-authority/re-enrollmentwith{ "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/offerswith optional{ "ttl_secs": 600 }issues an offer only when authority is unclaimed.POST /api/servers/{id}/agent-authority/offers/{offer_id}/replacereplaces 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-authorityrevokes 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
| 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
| 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 |