Sandbox API

Sandboxes

Long-lived workspace / desktop sessions

Long-lived workspace / desktop sessions

Every request needs a credential — see Authentication.

MethodPathSummary
GET/sandbox/sandboxes/v1List Sandboxes
POST/sandbox/sandboxes/v1Create Sandbox
POST/sandbox/sandboxes/v1/_reapReap Sandboxes
DELETE/sandbox/sandboxes/v1/{sandbox_id}Destroy Sandbox
GET/sandbox/sandboxes/v1/{sandbox_id}Get Sandbox
PATCH/sandbox/sandboxes/v1/{sandbox_id}Update sandbox lifetime (TTL / expiry / autostop)
GET/sandbox/sandboxes/v1/{sandbox_id}/artifactsList Sandbox Artifacts
GET/sandbox/sandboxes/v1/{sandbox_id}/artifacts/{capture_id}Get Sandbox Artifact
POST/sandbox/sandboxes/v1/{sandbox_id}/captureCapture Sandbox
GET/sandbox/sandboxes/v1/{sandbox_id}/eventsSSE sandbox lifecycle events
POST/sandbox/sandboxes/v1/{sandbox_id}/execExec Sandbox
DELETE/sandbox/sandboxes/v1/{sandbox_id}/filesDelete File
GET/sandbox/sandboxes/v1/{sandbox_id}/filesGet File
PUT/sandbox/sandboxes/v1/{sandbox_id}/filesPut File
GET/sandbox/sandboxes/v1/{sandbox_id}/portsList TCP ports listening inside the sandbox (user apps)
POST/sandbox/sandboxes/v1/{sandbox_id}/screenshotScreenshot an app running inside the sandbox (headless Chromium)
POST/sandbox/sandboxes/v1/{sandbox_id}/startStart Sandbox
POST/sandbox/sandboxes/v1/{sandbox_id}/stopStop Sandbox
POST/sandbox/sandboxes/v1/{sandbox_id}/touchRecord activity (resets the idle auto-stop clock)
POST/sandbox/sandboxes/v1/{sandbox_id}/verifyVerify Sandbox
GET/sandbox/sandboxes/v1/{sandbox_id}/viewerMint viewer URL or proxy the desktop viewer UI
POST/sandbox/sandboxes/v1/{sandbox_id}/viewer/actionsUpload the viewer action log (clicks, scrolls, keys, searches)
POST/sandbox/sandboxes/v1/{sandbox_id}/viewer/annotationsSubmit a task-ambiguity label for the session
POST/sandbox/sandboxes/v1/{sandbox_id}/viewer/recordingsUpload a viewer session screen recording
POST/sandbox/sandboxes/v1/{sandbox_id}/viewer/screenshotsUpload a screenshot captured from the viewer canvas
POST/sandbox/sandboxes/v1/{sandbox_id}/viewer/startStart Viewer
POST/sandbox/sandboxes/v1/{sandbox_id}/viewer/stopStop Viewer
POST/sandbox/sandboxes/v1/{sandbox_id}/viewer/tokenRemint a fresh signed viewer URL (token refresh)
POST/sandbox/sandboxes/v1/{sandbox_id}/workspace/syncSync tenant GCS workspace ↔ guest SandboxWorkspace
POST/sandbox/sandboxes/v1/environments/pairsCreate or reconnect to a paired desktop and private companion
DELETE/sandbox/sandboxes/v1/environments/pairs/{pair_id}Asynchronously destroy both paired environment children
GET/sandbox/sandboxes/v1/environments/pairs/{pair_id}Get durable paired environment status
POST/sandbox/sandboxes/v1/images/buildBuild-or-resolve a content-addressed desktop image
GET/sandbox/sandboxes/v1/images/build/{build_id}Poll desktop image build status
GET/sandbox/sandboxes/v1/images/build/{build_id}/eventsSSE desktop image build events

Common headers

Accepted on every endpoint on this page.

NameInTypeRequiredDescription
x-correlation-idheaderstringnoEnd-to-end correlation id for this eval run. When set, the gateway and downstream services honor it verbatim in logs, Cloud Trace span attributes, async job payloads, and Langfuse trace.id. When omitted, the gateway generates a ULID and echoes it on the response.
X-Sandbox-Project-Idheaderstring | nullnoProject to bill and rate-limit this request against. Validated against the credential: a project-scoped token may only name its own project, and gets 403 otherwise. Defaults to the token's project when omitted.
X-Sandbox-Tenant-Idheaderstring | nullnoTenant for this request. Must match the credential's tenant when the credential carries one.

Endpoints

List Sandboxes

GET /sandbox/sandboxes/v1

Parameters

NameInTypeRequiredDescription
task_idquerystring | nullno
reuse_fingerprintquerystring | nullnoFilter by create-intent fingerprint (sha256:…).
statusquerystring | nullno

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Create Sandbox

POST /sandbox/sandboxes/v1

Request body

application/json, required — CreateSandboxRequest

FieldTypeRequiredDescription
profilestringnoDefault: "sandboxes-default".
sourceobject | nullnoWorkspace seed. {type: archive_url|gcs_prefix, uri}, {type: snapshot, seq}, or {type: workspace_latest} to restore the latest snapshot any earlier sandbox of the same task workspace (task_id / labels.task_id / labels.ctp_task_id, or workspace_key) wrote in this tenant/project. The create response's source names the snapshot it pinned (sandbox_id + snapshot_seq); with no snapshot yet the workspace starts empty.
image_refstring | nullnoImmutable pin from POST …/images/build: OCI repo@sha256:<digest> or gce:projects/{project}/global/images/{name}. Floating tags rejected.
autostop_secnumber | nullnoIdle seconds before the sandbox is stopped (default 1800). Returned on create/GET so clients can show session policy.
ttl_secnumber | nullnoHard max lifetime in seconds before destroy (default 86400). expires_at on the record is created_at + effective ttl. Values above the profile max_ttl_sec (default 30 days) are clamped and reported in warnings. With reuse=true a larger ttl extends the reused sandbox. Extend later with PATCH /v1/{sandbox_id}.
linked_job_idstring | nullno
task_idstring | nullnoOptional Gen Studio / CTP task id for labels and episode metadata; when omitted, sandbox_id is used.
reusebooleannoWhen true, return an existing non-destroyed sandbox whose create fingerprint matches (owner salt + tenant/project + profile + image_ref + workspace_key + purpose/template labels) instead of provisioning a new session. Default false so pass@k / episode reset stay create-always. Default: false.
reuse_saltstring | nullnoOptional client nonce mixed into the fingerprint salt. Rotate to force a fresh VM while keeping the same task_id. Required for fingerprinting when the caller has no Keycloak owner principal.
restore_latestbooleannoWhen true and no sandbox is reused, seed the new sandbox from the task workspace's latest snapshot (same as source.type=workspace_latest). Ignored when source is set or the task has no snapshot yet. Default false so creates stay fresh unless asked. Default: false.
labelsobjectnoConsumer tags for analytics (trainer, pass, program, …).

Responses

StatusDescriptionBody
201Successful Responseany
422Validation ErrorHTTPValidationError

Reap Sandboxes

POST /sandbox/sandboxes/v1/_reap

Operator hook: stop/destroy idle sandboxes for this scope.

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Destroy Sandbox

DELETE /sandbox/sandboxes/v1/{sandbox_id}

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
discard_unsavedquerybooleannoDelete the workspace volume even when it holds work the last save did not capture (checkpoint_failed_at set, or the pod was lost). Without it such a volume is kept.

Responses

StatusDescriptionBody
204Successful Response—
422Validation ErrorHTTPValidationError

Get Sandbox

GET /sandbox/sandboxes/v1/{sandbox_id}

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Update sandbox lifetime (TTL / expiry / autostop)

PATCH /sandbox/sandboxes/v1/{sandbox_id}

Extend or shorten a sandbox lifetime. Clamped values return warnings.

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Request body

application/json, required — UpdateSandboxLifetimeRequest

FieldTypeRequiredDescription
ttl_secnumber | nullnoNew lifetime counted from now: expires_at becomes now + ttl_sec (may shorten or extend). Clamped to the profile max_ttl_sec (default 30 days).
expires_atstring | nullnoAbsolute ISO 8601 expiry (naive values are UTC). Mutually exclusive with ttl_sec; must be in the future; clamped to now + max_ttl_sec.
autostop_secnumber | nullnoIdle seconds before auto-stop. 0 disables idle stop (TTL still applies).

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

List Sandbox Artifacts

GET /sandbox/sandboxes/v1/{sandbox_id}/artifacts

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
kindquerystring | nullno
limitqueryintegerno

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Get Sandbox Artifact

GET /sandbox/sandboxes/v1/{sandbox_id}/artifacts/{capture_id}

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
capture_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Capture Sandbox

POST /sandbox/sandboxes/v1/{sandbox_id}/capture

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

SSE sandbox lifecycle events

GET /sandbox/sandboxes/v1/{sandbox_id}/events

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
Last-Event-IDheaderstring | nullno

Responses

StatusDescriptionBody
200Successful Responseany
422Validation ErrorHTTPValidationError

Exec Sandbox

POST /sandbox/sandboxes/v1/{sandbox_id}/exec

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Request body

application/json, required — ExecRequest

FieldTypeRequiredDescription
commandstring[]yes
cwdstring | nullno
timeout_secnumber | nullno
envobject | nullno

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError
504The command outlived timeout_sec (default 3600 s). Body: &#123;"detail", "code": "exec_timeout", "timeout_sec", "correlation_id"&#125;. Processes it started may still be running in the sandbox.—

Delete File

DELETE /sandbox/sandboxes/v1/{sandbox_id}/files

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
pathquerystringyes

Responses

StatusDescriptionBody
204Successful Response—
422Validation ErrorHTTPValidationError

Get File

GET /sandbox/sandboxes/v1/{sandbox_id}/files

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
pathquerystringyes

Responses

StatusDescriptionBody
200Successful Responseany
422Validation ErrorHTTPValidationError

Put File

PUT /sandbox/sandboxes/v1/{sandbox_id}/files

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
pathquerystringyes

Request body

application/json, required

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

List TCP ports listening inside the sandbox (user apps)

GET /sandbox/sandboxes/v1/{sandbox_id}/ports

Read-only probe of /proc/net/tcp&#123;,6&#125;; does not count as session activity.

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
include_internalquerybooleannoAlso return platform listeners (OpenVSCode :8080, IDE helpers).

Responses

StatusDescriptionBody
200Successful Responseobject
404Sandbox not found in the caller's tenant/project—
409Sandbox is not running—
422Validation ErrorHTTPValidationError
502The in-sandbox port probe failed—

Screenshot an app running inside the sandbox (headless Chromium)

POST /sandbox/sandboxes/v1/{sandbox_id}/screenshot

Load http://127.0.0.1:&#123;port&#125;&#123;path&#125; in the pod and store the PNG as an artifact.

Same artifact store as POST …/capture (GET …/artifacts lists it). Counts as session activity. Omit port when exactly one app is listening.

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
inlinequerybooleannoInclude the PNG as base64.

Request body

application/json, optional

Responses

StatusDescriptionBody
200Successful Responseobject
404Sandbox not found in the caller's tenant/project—
409Nothing is listening on the port, the sandbox is not running, or the image has no headless browser—
413PNG exceeds SANDBOX_VIEWER_SCREENSHOT_MAX_BYTES—
422Invalid target: external URL, redirect out of the sandbox, ambiguous auto-detection, or bad path/viewport—
502The app did not load (navigation error or timeout)—

Start Sandbox

POST /sandbox/sandboxes/v1/{sandbox_id}/start

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Stop Sandbox

POST /sandbox/sandboxes/v1/{sandbox_id}/stop

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Record activity (resets the idle auto-stop clock)

POST /sandbox/sandboxes/v1/{sandbox_id}/touch

Heartbeat between agent turns so idle auto-stop does not fire.

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful ResponseSandboxLifetime
422Validation ErrorHTTPValidationError

Verify Sandbox

POST /sandbox/sandboxes/v1/{sandbox_id}/verify

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Request body

application/json, required — VerifyRequest

FieldTypeRequiredDescription
require_verifier_evidencebooleannoDefault: false.

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Mint viewer URL or proxy the desktop viewer UI

GET /sandbox/sandboxes/v1/{sandbox_id}/viewer

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseany
422Validation ErrorHTTPValidationError

Upload the viewer action log (clicks, scrolls, keys, searches)

POST /sandbox/sandboxes/v1/{sandbox_id}/viewer/actions

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Request body

application/json, required — ActionLogRequest

FieldTypeRequiredDescription
eventsActionEvent[]yes
recording_idstring | nullnoRecording this log is time-aligned with.

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Submit a task-ambiguity label for the session

POST /sandbox/sandboxes/v1/{sandbox_id}/viewer/annotations

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Request body

application/json, required — AmbiguityAnnotation

FieldTypeRequiredDescription
clarity"clear" | "ambiguous"yes
ambiguity_types"intent" | "referential" | "parametric" | "cross_modal"[]noRequired when clarity is 'ambiguous'.
severity"low" | "medium" | "high" | "blocking" | nullno
risk"low" | "medium" | "high" | nullno
feasibility"feasible" | "partially_feasible" | "infeasible" | "unknown" | nullno
alternate_answersstring[]noOther defensible answers a solver could have given.
root_of_confusionstring | nullnoWhat in the task made it ambiguous.
task_promptstring | nullnoInstruction that was annotated.
notesstring | nullno
annotatorstring | nullno
recording_idstring | nullno
actions_idstring | nullno

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Upload a viewer session screen recording

POST /sandbox/sandboxes/v1/{sandbox_id}/viewer/recordings

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes
duration_secquerynumber | nullno

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Upload a screenshot captured from the viewer canvas

POST /sandbox/sandboxes/v1/{sandbox_id}/viewer/screenshots

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Start Viewer

POST /sandbox/sandboxes/v1/{sandbox_id}/viewer/start

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful ResponseViewerDescriptor
422Validation ErrorHTTPValidationError

Stop Viewer

POST /sandbox/sandboxes/v1/{sandbox_id}/viewer/stop

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Remint a fresh signed viewer URL (token refresh)

POST /sandbox/sandboxes/v1/{sandbox_id}/viewer/token

Issue a new viewer descriptor when the previous signed token is near expiry.

Requires API key / Keycloak / team token — not an expired viewer cookie. Gen Studio should call this and replace the iframe src with the new url.

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Responses

StatusDescriptionBody
200Successful ResponseViewerDescriptor
422Validation ErrorHTTPValidationError

Sync tenant GCS workspace ↔ guest SandboxWorkspace

POST /sandbox/sandboxes/v1/{sandbox_id}/workspace/sync

Parameters

NameInTypeRequiredDescription
sandbox_idpathstringyes

Request body

application/json, required — WorkspaceSyncRequest

FieldTypeRequiredDescription
direction"pull" | "push"yespull = GCS→guest SandboxWorkspace; push = guest→GCS snapshot.

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Create or reconnect to a paired desktop and private companion

POST /sandbox/sandboxes/v1/environments/pairs

Request body

application/json, required — CreatePairedEnvironmentRequest

FieldTypeRequiredDescription
attempt_keystringyesRequired stable trial/attempt identity. Reusing it with the same immutable pins reconnects to the same pair; changing it creates a clean pair.
taskPairTaskPinRequestyes
desktopPairDesktopPinRequestyes
companionPairCompanionPinRequestyes

Responses

StatusDescriptionBody
202Successful Responseany
422Validation ErrorHTTPValidationError

Asynchronously destroy both paired environment children

DELETE /sandbox/sandboxes/v1/environments/pairs/{pair_id}

Parameters

NameInTypeRequiredDescription
pair_idpathstringyes

Responses

StatusDescriptionBody
202Successful Responseany
422Validation ErrorHTTPValidationError

Get durable paired environment status

GET /sandbox/sandboxes/v1/environments/pairs/{pair_id}

Parameters

NameInTypeRequiredDescription
pair_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

Build-or-resolve a content-addressed desktop image

POST /sandbox/sandboxes/v1/images/build

Publish a curated desktop image via the platform BuildKit pool.

Default (async): 202 + build_id; poll GET …/images/build/&#123;build_id&#125; or stream GET …/images/build/&#123;build_id&#125;/events. Pass sync=true for the legacy hold-open behaviour (gateway long proxy timeout).

Parameters

NameInTypeRequiredDescription
syncquerybooleannoWhen true, hold the connection until BuildKit finishes (legacy).
Idempotency-Keyheaderstring | nullno
X-Sandbox-Job-Idheaderstring | nullno

Request body

application/json, required — BuildDesktopImageRequest

FieldTypeRequiredDescription
profilestringnoDefault: "desktop-ubuntu".
appsstring[] | nullnoCatalog desktop_app ids (e.g. chrome). Mutually exclusive with bundle.
bundlestring | nullnoCatalog desktop_app_bundle id (e.g. osworld). Mutually exclusive with apps.
datapoint_idstring | nullnoOptional builder tag prefix; defaults to sandboxes-{profile}.

Responses

StatusDescriptionBody
200Successful Responseany
422Validation ErrorHTTPValidationError

Poll desktop image build status

GET /sandbox/sandboxes/v1/images/build/{build_id}

Parameters

NameInTypeRequiredDescription
build_idpathstringyes

Responses

StatusDescriptionBody
200Successful Responseobject
422Validation ErrorHTTPValidationError

SSE desktop image build events

GET /sandbox/sandboxes/v1/images/build/{build_id}/events

Parameters

NameInTypeRequiredDescription
build_idpathstringyes
Last-Event-IDheaderstring | nullno

Responses

StatusDescriptionBody
200Successful Responseany
422Validation ErrorHTTPValidationError

Schemas

The object shapes referenced above.

ActionEvent

One operator interaction inside the viewer.

FieldTypeRequiredDescription
atnumberyesMilliseconds since the recording started.
typestringyesclick, scroll, key, search, screenshot…
xinteger | nullno
yinteger | nullno
delta_xnumber | nullno
delta_ynumber | nullno
keystring | nullno
textstring | nullno
detailobject | nullno

ActionLogRequest

FieldTypeRequiredDescription
eventsActionEvent[]yes
recording_idstring | nullnoRecording this log is time-aligned with.

AmbiguityAnnotation

Task-ambiguity label for a session, with its evidence references.

FieldTypeRequiredDescription
clarity"clear" | "ambiguous"yes
ambiguity_types"intent" | "referential" | "parametric" | "cross_modal"[]noRequired when clarity is 'ambiguous'.
severity"low" | "medium" | "high" | "blocking" | nullno
risk"low" | "medium" | "high" | nullno
feasibility"feasible" | "partially_feasible" | "infeasible" | "unknown" | nullno
alternate_answersstring[]noOther defensible answers a solver could have given.
root_of_confusionstring | nullnoWhat in the task made it ambiguous.
task_promptstring | nullnoInstruction that was annotated.
notesstring | nullno
annotatorstring | nullno
recording_idstring | nullno
actions_idstring | nullno

AppScreenshotRequest

Screenshot the user's app from a headless browser inside the sandbox.

FieldTypeRequiredDescription
portinteger | nullnoApp port inside the sandbox. Omit when exactly one app is listening.
urlstring | nullnoFull URL; host must be the sandbox itself (localhost, 127.0.0.1, ::1 or the pod IP). External URLs are rejected.
pathstring | nullnoPath on the app (with port), e.g. /dashboard?tab=1. Default /.
viewportViewportno
full_pagebooleannoDefault: false.
wait_msintegernoExtra settle time after the load event (HMR/SPAs render late). Default: 1500.

BuildDesktopImageRequest

Build-or-resolve a content-addressed desktop image from curated catalog apps.

FieldTypeRequiredDescription
profilestringnoDefault: "desktop-ubuntu".
appsstring[] | nullnoCatalog desktop_app ids (e.g. chrome). Mutually exclusive with bundle.
bundlestring | nullnoCatalog desktop_app_bundle id (e.g. osworld). Mutually exclusive with apps.
datapoint_idstring | nullnoOptional builder tag prefix; defaults to sandboxes-{profile}.

CreatePairedEnvironmentRequest

FieldTypeRequiredDescription
attempt_keystringyesRequired stable trial/attempt identity. Reusing it with the same immutable pins reconnects to the same pair; changing it creates a clean pair.
taskPairTaskPinRequestyes
desktopPairDesktopPinRequestyes
companionPairCompanionPinRequestyes

CreateSandboxRequest

FieldTypeRequiredDescription
profilestringnoDefault: "sandboxes-default".
sourceobject | nullnoWorkspace seed. &#123;type: archive_url|gcs_prefix, uri&#125;, &#123;type: snapshot, seq&#125;, or &#123;type: workspace_latest&#125; to restore the latest snapshot any earlier sandbox of the same task workspace (task_id / labels.task_id / labels.ctp_task_id, or workspace_key) wrote in this tenant/project. The create response's source names the snapshot it pinned (sandbox_id + snapshot_seq); with no snapshot yet the workspace starts empty.
image_refstring | nullnoImmutable pin from POST …/images/build: OCI repo@sha256:<digest> or gce:projects/{project}/global/images/{name}. Floating tags rejected.
autostop_secnumber | nullnoIdle seconds before the sandbox is stopped (default 1800). Returned on create/GET so clients can show session policy.
ttl_secnumber | nullnoHard max lifetime in seconds before destroy (default 86400). expires_at on the record is created_at + effective ttl. Values above the profile max_ttl_sec (default 30 days) are clamped and reported in warnings. With reuse=true a larger ttl extends the reused sandbox. Extend later with PATCH /v1/{sandbox_id}.
linked_job_idstring | nullno
task_idstring | nullnoOptional Gen Studio / CTP task id for labels and episode metadata; when omitted, sandbox_id is used.
reusebooleannoWhen true, return an existing non-destroyed sandbox whose create fingerprint matches (owner salt + tenant/project + profile + image_ref + workspace_key + purpose/template labels) instead of provisioning a new session. Default false so pass@k / episode reset stay create-always. Default: false.
reuse_saltstring | nullnoOptional client nonce mixed into the fingerprint salt. Rotate to force a fresh VM while keeping the same task_id. Required for fingerprinting when the caller has no Keycloak owner principal.
restore_latestbooleannoWhen true and no sandbox is reused, seed the new sandbox from the task workspace's latest snapshot (same as source.type=workspace_latest). Ignored when source is set or the task has no snapshot yet. Default false so creates stay fresh unless asked. Default: false.
labelsobjectnoConsumer tags for analytics (trainer, pass, program, …).

ExecRequest

FieldTypeRequiredDescription
commandstring[]yes
cwdstring | nullno
timeout_secnumber | nullno
envobject | nullno

HTTPValidationError

FieldTypeRequiredDescription
detailValidationError[]no

PairCompanionPinRequest

FieldTypeRequiredDescription
profilestringyesCatalog companion profile id (e.g. companion-drawio, companion-erpnext).
applicationstringyesCatalog desktop_app id with companion pins (e.g. drawio, erpnext).
state_model"file" | "stateful"yesMust match the catalog desktop_app state_model for application.
image_refstringyesImmutable OCI repo@sha256:<digest> companion pin.
application_versionstringyesCatalog application version. The server verifies that this version and image_ref are the exact catalog-owned pair for application.
evaluator_target"desktop" | "companion"noPinned evaluator target for this task revision. Default: "desktop".

PairDesktopPinRequest

FieldTypeRequiredDescription
profilestringnoDefault: "desktop-ubuntu".
image_refstringyesImmutable gce:projects/{project}/global/images/{name} desktop pin.

PairTaskPinRequest

FieldTypeRequiredDescription
task_idstringyes
revisionstringyesImmutable full initial-state revision or digest covering the task payload and all seeded file state. The paired-environment API does not import a separate companion state snapshot.

SandboxLifetime

Lifetime fields of a sandbox record (touch / lifetime responses).

FieldTypeRequiredDescription
sandbox_idstringyes
statusstringyes
last_activitynumberyesUnix epoch seconds of the last activity.
autostop_secnumber | nullnoIdle seconds before auto-stop; 0 or null = never.
idle_stop_atnumber | nullnoEpoch seconds when idle auto-stop fires if nothing else happens.
ttl_secnumber | nullnoTotal lifetime: expires_at - created_at.
expires_atnumber | nullnoUnix epoch seconds when the sandbox is destroyed.

UpdateSandboxLifetimeRequest

Change a sandbox's lifetime. Values above the profile cap are clamped.

FieldTypeRequiredDescription
ttl_secnumber | nullnoNew lifetime counted from now: expires_at becomes now + ttl_sec (may shorten or extend). Clamped to the profile max_ttl_sec (default 30 days).
expires_atstring | nullnoAbsolute ISO 8601 expiry (naive values are UTC). Mutually exclusive with ttl_sec; must be in the future; clamped to now + max_ttl_sec.
autostop_secnumber | nullnoIdle seconds before auto-stop. 0 disables idle stop (TTL still applies).

ValidationError

FieldTypeRequiredDescription
locstring | integer[]yes
msgstringyes
typestringyes
inputanyno
ctxobjectno

VerifyRequest

FieldTypeRequiredDescription
require_verifier_evidencebooleannoDefault: false.

ViewerDescriptor

Signed desktop viewer entry returned on running desktop/ide sandboxes.

FieldTypeRequiredDescription
urlstringyesGateway URL to open the viewer (includes signed token).
mode"novnc" | "guacamole" | "provider" | "selkies-ws" | "openvscode"yesIntegration mode for the external viewer_ui library.
embedstringnoDefault: "iframe".
input_enabledbooleanyesFalse while the sandbox is not in running status.
resolutioninteger[]no
expires_atintegeryesUnix epoch seconds when the signed viewer token in url expires. Remint via POST /v1/{sandbox_id}/viewer/token before this time.
guest_usernamestring | nullnoGuest OS login name when the provider exposes identity.
guest_hostnamestring | nullnoGuest OS hostname shown in the desktop shell.
guest_homestring | nullnoGuest home directory.
workspace_mountstring | nullnoGuest path for tenant workspace files (SandboxWorkspace).
stream_urlstring | nullnoOptional C1 gateway WebSocket path for pixels/input (/sandbox/stream/v1/{id}/websockify?ticket=…).
guest_urlstring | nullnoOptional ticket-authenticated guest health URL (/sandbox/stream/v1/{id}/guest/healthz?ticket=…).

Viewport

FieldTypeRequiredDescription
widthintegernoDefault: 1280.
heightintegernoDefault: 800.

WorkspaceSyncRequest

FieldTypeRequiredDescription
direction"pull" | "push"yespull = GCS→guest SandboxWorkspace; push = guest→GCS snapshot.

Machine-readable spec: OpenAPI YAML.

On this page

Common headersEndpointsList SandboxesParametersResponsesCreate SandboxRequest bodyResponsesReap SandboxesResponsesDestroy SandboxParametersResponsesGet SandboxParametersResponsesUpdate sandbox lifetime (TTL / expiry / autostop)ParametersRequest bodyResponsesList Sandbox ArtifactsParametersResponsesGet Sandbox ArtifactParametersResponsesCapture SandboxParametersResponsesSSE sandbox lifecycle eventsParametersResponsesExec SandboxParametersRequest bodyResponsesDelete FileParametersResponsesGet FileParametersResponsesPut FileParametersRequest bodyResponsesList TCP ports listening inside the sandbox (user apps)ParametersResponsesScreenshot an app running inside the sandbox (headless Chromium)ParametersRequest bodyResponsesStart SandboxParametersResponsesStop SandboxParametersResponsesRecord activity (resets the idle auto-stop clock)ParametersResponsesVerify SandboxParametersRequest bodyResponsesMint viewer URL or proxy the desktop viewer UIParametersResponsesUpload the viewer action log (clicks, scrolls, keys, searches)ParametersRequest bodyResponsesSubmit a task-ambiguity label for the sessionParametersRequest bodyResponsesUpload a viewer session screen recordingParametersResponsesUpload a screenshot captured from the viewer canvasParametersResponsesStart ViewerParametersResponsesStop ViewerParametersResponsesRemint a fresh signed viewer URL (token refresh)ParametersResponsesSync tenant GCS workspace ↔ guest SandboxWorkspaceParametersRequest bodyResponsesCreate or reconnect to a paired desktop and private companionRequest bodyResponsesAsynchronously destroy both paired environment childrenParametersResponsesGet durable paired environment statusParametersResponsesBuild-or-resolve a content-addressed desktop imageParametersRequest bodyResponsesPoll desktop image build statusParametersResponsesSSE desktop image build eventsParametersResponsesSchemasActionEventActionLogRequestAmbiguityAnnotationAppScreenshotRequestBuildDesktopImageRequestCreatePairedEnvironmentRequestCreateSandboxRequestExecRequestHTTPValidationErrorPairCompanionPinRequestPairDesktopPinRequestPairTaskPinRequestSandboxLifetimeUpdateSandboxLifetimeRequestValidationErrorVerifyRequestViewerDescriptorViewportWorkspaceSyncRequest