Run commands
Last updated 3 November 2026
Machines are not open yet. These pages describe Machines as they will open; until then, a create answers region_not_offered (422), “Machines are not offered in any region yet.”
Run one command in a Machine over HTTPS and get its output, its exit status and how it ended in the answer. The command lives exactly as long as the call: an agent’s tool call, a test run, a quick look at what is on disk.
Planned Not served yet. This page describes how it will work, as decided; until it is served, every request below answers 404 at https://api.us-east-1.tonbo.sh/v1. The Machines API reference lists each operation, marked Planned.
Run a command
Send the command as an argv to the cell origin of the Machine’s region, with a key of your account:
curl -sS https://api.us-east-1.tonbo.sh/v1/machines/hello/exec \
-H "Authorization: Bearer $TONBO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"command": ["ls", "-la", "/app"], "timeout_seconds": 60}'The answer is one document once the command has ended:
{
"data": {
"op": "0193a6c4e8a07d2c9f3b5a1e6d4c2b10",
"deadline": "2026-11-03T09:31:00Z",
"reason": "exited",
"exit_code": 0,
"signal": null,
"duration_ms": 41,
"killed_processes": 0,
"stdout": { "encoding": "utf-8", "head": "total 8\n…", "tail": "", "bytes": 312, "omitted_bytes": 0 },
"stderr": { "encoding": "utf-8", "head": "", "tail": "", "bytes": 0, "omitted_bytes": 0 },
"machine": { "woke": false, "…": "…" }
}
}With Accept: application/x-ndjson it streams instead, one JSON object per line: a start line, then stdout and stderr lines (base64) in the order the command wrote them, a tick after 30 seconds without output, and an end line with the same fields as the document.
How the command runs
- Without a shell:
command[0]is found on the program’sPATH. Run["sh", "-c", "…"]for pipes and globs. - In
cwd, the image’s working directory by default, with the program’s environment plus the call’senv, and stdin fromstdin(base64, up to 1 MiB) or empty. - As
user: a name or uid from the image’s/etc/passwd, orroot; the image’s user when you leave it out. - With the program’s resource limits, 1,048,576 open files among them; a command may lower its own, or raise them as root.
Limits
timeout_secondsis 10 minutes by default and at most 1 hour, counted from the command’s start, after any wake. Longer work is a background process.- Output is capped at 64 MiB, both streams together; the document keeps the first and the last 512 KiB of each.
- The request body is at most 2 MiB, and a Machine runs at most 16 commands at once, an account 64.
The command ends, and everything it started with it, when it exits, at its deadline, at the output cap, when it is killed, or when your connection closes or stops reading.
Waking and staying awake
A call wakes an asleep Machine first, with the same checks and the same credit as any wake (see Sleep, wake and stop), and its answer says whether it woke the Machine. While a command runs, it keeps the Machine awake. Every wake starts fresh, so a command that woke the Machine sees its image, its database and its Volume, not files an earlier wake left on other disks (see What lasts).
Tonbo-Wake: neverruns the command only if the Machine is awake, and otherwise answers 409 without waking it.expect_activation, theTonbo-Activationof an earlier answer, runs it only in that same boot, and otherwise answers 409activation_changed, so a sequence of calls never lands half on a fresh boot.- Between calls, a hold keeps the Machine awake.
When the answer is lost
- A 200 means the command started exactly once.
- Any refusal other than 502
lostmeans it did not start. - A 502
lost, or a connection that broke before the answer began, means Tonbo does not know whether it started. Send the same request with the sameIdempotency-Key: the repeat answers the first call’s record and never runs it again. Keys are kept 24 hours.
Refusals
- 422
command_not_found,command_not_executable,cwd_not_foundoruser_not_found: nothing ran. - 409
activation_changed: another boot runs, or none does; nothing woke. - 429
exec_limit: too many commands run at once; wait for one to end. - A wake’s own refusals, such as 402
payment_required, pass through as a request to a port gets them.
What a command writes outside the Volume is gone at the next sleep: keep results in the database or on the Volume.