API
The API is Bitsmith’s stable HTTP surface: REST endpoints for the resources the server manages: virtual machines, LXC containers, apps, folders, connected storage, the reverse proxy, and sandboxes. MCP exposes the same operations to agent clients; the API complements it for integrations that are not MCP clients: scripts, server-side services, and anything that can send a bearer token. Both transports use the same agent tokens, the same scopes, and the same activity log, so a token you create works on both with no extra setup.
Endpoints
Section titled “Endpoints”The API lives under /api/v1/ and authenticates with
Authorization: Bearer <token>, where the token is one you created on the
Access tokens page (System, Agent access).
Resources follow standard REST conventions:
GET /api/v1/vmslists the collection,POST /api/v1/vmscreates one.GET /api/v1/vms/12reads an item by its path parameter;PATCHupdates,DELETEremoves.- Actions live on the item as sub-paths:
POST /api/v1/vms/12/start,POST /api/v1/vms/12/exec,POST /api/v1/vms/12/template. - Every domain has the same shape:
/api/v1/lxc,/api/v1/apps,/api/v1/folders,/api/v1/locations,/api/v1/proxy,/api/v1/sandboxes, plus/api/v1/system,/api/v1/activity,/api/v1/peers, and/api/v1/tasks.
Path parameters are part of the URL and always named id or the natural
sub-resource name (image_id, sub_path). A path parameter fills the
operation’s argument of the same name; for example, the {id} in
/api/v1/vms/{id} is the VM ID. The rest of an operation’s arguments go
in the JSON body for POST, PATCH, and PUT, and in the query string for
GET and DELETE. peer_id works in either place, wherever the operation
accepts it.
The full listing for this release (every endpoint, its method and path, its
summary, its scope, and the JSON schema of its arguments) is generated in the
API reference. The catalog is defined by
your server build, so GET /api/v1/catalog remains the authoritative source
for what a given server can do: read it when in doubt.
The plain-HTTP listener answers these paths directly rather than redirecting
to HTTPS, for the same reason it does for /mcp: plain curl and integration
code cannot click through a self-signed certificate.
Examples
Section titled “Examples”List the virtual machines:
curl -s http://<your-server>/api/v1/vms -H "Authorization: Bearer $TOKEN"Create a folder:
curl -s -X POST http://<your-server>/api/v1/folders \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"storage_id": "tank", "name": "agent-inbox"}'Start VM 12:
curl -s -X POST http://<your-server>/api/v1/vms/12/start \ -H "Authorization: Bearer $TOKEN"Read the live catalog:
curl -s http://<your-server>/api/v1/catalog -H "Authorization: Bearer $TOKEN"Calling a paired server
Section titled “Calling a paired server”Operations that act on a single server accept an optional peer_id argument,
in the body or the query string, that routes the call to a paired server. The
peer runs it with your token’s scopes forwarded across; leave the argument out
to target the server you called.
Errors
Section titled “Errors”Every error comes back as {"error": "..."} with a status code:
| Status | Meaning |
|---|---|
400 | The body is not a JSON object, or an argument does not fit the schema. |
401 | No token, or a token that does not match. |
403 | The token lacks the scope the endpoint needs. |
404 | The path is not an endpoint this server offers, or the resource it names does not exist. |
405 | Wrong method for the path; the Allow header lists the valid ones. |
409 | The resource’s state blocks the call, such as changing a running VM. |
413 | The request body is over 1 MiB. |
500 | The call failed in a way that has no specific code; the error text names what happened. |
502 | The call was routed to a paired server that failed to run it. |
503 | A host dependency such as the VM runtime is unavailable. |
How calls are recorded
Section titled “How calls are recorded”Every mutating call writes one row to the
Activity log, attributed to the token’s
name, exactly as an MCP call would. The row’s metadata records which transport
it arrived on: mcp, api, or cluster (the peer that ran a forwarded call).
Read-only calls are not recorded.