Skip to main content
Lifecycle mutations are asynchronous. Create, update, and delete are accepted immediately; the sandbox record then converges, and its state field reports what has actually been observed, never what was merely requested. Poll GET /v1/sandboxes/{id} (or let the CLI wait) until the state you need is observed.

States

Failed and terminated records stay readable through GET /v1/sandboxes/{id} for a retention window, then return 404 not_found.

Create

Create names at most one source, --image or --from <snapshot>; omitting both selects the platform default image. Passing both flags does not name two sources: the snapshot is still the source, and the image is the base its workspace lands on — see restore onto a different image. It returns once the API accepts the request; the CLI then waits until the sandbox is running. Names are unique among the project’s sandboxes that have not finished deleting (1–63 characters, lowercase letters, digits, interior hyphens); a duplicate returns 409 name_conflict. A sandbox still terminating holds its name until it reaches terminated, and a failed or quarantined sandbox keeps its name for as long as its record is retained. Retries are safe: the CLI generates an idempotency key per invocation, or pass --idempotency-key so an automated caller’s retry replays the original sandbox instead of creating another — reuse a name with a fresh key, since replaying the old key returns the original sandbox rather than creating a successor. Pin images by digest when reproducibility matters; a tag is not a stable identity.

TTL

--ttl <seconds> bounds the sandbox lifetime; omitted, the deployment default applies. The record reports the expiry as expires_at. Updating the TTL restarts the clock from the time of the update. Expiry is terminal for the runtime.

Stop and start

Stop seals and stops the workload; start wakes a stopped sandbox and is a no-op on one already running:
The contract: stop is accepted from ready or running and is idempotent from stopped; start wakes stopped and is idempotent from running; a start racing an in-flight stop waits for the stop to win. Anything outside that is refused by state, so a stop can never wedge a sandbox behind a transition nothing completes. Processes and memory are not resumed across a stop: a stop captures the process tree and records that image as the sandbox’s restore point, but a start does not replay it, so the workload begins again from its image (see memory capture). What survives is the sandbox’s identity, its name, and — on the durable storage class — its /workspace, which reattaches to the sandbox when it starts again. Everything outside /workspace comes back from the image. On the default node-bound class, nothing on disk survives either, so treat a stop there as a fresh start with the same identity.

Delete

Delete is permanent and accepted once for any sandbox that still holds resources, failed included; a second delete returns 404 not_found, and a quarantined sandbox refuses with 409 quarantined. It destroys the runtime, its node-bound storage, and the durable workspace volume if the sandbox has one. Snapshots are separate resources and outlive the sandboxes they came from. The deleted sandbox’s name is free to reuse as soon as it reaches terminated, and its record is retained so the project’s history stays readable. A released name no longer addresses that record: commands that take a name resolve it to the sandbox holding it now, and a deleted sandbox is addressed by its id. List them with hiloop sandbox list --all.

Failures

A failed or quarantined sandbox carries a stable state_reason code and a human-readable message. Out-of-band runtime death converges to a terminal state rather than leaving the record running while commands fail. Errors across all routes use a flat {code, message, request_id} envelope with stable codes, for example sandbox_not_running (409), unsupported_capability (422), and quota_exceeded (429, create admission only). See reliability for retry and durability semantics and troubleshooting for diagnosis.