Build

Sandboxes

Execute Python and Node.js code in isolated, network-disabled containers with per-second billing.

Sandboxes run short Python or Node.js programs in disposable, network-disabled containers on a dedicated sandbox node. Code never executes in the web or gateway process. Each execution is reserved, billed per second and receipted like an inference request.

Endpoint

POST/v1/sandbox/executions

Requires an API key with the sandboxes scope. The call is synchronous: it returns when the program exits or times out.

Request body

ParameterTypeRequiredDescription
runtimestringRequiredpython or node.
codestringRequiredComplete program source, 1–100,000 characters and at most 100 KB as UTF-8. Print results to stdout.
timeout_secondsintegerOptional1–30. Defaults to the sandbox configuration's timeout, or the project's maximum (30 s by default). Always capped by the project policy.
sandbox_idstringOptionalA sandbox configuration created in the console. Supplies runtime, timeout, memory and CPU settings; runtime must match. Unknown IDs return 404.

Programs receive no stdin and cannot open network connections.

Example

curl https://www.hushcompute.xyz/v1/sandbox/executions \
  -H "Authorization: Bearer $HUSH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "runtime": "python",
    "timeout_seconds": 10,
    "code": "import statistics\nprint(statistics.mean([3, 5, 8, 13]))"
  }'

Response

200 OK
{
  "id": "sbxr_01K58ZY3D5F7H9K2M4P6R8T1V3",
  "object": "sandbox.execution",
  "status": "completed",
  "exit_code": 0,
  "stdout": "7.25\n",
  "stderr": "",
  "stdout_truncated": false,
  "stderr_truncated": false,
  "duration_ms": 412,
  "runner": "docker",
  "receipt": {
    "id": "rcpt_01K58ZY3E8G1J3L5N7Q9S2U4W6",
    "hash": "0x1c7e…9d20",
    "signature": "0x44ab…f31c",
    "signer": "0x3A4c…91De",
    "url": "https://www.hushcompute.xyz/proofs/rcpt_01K58ZY3E8G1J3L5N7Q9S2U4W6"
  },
  "billing": {
    "cost_micro_usd": "40",
    "cost_usd": "0.00004",
    "fingerprint_salt": "0x8e30…b6a1"
  }
}
FieldTypeDescription
idstringExecution ID (sbxr_…). Recorded as request_id in the receipt.
objectstringsandbox.execution
statusstringcompleted, timeout or failed. See Statuses.
exit_codeinteger | nullThe program's exit code; null when it did not exit normally.
stdoutstringStandard output, up to the output cap.
stderrstringStandard error, up to the output cap.
stdout_truncatedbooleantrue if stdout exceeded the cap and was cut at a UTF-8 boundary.
stderr_truncatedbooleantrue if stderr exceeded the cap.
duration_msintegerWall-clock execution time. The billed duration.
runnerstringdocker in production. See Local development.
receiptobjectid, hash, signature, signer, url. Also sent as x-receipt-id.
billingobjectcost_micro_usd, cost_usd, and fingerprint_salt for the receipt's fingerprints.

A non-zero exit code is not an API error: the response is HTTP 200 and the execution is billed and receipted.

Limits

ResourceDefaultNotes
Timeout30 sPer execution; 1–30 s. The program is stopped when it is reached.
Memory256 MBNo swap. Configurable per sandbox between 64 and 512 MB, capped by the project policy (256 MB by default).
CPU0.5 vCPUConfigurable per sandbox, up to 2 vCPU.
Processes64Maximum PIDs inside the container.
Output64 KBPer stream: stdout and stderr are capped separately.
Workspace16 MB/workspace and /tmp are in-memory, non-executable filesystems. Files larger than 16 MB cannot be written.
Open files256
NetworkDisabledNo network interface is attached. It cannot be enabled.
Code size100 KB

Isolation

Separate execution node

The gateway sends each execution to a sandbox node over an authenticated internal protocol. Requests are signed with HMAC-SHA256 over the method, path, timestamp and body hash; the node rejects timestamps more than 60 seconds off and replayed execution IDs. Responses are signed too, and the gateway verifies the signature before a result is billed or committed to a receipt.

Per-execution container

  • A fresh container for every execution, removed afterwards. Nothing persists between executions.
  • No network (the container has no network interface).
  • Read-only root filesystem; only the in-memory workspace and /tmp are writable, and neither allows executing binaries.
  • Runs as an unprivileged, non-root user with all Linux capabilities dropped and privilege escalation disabled.
  • cgroup limits on memory (without swap), CPU and process count; file size, open file and core dump limits.
  • Code is passed to a fixed launcher over stdin, never through command-line arguments. Runtime images are pinned locally and never pulled at execution time.
  • Container logging is disabled, so program output is not persisted by the container runtime.

Pricing

Executions are billed per started second of wall-clock time, with a minimum of 1 second:

MemoryµUSD per secondUSD per hour
≤ 256 MB40$0.144
> 256 MB80$0.288

These are the default rates; operators can set a different per-second base price. Before execution the gateway reserves the cost of the full timeout, and it releases the unused part when the program finishes.

ExampleµUSDUSD
300 ms at 256 MB (1 s minimum)40$0.00004
2.4 s at 256 MB (3 started seconds)120$0.00012
10 s at 512 MB800$0.0008
Reservation for a 30 s timeout at 256 MB1,200$0.0012

Statuses and receipts

statusMeaningReceipt status
completedThe program ran and exited. Check exit_code for success.succeeded
timeoutThe program was stopped at the timeout.timeout
failedThe runtime could not complete the execution.failed

Receipts for executions have operation: "sandbox.execute", model: null, the runtime, zero token counts and latency_ms equal to the execution duration. The input fingerprint commits to {"code":…,"runtime":…} and the output fingerprint to {"exit_code":…,"stderr":…,"stdout":…} as returned. See Receipts.

Errors

TypeHTTPCause
invalid_request400Invalid runtime, empty or oversized code, timeout out of range, or runtime not matching sandbox_id.
insufficient_scope403The key lacks the sandboxes scope.
not_found404sandbox_id does not exist in this project.
budget_exceeded / insufficient_balance402The timeout reservation does not fit the limits or balance.
rate_limit_exceeded429Key or project requests-per-minute limit reached.
sandbox_error502The sandbox node was unreachable, rejected the request, or returned an unauthenticated or malformed response.
service_unavailable503Sandbox capacity is temporarily exhausted. Retry after 5 seconds.

When the node cannot run the code (sandbox_error, service_unavailable), the reservation is released and no receipt is issued.

Local development

The runner field states how an execution was handled. Production deployments use docker. Two development-only modes exist:

  • dev-process: runs code as a plain host process with no isolation. The sandbox node refuses this runner in production.
  • mock: used when no sandbox node is configured on a development deployment. Code is not executed; stdout says so.

Availability

CapabilityStatus
Python and Node.js executionsLive
Sandbox configurations (console)Live
Persistent sandbox sessionsComing soon
Network accessNot supported