Run commands and files
Run a command on your box and get its exit code, leave one running and follow it live, read any command's output later even with the box paused, or copy files either way, from the CLI or any script holding an API key, with nothing to install on the box.
Run a command
prized exec -- make testIt runs under sh -c in your home directory on the box with your local stdin connected, and stdout, stderr, and the exit code come straight back. A suspended box wakes first; a box name before -- picks another box.
| Command | What it does |
|---|---|
prized exec -- npm test | Run in your home on the default box; the exit code is npm test's. |
prized exec box-a7f3 --cwd app -- npm test | Run on a named box, in ~/app (--cwd is relative to your home, or absolute). |
prized exec --timeout 10m -- ./build.sh | Kill the command after 10 minutes (TERM, then KILL 5 s later): exit 124, and stderr ends with prized: command timed out after 600s (SIGTERM). No limit by default. |
prized exec --env CI=1 --env NODE_ENV=test -- npm test | Add environment variables (repeatable, up to 32). |
prized exec --json -- make | Capture instead of stream: one object with exitCode, signal, timedOut, stdout, stderr. |
- Quoting. The words after
--are joined and passed tosh -c, so quote as for ssh:prized exec -- 'cd app && npm test'runs both halves on the box. It is a plainsh, not your login shell; tools only your.bashrcputs on PATH needprized exec -- bash -lc 'npm test'. --timeouthere limits the command, not the network request as on other commands.- Exit code: the remote command's, or ssh's 255 when the box was unreachable, after a
prized:line saying why (Troubleshooting). With--json,oksays whether the command ran andexitCodewhat it returned; an unreachable box exits 3 with the reason inerror.timedOutis true only when the time limit ended the command (one exiting 124 by itself isexitCode: 124, timedOut: false).
Detached processes
prized exec --detach -- ./train.sh
# started p_3f9c0a1b2d4e (pid 41213) in /home/ubuntu--detach returns a process id at once; the process outlives your terminal and ssh session, logging to files on the box.
| Command | What it does |
|---|---|
prized exec --detach -- CMD | Start CMD detached (--cwd and --env apply) and print its id. |
prized exec --status p_3f9c0a1b2d4e | Running or exited, the exit code or signal, start and finish times, and the tail of each log. |
prized exec --status p_… --tail 1m | How much of each log to show: bytes, or 4k, 1m (default 16k, cap 1m). |
prized exec --kill p_3f9c0a1b2d4e | Stop it: TERM to its process group, then KILL if it is still there after 5 s. |
prized exec --ps | Every detached process on the box, running or finished. |
prized exec logs p_3f9c0a1b2d4e --follow | Print its output live until it ends, then exit with its exit code (Command history). |
--status, --kill, and --ps never wake a suspended box (they exit 5 and say so); starting a command does. logs --follow never wakes one either: it prints what the history keeps and exits 0 while the command is still running. The process id is also the command's id in its history.
Each detached process keeps everything in one directory on the box, for ls, tail -f, and your scripts:
File in ~/ | Contents |
|---|---|
cmd, cwd | The command line as given, and the absolute directory it ran in. |
pid | The process id (also its process group id). |
boot_id | The box's boot id at start. After a reboot the process reads as lost and is never signalled; Medium and larger boxes reboot on resume, any box after a resize, a region move, or a wake from deep sleep (Pause and resume). |
started_at | Start time, RFC 3339 UTC. |
stdout.log, stderr.log | The output, appended as it happens. |
exit | Written when the command ends: the exit code, or 128 + signal. |
Command history
prized exec history
# ID STATUS MODE STARTED COMMAND
# p_3f9c0a1b2d4e exited 0 detached 2026-10-11 14:02:11 ./train.sh
# p_81c07e9d55a0 exited 1 sync 2026-10-11 13:58:40 npm testEvery command prized exec or POST /exec runs, in the foreground or detached, is recorded: the command line, the directory, who ran it, how and when it ended, how many bytes it printed, and up to the last 1 MiB of its stdout and of its stderr. History lives with Prized, not on the box, so it reads the same while the box is paused or stopped. Each record is kept 30 days.
| Command | What it does |
|---|---|
prized exec history [BOX] | The box's commands, newest first; --limit N and --before CURSOR page through older ones. |
prized exec logs [BOX] ID | One command's stdout, as much as is kept; --stderr for stderr, --offset N to start at a byte. |
prized exec logs ID --follow | A running detached command's output live, from the box, until it ends; then the command's exit code. |
prized exec history --delete ID | Delete one record and its output. |
prized exec history --delete-all | Delete every record of the box (asks unless -y). |
- Terminal display: logs remove control characters except tabs and newlines, so colors and cursor movements are not replayed. Files and pipes receive the original bytes; view those exports with a terminal-safe viewer.
--offsetcounts original bytes, not displayed characters. - Status is
running,exited,killed(ended by a signal),timed_out,failed(it never ran: the box was unreachable, or a detached start failed), orlost(the box restarted under a detached command, or it reported nothing for 24 hours). - Detached output reaches the history from the box every few seconds; the last few seconds before a pause show up once the box runs again.
--followreads the box itself, so it is live and complete. - Untrusted live address: if
--followrefuses the live-log address, it says so and prints retained history instead, without sending your login token there. Output may be incomplete while the command is still running. - Past 1 MiB a stream keeps its end and is marked truncated (
stdoutTruncated). A stream also keeps at most 256 stored chunks: adjacent small writes are combined, but gaps can make this limit trim older output sooner. Output pages report missing bytes asskipped. The log in~/on the box keeps everything..prized/ processes/ <id>/ - Who can read it: anyone in the workspace who can see the box, so a contractor only their own boxes, and a key limited to some boxes only those boxes (any other answers
404). A limited API key needs Boxes: Write to read history, since command lines and output can carry secrets. - Deleting the box deletes its history.
Copy files
prized cp ./notes.md :notes.mdprized cp works like scp: exactly one side is on the box, written BOX:PATH (a bare :PATH is the configured box), and box paths are relative to your home unless absolute. Files are written whole and keep their modes, so an interrupted copy never leaves a half-written file; if one file fails, the copy stops with its error and the files already copied stay.
- Symlinks are skipped and counted, one named as
SRCincluded: name the file it points at instead. - Hard links (common in pnpm and Nix trees) are skipped and counted the same way, and refused as
SRC: copy the file to a new name to send it. - A download writes only under
DST: an entry that would land outside it stops the copy, and so does a target directory that is itself a symlink (name the directory it points at).
| Command | What it does |
|---|---|
prized cp ./file.txt : | Copy a file into your home on the box, keeping its name. |
prized cp -r ./site box-a7f3:www | Copy a directory tree (-r is required for directories). |
prized cp box-a7f3:logs/app.log ./ | Copy a file from the box into the current directory. |
prized cp -r :proj/dist ./dist | Copy a directory tree from the box. |
For a live view of the whole box in Finder instead, see Mount.
The edge API
Everything above is also HTTP, for scripts and agents with no prized installed: routes sit under $EDGE/v1/box/{box}/ (the box's name or id), the bearer is an API key from Dashboard → Settings → API keys, and the base URL is edge.url in GET /api/v1/me.
export PRIZED_API_KEY=dcp_…
EDGE=$(curl -s -H "Authorization: Bearer $PRIZED_API_KEY" https://api.prized.dev/api/v1/me | jq -r .edge.url)Only POST /exec wakes a suspended box; the other routes answer box_not_running. Every route, and how paths are read, is on API reference: The edge; the box's coding agent has its own, on Prompt an agent remotely. History is read from the control plane instead (API reference: Command history), so it needs no running box.
GET /exec/{processId}/stream follows a detached process as Server-Sent Events, with byte offsets you reconnect from:
curl -sN -H "Authorization: Bearer $PRIZED_API_KEY" "$EDGE/v1/box/ci-42/exec/p_3f9c0a1b2d4e/stream?stdoutOffset=0&stderrOffset=0"
# event: attached
# id: 0:0
# data: {"processId":"p_3f9c0a1b2d4e","stdoutOffset":0,"stderrOffset":0}
#
# event: stdout
# id: 13:0
# data: {"data":"compiling...\n","offset":0,"nextOffset":13}
#
# event: exit
# id: 13:0
# data: {"status":"exited","exitCode":0,"signal":null,"stdoutOffset":13,"stderrOffset":0}A heartbeat event comes after 15 seconds of silence; after 10 minutes the stream sends reconnect with the offsets and ends, so open it again from there (an EventSource resumes by itself from the id: line). Reading from the box's own log, a reconnect never skips or repeats a byte.
Errors
A failed request answers {"ok": false, "error": {"code", "message"}}; every code is on API reference: Errors.
Limits
Caps for runs, files, and the edge API, request rate included, are on Limits.