Run a command and wait for its result, stream its output, or start a background command and poll it.
A sandbox runs commands in two ways. Pick the one that matches how long the work takes.
| ends when | read its output | |
|---|---|---|
POST /sandboxes/{sandbox_id}/exec | the request ends | in the answer, or as a stream |
POST /sandboxes/{sandbox_id}/commands | it exits, its timeout ends, you signal it, or its sandbox stops | poll the command |
Wait for the result
exec runs one command and answers its exit code and its output. It is the right call for a build step, a test run
or a script that ends in seconds or minutes.
curl -sS --fail-with-body "https://api.munito.ai/sandboxes/v1/sandboxes/$SANDBOX/exec" \
-H "Authorization: Bearer $MUNITO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"command": "pytest -q", "timeout": 600}'- A string runs in
bash -lc. A list is the argument vector itself. "stream": trueanswers NDJSON events as the command writes, instead of one result at its end.- A command runs for at most 1,800 seconds.
- The command ends with its request. A client that leaves kills the command.
Start a background command
A background command answers at once with an id, and keeps running. Use it for a dev server, a watcher, a long training step, or any work that outlives one HTTP request.
CMD=$(curl -sS --fail-with-body "https://api.munito.ai/sandboxes/v1/sandboxes/$SANDBOX/commands" \
-H "Authorization: Bearer $MUNITO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"command": "npm run dev"}' | jq -r .id)Then read it, poll it, and stop it:
# Its status and its whole output so far.
curl -sS --fail-with-body "https://api.munito.ai/sandboxes/v1/sandboxes/$SANDBOX/commands/$CMD" \
-H "Authorization: Bearer $MUNITO_API_KEY"
# Only what the command wrote after the first 4,096 bytes of each stream.
curl -sS --fail-with-body \
"https://api.munito.ai/sandboxes/v1/sandboxes/$SANDBOX/commands/$CMD?stdout=4096&stderr=4096" \
-H "Authorization: Bearer $MUNITO_API_KEY"
# Ask it to stop with SIGTERM, or send 9 for SIGKILL.
curl -sS --fail-with-body "https://api.munito.ai/sandboxes/v1/sandboxes/$SANDBOX/commands/$CMD/signal" \
-H "Authorization: Bearer $MUNITO_API_KEY" \
-H "Content-Type: application/json" -d '{"signal": 15}'GET /sandboxes/{sandbox_id}/commandslists them, the newest first, with no output.statusisrunning, thenexitedwith anexit_code, orfailedwhen the sandbox lost the command.- A command that a signal stopped has the
exit_code128 plus the signal. - A
DELETEkills a command that runs and drops what the sandbox keeps of it.
Read the output as it grows
Each answer carries stdout_bytes and stderr_bytes: the bytes of each stream so far. Pass them back as stdout
and stderr, and the next answer holds only what follows. A poll loop then reads each byte once.
What a sandbox holds
- A sandbox runs 16 background commands at once. Start one more and it answers
too_many_commands. - The sandbox keeps 1 MiB of each stream. A command that writes more sets
truncated, and the rest is left out. Write the output to a file for more, and read the file. - The commands live with their sandbox. A pause, a stop and a restart of the sandbox all end them, and the sandbox then holds no record of them.
- A background command runs for at most 24 hours, and the timeout of its sandbox still ends it first.