Reference / Agent Sandboxes

Run a command

Run bash -lc in a running sandbox and stream stdout, stderr and the exit result.

POST/v1/customer/tenants/{tenantId}/sandboxes/{sandboxId}/exec

Base URL: https://api.runzivo.dev

Authentication

Send Authorization: Bearer <token> with a customer access token or workspace API key.

API key permission: sandboxes:write. These are permissions, not legacy scopes. A key with the all:all scope also works, limited by its creator's current workspace permissions.

Parameters

Path and query parameters
FieldDescription
tenantIdstring · pathRequiredYour workspace's tenant ID. Replace the placeholder with an ID your token can access.
sandboxIdstring · pathRequiredThe id returned when the sandbox was created: sbx_ followed by 24 lowercase hexadecimal characters.

Request body

Send Content-Type: application/json.

JSON request fields
FieldDescription
cmdstringRequiredNonblank shell command, at most 64 KiB; no NUL bytes. Runs as bash -lc.
cwdstringOptionalAbsolute working directory; default /workspace. Published schema maximum: 1024 characters.
envobjectOptionalUp to 64 environment variables. Names match ^[A-Za-z_][A-Za-z0-9_]{0,127}$; values at most 8192 bytes, without NUL.
timeout_secondsintegerOptional1–3600 seconds; default 300 when omitted.

Behavior and limits

  • Send application/json; request body limit 128 KiB. Up to four concurrent commands per sandbox; otherwise 409 session_limit_reached.
  • Each stdout/stderr line has base64 data. The final exit line has exit_code, timed_out and truncated; reason appears when the sandbox stopped, expired or was deleted.
  • Disconnecting cancels the command. Output is capped at 8 MiB. A timed-out command still running 30 seconds past its timeout is cancelled with exit code 124; truncation ends with code 137.

Responses

HTTP response codes
StatusMeaning
200 Stream openedapplication/x-ndjson
400 Invalid requestMalformed JSON, unknown fields or invalid values. Terminal upgrades also reject malformed handshakes.
401 UnauthorizedMissing or invalid bearer token. A ticketed terminal request can instead return ticket_invalid.
403 ForbiddenThe caller lacks workspace membership or permission, or the API key is not allowed. Codes include tenant_membership_required, permission_required and api_key_scope_required.
404 Not foundNo sandbox with this ID exists in the authorized workspace.
409 ConflictThe operation is not allowed in the current sandbox state. See the operation notes for other possible conflict codes.
500 Internal errorThe server could not complete the request.
503 UnavailableSandbox service is unavailable. Exec and terminal operations can also return sandbox_exec_unavailable.

Examples use synthetic IDs, dates and values. Read the actual response and status in your workspace.

Sandbox limits and billing →

Page tools

View as Markdown
Ask AI about this pageOpen in ChatGPTOpen in ClaudeOpen in Cursor

Claude shows a caution banner on any prefilled prompt. That is expected: review the prompt, then send it.

Request example

Illustrative request. Set RUNZIVO_TOKEN and TENANT_ID, and SANDBOX_ID in your shell. Replace placeholders with your own values. This page does not send requests.

cURL
curl --no-buffer --request POST \
  "https://api.runzivo.dev/v1/customer/tenants/${TENANT_ID}/sandboxes/${SANDBOX_ID}/exec" \
  --header "Authorization: Bearer ${RUNZIVO_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{
  "cmd": "printf '"'"'hello\\n'"'"'",
  "cwd": "/workspace",
  "timeout_seconds": 300
}'

Response example

application/x-ndjson · Illustrative stream. Decode each output chunk's data from base64. These are separate lines, not a JSON array.

200 · application/x-ndjson
{"type":"stdout","data":"aGVsbG8K"}
{"type":"exit","exit_code":0,"timed_out":false,"truncated":false}
All response examples (also available without JavaScript)

200 Stream opened

Illustrative stream. Decode each output chunk's data from base64. These are separate lines, not a JSON array.

application/x-ndjson
{"type":"stdout","data":"aGVsbG8K"}
{"type":"exit","exit_code":0,"timed_out":false,"truncated":false}

400 Invalid request

Malformed JSON, unknown fields or invalid values. Terminal upgrades also reject malformed handshakes.

application/json
{
  "error": {
    "code": "invalid_request"
  }
}

401 Unauthorized

Missing or invalid bearer token. A ticketed terminal request can instead return ticket_invalid.

application/json
{
  "error": {
    "code": "unauthorized"
  }
}

403 Forbidden

The caller lacks workspace membership or permission, or the API key is not allowed. Codes include tenant_membership_required, permission_required and api_key_scope_required.

application/json
{
  "error": {
    "code": "permission_required"
  }
}

404 Not found

No sandbox with this ID exists in the authorized workspace.

application/json
{
  "error": {
    "code": "sandbox_not_found"
  }
}

409 Conflict

The operation is not allowed in the current sandbox state. See the operation notes for other possible conflict codes.

application/json
{
  "error": {
    "code": "sandbox_wrong_state"
  }
}

500 Internal error

The server could not complete the request.

application/json
{
  "error": {
    "code": "internal_error"
  }
}

503 Unavailable

Sandbox service is unavailable. Exec and terminal operations can also return sandbox_exec_unavailable.

application/json
{
  "error": {
    "code": "sandboxes_unavailable"
  }
}

Ask Docs

Ask a question and open it in your AI assistant. The prompt tells it to answer from the Runzivo docs and link the pages it used.

Try asking

Your question opens in the assistant you pick, under its own terms. Runzivo does not see or store it.