Sign in

Run code from an AI agent in an isolated VM

Run an AI agent's commands in a microVM of its own: create a sandbox, run each command with a timeout, move files in and out, and delete it, with what it costs.

On this page8

Code an agent writes can delete files, fill a disk or loop forever, so run it away from the machine that runs the agent. A sandbox is a microVM made for that:

  • Its own kernel. A separate virtual machine, not a container sharing a kernel.
  • No sudo. Commands run as the user prized, so there is no apt; pip installs into a venv.
  • Outbound only. It reaches the internet, nothing reaches it from outside, and sandboxes cannot reach each other.
  • Gone when you delete it, disk and memory included.

1. Get an API key

Open Sandboxes and choose Create API key, or make one under Dashboard → Settings → API keys with Full access, or Custom with Sandboxes: Write. Then, where your agent runs, with curl and jq installed:

export PRIZED_API_KEY=dcp_…
API=https://api.prized.dev/api/v1
AUTH="Authorization: Bearer $PRIZED_API_KEY"

2. Create a sandbox

SBX=$(curl -s -X POST "$API/sandboxes" -H "$AUTH" -H "Content-Type: application/json" -d '{"template":"prized-base-v1","resources":{"vcpu":2,"memoryMb":4096},"maxRuntimeMin":60}' | jq -er '.sandbox.id // error(.error)') &&
while [ "$(curl -s "$API/sandboxes/$SBX" -H "$AUTH" | jq -r .sandbox.state)" = starting ]; do sleep 1; done &&
TOOLBOX=$(curl -s "$API/sandboxes/$SBX" -H "$AUTH" | jq -er .sandbox.toolboxBase) &&
curl -sS --retry 5 --retry-all-errors --fail -o /dev/null -X POST "$TOOLBOX/process/execute" -H "$AUTH" -H "Content-Type: application/json" -d '{"command":"true"}'

prized-base-v1 has Python 3, Node.js 22 and git; prized-agent-v1 adds Claude Code and Codex (Templates). maxRuntimeMin deletes the sandbox an hour after the create, so one your agent forgets stops costing money.

The &&s stop at the first failure, so a refused create prints its error and sends nothing else. The last line runs true until the sandbox takes commands: for a moment after running, a request can still answer 409 or 502 (The edge). Retry only a harmless command like this one, since after a 502 the command may have run.

3. Run the agent's command

CMD='python3 -c "print(sum(range(10)))"'
curl -s -X POST "$TOOLBOX/process/execute" -H "$AUTH" -H "Content-Type: application/json" -d "$(jq -n --arg c "$CMD" '{command: $c, timeout: 120}')"
# {"stdout":"45\n","stderr":"","exitCode":0,"durationMs":24}

jq --arg passes the command through unchanged, quotes included; hand stdout, stderr and exitCode back to the agent as the tool's result.

  • A failed command still answers 200; read exitCode.
  • timeout is in seconds, 300 unless set and 3,600 at most. At the limit, the command and the processes it started are killed ("exitCode": -1, "timedOut": true); one that left its process group, such as with setsid, runs on until you delete the sandbox.
  • State carries over from one command to the next. Commands run in /home/prized/work unless they name another cwd, and keep the first 4 MiB of each output stream.

4. Move files in and out

Here the agent's script main.py goes in and runs, and the out.csv it writes comes back:

curl -sS --fail -X POST "$TOOLBOX/files/upload?path=/home/prized/work/main.py" -H "$AUTH" --data-binary @main.py
curl -s -X POST "$TOOLBOX/process/execute" -H "$AUTH" -H "Content-Type: application/json" -d '{"command":"python3 main.py"}' | jq .exitCode
curl -sS --fail "$TOOLBOX/files/download?path=/home/prized/work/out.csv" -H "$AUTH" -o out.csv

Paths are absolute and inside /home/prized, up to 100 MiB a file (Sandbox API: Files). With curl --fail, a failed copy says so and exits non-zero, rather than saving the error as out.csv; delete the sandbox only after the download worked.

5. Delete it

curl -sS --fail -X DELETE "$API/sandboxes/$SBX" -H "$AUTH" > /dev/null

From the CLI

An agent with a shell can use the prized CLI (v0.21.0 or later), which reads PRIZED_API_KEY (CLI):

ID=$(prized sandbox create --vcpu 2 --memory 4 --max-runtime 1h)
prized sandbox cp main.py $ID:main.py
prized sandbox exec $ID --timeout 2m -- python3 main.py
prized sandbox cp $ID:out.csv out.csv &&
prized sandbox rm $ID

exec exits with the command's code, or 124 on a timeout.

What it costs

A running sandbox bills per second, with no minimum: $0.04 per vCPU-hour, $0.0125 per GB-hour of memory, and $0.0001 per GB-hour of disk (Billing: Sandboxes).

2 vCPU, 4 GB4 vCPU, 8 GB (the default)
Running, per hour$0.131$0.261
One sandbox for 5 minutes$0.011$0.022
1,000 of them$10.92$21.75

Both include the 10 GB disk; paused, a sandbox bills only its disk and saved memory.

On the free credit

The $30 of free credit covers about 2,700 five minute sandboxes at 2 vCPU. Until the workspace has paid in, it runs 4 sandboxes at once, 8 vCPU and 16 GB in total, each up to 2 vCPU, 4 GB and 60 minutes. A top-up or a plan lifts this to the full quotas and a lifetime of up to 24 hours, paused time included (Free credit limits).