Sandbox

Create, find, connect to and control sandboxes, and their lifecycle: wait, suspend, resume, restart, detach and delete.

cua.sandboxes() returns the Sandboxes collection; each sandbox is a Sandbox handle. The same options run locally and in the cloud: on is the switch (local, cloud, direct:<addr>), kind and runtime pick the machine.

Python programs usually use the high-level API instead: cua_sandbox.Sandbox.

A sandbox's id() is its ref, and every call that takes a sandbox name accepts one:

RefMeaning
local:<name>A sandbox on this computer
aws:<name>A sandbox in your own cloud (gcp: and modal: the same way)
direct:<host:port>A computer reached by address
relay:<computer-id>An account computer reached through the relay (a Space)
<name>A bare name, searched across locations; AmbiguousSandbox when it matches more than one

Readiness never assumes a guest agent: the provider reports the sandbox running, then the wait_for probes run, and creation fails fast if the sandbox exits.

Sandboxes#

Creates, finds and manages sandboxes.

Returned by Cua.sandboxes.

MethodDescription
cancel_createCancels the create of the named sandbox name that is still running (in this process or the daemon): the work in flight stops (an image download, a boot) and what the create made is deleted; a sandbox of that name that existed before is never touched.
connectReattaches to a sandbox by ref (local:<name>, cloud:<name>, direct:<host:port>, a legacy id) or by a name that is unique across locations (else AmbiguousSandbox, listing the qualified refs).
connect_urlConnects directly to a machine by URL (http(s)://host:port, bare host:port or a relay URL) with an optional spacesd token.
createCreates (local, your cloud, a provider) or connects (direct) a sandbox and waits for the provider and every readiness probe.
deleteDeletes a sandbox by ref or unique name.
getOne sandbox's info, by ref or unique name.
listSandboxes, each tagged with its location.
list_allDeprecated: Sandboxes.list with no location lists everything.
list_with_warningsSandboxes.list with what the listing left out.
bakeBakes a Docker Compose project into a checkpoint that forks start from with its containers already running: a local VM (by default the docker tier, dockerd up at boot), the project uploaded, docker compose up --wait, the stack checked (every service running or healthy, none restarted) and health commands passed, run commands, then a live memory checkpoint.
checkpointSaves sandbox name's state as checkpoint (memory and disk on a microVM or a QEMU VM; a container's filesystem).
checkpointsEvery checkpoint: this machine's (oldest first), then those your machines that provide Spaces hold, each name once (CheckpointSummary.host).
create_poolCreates a pool: sandboxes of image (and options' shape) kept ready on this machine by cua daemon, so that a create from the pool (SandboxCreateOptions.pool) takes one in about 0.1 s.
delete_checkpointDeletes a checkpoint, here and on every machine of yours that holds a copy (forks made from it keep running).
delete_poolDeletes pool name: its ready sandboxes go; sandboxes created from it stay.
forkStarts name from a sandbox (running or stopped) or a checkpoint.
fork_groupsSandboxes.fork_many for several checkpoints at once: each group (the forks of one checkpoint that belong together) goes to one machine, and groups of different checkpoints spread.
fork_manyForks checkpoint source count times at once and returns the running batch: each fork is reported as soon as it is ready (or failed: one failure does not stop the others).
get_poolPool name, with what it holds now.
list_poolsEvery pool, with what each holds now.
pin_checkpointPins (pinned) or unpins a checkpoint.
prune_checkpointsDeletes every checkpoint that is not pinned (forks made from them keep running); returns their names.
publish_checkpointUploads checkpoint name to fallback (S3, or a folder every machine mounts), so batches on your other machines copy it from there when this machine cannot be reached.

Sandboxes.cancel_create#

Cancels the create of the named sandbox name that is still running (in this process or the daemon): the work in flight stops (an image download, a boot) and what the create made is deleted; a sandbox of that name that existed before is never touched. Finished image downloads stay cached. Returns what was removed, or None when no create of that name was running. The create itself fails with Cancelled.

async def cancel_create(self, name: str) -> Optional[str]
ParameterTypeDefault
nameStringrequired

Returns Option<String> · Async · Raises CuaError (Cancelled)

Sandboxes.connect#

Reattaches to a sandbox by ref (local:<name>, cloud:<name>, direct:<host:port>, a legacy id) or by a name that is unique across locations (else AmbiguousSandbox, listing the qualified refs).

async def connect(self, name: str) -> Sandbox
ParameterTypeDefault
nameStringrequired

Returns Sandbox · Async · Raises CuaError (AmbiguousSandbox)

Sandboxes.connect_url#

Connects directly to a machine by URL (http(s)://host:port, bare host:port or a relay URL) with an optional spacesd token. No daemon is assumed and nothing is probed.

async def connect_url(self, url: str, token: Optional[str], name: Optional[str]) -> Sandbox
ParameterTypeDefault
urlStringrequired
tokenOption<String>required
nameOption<String>required

Returns Sandbox · Async · Raises CuaError

Example

import asyncio
 
import cua
 
async def main():
    sb = await cua.embedded().sandboxes().connect_url(URL, TOKEN, "dev")  # your spacesd's address and token
    guest = await sb.spacesd(None)
    out = await guest.run(cua.SpacesdCommand(program="echo", args=["hi"]))
    print(out.stdout)
 
asyncio.run(main())

Sandboxes.create#

Creates (local, your cloud, a provider) or connects (direct) a sandbox and waits for the provider and every readiness probe. on: "cloud" fails with the "Cua Cloud has ended" error.

async def create(self, options: SandboxCreateOptions) -> Sandbox
ParameterTypeDefault
optionsSandboxCreateOptionsrequired

Returns Sandbox · Async · Raises CuaError

Example

import asyncio
 
import cua
 
async def main():
    c = cua.embedded()
    sb = await c.sandboxes().create(cua.SandboxCreateOptions(
        on="local",                                    # or "aws"
        image=cua.canonical_image("linux", None),
        name="dev",
        wait_for=[cua.ReadinessProbe(service="env")],  # until its spacesd answers
    ))
    guest = await sb.spacesd(None)
    print((await guest.sh("uname -a", None)).stdout.decode())
    await sb.delete()
 
asyncio.run(main())

Sandboxes.delete#

Deletes a sandbox by ref or unique name.

async def delete(self, name: str) -> None
ParameterTypeDefault
nameStringrequired

Async · Raises CuaError

Sandboxes.get#

One sandbox's info, by ref or unique name.

async def get(self, name: str) -> SandboxInfo
ParameterTypeDefault
nameStringrequired

Returns SandboxInfo · Async · Raises CuaError

Sandboxes.list#

Sandboxes, each tagged with its location. None (the default): all of them, local and direct, whatever the default location is. "local" or "direct": only those. Cua Cloud has ended, so "cloud" lists none.

async def list(self, location: Optional[str]) -> List[SandboxInfo]
ParameterTypeDefault
locationOption<String>required

Returns Vec<SandboxInfo> · Async · Raises CuaError

Sandboxes.list_all#

Deprecated: Sandboxes.list with no location lists everything.

async def list_all(self) -> List[SandboxInfo]

Returns Vec<SandboxInfo> · Async · Raises CuaError

Sandboxes.list_with_warnings#

Sandboxes.list with what the listing left out.

async def list_with_warnings(self, location: Optional[str]) -> SandboxListing
ParameterTypeDefault
locationOption<String>required

Returns SandboxListing · Async · Raises CuaError

Sandbox#

A sandbox handle.

Returned by Sandboxes.connect, Sandboxes.connect_url, Sandboxes.create, Sandboxes.fork.

MethodDescription
overlayInjects binaries (see Overlay): each replaces its guest file atomically, is recorded under /var/lib/cua/overlays with its sha256, and what runs it is restarted.
spacesdAttaches to cua-spacesd inside the sandbox (the env service or guest port 3211).
viewer_urlA browser link to this sandbox's desktop in the cua-spacesd HTML5 viewer (/viewer on the env service): video, audio, input, clipboard, file drop and folder sharing, in any modern browser.
agentsCoding agents inside this sandbox (needs cua-spacesd): run a harness over ACP, stream normalized events, follow up, interrupt, collect results; runs outlive this handle.
deleteDeletes (local: removes it; direct: forgets it; your cloud: deletes the machine).
expires_at_unixWhen this sandbox's lifetime ends (Sandbox.set_lifetime), as Unix seconds; None when it has none.
forwardForwards a loopback port to guest port: a TCP forward locally (and over cua-spacesd's tunnel when the image has it).
guest_displayThe guest display without cua-spacesd: the VM's VNC endpoint and a host command that opens it (lume attach).
guest_screenshotCaptures the guest framebuffer as PNG without cua-spacesd.
guest_shRuns line with /bin/sh -c in the guest without cua-spacesd, to completion (default timeout 120 s).
keep_aliveExtends the sandbox's lease by seconds, for a provider that has one.
mcpAn MCP client (the official Rust SDK) for the MCP server behind service at path (default /mcp).
mcp_configWhere the MCP server behind service is (URL of its endpoint at path, default /mcp, plus the headers every request needs), for any MCP client.
open_media_bridgeOpens a media session and returns a loopback WebSocket bridge for a webview (daemon mode).
public_urlA shareable URL for service that stops working after ttl_seconds (60 s to 24 h, default 1 h): a loopback URL with its own token, served by the cua daemon (started if needed; CUA_BIN names the CLI).
refreshFresh info (status from the provider).
resizeGives a local VM another shape: cpus vCPUs, memory_mb MiB of memory and a disk grown to disk_gb GiB (each None keeps it).
restartRestarts.
resumeResumes.
revoke_public_urlRevokes a URL from public_url.
serviceA named service (for example "server" or "env").
set_lifetimeGives this local sandbox a lifetime of seconds from now, replacing any earlier one: the cua daemon then deletes it (on_expire "delete", the default) or suspends it ("suspend"), whether or not this process is still running.
suspendSuspends.
wait_readyWaits until every probe passes.
AccessorReturnsDescription
id()StringQualified ref (local:<name>, cloud:<name>, direct:<host:port>), the same kind of value local and in the cloud; it round-trips through Sandboxes.connect.
image_info()Option<ImageInfo>The image this sandbox runs, as resolved and pinned at create time: the digest and variant that actually ran. None for direct (URL) connections, images not resolved from a registry, and the daemon topology.
info()SandboxInfoInfo as of creation / connection.
is_ephemeral()boolWhether the sandbox is torn down on delete and has no state file.
kind()StringWhat kind of machine: container, vm or microvm (empty when not known).
location()StringWhere it runs: local, cloud, direct or relay.
name()StringName.
runtime()StringThe engine that runs it (gvisor, runc, qemu, lume, kubevirt; empty when not known).
runtime_type()Stringruntime_type.

Sandbox.overlay#

Injects binaries (see Overlay): each replaces its guest file atomically, is recorded under /var/lib/cua/overlays with its sha256, and what runs it is restarted. Local containers go through the container engine; other sandboxes need cua-spacesd and root (or passwordless sudo) in the guest. timeout_ms bounds a cua-spacesd restart (default 180 s).

async def overlay(self, overlays: List[Overlay], timeout_ms: Optional[int] = None) -> List[OverlayResult]
ParameterTypeDefault
overlaysVec<Overlay>required
timeout_msOption<u32>None

Returns Vec<OverlayResult> · Async · Raises CuaError

Sandbox.spacesd#

Attaches to cua-spacesd inside the sandbox (the env service or guest port 3211). Fails with SpacesdNotAvailable when none answers; sandbox lifecycle never depends on it.

async def spacesd(self, probe_timeout_ms: Optional[int]) -> SpacesdClient
ParameterTypeDefault
probe_timeout_msOption<u32>required

Returns SpacesdClient · Async · Raises CuaError (SpacesdNotAvailable)

Sandbox.viewer_url#

A browser link to this sandbox's desktop in the cua-spacesd HTML5 viewer (/viewer on the env service): video, audio, input, clipboard, file drop and folder sharing, in any modern browser. The link carries a scoped viewer ticket, never the sandbox token. Needs cua-spacesd in the sandbox.

async def viewer_url(self, options: Optional[ViewerOptions] = None) -> ViewerLink
ParameterTypeDefault
optionsOption<ViewerOptions>None

Returns ViewerLink · Async · Raises CuaError

SandboxInfo record#

A sandbox as listed.

Returned by Sandbox.info, Sandbox.refresh, Sandboxes.get, Sandboxes.list, Sandboxes.list_all.

FieldTypeDefaultDescription
nameStringName.
kindStringWhat kind of machine: container, vm or microvm (empty when not known: an existing machine).
runtimeStringThe engine that runs it: gvisor, runc, qemu, lume or a provider's own (empty when not known).
runtime_type / runtimeTypeStringruntime_type as persisted (direct, gvisor, qemu, ...); prefer location, kind and runtime.
statusSandboxStatusStatus.
status_detail / statusDetailOption<String>Provider's word for an unknown status.
ephemeralboolNo state file; torn down on delete.
servicesHashMap<String, u16>Declared services: name → guest port (0 = only the name is known).
endpointsHashMap<String, String>Service base URLs by name.
imageOption<String>Image, when known.
idStringQualified ref: local:<name>, direct:<host:port> or <provider>:<name>. Every call that takes a sandbox name accepts it.
phaseSandboxPhasePortable phase: provisioning, starting, ready or stopped.
locationStringWhere it runs: local, direct (a machine by address), relay or a provider.
expires_at_unix / expiresAtUnixOption<i64>When it expires unless kept alive (unix seconds), when known.
provider_details / providerDetailsHashMap<String, String>Provider internals (local: backend, container_id). Not part of the portable API.
image_info / imageInfoOption<ImageInfo>NoneThe image as resolved and pinned at create time (digest, variant). None for direct connections, images not resolved from a registry, and the daemon topology.
stop_reason / stopReasonOption<String>NoneWhy a local sandbox stopped without being asked to, in plain words ("out of memory", "killed", "exited with code 1"); None otherwise.

SandboxListing record#

A sandbox listing and what it left out.

Returned by Sandboxes.list_with_warnings.

FieldTypeDefaultDescription
sandboxesVec<SandboxInfo>Sandboxes, each with its location.
warningsVec<String>Sources left out of the listing.

SandboxPhase enum#

Portable lifecycle phase, the same words on every provider.

SandboxPhase.PROVISIONING
SandboxPhase.STARTING
SandboxPhase.READY
SandboxPhase.STOPPED
VariantDescription
ProvisioningBeing created.
StartingBooting; readiness probes have not passed yet.
ReadyRunning and ready.
StoppedStopped or suspended.

SandboxStatus enum#

Coarse lifecycle status.

SandboxStatus.RUNNING
SandboxStatus.SUSPENDED
SandboxStatus.STOPPED
SandboxStatus.PROVISIONING
SandboxStatus.UNKNOWN
VariantDescription
RunningRunning (or bound).
SuspendedSuspended or scaled to zero.
StoppedStopped.
ProvisioningStarting.
UnknownUnknown; see SandboxInfo.status_detail.

Overlay record#

A binary to inject into a sandbox.

FieldTypeDefaultDescription
nameStringcua-driver, cua-spacesd, or any name (then target is required). Letters, digits, ., _, -.
pathStringThe local file to inject.
targetOption<String>NoneGuest path to replace. Default: resolved for cua-driver and cua-spacesd.
sourceOption<String>NoneProvenance recorded with it (for example the git sha it was built from). Default: the local path.

OverlayResult record#

What an overlay did.

Returned by Sandbox.overlay.

FieldTypeDefaultDescription
nameStringOverlay name.
targetStringGuest path that was replaced.
sha256Stringsha256 (hex) of the injected file (pass it to cua doctor --expect NAME=sha256:<hex>).
previous_sha256 / previousSha256Stringsha256 of the file it replaced, empty when there was none.
sizeu64Bytes.
restartedStringHow the running program was restarted (supervisor:cua-spacesd, systemd:cua-spacesd.service, stopped:<pids>), empty when nothing ran it.

A link to the sandbox desktop in the cua-spacesd HTML5 viewer.

Returned by Sandbox.viewer_url.

FieldTypeDefaultDescription
urlStringOpen this in any modern browser. The credential is in the fragment (#ticket=), which browsers never send to a server.
expires_at_unix / expiresAtUnixi64When the link stops working for new connections (unix seconds).

ViewerOptions record#

Options for Sandbox.viewer_url.

FieldTypeDefaultDescription
ttl_seconds / ttlSecondsOption<u32>NoneLifetime of the link in seconds (60 to 86400). Default 3600.
view_only / viewOnlyboolfalseWatch only: no input, clipboard, files or microphone.
clipboardbooltrueTwo-way clipboard sync.
files_root / filesRootOption<String>NoneGuest directory for uploads and folder sharing (~ is the desktop user's home). None means ~; an empty string turns files off.
microphonebooltrueAllow the microphone (also subject to the sandbox's uplink policy).

contrib_providers_built#

The contrib providers this build includes (empty unless built with the contrib feature).

def contrib_providers_built() -> List[str]

Returns Vec<String>

sandbox_locations#

Every location word on= accepts, in display order: local, cloud, then the contrib providers (e2b, daytona, modal, ...) and your own clouds (aws, gcp, hetzner). A word is listed whether or not this build includes that provider (see contrib_providers_built).

def sandbox_locations() -> List[str]

Returns Vec<String>