API reference
The swarm-server API is HTTPS-only and authenticated with mutual TLS. This reference describes the current wire contract; it is stable in practice but not frozen while Swarm is in beta.
Base and authentication
Section titled “Base and authentication”- Base URL:
https://<server>:8800(whateverlisten_addris). - Authentication: every
/api/*endpoint requires a client certificate signed by the swarm CA.GET /healthzandGET /caare public. - Enrollment:
POST /enrollwith a one-time token and a PKCS#10 CSR returns a CA-signed client certificate. The CLI wraps this asswarm login. - Errors: all non-2xx responses are JSON:
{"error": "<message>"}.
System
Section titled “System”GET /healthz
Section titled “GET /healthz”Liveness probe. Returns version fields.
GET /ca
Section titled “GET /ca”Public. Returns the swarm CA certificate (PEM) — the trust anchor clients pin.
POST /enroll
Section titled “POST /enroll”Mint a client certificate from a one-time token.
Request: {"token": "<one-time-token>", "csr": "<PKCS#10 PEM>"}
Response:
| Field | Type | Description |
|---|---|---|
cert_pem |
string | Signed client certificate (PEM) |
serial |
string | Certificate serial |
cn |
string | Common name |
expires_at |
timestamp | Expiry (365 days) |
ca_pem |
string | The swarm CA certificate (PEM) |
POST /api/enroll-tokens
Section titled “POST /api/enroll-tokens”Mint a fresh one-time enrollment token (requires an enrolled client,
i.e. mTLS). Response: {"token": "...", "expires_at": "..."}.
Wrapped by swarm server token.
GET /api/users
Section titled “GET /api/users”List enrolled users and revocation status. Response:
{"users": [{"serial", "cn", "issued_at", "expires_at", "revoked"}]}.
POST /api/revocations
Section titled “POST /api/revocations”Revoke a client certificate. Request: {"serial": "..."}. Takes
effect immediately.
GET /api/log-level / PUT /api/log-level
Section titled “GET /api/log-level / PUT /api/log-level”Get/set the server log level. Body: {"level": "trace|debug|info|warn|error"}.
Response: {"level": "..."}.
Virtual machines
Section titled “Virtual machines”GET /api/vms
Section titled “GET /api/vms”List VMs. Response: [{"id", "name", "ip", "private_ip", "provider", "status", "bootstrapped", "plan", "zone", "template", "disk_size_gb", "created_at", "container_count"}]. Live status is
refreshed from the provider.
POST /api/vms
Section titled “POST /api/vms”Create a VM.
| Field | Type | Notes |
|---|---|---|
name |
string | Required; display name; hostname derived unless hostname set |
template |
string | OS template UUID |
plan |
string | Plan code (see GET /api/plans) |
zone |
string | Zone code (see GET /api/zones) |
hostname |
string | Optional; valid lowercase hostname/FQDN |
network |
string | Optional; private network to join |
disk_size_gb |
int | Optional; 10–2048; 0 = plan’s storage size |
Response: {"id", "name", "ip", "private_ip", "provider", "status"}.
GET /api/vms/{id}
Section titled “GET /api/vms/{id}”VM details, including provisioning config (plan, zone,
template, disk_size_gb) and live container_count.
DELETE /api/vms/{id}
Section titled “DELETE /api/vms/{id}”Destroy a VM.
POST /api/vms/{id}/bootstrap
Section titled “POST /api/vms/{id}/bootstrap”Re-bootstrap a VM: push the agent binary, restart services.
Catalog
Section titled “Catalog”GET /api/templates
Section titled “GET /api/templates”OS templates. Response: [{"uuid", "title", "zone", "size"}].
Honors a configured default zone unless ?all=1.
GET /api/plans
Section titled “GET /api/plans”Server plans. Response: [{"name", "core_number", "memory_amount", "storage_size", "storage_tier"}].
GET /api/zones
Section titled “GET /api/zones”Datacenter zones. Response: ["fi-hel1", ...].
GET /api/networks
Section titled “GET /api/networks”Private networks available to the account.
Response: {"networks": [{"id", "name", "zone", "server_in"}]}.
Containers
Section titled “Containers”GET /api/containers
Section titled “GET /api/containers”List containers. Response:
[{"id", "vm_id", "vm_name", "alias", "repo", "ref", "status", "container_id", "env_keys", "secrets", "created_at"}]. env_keys
and secrets are key/name surfaces only — values are never returned.
Live Docker status is queried from each VM’s agent.
GET /api/containers/{id}
Section titled “GET /api/containers/{id}”Container details. Accepts ID or alias.
PATCH /api/containers/{id}
Section titled “PATCH /api/containers/{id}”Rename. Request: {"alias": "<new-alias>"}. Aliases must match
[A-Za-z0-9][A-Za-z0-9_-]{0,62} and be unique (409 on conflict).
DELETE /api/containers/{id}
Section titled “DELETE /api/containers/{id}”Remove a container (stops it on the VM, removes from registry).
ANY /api/containers/{id}/proxy/<path>
Section titled “ANY /api/containers/{id}/proxy/<path>”Container HTTP proxy. Forwards to the service inside the container; mTLS-authenticated like the rest of the API. See the proxy guide for the wire contract and error strings.
Deployments (async)
Section titled “Deployments (async)”POST /api/deployments
Section titled “POST /api/deployments”Dispatch a deployment (single or batch).
| Field | Type | Notes |
|---|---|---|
repo |
string | Required; git URL to clone |
ref |
string | Branch/tag/commit; default branch if empty |
vm |
string | Target VM (name or UUID); auto-placement if empty |
count |
int | 1–100; default 1 |
alias |
string | Base alias; numeric suffix when count > 1 |
env |
map | KEY: VALUE; stored server-side, never returned |
secrets |
string[] | Named secret-store entries to inject |
Response (immediate dispatch result):
{"deployment_id": "...", "containers": [...]}.
GET /api/deployments/{id}
Section titled “GET /api/deployments/{id}”Deployment status: {"id", "status", "containers": [{"id", "alias", "vm_id", "vm_name", "status", "container_id", "error"}], "created_at", "updated_at"}. Deployment statuses:
in_progress, completed, partial_failure, failed.
SSH keys (operator VM access)
Section titled “SSH keys (operator VM access)”GET /api/ssh-keys
Section titled “GET /api/ssh-keys”List registered keys. Response: {"keys": [{"name", "key"}]}.
POST /api/ssh-keys
Section titled “POST /api/ssh-keys”Register a key. Request: {"name": "...", "key": "<public key>"}.
Keys are baked into VMs created after registration.
DELETE /api/ssh-keys/{name}
Section titled “DELETE /api/ssh-keys/{name}”Remove a registered key.
Git credentials
Section titled “Git credentials”GET /api/git-credentials
Section titled “GET /api/git-credentials”List. Response: {"credentials": [{"host", "username", "has_token"}]} — tokens are never returned.
POST /api/git-credentials
Section titled “POST /api/git-credentials”Register. Request: {"host": "...", "username": "...", "token": "..."}.
DELETE /api/git-credentials/{host}
Section titled “DELETE /api/git-credentials/{host}”Remove.
Secrets
Section titled “Secrets”GET /api/secrets
Section titled “GET /api/secrets”List. Response: {"secrets": [{"name", "has_value"}]} — values are
never returned.
POST /api/secrets
Section titled “POST /api/secrets”Set (upsert). Request: {"name": "...", "value": "..."}. Names must
be valid env var keys ([A-Za-z_][A-Za-z0-9_]*).
DELETE /api/secrets/{name}
Section titled “DELETE /api/secrets/{name}”Remove.