CrowNest
Concepts

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/run waits for the process to exit and returns the completed command, including exitCode, stdout, and stderr. It also accepts collect and collectOn to export artifacts when the command finishes.
  • POST /v1/sandboxes/{id}/commands/start returns 202 immediately with the command in status queued or starting. Poll GET /v1/commands/{commandId} or follow the log stream to track it. start doesn't accept collect or collectOn.

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.

StatusMeaning
queuedAccepted, waiting to start.
startingThe process is launching.
runningThe process is executing.
exitedThe process exited on its own; check exitCode.
failedThe command could not run or failed abnormally.
canceledYou canceled the command.
timed_outThe command exceeded timeoutMs.
killedThe 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 CROWNEST prefix; doing so returns reserved_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

On this page