Authentication
Send requests to:Authorization header. Requests
operate within the key’s organization. The following example expects the key in
LITHOSBOX_TOKEN and lists that organization’s sandboxes:
Content-Type: application/json. Fields ending in
_unix_ns use Unix nanoseconds; fields ending in _unix use Unix seconds.
Time-range query parameters use RFC3339 timestamps.
Sandboxes
Create a sandbox
POST /vms returns 201 and a sandbox object. Send {} to use the default
environment, or choose at most one source:
Optional fields are
cpus, memory_mb, runtime, disable_internet,
allow_egress, writable_size_bytes, dataset or datasets, timeout_s, and vm_id. See Limits for valid values.
Template and snapshot restores retain their source configuration.
dataset names a read-only dataset granted to your organization and mounts it at
/datasets/<name>. To attach several, send "datasets": ["a", "b"] instead: up to
10 distinct names, each mounted at /datasets/<name> in the order given. Send one
of dataset or datasets, not both. Send them with image or with neither source;
combining them with template or snapshot_id returns 400. Datasets are fixed
at creation. See Datasets.
allow_egress is a list of destinations the sandbox may still reach, with all
other outbound traffic blocked: hostnames, *. wildcards, and public IPv4
addresses or CIDRs, up to 256. A non-empty list implies disable_internet. A
create from a snapshot without allow_egress keeps the snapshot’s list. See
Outbound network policy.
timeout_s is the sandbox’s lifetime in whole seconds: the sandbox is deleted that
long after its creation, whatever its state, just as DELETE /vms/{id} would. Omit it
for the platform default (no lifetime); 0 asks for none. Values from 0 to 3153600000
(100 years) are accepted; anything else, including a fraction or a string, returns
400. The lifetime is fixed at creation. See Set a lifetime.
Provide a UUID in vm_id and reuse it when retrying the same create request. If
you lose the response, check GET /vms/{id} before issuing a new create. The
Python SDK supplies and reuses an ID automatically within each create call.
Find or delete sandboxes
The sandbox object includes these fields:
Common states are
creating, running, slept, archived, interrupted,
deleting, and failed. Transitions may also report waking, archiving, or
migrating.
Use the state and error response to decide which action is available; see
Lifecycle actions.
Run a command
POST /vms/{id}/exec accepts an argument list:
stdin_b64 for base64-encoded input, with at most 4 MiB of decoded data.
For shell syntax, pass args such as ["sh", "-c", "pwd && ls"].
The response includes exit_code, stdout, stderr, stdout_truncated, and
stderr_truncated. Check the exit code; a successful HTTP response does not mean
the command succeeded. Foreground completion does not imply every child process
has exited. See Run commands for background-job patterns.
Keep a shell session
Use the samesession_id for commands that need shared working-directory and
environment state:
{"session_id": "my-shell", "close_session": true} to the same endpoint.
Sessions have the same synchronous command deadline as ordinary execution.
Lifecycle actions
The HTTP routes for archive and unarchive are
/stop and /start. An archived
sandbox needs an explicit /start; commands do not unarchive it. A sleeping
sandbox wakes on a command or file operation, whether it was slept by /sleep
or by the idle policy.
Reboot returns 409 for an archived sandbox; unarchive first. Restart your
application’s servers after rebooting. See Recovery for
interrupted or unavailable sandboxes.
Fork a sandbox
POST /vms/{id}/branch creates an independent copy and returns 201 with a
sandbox object. You may supply a UUID in child_vm_id for retrying a single fork.
To request several copies from the same point, send {"count": 4}. Counts from
2 to 16 return {"vms": [...]}. Copies count toward the organization’s sandbox limit.
A fork inherits its parent’s datasets; sending dataset or datasets on a fork returns 400.
A fork does not inherit its parent’s lifetime: send timeout_s with the fork to give each
copy one, or omit it for the platform default.
Forks include files and running processes. Fork between commands, and reconnect
external services independently in each copy. See Save, restore, fork.
Outbound network policy
PUT /vms/{id}/egress replaces a sandbox’s outbound policy. The body is the whole
policy; nothing is merged with the previous one:
It returns
200 with disable_internet, allow_egress, and applied.
applied is false for an archived sandbox, which takes the policy when it is
unarchived. Connections the new policy no longer allows are closed. Repeating the
same request is safe.
URLs, ports, paths, IPv6, a bare
*, and private or reserved ranges return 400
naming the entry. DNS in the sandbox answers only listed names. See
Limit outbound network access.
Public endpoints
Use
public_url to access an HTTP server listening on the specified sandbox port.
Leave public_port unset or zero to use the assigned port. Anyone with the URL
can reach the application, so add authentication where needed.
An endpoint on an archived sandbox becomes usable after unarchive. The URL is
preserved, but it may briefly return 404 during reconnection. Deleting the
sandbox makes the endpoint unavailable. See Expose a web service.
Snapshots and exports
Save and manage snapshots
A snapshot object includes
snapshot_id, vm_id, parent_snapshot_id, state,
durable, image, data_bytes, and created_unix_ns. Poll the snapshot until
durable is true before relying on it for recovery or exporting it.
data_bytes is the snapshot’s size in real bytes: all of its data, excluding the
base image and any dataset. It is 0 until the size has been measured, shortly
after the snapshot becomes durable. Storage limits and usage count this size.
The original sandbox keeps running unless you request leave_paused=true (the
field keeps its historical name). That option leaves it sleeping until the next
command or file access, which wakes it automatically.
Restore by sending {"snapshot_id": "YOUR_SNAPSHOT_ID"} to POST /vms.
Restoring creates a new sandbox; deleting the original does not delete its snapshots.
Export a snapshot
An export moves from
pending to ready or failed. When ready, files contains
links for memory.img.zst and disk.img.zst compressed with Zstandard, plus
state.json and manifest.json metadata. Each file entry includes its name, size,
checksum, and download URL. expires_unix gives the export’s expiry time in Unix
seconds; download the files before the links expire.
Exports are for downloading and inspecting saved data. The API does not import an
export to restore a sandbox; use the original snapshot ID for restoration.
Deleting the source snapshot does not revoke a completed export. Delete the
export separately if you want to remove its files before expiry.
Templates
POST /templates creates a reusable environment. name and image are required;
version, cpus, memory_mb, runtime, and disable_internet are optional.
A template has no egress allowlist: a non-empty allow_egress returns 400. Send
allow_egress with each POST /vms that uses the template, or set it later with
PUT /vms/{id}/egress.
Template fields include
template_id, name, version, source_image,
status, status_detail, runtime, base_snapshot_id, created_unix_ns, and
last_used_unix_ns. Wait for status="ready" before creating from the template.
If it becomes failed, read status_detail for the reason.
The list can include read-only shared templates marked shared=true. You can also
look up a shared template ID returned in an image-preparation error. A later create
using the same image can retry preparation if a shared template failed.
Registries
POST /registries stores credentials for a registry and returns 204. For a
username and token or password, use:
host, kind="ecr-assume-role", role_arn, and external_id.
These credentials apply to your organization’s image pulls.
See Private registries for an SDK example
that reads credentials from environment variables.
Activity and metrics
Recent samples contain
at_unix, interval_s, cpu_ms, mem_mb, rx_bytes,
tx_bytes, and state. They cover approximately two hours at 30-second intervals.
History uses minute intervals and accepts hours from 1 to 360, or start and
end as RFC3339 timestamps, up to 15 days back. A point with measured=false
represents a missing measurement.
Events and historical metrics can be queried after sandbox deletion within their
retention periods. Live logs are unavailable for archived sandboxes; reading logs
from a sleeping sandbox does not wake it.
Usage
GET /usage?start=<RFC3339>&end=<RFC3339> returns organization usage, defaulting
to the last 24 hours. A query window can cover up to 32 days.
The response contains start, end, a states array, and storage totals. An
empty states array means no usage was recorded for the window.
Each states entry names a state and sums that state’s usage:
Storage totals are byte-seconds, measured in the real size of your data. Divide
one by the window length in seconds for the average size held:
Real bytes are the only storage size.
snapshot_byte_seconds and
stored_byte_seconds are deprecated and scheduled for removal; do not build on them.
Usage is reported in minute intervals, so short runs and state changes may be
grouped within an interval. Deleted snapshots and exports stop accumulating usage.
Add key=<API key ID> to /usage, /usage/series, /rated-usage, or /audit
to narrow the result to one API key: usage of the sandboxes that key created, or
the records of requests it made. Send key= with an empty value for activity no
API key carried, such as the console. Omit key for the whole organization.
Storage is never attributed to a key.
GET /usage/series?hours= or start=&end= returns a time series for activity charts.
Rated usage
GET /rated-usage?start=<RFC3339>&end=<RFC3339> returns your usage priced by
hour. It covers closed hourly periods whose start falls in the window, defaulting
to the last 24 hours, up to 32 days. The response contains start, end,
rows, rate_cards, totals, and closed_through_unix_ns, the end of the last
closed hour.
totals sums every returned row, corrections included. Each rate_cards entry
gives a card’s version, effective_from_unix_ns, storage_model, and its
rates; disk_nanos_per_gb_month prices disk above disk_free_bytes per sandbox, and
reserved_cpu_nanos_per_vcpu_hour and reserved_memory_nanos_per_gib_hour
are null on a card that prices no reservations. reservations lists your
reservations active in the window: id, vcpus, memory_mb, starts_at_unix,
and ends_at_unix (0 while open-ended). A reservation is billed every hour it
is active and doesn’t reserve placement capacity. total_nanos is what your credit balance is charged for the row.
GET /rated-usage/keys accepts the same window and returns totals plus a
keys array of {"key_id", "totals"}, one per API key that created sandboxes.
The keys’ totals sum exactly to totals. Storage and reservations appear under
the empty key_id, which also holds usage that no API key carried.
Account
Audit
GET /audit?limit=200&before= returns {"records": [...], "next_before": ...}.
Records include id, key_id, action, resource, outcome, request_id, and
at, newest first. Use next_before as the next request’s before value to
continue through older records.
Status codes
Common
409 messages include sandbox is archived (sandbox is stopped)
(unarchive first), sandbox is busy (a sleep was refused because running work
keeps the sandbox awake), a template that is not ready,
or a snapshot with an export in progress. A checkpoint attempt on an
unresponsive sandbox can also return 409 with sandbox agent unreachable.
Match errors on the SDK’s typed exceptions — SandboxArchivedError for the
archived refusal — rather than on message text. Message wording can change; the
state names reported by the API do not. If you must inspect the text, match
archived.
Follow Retry-After for rate-limited requests. x-ratelimit-* headers are advisory
and describe the budget observed by that response. DELETE requests are exempt
from rate limits. See Request rates.