API reference¶
Private beta
Signups are invite-only. Request an invite. The SDKs are on PyPI and npm; you still need a dashboard API key to call this API.
The REST API is the actual product — the SDKs are thin wrappers over it. Use it directly from any language.
Base URL¶
The SDKs default to this base URL; SISTEMO_BASE_URL overrides it.
Authentication¶
Send your API key as a Bearer token on every request:
See Authentication for scopes (read vs full) and how to create keys.
Send a real User-Agent, or the WAF answers before we do
Cloud sits behind a WAF that refuses some default client user-agents — notably Python's stdlib Python-urllib/x.y. It never reaches the API, so you get a 403 that is not one of ours: content-type: text/plain, the body error code: 1010, and a cf-ray header. Our own 403 is JSON with a code.
Both SDKs already send one (sistemo-python/<version>, @sistemo/sdk), so this only affects hand-rolled clients. Name yours:
req = urllib.request.Request(url)
req.add_header("User-Agent", "my-app/1.0") # anything specific to you
⚠ A generic UA is also worth avoiding for your own sake — it is what you would be throttled with if we ever rate-limit by client.
Conventions¶
- JSON request and response bodies (
Content-Type: application/json). - Timestamps are RFC 3339 / ISO 8601 UTC (
2026-06-23T17:30:43Z). - IDs are UUIDs.
- Errors use HTTP status codes + a JSON body
{ "detail": "...", "code": "..." }. See Errors. - Idempotency — pass an
Idempotency-Keyheader onPOST /v1/machinesto safely retry creates.
Endpoints at a glance¶
| Group | Endpoints |
|---|---|
| Machines | GET/POST /v1/machines, GET /v1/machines/{id}, POST …/stop, …/start, DELETE … |
| Exec | POST/GET/DELETE /v1/machines/{id}/execs |
| Volumes | GET/POST /v1/volumes, POST …/attach, …/detach, DELETE … |
| Snapshots | POST/GET …/snapshots, GET /v1/snapshots, POST …/restore, DELETE … |
| Images | GET /v1/images |
| Activity | GET /v1/activity, GET /v1/machines/{id}/activity |
| Quotas | GET /v1/quotas |
| Billing & usage | GET /v1/billing/{balance,rates,usage,usage/by-resource,usage/series} |
| API keys | GET/POST/DELETE /v1/api-keys (dashboard session only) |
Rate limits¶
Mutating routes are rate-limited per account; exec has its own limit. On 429, back off and retry (see Errors).
Known limits¶
Stated up front so you can design around them rather than discover them:
| Command duration | Default 120 s, max 24 h. Enforced in the machine |
| Command output | 32 MiB per stream, truncated if cut — files |
| File transfer | No file API. Use exec, or let the sandbox fetch over the network |
| Streaming / reconnect | sb.start() / GET …/execs/{id} — long-running |
More in the FAQ.