Skip to main content
A background process is a command that keeps running in the sandbox after your client disconnects, crashes, or restarts. Any program that holds its ID can read its output later. Before You Begin: BOXROUTER_API_KEY set and a client installed, as in the quickstart. The CLI examples that send input use jq.

Start It and Wait for the Exit

start runs your Bash command in a login shell and returns a process object right away. wait reads until the process has exited, then returns the same result as exec: stdout and stderr as text, and exit_code. Ask for output="bytes" (output: 'bytes' in TypeScript) to get the exact bytes of binary output.
The SDK examples dispose of the sandbox when their scope exits. The CLI example requests deletion on exit. If creation ends without a sandbox ID, follow Recover from Errors before retrying. A nonzero exit raises no error: wait returns it as exit_code, and boxrouter process wait exits with it. The process has no timeout of its own and ends when the sandbox’s lifetime ends or when you cancel it.

Advanced: Read Process Output over HTTP

In the CLI, boxrouter process read SANDBOX_ID PROCESS_ID prints a running process’s new stdout and stderr without waiting, then the --stdout and --stderr offsets for the next read, or the exit status once the process has ended. Start from offset 0 by passing neither. A raw HTTP read never waits for new output. It returns a bounded chunk plus next_stdout and next_stderr; pass those offsets on the next request so output is neither missed nor repeated. The response encodes stdout and stderr as Base64. REST has no blocking wait helper, so use the SDK wait() or CLI process wait for a complete result. See the read-process reference for the request and response fields. exit_code is null until the process has ended and both streams have been read to their ends. SDK wait() polls for you. If you give it a timeout, it raises TimeoutError (in Python and TypeScript) without stopping the process.

Reconnect from Another Process

Save the sandbox ID and the process ID. The first script below starts the process and exits without destroying anything. On an API that returns output fields, the second script reads the whole output from offset 0 and destroys the sandbox. If the start script fails before it prints both IDs, destroy the sandbox yourself; it keeps running and billing.
Later, from any process, pass both IDs to the second script:
Process output uses sandbox storage, so large output can fill the available space. After the process finishes, remove output you no longer need. The output is unavailable once the sandbox ends or is replaced. Read the result promptly: a process result is kept with a limit and can be lost. If a read returns 410 expired, the retained output is no longer available. BoxRouter does not run the command again.

Cancel and Clean Up

cancel (boxrouter process kill) ends the process group and returns once BoxRouter has accepted the request. Call wait or read to see the exit. Cancelling a finished process succeeds and does nothing.
The status of a cancelled process comes from the signal that ended it, so check for nonzero instead of an exact value. remove deletes a finished process’s retained output; afterwards a read answers 410 expired.

Send Input

To send interactive input, use a route that accepts process input after the API reconnects:
  1. Name processes.input in requirements when you check routes with client.sandboxes.match, and send the same requirement when creating the sandbox.
  2. Check matched.eligible. An empty list means no route satisfies the request.
Without the requirement, start fails with not_named and nothing runs.
write_stdin sends exactly your text, with no newline added. Write process input states what input guarantees, including after a reconnect. Start a process and Get observed process state have the full requests.

Next Steps

Work with Files

Move files in and out of a sandbox.

Connect to a Sandbox

Open a terminal or a preview URL.

How a Sandbox Runs and Ends

The clocks that bound a process.