SandboxREST APISandboxes and GPU routes

Sandboxes and GPU routes

Create and manage sandboxes, their snapshots, branches and egress rules, and attach GPU leases.

Every route is on https://sandbox.tangle.tools and takes your account API key as Authorization: Bearer <key> unless it says otherwise. Errors use the shape in Error codes. This page is generated from the OpenAPI document, which also has every response schema.

Sandboxes

RouteDoes
POST /v1/sandboxesCreate a new sandbox
GET /v1/sandboxesList sandboxes
GET /v1/sandboxes/admissionCheck whether the default placement pool can admit a new sandbox
POST /v1/sandboxes/batch/runRun multiple tasks in parallel
POST /v1/sandboxes/delete-matchingDelete every sandbox whose metadata matches
GET /v1/sandboxes/runs/{run}List the sandbox compute generations created for a caller run
GET /v1/sandboxes/self/identityGet the ID of the calling sandbox
GET /v1/sandboxes/{id}Get sandbox details
DELETE /v1/sandboxes/{id}Delete a sandbox
POST /v1/sandboxes/{id}/branchBranch a running sandbox into copy-on-write children
GET /v1/sandboxes/{id}/driverGet sandbox driver info
PATCH /v1/sandboxes/{id}/egressUpdate sandbox egress policy
GET /v1/sandboxes/{id}/egress/activityList the hosts a sandbox reached
GET /v1/sandboxes/{id}/egress/denialsList recent egress denials
GET /v1/sandboxes/{id}/egress/usageGet a sandbox’s egress for a calendar month
GET /v1/sandboxes/{id}/env-recoveryRead caller credential recovery policy
PUT /v1/sandboxes/{id}/env-recoveryReplace or dry-run a stopped sandbox’s caller resupply policy
GET /v1/sandboxes/{id}/eventsSubscribe to sandbox events (SSE)
POST /v1/sandboxes/{id}/imagesPublish the sandbox workspace as an image
GET /v1/sandboxes/{id}/mcpGet an MCP endpoint for this sandbox
POST /v1/sandboxes/{id}/native-credentialsInstall a native CLI credential in a sandbox
GET /v1/sandboxes/{id}/operations/{operationId}Get an accepted stop, snapshot or delete
GET /v1/sandboxes/{id}/placement-attestationRead verified HIPAA placement evidence
POST /v1/sandboxes/{id}/rebuildRebuild a stopped sandbox runtime
POST /v1/sandboxes/{id}/resumeResume a stopped sandbox
POST /v1/sandboxes/{id}/rolloutsFork a running agent sandbox N ways and run the same turn in each
GET /v1/sandboxes/{id}/rollouts/{rolloutId}Poll a rollout’s status and scored per-child results
GET /v1/sandboxes/{id}/runtime/{path}Send a GET request to the sandbox runtime
HEAD /v1/sandboxes/{id}/runtime/{path}Send a HEAD request to the sandbox runtime
POST /v1/sandboxes/{id}/runtime/{path}Send a POST request to the sandbox runtime
PUT /v1/sandboxes/{id}/runtime/{path}Send a PUT request to the sandbox runtime
PATCH /v1/sandboxes/{id}/runtime/{path}Send a PATCH request to the sandbox runtime
DELETE /v1/sandboxes/{id}/runtime/{path}Send a DELETE request to the sandbox runtime
POST /v1/sandboxes/{id}/scoped-tokenMint a scoped consumer-side token for direct sandbox access
POST /v1/sandboxes/{id}/snapshotCreate a snapshot of sandbox state
POST /v1/sandboxes/{id}/snapshotsCreate a snapshot of sandbox state
GET /v1/sandboxes/{id}/snapshotsList snapshots for a sandbox
GET /v1/sandboxes/{id}/snapshots/jobs/{jobId}Get sandbox snapshot restore job status
DELETE /v1/sandboxes/{id}/snapshots/{snapshotId}Delete a sandbox snapshot
POST /v1/sandboxes/{id}/snapshots/{snapshotId}/restoreRestore a sandbox from a snapshot
POST /v1/sandboxes/{id}/stopStop a sandbox (keeps state)
GET /v1/sandboxes/{id}/traceExport sandbox trace and intelligence envelope
POST /v1/sandboxes/{id}/workspace-operations/lookupLook up an idempotent workspace operation
GET /v1/shapesList sandbox shape presets and the caller’s ceiling

Create a new sandbox

POST /v1/sandboxes

Request body (application/json):

FieldTypeRequiredDescription
namestringNo
ownerContext”inherit” | “isolated”No
funding”wallet” | “referral_credit”No
driverobjectNo
runtime”docker” | “firecracker”No
environmentstringNo
gitobjectNo
cwdobjectNo
barebooleanNo
agentbooleanNo
requireNativeSessionCapturebooleanNo
sessionCapture”discard”No
skipWarmPoolbooleanNo
capacityClass”spare_only”No
confidentialobjectNo
envobjectNo
envRecoveryobjectNo
resourcesobjectNo
gpuLeaseobjectNo
backendobjectNo
sshEnabledbooleanNo
sshPublicKeysarray of objectNo
sshKeyIdsarray of objectNo
webTerminalEnabledbooleanNo
proxySecretsobjectNo
secrets”all” or array of object or nullNo
maxLifetimeSecondsnumberNo
idleTimeoutSecondsnumberNo
coldTimeoutSecondsintegerNo
deleteAfterStoppedSecondsintegerNo
retainobjectNo
metadataobjectNo
storageobjectNo
ephemeralbooleanNo
fromSnapshotstringNo
fromSandboxIdstringNo
startupScriptIdsarray of objectNo
teamIdstringNo
capabilitiesarray of objectNo
privacyobjectNo
complianceobject or array of objectNo
egressPolicyobjectNo
templateIdstringNo
publicTemplateIdstringNo
publicTemplateVersionIdstringNo
idempotencyKeystringNo
billingOwnerIdstringNo
StatusMeaning
201Sandbox created
400Invalid request
401Platform refused the caller’s credential
402Subscription inactive
403Driver not allowed, platform refused authorization, PROFILE_SECRET_ISOLATION_UNAVAILABLE: a new sandbox cannot declare backend.metadata.profileSecretIsolation; declare it on a session of a running sandbox, or COMPLIANCE_NOT_ENTITLED: the body asks for compliance.hipaa but the caller’s credential carries no HIPAA entitlement
404Template not found
409Template artifact not ready
413Request payload too large or restore snapshot exceeds its quota
422GIT_CLONE_REFUSED: the repository refused the clone’s credentials. Terminal: a retry with the same Idempotency-Key answers the same refusal. PROFILE_FILE_MOUNT_OUTSIDE_ROOTS: a backend.profile.resources.files path is outside the sandbox’s writable roots; path names it. Terminal, answered before provisioning
429Quota exceeded
500Internal error
501Templates not configured
502Upstream service failed
503Dependent service unavailable, or COMPLIANCE_CELL_UNAVAILABLE: the selected, source or recorded placement pool does not admit the caller’s current compliance entitlement, or no enabled HIPAA-designated placement pool can take the create now (none configured, disabled, down or full); it was not placed in any other placement pool. Retry-After is set

List sandboxes

GET /v1/sandboxes

ParameterInRequiredTypeDescription
resolveCreatequeryNo”true” | “false”
expectedCellIdqueryNostring
billingOwnerIdqueryNostring
statusqueryNo”pending” | “provisioning” | “running” | “stopped” | “failed” | “expired” | “deleted” or array of “pending” | “provisioning” | “running” | “stopped” | “failed” | “expired” | “deleted”
limitqueryNointeger or null
offsetqueryNointeger or null
scopequeryNostring
runqueryNostring
StatusMeaning
200List of sandboxes
400Invalid create-resolution identity or scope
403Sandbox credential cannot list account-wide sandboxes
503A sandbox backend or create-resolution billing authority did not answer; retry

Check whether the default placement pool can admit a new sandbox

GET /v1/sandboxes/admission

ParameterInRequiredTypeDescription
runtimequeryNo”docker” | “firecracker”
roomqueryNo”true” | “false”
runtimeBackendqueryNo”docker” | “firecracker”Deprecated on 2026-11-05 and removed from current SDK releases: send runtime and omit driver.
billingOwnerIdqueryNostring
routingqueryNo”true” | “false”
ownerIdqueryNostring
StatusMeaning
200Read-only admission snapshot; a ready result does not reserve a host
403Sandbox-bound credentials cannot inspect placement pool admission, or the caller may not bill the named billingOwnerId
503Admission state could not be checked

Run multiple tasks in parallel

POST /v1/sandboxes/batch/run

Without Idempotency-Key, disconnecting stops the batch. With a key, the exact-body run continues and later matching requests join or replay it. Persistent reuseKey selects stable workspaces independently.

ParameterInRequiredTypeDescription
Idempotency-KeyheaderNostringOpt-in retry identity. The keyed batch continues after disconnect; matching retries join or replay it.

Request body (application/json): one of 2 shapes; see the OpenAPI document.

StatusMeaning
200SSE stream of batch progress
400Invalid batch request
401Authentication required or invalid
403Caller is not allowed to run the batch
409Retry identity or persistent workspace state conflicts
413Batch request payload is too large
429Batch rate, concurrency, or capacity limit exceeded
500Batch execution failed
502Sandbox service request failed
503Batch service or compute capacity is unavailable
504Sandbox service request timed out

Delete every sandbox whose metadata matches

POST /v1/sandboxes/delete-matching

Deletes the caller’s own sandboxes whose metadata values start with the given prefixes, at most 25 per call in ID order, and reports each one. When matches remain, pass next as after to attempt them. Repeating the call is safe: a confirmed-gone sandbox no longer matches. Stop creating matching sandboxes before calling, and call again once in-flight creates have settled: complete covers only the sandboxes this call listed.

Request body (application/json):

FieldTypeRequiredDescription
metadataPrefixobjectYesMetadata key to required value prefix. A sandbox matches when every named key holds a string value that starts with its prefix.
cascadebooleanNo
until”removed”No
afterstringNo
StatusMeaning
200Per-sandbox delete results
400Invalid request
403Sandbox credential cannot select account-wide deletes

List the sandbox compute generations created for a caller run

GET /v1/sandboxes/runs/{run}

ParameterInRequiredTypeDescription
runpathYesstring
limitqueryNointegerGenerations per page (default 1000).
cursorqueryNostringThe nextCursor of the previous page.
StatusMeaning
200Generations created for the run, oldest first
400The cursor is malformed
403Sandbox credential cannot read account-wide sandboxes
501This runtime does not index generations by caller run

Get the ID of the calling sandbox

GET /v1/sandboxes/self/identity

Needs a credential bound to one sandbox. An account API key gets 403: select the sandbox by ID instead. The response is not cached.

StatusMeaning
200ID of the sandbox the credential is bound to
401No authenticated caller (UNAUTHORIZED)
403The credential is not bound to a sandbox (SANDBOX_SELF_UNBOUND)

Get sandbox details

GET /v1/sandboxes/{id}

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
StatusMeaning
200Sandbox details
400Invalid request
403Driver not allowed
404Sandbox not found
500Internal server error

Delete a sandbox

DELETE /v1/sandboxes/{id}

Deletes the sandbox. A sandbox with live branch children is refused (409 CHILDREN_EXIST) unless cascade=true, which deletes the whole lineage children-first. Platform-managed snapshot repositories are reclaimed after the deleted-retention window for internal accounts only; customer repositories remain until explicitly deleted by their owner. Preservation holds and active exports/restores are honored. With wait=false it may instead answer 202 as soon as the delete is durably accepted: poll operation.statusUrl (or Location) until the operation is succeeded (with result.deleted) or failed. The runtime runs and bills until the delete kills it. An Idempotency-Key names the delete for a retry whose 202 was lost. With until=removed, that status URL keeps polling through physical reclaim. Cascades keep the synchronous answer; a 200 means the delete finished.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
retireCreatequeryNo”true” | “false”
runqueryNostring
expectedCellIdqueryNostring
billingOwnerIdqueryNostring
cascadequeryNo”true” | “false”
untilqueryNo”removed”
waitqueryNo”true” | “false”
StatusMeaning
200Sandbox deleted, or already absent
202Delete accepted (wait=false); it finishes in the background. Or create retirement is pending
400Invalid request
403Driver not allowed
404Sandbox not found
409Sandbox has live branch children, lacks a confirmed final snapshot, could not prove absence, is under an operator retention hold, or its Idempotency-Key names a different delete
500Delete failed
503Sandbox billing state is temporarily unavailable

Branch a running sandbox into copy-on-write children

POST /v1/sandboxes/{id}/branch

Forks a RUNNING sandbox’s live memory into count copy-on-write children that share the parent’s pages at branch time (Firecracker UFFD copy-on-write). The parent stays running. Fails loud when the active driver cannot branch live memory; it never degrades to fresh, empty sandboxes.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
Idempotency-KeyheaderNostringOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.

Request body (application/json):

FieldTypeRequiredDescription
countintegerNo
envobjectNo
metadataobjectNo
idempotencyKeystringNoOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.
StatusMeaning
200Children materialized, or the stored result of an earlier branch
400Invalid request
403Driver not allowed
404Sandbox not found
409Another request holds this idempotency key, or the key is bound to a different request body
429Concurrent session limit exceeded, or the operation ledger is full
500Internal server error
503Active driver does not support live branching

Get sandbox driver info

GET /v1/sandboxes/{id}/driver

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
StatusMeaning
200Driver info
400Invalid request
403Driver not allowed
404Sandbox not found
500Internal server error

Update sandbox egress policy

PATCH /v1/sandboxes/{id}/egress

Update the egress (outbound network) policy for a running sandbox. The proxy is restarted with the new policy (~2-5s downtime).

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID

Request body (application/json):

FieldTypeRequiredDescription
mode”open” | “strict” | “blocked”No
allowDomainsarray of string or objectNo
includeImplicitDomainsbooleanNo
StatusMeaning
200Policy updated
400Invalid request
403Forbidden
404Sandbox not found
409Driver does not support runtime policy updates
500Internal error

List the hosts a sandbox reached

GET /v1/sandboxes/{id}/egress/activity

Every destination this sandbox’s egress proxy allowed or refused in the inspected window, and whether that observation can be trusted. This is the OPPOSITE question to /egress/denials, and unlike that route it is deliberately not best-effort: it exists to support the negative claim ‘this sandbox reached nothing’, which an empty list cannot carry on its own. destinations: [] with complete: true is evidence; destinations: [] with complete: false is an absence of evidence, and incompleteReasons names what was missing. A hop that could not reach the host reports hop-unreachable rather than an empty list, so an unreadable path can never be read as a clean sandbox.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
limitqueryNointeger
StatusMeaning
200What the sandbox reached, and whether that is decidable
403Forbidden
404Sandbox not found
409Egress is not enabled for this sandbox

List recent egress denials

GET /v1/sandboxes/{id}/egress/denials

Destinations this sandbox tried to reach that its egress policy refused, newest first. The sandbox’s 403 body names each refusal’s host and policy (the same pair as rejectedBy); this keeps the history. Best-effort: an empty list means either nothing was refused or the proxy is no longer readable.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
limitqueryNointeger
StatusMeaning
200Refused destinations
403Forbidden
404Sandbox not found

Get a sandbox’s egress for a calendar month

GET /v1/sandboxes/{id}/egress/usage

Bytes this sandbox sent in one calendar month (UTC), the account’s allowance it shares (2 TB per account per month on paid plans, 100 GiB on Free), the account’s total and overage, and the USD the meter charged or reserved for this sandbox’s captures.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
monthqueryNostringCalendar month, YYYY-MM in UTC. Defaults to the current month.
StatusMeaning
200The sandbox’s egress for the month
403Forbidden
404Sandbox not found

Read caller credential recovery policy

GET /v1/sandboxes/{id}/env-recovery

ParameterInRequiredTypeDescription
idpathYesstring
StatusMeaning
200Credential recovery metadata (no values)
400Invalid policy
401Authentication required
403Owner or team admin required
404Sandbox not found
409Sandbox must be stopped
500Policy unavailable
502Invalid upstream response
503Upstream unavailable

Replace or dry-run a stopped sandbox’s caller resupply policy

PUT /v1/sandboxes/{id}/env-recovery

ParameterInRequiredTypeDescription
idpathYesstring

Request body (application/json):

FieldTypeRequiredDescription
envRecoveryobjectYes
dryRunbooleanNo
StatusMeaning
200Credential recovery metadata (no values)
400Invalid policy
401Authentication required
403Owner or team admin required
404Sandbox not found
409Sandbox must be stopped
500Policy unavailable
502Invalid upstream response
503Upstream unavailable

Subscribe to sandbox events (SSE)

GET /v1/sandboxes/{id}/events

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
StatusMeaning
200SSE stream of sandbox events
400Invalid request
403Driver not allowed
404Sandbox not found

Publish the sandbox workspace as an image

POST /v1/sandboxes/{id}/images

Builds the Dockerfile in the sandbox workspace and pushes the image to the registry named in repository, with the credentials in auth. The sandbox must be running, and filesystemIncarnationId must be the value its details report. The request can take up to 15 minutes. Send an Idempotency-Key to make a retry safe; reusing a key with different inputs fails with IDEMPOTENCY_KEY_REUSED. A key is generated when you omit one, and the response returns it.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
Idempotency-KeyheaderNostring

Request body (application/json):

FieldTypeRequiredDescription
contextPathstringNo
dockerfilePathstringNo
repositorystringYes
authobjectYes
platform”linux/amd64” | “linux/arm64”No
filesystemIncarnationIdstringYes
StatusMeaning
200Image pushed
400Invalid request or Idempotency-Key (INVALID_REQUEST, INVALID_IDEMPOTENCY_KEY), the sandbox’s driver cannot be routed, or the build refused an input such as the context path or repository
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED)
404Sandbox not found (PROJECT_NOT_FOUND)
408The publication was cancelled (IMAGE_PUBLISH_CANCELLED)
409The sandbox is not ready or running, its filesystem changed since filesystemIncarnationId was read, or another publication is active (SANDBOX_NOT_READY, SANDBOX_NOT_RUNNING, FILESYSTEM_TRANSITIONING, FILESYSTEM_INCARNATION_CHANGED, WORKSPACE_IMAGE_OPERATION_IN_PROGRESS, IDEMPOTENCY_KEY_REUSED)
429The registry or the image builder is throttling
500Build or push failed (IMAGE_BUILD_FAILED, IMAGE_PUBLISH_FAILED)
501The sandbox driver cannot publish images (DRIVER_CAPABILITY_MISSING)
502The sandbox service returned an invalid result, or the publication failed for an unlisted reason (INVALID_IMAGE_PUBLISH_RESPONSE, IMAGE_PUBLISH_FAILED)
503Publication is unavailable, or its outcome could not be confirmed; retry with the same Idempotency-Key (IMAGE_PUBLISH_UNAVAILABLE, IMAGE_PUBLISH_OUTCOME_UNKNOWN)

Get an MCP endpoint for this sandbox

GET /v1/sandboxes/{id}/mcp

Returns a paste-able MCP host config (Claude Desktop, Cursor, claude-code, codex, …) plus a freshly-minted, capability-scoped JWT. The token is short-lived and can ONLY call MCP routes; it cannot reach admin endpoints (/exec, /files, …) on the sandbox. Call again to rotate.

?capabilities=computer_use is also the mint route for desktop control: the resulting token is what POST /computer-use/action, /a11y, and /mcp require. POST /v1/sandboxes/{id}/scoped-token cannot grant it; that route covers session reads, files, and terminals only.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
capabilitiesqueryNostring
serverNamequeryNostring
ttlMinutesqueryNointeger
StatusMeaning
200MCP endpoint config + scoped token
400Invalid request
403Driver not allowed or sandbox not yours
404Sandbox not found
502Invalid sandbox service response
503Sandbox public edge is still attaching; retry shortly

Install a native CLI credential in a sandbox

POST /v1/sandboxes/{id}/native-credentials

Names a stored secret; no secret value is sent or returned. claude-code takes a token reference, codex a bundle or files reference. Needs write access to the sandbox, and a personal sandbox must be owned by the caller. Isolated sandboxes are refused. The grant is recorded as a sandbox.native_credential.grant audit event.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID

Request body (application/json):

FieldTypeRequiredDescription
harness”claude-code” | “codex”Yes
cliAuthobjectYes
StatusMeaning
200The reference is echoed back. A legacy seat replies installed: true. A canonical seat replies with its proxySecretReceipt and no installed field; status proxy-installed means the egress proxy admitted the seat and HOME delivery is still pending.
400Invalid credential reference, or the sandbox’s driver cannot be routed
403The credential or team role cannot use this sandbox, the sandbox is isolated, or the caller does not own it (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED)
409A held seat cannot switch live (NATIVE_CREDENTIAL_SEAT_SWITCH_UNSUPPORTED)
503Installation was not confirmed, or the sandbox service did not answer (NATIVE_CREDENTIAL_GRANT_UNAVAILABLE, HOST_UNAVAILABLE)

Get an accepted stop, snapshot or delete

GET /v1/sandboxes/{id}/operations/{operationId}

Reports an operation a wait=false stop, snapshot or delete accepted. Poll until state is succeeded or failed. Still readable after the sandbox is deleted: a delete is authorized from the scope it was accepted under (its owner, or a current member of its team). Unknown ids and ids of other tenants answer the same 404. waitMs holds the read while it runs; a delete holds 10 s.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
operationIdpathYesstringOperation ID
untilqueryNo”removed”
waitMsqueryNointeger or null
StatusMeaning
200Operation
400Invalid request
403Not allowed
404Operation not found
500Failed to read the operation
502Invalid sandbox service response
503The sandbox service is unavailable

Read verified HIPAA placement evidence

GET /v1/sandboxes/{id}/placement-attestation

ParameterInRequiredTypeDescription
idpathYesstring
StatusMeaning
200Server-issued placement evidence
400Invalid sandbox target
403Sandbox access forbidden
404Sandbox or placement evidence not found
503Evidence unavailable

Rebuild a stopped sandbox runtime

POST /v1/sandboxes/{id}/rebuild

Requires a stopped sandbox. Confirms a durable snapshot, then creates a new runtime under the same sandbox ID. The optional env body resupplies public values that are not stored at rest. A refused rebuild keeps the stopped runtime.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
StatusMeaning
200Sandbox resumed
400Invalid request
403Driver not allowed
404Sandbox not found
409Sandbox is not in a resumable lifecycle state, a new runtime needs env values only the caller holds (RESUME_ENV_REQUIRED), or its workspace could not be restored into a new runtime (RESUME_RESTORE_REFUSED)
429Concurrent session limit exceeded
500Internal server error
502Integration bundle refresh failed
503Platform integrations unavailable

Resume a stopped sandbox

POST /v1/sandboxes/{id}/resume

Resumes a stopped sandbox. A sandbox that is already running answers 200 with its current state. The optional JSON body { "env": { "KEY": "value" } } resupplies public env values that are not stored at rest, such as a per-run coordination token or a secret passed at create. A resume that must build a new runtime without them answers 409 RESUME_ENV_REQUIRED with missingEnvKeys. The values are used only when the resume builds a new runtime.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
StatusMeaning
200Sandbox resumed
400Invalid request
403Driver not allowed
404Sandbox not found
409Sandbox is not in a resumable lifecycle state, a new runtime needs env values only the caller holds (RESUME_ENV_REQUIRED), or its workspace could not be restored into a new runtime (RESUME_RESTORE_REFUSED)
429Concurrent session limit exceeded
500Internal server error
502Integration bundle refresh failed
503Platform integrations unavailable

Fork a running agent sandbox N ways and run the same turn in each

POST /v1/sandboxes/{id}/rollouts

Speculative rollouts: branches the RUNNING sandbox into n copy-on-write children, sends the same message parts to a fresh agent session in every child in parallel, and (optionally) scores each child by running scorer.command inside it; exit 0 passes and stdout is parsed as the numeric score. Responds once the children exist; poll GET /v1/sandboxes/{id}/rollouts/{rolloutId} for turn results, per-child errors, and the winner. Children are KEPT for the caller to promote or delete: they are first-class sandboxes that live independently of the parent (deleting the parent reaps only the shared branch-base snapshots once the children are gone; a parent with live children refuses delete without cascade=true).

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID

Request body (application/json):

FieldTypeRequiredDescription
nintegerYes
partsarray of objectYes
scorerobjectNo
StatusMeaning
202Children materialized; turns running
400Invalid request
403Driver not allowed
404Sandbox not found
429Concurrent session limit exceeded, or provisioning saturated
500Internal server error
503Active driver does not support live branching

Poll a rollout’s status and scored per-child results

GET /v1/sandboxes/{id}/rollouts/{rolloutId}

Failed or timed-out children appear as result entries with error set and no score; partial results are never dropped. winner is the child with the highest numeric score (command scorer only).

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
rolloutIdpathYesstring
StatusMeaning
200Rollout state
400Invalid request
403Driver not allowed
404Sandbox or rollout not found
500Internal server error

Send a GET request to the sandbox runtime

GET /v1/sandboxes/{id}/runtime/{path}

Forwards the request to the sandbox runtime at the same sub-path and relays its status, headers and body. Accepts an account API key or a scoped sandbox token from POST /v1/sandboxes/{id}/scoped-token. Needs read access to the sandbox. A GET with Upgrade: websocket to terminals/{connectionId}/ws or ssh opens a WebSocket and answers 101; a scoped token can open only the terminal socket. A request that starts paid compute, such as an agent run or exec, is refused with 402 or 429 while the paying account has debt or is below the balance floor, and it resumes a suspended sandbox first. Runtime error bodies are returned in the standard error shape.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
pathpathYesstringRuntime sub-path, such as agents/run or files/tree. It cannot contain .. or start with a slash.
StatusMeaning
101WebSocket upgrade accepted (terminal and SSH sub-paths)
200The runtime’s response, relayed with its own status, headers and body
400Invalid sandbox ID or sub-path, an execution time limit above the deployment maximum, or a request the runtime refused (INVALID_REQUEST, EXECUTION_TTL_EXCEEDS_LIMIT)
401A WebSocket upgrade needs a signed-in user
402The paying account has recorded debt, or the model credential’s budget is spent (INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox, a scoped token cannot use this sub-path, or secret isolation could not be proved
404Sandbox not found or already ended
413The request body is over the proxy limit
429The plan’s runtime request rate is reached, or the paying account is below the admission floor (RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED)
500Internal error
502An agent run’s event stream ended without a result (AGENT_RUN_STREAM_INCOMPLETE)
503The sandbox service or the runtime did not answer; retry after Retry-After

Send a HEAD request to the sandbox runtime

HEAD /v1/sandboxes/{id}/runtime/{path}

Forwards the request to the sandbox runtime at the same sub-path and relays its status, headers and body. Accepts an account API key or a scoped sandbox token from POST /v1/sandboxes/{id}/scoped-token. Needs read access to the sandbox. A request that starts paid compute, such as an agent run or exec, is refused with 402 or 429 while the paying account has debt or is below the balance floor, and it resumes a suspended sandbox first. Runtime error bodies are returned in the standard error shape.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
pathpathYesstringRuntime sub-path, such as agents/run or files/tree. It cannot contain .. or start with a slash.
StatusMeaning
200The runtime’s response, relayed with its own status, headers and body
400Invalid sandbox ID or sub-path, an execution time limit above the deployment maximum, or a request the runtime refused (INVALID_REQUEST, EXECUTION_TTL_EXCEEDS_LIMIT)
402The paying account has recorded debt, or the model credential’s budget is spent (INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox, a scoped token cannot use this sub-path, or secret isolation could not be proved
404Sandbox not found or already ended
413The request body is over the proxy limit
429The plan’s runtime request rate is reached, or the paying account is below the admission floor (RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED)
500Internal error
502An agent run’s event stream ended without a result (AGENT_RUN_STREAM_INCOMPLETE)
503The sandbox service or the runtime did not answer; retry after Retry-After

Send a POST request to the sandbox runtime

POST /v1/sandboxes/{id}/runtime/{path}

Forwards the request to the sandbox runtime at the same sub-path and relays its status, headers and body. Accepts an account API key or a scoped sandbox token from POST /v1/sandboxes/{id}/scoped-token. Needs write access to the sandbox. POST agents/run answers when the run finishes, with { success: true, data } or { success: false, error } under the run’s status. POST agents/run/stream answers with an event stream. A request that starts paid compute, such as an agent run or exec, is refused with 402 or 429 while the paying account has debt or is below the balance floor, and it resumes a suspended sandbox first. Runtime error bodies are returned in the standard error shape.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
pathpathYesstringRuntime sub-path, such as agents/run or files/tree. It cannot contain .. or start with a slash.

Request body: application/json.

StatusMeaning
200The runtime’s response, relayed with its own status, headers and body
400Invalid sandbox ID or sub-path, an execution time limit above the deployment maximum, or a request the runtime refused (INVALID_REQUEST, EXECUTION_TTL_EXCEEDS_LIMIT)
402The paying account has recorded debt, or the model credential’s budget is spent (INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox, a scoped token cannot use this sub-path, or secret isolation could not be proved
404Sandbox not found or already ended
413The request body is over the proxy limit
429The plan’s runtime request rate is reached, or the paying account is below the admission floor (RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED)
500Internal error
502An agent run’s event stream ended without a result (AGENT_RUN_STREAM_INCOMPLETE)
503The sandbox service or the runtime did not answer; retry after Retry-After

Send a PUT request to the sandbox runtime

PUT /v1/sandboxes/{id}/runtime/{path}

Forwards the request to the sandbox runtime at the same sub-path and relays its status, headers and body. Accepts an account API key or a scoped sandbox token from POST /v1/sandboxes/{id}/scoped-token. Needs write access to the sandbox. A request that starts paid compute, such as an agent run or exec, is refused with 402 or 429 while the paying account has debt or is below the balance floor, and it resumes a suspended sandbox first. Runtime error bodies are returned in the standard error shape.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
pathpathYesstringRuntime sub-path, such as agents/run or files/tree. It cannot contain .. or start with a slash.

Request body: application/json.

StatusMeaning
200The runtime’s response, relayed with its own status, headers and body
400Invalid sandbox ID or sub-path, an execution time limit above the deployment maximum, or a request the runtime refused (INVALID_REQUEST, EXECUTION_TTL_EXCEEDS_LIMIT)
402The paying account has recorded debt, or the model credential’s budget is spent (INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox, a scoped token cannot use this sub-path, or secret isolation could not be proved
404Sandbox not found or already ended
413The request body is over the proxy limit
429The plan’s runtime request rate is reached, or the paying account is below the admission floor (RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED)
500Internal error
502An agent run’s event stream ended without a result (AGENT_RUN_STREAM_INCOMPLETE)
503The sandbox service or the runtime did not answer; retry after Retry-After

Send a PATCH request to the sandbox runtime

PATCH /v1/sandboxes/{id}/runtime/{path}

Forwards the request to the sandbox runtime at the same sub-path and relays its status, headers and body. Accepts an account API key or a scoped sandbox token from POST /v1/sandboxes/{id}/scoped-token. Needs write access to the sandbox. A request that starts paid compute, such as an agent run or exec, is refused with 402 or 429 while the paying account has debt or is below the balance floor, and it resumes a suspended sandbox first. Runtime error bodies are returned in the standard error shape.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
pathpathYesstringRuntime sub-path, such as agents/run or files/tree. It cannot contain .. or start with a slash.

Request body: application/json.

StatusMeaning
200The runtime’s response, relayed with its own status, headers and body
400Invalid sandbox ID or sub-path, an execution time limit above the deployment maximum, or a request the runtime refused (INVALID_REQUEST, EXECUTION_TTL_EXCEEDS_LIMIT)
402The paying account has recorded debt, or the model credential’s budget is spent (INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox, a scoped token cannot use this sub-path, or secret isolation could not be proved
404Sandbox not found or already ended
413The request body is over the proxy limit
429The plan’s runtime request rate is reached, or the paying account is below the admission floor (RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED)
500Internal error
502An agent run’s event stream ended without a result (AGENT_RUN_STREAM_INCOMPLETE)
503The sandbox service or the runtime did not answer; retry after Retry-After

Send a DELETE request to the sandbox runtime

DELETE /v1/sandboxes/{id}/runtime/{path}

Forwards the request to the sandbox runtime at the same sub-path and relays its status, headers and body. Accepts an account API key or a scoped sandbox token from POST /v1/sandboxes/{id}/scoped-token. Needs write access to the sandbox. A request that starts paid compute, such as an agent run or exec, is refused with 402 or 429 while the paying account has debt or is below the balance floor, and it resumes a suspended sandbox first. Runtime error bodies are returned in the standard error shape.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
pathpathYesstringRuntime sub-path, such as agents/run or files/tree. It cannot contain .. or start with a slash.

Request body: application/json.

StatusMeaning
200The runtime’s response, relayed with its own status, headers and body
400Invalid sandbox ID or sub-path, an execution time limit above the deployment maximum, or a request the runtime refused (INVALID_REQUEST, EXECUTION_TTL_EXCEEDS_LIMIT)
402The paying account has recorded debt, or the model credential’s budget is spent (INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox, a scoped token cannot use this sub-path, or secret isolation could not be proved
404Sandbox not found or already ended
413The request body is over the proxy limit
429The plan’s runtime request rate is reached, or the paying account is below the admission floor (RATE_LIMIT_EXCEEDED, QUOTA_EXCEEDED)
500Internal error
502An agent run’s event stream ended without a result (AGENT_RUN_STREAM_INCOMPLETE)
503The sandbox service or the runtime did not answer; retry after Retry-After

Mint a scoped consumer-side token for direct sandbox access

POST /v1/sandboxes/{id}/scoped-token

Session/project tokens read SessionGateway streams. Runtime tokens grant session-runtime: read + workspace + terminal, or read-only: sandbox-wide read. Set access: read-only on session-runtime for session-bound read alone; the response must echo that restriction. Runtime read includes screenshots; workspace adds file writes and terminal adds its WebSocket. No scope here grants desktop input, /a11y or /mcp: mint computer_use separately at GET /v1/sandboxes/{id}/mcp?capabilities=computer_use. Missing-capability 403 responses identify the required capability and its mint route.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID

Request body (application/json): one of 3 shapes; see the OpenAPI document.

StatusMeaning
200Scoped token issued
400Invalid scope or missing sessionId for session scope
403Caller does not own this sandbox
404Sandbox not found
500Internal server error
502Invalid sandbox service response

Create a snapshot of sandbox state

POST /v1/sandboxes/{id}/snapshot

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
waitqueryNo”true” | “false”
Idempotency-KeyheaderNostringOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.

Request body (application/json):

FieldTypeRequiredDescription
tagsarray of stringNo
idempotencyKeystringNoOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.
StatusMeaning
200Snapshot created, or the stored result of an earlier create
202Snapshot accepted; it is captured in the background
400Invalid request
403Driver not allowed
404Sandbox not found
409Snapshot limit reached, or this idempotency key is bound to a different request body
500Snapshot failed
502Upstream snapshot service returned success without a snapshot ID
503Snapshot quota check unavailable

Create a snapshot of sandbox state

POST /v1/sandboxes/{id}/snapshots

Answers 202 once capture is durably accepted. Poll operation.statusUrl until succeeded or failed; a successful result names the snapshot. Writes made before the request are included. Wait for completion before writing data that must remain outside the snapshot.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
waitqueryNo”true” | “false”
Idempotency-KeyheaderNostringOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.

Request body (application/json):

FieldTypeRequiredDescription
tagsarray of stringNo
idempotencyKeystringNoOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.
StatusMeaning
200Snapshot created, or the stored result of an earlier create
202Snapshot accepted; it is captured in the background
400Invalid request
403Driver not allowed
404Sandbox not found
409Snapshot limit reached, or this idempotency key is bound to a different request body
500Snapshot failed
502Upstream snapshot service returned success without a snapshot ID
503Snapshot quota check unavailable

List snapshots for a sandbox

GET /v1/sandboxes/{id}/snapshots

For a deleted sandbox whose final snapshot is retained, its owner gets that snapshot alone, marked final, with deleted: true. Anyone else, a team member included, gets 404, as for a sandbox with no retained snapshot.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
StatusMeaning
200List of snapshots
400Invalid request
403Driver not allowed
404Sandbox not found
500Snapshot listing failed
501Snapshot backend unavailable
503Retryable snapshot service failure

Get sandbox snapshot restore job status

GET /v1/sandboxes/{id}/snapshots/jobs/{jobId}

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
jobIdpathYesstringRestore job ID
waitMsqueryNointeger or nullHold the answer until the job finishes, up to this many milliseconds
StatusMeaning
200Restore job status
400Invalid request
403Driver not allowed
404Sandbox or job not found
500Failed to fetch restore job status
501Restore job queue unavailable

Delete a sandbox snapshot

DELETE /v1/sandboxes/{id}/snapshots/{snapshotId}

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
snapshotIdpathYesstringSnapshot ID
StatusMeaning
200Snapshot deleted, or already absent
400Invalid request
403Driver not allowed
404Sandbox not found
500Delete failed
501Snapshot backend unavailable
503Host restarting or unreachable; retry

Restore a sandbox from a snapshot

POST /v1/sandboxes/{id}/snapshots/{snapshotId}/restore

Restores the whole workspace from the snapshot. The optional JSON body { "paths": ["relative/path"] } restores only those workspace-relative paths and leaves every other file untouched; an empty body restores the whole workspace. A body that is present but is not that JSON object answers 400, and nothing is restored. With waitMs the 202 is held until the job finishes and carries its status, so the caller needs no poll. A repeat under the same Idempotency-Key answers the same job for an hour after it ends; the same key with another snapshot or paths is another restore.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
snapshotIdpathYesstringSnapshot ID
waitMsqueryNointeger or nullHold the answer until the job finishes, up to this many milliseconds
Idempotency-KeyheaderNostringOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.
StatusMeaning
200Snapshot restored
202Restore accepted
400Invalid request
403Driver not allowed
404Sandbox or snapshot not found
500Restore failed
501Snapshot backend unavailable
502Invalid sandbox service response

Stop a sandbox (keeps state)

POST /v1/sandboxes/{id}/stop

Answers once the sandbox is stopped and its final workspace generation is durable. With wait=false it may instead answer 202 as soon as the stop is durably accepted: poll operation.statusUrl (or Location) until the operation is succeeded or failed. Billing runs until the runtime is actually stopped, and a resume issued meanwhile waits for the stop. A 200 to a wait=false request means the stop already finished synchronously. A synchronous stop accepts { "retain": { "paths": ["relative/path"] } } to export its exact remotely confirmed stopped workspace before answering.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
waitqueryNo”true” | “false”
StatusMeaning
200Sandbox stopped
202Stop accepted; it finishes in the background
400Invalid request
403Driver not allowed
404Sandbox not found
409Refused with a typed end: SUSPEND_REQUIRES_MANAGED_HOME, RUNTIME_GONE, FINAL_SUSPEND_UNCONFIRMED or RUN_SESSION_CAPTURE_PENDING; retryable: false answers every repeat the same
500Internal server error
503Sandbox billing state is temporarily unavailable

Export sandbox trace and intelligence envelope

GET /v1/sandboxes/{id}/trace

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
includeIntelligencequeryNo”true” | “false”
StatusMeaning
200Sandbox trace export
400Invalid request
403Driver not allowed
404Sandbox not found
500Internal server error

Look up an idempotent workspace operation

POST /v1/sandboxes/{id}/workspace-operations/lookup

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID

Request body (application/json):

FieldTypeRequiredDescription
kind”checkpoint” | “fork”Yes
idempotencyKeystringYesOpt-in retry identity. A retry with this key and the same body replays the stored result instead of running a second operation.
requestobjectNo
StatusMeaning
200Operation lookup outcome
400Invalid request

List sandbox shape presets and the caller’s ceiling

GET /v1/shapes

Returns the named sandbox sizes, which one is the platform’s default, and the largest shape this account can be granted on this deployment. Presets are the platform’s numbers and are not clamped per account: a preset above ceiling (the default small on a plan whose ceiling sits below it) is granted clamped to the ceiling when the create names no size or marks the size advisory, and refused with RESOURCES_EXCEED_LIMIT when the create names that preset’s numbers explicitly. default names the platform’s default preset: a create that sends no resources receives that preset’s CPU and memory, but its disk is currently held at 2 GiB (the host warm-seed quota) rather than the preset’s, so name resources.diskGB when you need more.

StatusMeaning
200Shapes retrieved successfully
500Internal error

GPU

RouteDoes
GET /v1/sandboxes/{id}/gpu/leasesList GPU leases
POST /v1/sandboxes/{id}/gpu/leasesAttach a GPU lease
PATCH /v1/sandboxes/{id}/gpu/leases/{leaseId}Renew a GPU lease
DELETE /v1/sandboxes/{id}/gpu/leases/{leaseId}Detach a GPU lease
GET /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}Send a GET request to a GPU lease endpoint
POST /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}Send a POST request to a GPU lease endpoint
PUT /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}Send a PUT request to a GPU lease endpoint
PATCH /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}Send a PATCH request to a GPU lease endpoint
DELETE /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}Send a DELETE request to a GPU lease endpoint
POST /v1/sandboxes/{id}/gpu/leases/{leaseId}/execRun a command on a GPU lease
GET /v1/sandboxes/{id}/gpu/providersList GPU providers

List GPU leases

GET /v1/sandboxes/{id}/gpu/leases

Needs read access to the sandbox. Each lease’s endpointUrl is its serving URL on this API. A destroyed lease in the list has its final charge recorded once.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
StatusMeaning
200GPU leases
400The sandbox’s driver cannot be routed
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
500The leases could not be listed (GPU_LEASE_LIST_FAILED)
503The lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Attach a GPU lease

POST /v1/sandboxes/{id}/gpu/leases

Needs admin access to the sandbox and a paid seat or funded balance. The plan’s accelerator limit applies per sandbox. maxSpendUsd and maxLifetimeSeconds end the lease when reached.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID

Request body (application/json):

FieldTypeRequiredDescription
providerstringNo
imagestringNo
envobjectNo
diskGbintegerNo
volumeGbintegerNo
volumeMountPathstringNo
regionstringNo
manifestobjectNo
commandarray of stringNo
portsarray of integerNo
endpointobjectNo
allowSpotbooleanNo
maxHourlyUsdnumberNo
weightsobjectNo
armsarray of objectNo
maxSpendUsdnumberYes
maxLifetimeSecondsintegerYes
idleTimeoutSecondsintegerNo
acceleratorobjectYes
StatusMeaning
201GPU lease attached
400Invalid request, the plan’s accelerator limit or the spend cap refused it, or the sandbox’s driver cannot be routed (INVALID_REQUEST, ACCELERATOR_LIMIT_EXCEEDED, GPU_SPEND_CAP_EXCEEDED)
402The account has no paid seat or funded balance (PAYMENT_REQUIRED, INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease is not ready
429The paying account’s balance is below the admission floor (QUOTA_EXCEEDED)
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Renew a GPU lease

PATCH /v1/sandboxes/{id}/gpu/leases/{leaseId}

Sets a new lifetime or spend cap. Send at least one of maxLifetimeSeconds and maxSpendUsd. Needs admin access to the sandbox and a paid seat or funded balance.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID

Request body (application/json):

FieldTypeRequiredDescription
maxSpendUsdnumberNo
maxLifetimeSecondsintegerNo
StatusMeaning
200GPU lease renewed
400Invalid request, or the spend cap refused it (INVALID_REQUEST, GPU_SPEND_CAP_EXCEEDED)
402The account has no paid seat or funded balance (PAYMENT_REQUIRED, INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease is not ready
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Detach a GPU lease

DELETE /v1/sandboxes/{id}/gpu/leases/{leaseId}

Needs write access to the sandbox. Destroys the lease and records its final charge. The response carries the lease’s billing summary.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID
StatusMeaning
200GPU lease detached
400The sandbox’s driver cannot be routed
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease is not ready
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Send a GET request to a GPU lease endpoint

GET /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}

Forwards the request to the lease’s HTTPS serving endpoint, with its query string, body, Content-Type and Accept. The response status, headers and body are the endpoint’s. Needs write access to the sandbox. A request in flight counts as lease activity.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID
pathpathYesstringPath on the serving endpoint, without a leading slash; empty for its root
StatusMeaning
200The serving endpoint’s response, relayed with its own status, headers and body
400The path leaves the serving endpoint
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease has no serving endpoint, or its credential is unavailable
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Send a POST request to a GPU lease endpoint

POST /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}

Forwards the request to the lease’s HTTPS serving endpoint, with its query string, body, Content-Type and Accept. The response status, headers and body are the endpoint’s. Needs write access to the sandbox. A request in flight counts as lease activity.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID
pathpathYesstringPath on the serving endpoint, without a leading slash; empty for its root

Request body: application/json.

StatusMeaning
200The serving endpoint’s response, relayed with its own status, headers and body
400The path leaves the serving endpoint
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease has no serving endpoint, or its credential is unavailable
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Send a PUT request to a GPU lease endpoint

PUT /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}

Forwards the request to the lease’s HTTPS serving endpoint, with its query string, body, Content-Type and Accept. The response status, headers and body are the endpoint’s. Needs write access to the sandbox. A request in flight counts as lease activity.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID
pathpathYesstringPath on the serving endpoint, without a leading slash; empty for its root

Request body: application/json.

StatusMeaning
200The serving endpoint’s response, relayed with its own status, headers and body
400The path leaves the serving endpoint
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease has no serving endpoint, or its credential is unavailable
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Send a PATCH request to a GPU lease endpoint

PATCH /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}

Forwards the request to the lease’s HTTPS serving endpoint, with its query string, body, Content-Type and Accept. The response status, headers and body are the endpoint’s. Needs write access to the sandbox. A request in flight counts as lease activity.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID
pathpathYesstringPath on the serving endpoint, without a leading slash; empty for its root

Request body: application/json.

StatusMeaning
200The serving endpoint’s response, relayed with its own status, headers and body
400The path leaves the serving endpoint
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease has no serving endpoint, or its credential is unavailable
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Send a DELETE request to a GPU lease endpoint

DELETE /v1/sandboxes/{id}/gpu/leases/{leaseId}/endpoint/{path}

Forwards the request to the lease’s HTTPS serving endpoint, with its query string, body, Content-Type and Accept. The response status, headers and body are the endpoint’s. Needs write access to the sandbox. A request in flight counts as lease activity.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID
pathpathYesstringPath on the serving endpoint, without a leading slash; empty for its root

Request body: application/json.

StatusMeaning
200The serving endpoint’s response, relayed with its own status, headers and body
400The path leaves the serving endpoint
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease has no serving endpoint, or its credential is unavailable
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

Run a command on a GPU lease

POST /v1/sandboxes/{id}/gpu/leases/{leaseId}/exec

Needs write access to the sandbox. Runs the command on the lease’s accelerator host and answers when it exits. The call is recorded as a sandbox exec access event.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
leaseIdpathYesstringGPU lease ID

Request body (application/json):

FieldTypeRequiredDescription
commandstringYes
timeoutMsintegerNo
envobjectNo
cwdstringNo
StatusMeaning
200Command result
400Invalid request (INVALID_REQUEST), or the sandbox’s driver cannot be routed
402The account that pays for the sandbox has recorded debt (INSUFFICIENT_BALANCE)
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
404Sandbox or lease not found
409The lease is not ready
429The paying account’s balance is below the admission floor (QUOTA_EXCEEDED)
500GPU lease operation failed
502The GPU provider failed (GPU_PROVIDER_ERROR)
503No GPU provider is configured (GPU_PROVIDER_NOT_CONFIGURED lists each provider and the variables it needs), the provider or the lease store is unavailable, or the sandbox service did not answer; retry after Retry-After

List GPU providers

GET /v1/sandboxes/{id}/gpu/providers

Needs read access to the sandbox. Checks each provider’s credential with a fresh read-only call. Send acceleratorKind to also get each provider’s hourly price for that GPU.

ParameterInRequiredTypeDescription
idpathYesstringSandbox ID
acceleratorKindqueryNostring
acceleratorCountqueryNonumber
acceleratorVramGbqueryNonumber
StatusMeaning
200GPU provider health
400Invalid query (INVALID_REQUEST), or the sandbox’s driver cannot be routed
403The credential or team role cannot use this sandbox (SANDBOX_KEY_RESOURCE_FORBIDDEN, INSUFFICIENT_ROLE, SANDBOX_ACCESS_DENIED, DRIVER_NOT_ALLOWED)
503Provider discovery is unavailable (GPU_PROVIDER_UNAVAILABLE), or the sandbox service did not answer; retry after Retry-After

Next steps