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
You run a command synchronously or asynchronously, depending 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, or quota_exceeded.
Timeouts
For blocking run, timeoutMs defaults to 60000 ms (1 minute); start
has no default timeout. Both accept up to 600000 ms (10 minutes). A command
that exceeds its timeout ends with status timed_out.
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: afterSeq and limit
(default 100, 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. Every event has a
type and createdAt. A log event adds seq, data, and stream; a
terminal event adds the final command; an error event adds code and
message. 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 isn't available yet. It
returns feature_not_enabled, since log download URLs require log archive
storage. To get the full output, page the logs endpoint with
afterSeq/nextSeq.
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 with afterSeq/nextSeq.
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