Commands
How command execution, statuses, timeouts, cancellation, and logs work in CrowNest sandboxes.
A command is a top-level process invocation record. You run commands inside
a sandbox either synchronously (run, which waits for exit) or
asynchronously (start, which returns immediately), then inspect the
result, cancel it, or follow its logs.
Run vs start
CrowNest offers two ways to execute a command, and the right one depends on how long the process runs.
POST /v1/sandboxes/{id}/commands/runwaits for the process to exit and returns the completed command, includingexitCode,stdout, andstderr. It also acceptscollectandcollectOnto export artifacts when the command finishes.POST /v1/sandboxes/{id}/commands/startreturns202immediately with the command in statusqueuedorstarting. PollGET /v1/commands/{commandId}or follow the log stream to track it.startdoesn't acceptcollectorcollectOn.
Both endpoints take command (required, non-empty), plus optional cwd,
env, and timeoutMs. Both are idempotent with an Idempotency-Key
header. We recommend run for short tasks and start for servers and
long-running work.
Statuses
The status field tracks the command through its lifecycle.
| Status | Meaning |
|---|---|
queued | Accepted, waiting to start. |
starting | The process is launching. |
running | The process is executing. |
exited | The process exited on its own; check exitCode. |
failed | The command could not run or failed abnormally. |
canceled | You canceled the command. |
timed_out | The command exceeded timeoutMs. |
killed | The sandbox was destroyed while the command ran; killedReason is sandbox_destroyed. |
Exit codes vs API errors
A non-zero exit code is not an API error. If your process runs and exits
with status 3, the API call still succeeds: the command has status exited
and exitCode: 3. Check status and exitCode on the command object to
decide whether the work succeeded.
API errors (the { "error": { "code", ... } } envelope) mean the request
itself failed — for example invalid_request, forbidden, not_found,
sandbox_destroyed, quota_exceeded, or command_timed_out.
Timeouts
Every command has a timeout. timeoutMs defaults to 60000 ms (1 minute)
and accepts up to 600000 ms (10 minutes). A command that exceeds its
timeout ends with status timed_out. Plan-level command duration limits
also apply; they're configurable beta defaults, so check your plan.
Environment variables
Pass env as a string map to set environment variables for the process.
Two rules apply:
- You can't set keys with the reserved
CROWNESTprefix; doing so returnsreserved_env_key. See injected environment context. - Values are ephemeral and never persisted. Pass them on each command.
Cancellation
Cancel a running command with POST /v1/commands/{commandId}/cancel. The
body takes an optional mode:
graceful(default) — asks the process to terminate (SIGTERM).force— kills the process immediately (SIGKILL).
The canceled command records cancelMode, canceledAt, and
terminationSignal. Cancellation is idempotent by state: canceling an
already-finished command doesn't error.
Logs
Command output is captured as ordered chunks, each with a sequence number
(seq) and a stream (stdout or stderr). There are three ways to get
logs.
Paginated chunks
GET /v1/commands/{commandId}/logs returns
{ data, hasMore, nextSeq? }. Query parameters: stream (stdout,
stderr, or combined, default combined), afterSeq, and limit
(default 50, max 100). Page with afterSeq=nextSeq until hasMore is
false.
Live SSE stream
GET /v1/commands/{commandId}/stream is a server-sent events stream. Event
types are log, heartbeat, terminal, and error, with fields seq,
type, timestamp, data, and stream. Resume after a disconnect with
the afterSeq query parameter or the Last-Event-ID header. If you resume
from a sequence outside the retention window, the stream returns a
stream_gap error.
Full download
POST /v1/commands/{commandId}/logs/download-url with body { stream }
returns { url, method: "GET", expiresAt } — a short-lived URL for the
complete log of that stream.
Output truncation
The stdout and stderr fields inlined on the command object can be
truncated for large outputs; stdoutTruncated and stderrTruncated tell
you when that happened. To get the full output, page through the logs
endpoint or request a log download URL.
Next steps
- Sandboxes — lifecycle and TTL behavior that affects running commands.
- Artifacts — export files with
collectandcollectOn. - SDK quickstart — run your first command.
- Commands API reference