Hanzo
Concepts

Sandboxes

The one compute primitive — a lease on a pod that runs somebody else's code. Four classes, two ways to end one, and no pool.

After this page you can run untrusted code and know exactly when it stops costing you money.

One primitive

A sandbox is a pod under a runtime boundary with a toolchain already in it, its own filesystem, and a lease that ends it. There is one object and one lifetime — a throwaway Python run and a multi-hour coding session are the same thing with different bounds.

curl -X POST https://api.hanzo.ai/v1/sandbox/lease \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"class":"exec"}'
hanzo sandboxes list

Every other operation acts on the sandbox that call returns.

Four classes

A closed set. Empty means exec.

ClassWhat it isWorking directoryLives for
execthrowaway; keeps nothing/mnt/dataseconds to minutes
devcoding, with the project disk attached/workhours
desktopdev plus a screen/workhours
androiddesktop plus a phone on that screen/workhours

Every class but exec requires a project, and a project has one live sandbox at a time — a second lease over a project that already has one is refused by name rather than silently giving you a second machine.

You may request a runtime (gvisor or kata-fc); the owner decides, and the answer tells you what you actually got.

Two verbs for ending, and the difference matters

stop ends the work. end ends the resource. A run that went wrong is still readable after stop, which is the whole reason they are two verbs.

Beyond that, ttlSec bounds the lease, and a reaper runs every minute: it ends expired leases and sleeps sandboxes idle for more than an hour. There is no pool — a sandbox is created for a lease and deleted at its end, and names are never reused, so a stale id can never reach somebody else's machine.

What the pod can do

Not what you can. Your credential never reaches the pod. A lease is handed one short-lived token, obtained by token exchange against your identity, acting as the hanzo-sandbox client, expiring with the lease, with no refresh token. The pod carries no cluster credential of its own.

Isolation is physical: a sandbox store is one file per org.

exec: a session is a sandbox

exec runs a whole program in one call, in thirteen languages — py, js, ts, bash, r, php, go, rs, c, cpp, java, d, f90.

curl -X POST https://api.hanzo.ai/v1/exec \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"language":"py","code":"print(6*7)"}'

It owns no store and no lifetime of its own — the session id it returns is a sandbox id. A non-zero exit is a 200 with stderr, not an error status: the call succeeded, the program failed, and those are different facts. Pass the same session_id again to keep the filesystem between runs.

Where it meets agents

POST /v1/sandbox/run narrates into a named session, and its output appends to that session's live log — the one an agent session stream is already watching. That is the seam between the two: a sandbox does the work, a session is the record of it.

Next

How is this guide?

On this page