CrowNest
API reference

Workspace Runs

Run an uploaded workspace archive in a curated CrowNest environment, stream events, and read durable evidence.

Workspace Runs are CrowNest's archive-based execution surface for agent and repo workflows. Create a run, upload a gzipped tar archive, start execution, stream events, then read the Evidence Bundle after the sandbox is gone.

Use Workspace Runs when you want CrowNest to execute a checked-out project, test suite, build, or agent-produced archive without keeping a sandbox open manually.

The API key needs workspace_run:create, workspace_run:read, and workspace_run:cancel for the run lifecycle. Runs that export artifacts also need artifact:create and file:read.

Archive input

Upload an existing .tar.gz or .tgz archive. The public API does not pack a local directory for you. For dirty checkout sync, use a client such as Crabbox or build the archive before calling CrowNest.

The Workspace Run object

FieldTypeDescription
idstringWorkspace Run ID, prefixed wsr_.
projectIdstringProject that owns the run.
statusstringawaiting_archive, archive_uploaded, starting, extracting, running, collecting, succeeded, failed, or canceled.
commandstringShell command executed after archive extraction.
templateSlugstringCrowNest template slug, such as python-node.
templateVersionIdstringFrozen CrowNest template version used for placement.
archiveobjectUploaded archive checksum, size, and upload timestamp.
artifactIdsarrayArtifacts collected from explicit artifact requests.
artifactErrorsarrayPer-path artifact collection errors.
cleanupStatusstringsucceeded, failed, pending, or not_requested.
evidenceAvailablebooleanTrue only when the durable Evidence Bundle has been persisted and GET /evidence can read it.
exitCodeintegerCommand exit code after completion.
failureClassstringuser_input, user_command, platform, or canceled when failed.
failureReasonstringStable failure reason, such as command_exit, timeout, or extraction_failed.
sandboxIdstringInternal CrowNest sandbox ID when available. Provider IDs are never exposed.

Create a run

POST /v1/workspace-runs — requires workspace_run:create. Accepts an Idempotency-Key header.

FieldTypeRequiredDescription
commandstringYesShell command to run after archive extraction.
projectIdstringNoProject to create the run in. Defaults to the key's project context.
templatestringNoCrowNest template slug. python-node is the launch template and default.
templateVersionIdstringNoSpecific CrowNest template version.
sandboxIdstringNoWarm sandbox to reuse. Its template must match the run template.
keepSandboxbooleanNoKeep the sandbox after the run instead of cleaning it up.
timeoutMsintegerNoCommand timeout in milliseconds.
metadataobjectNoSmall string labels for listing and evidence.
sourceMetadataobjectNoCaller-supplied source labels, such as repo or commit.
artifactsarrayNoExplicit relative paths to collect after the command finishes.

Artifact collection also requires artifact:create and file:read.

Terminal
curl -X POST https://api.crownest.dev/v1/workspace-runs \
  -H "Authorization: Bearer $CROWNEST_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: repo-test-01" \
  -d '{
    "template": "python-node",
    "command": "pnpm test",
    "timeoutMs": 120000,
    "artifacts": [{ "path": "coverage/lcov.info", "name": "coverage" }],
    "sourceMetadata": { "repo": "acme/app", "commit": "abc123" }
  }'

Returns 201 with { "workspaceRun": { ... } } and status awaiting_archive.

Upload an archive

For small archives, upload raw gzipped tar bytes directly:

PUT /v1/workspace-runs/{workspaceRunId}/archive — requires workspace_run:create.

Terminal
SHA=$(shasum -a 256 repo.tgz | awk '{print $1}')
SIZE=$(wc -c < repo.tgz | tr -d ' ')

curl -X PUT "https://api.crownest.dev/v1/workspace-runs/wsr_abc123/archive" \
  -H "Authorization: Bearer $CROWNEST_API_KEY" \
  -H "Content-Type: application/gzip" \
  -H "x-crownest-archive-sha256: $SHA" \
  -H "x-crownest-archive-size: $SIZE" \
  --data-binary @repo.tgz

Returns { "archive": { ... }, "workspaceRun": { ... } } with status archive_uploaded.

Archive size

Direct uploads are capped at 8 MiB. Use staged archive transfer for repo archives up to the returned transfer.maxSizeBytes.

Staged archive transfer

Use staged transfer for normal repo archives. CrowNest returns an upload target with an explicit uploadId, maxSizeBytes, headers, and finalize step.

  1. Create a transfer:

    Terminal
    curl -X POST "https://api.crownest.dev/v1/workspace-runs/wsr_abc123/archive-transfer" \
      -H "Authorization: Bearer $CROWNEST_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{ \"sha256\": \"$SHA\", \"sizeBytes\": $SIZE }"
  2. Upload the archive to transfer.uploadUrl with transfer.method and the returned transfer.headers. Production transfer URLs may point directly at storage; do not attach the CrowNest bearer token to external upload URLs.

  3. Finalize:

    Terminal
    curl -X POST "https://api.crownest.dev/v1/workspace-runs/wsr_abc123/archive/finalize" \
      -H "Authorization: Bearer $CROWNEST_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{ \"uploadId\": \"upl_abc123\", \"sha256\": \"$SHA\", \"sizeBytes\": $SIZE }"

Start execution

POST /v1/workspace-runs/{workspaceRunId}/start — requires workspace_run:create. Accepts an Idempotency-Key header.

The run must already have an uploaded archive. Start transitions through starting, extracting, and running, then finishes as succeeded, failed, or canceled.

Terminal
curl -X POST "https://api.crownest.dev/v1/workspace-runs/wsr_abc123/start" \
  -H "Authorization: Bearer $CROWNEST_API_KEY"

Read and stream events

GET /v1/workspace-runs/{workspaceRunId}/events — requires workspace_run:read.

Query parameters:

ParameterTypeDescription
afterSeqintegerReturn events after this sequence.
limitintegerMaximum events to return.
streambooleanSet true for server-sent events.

Stored event reads return { "data": [...], "hasMore": false, "nextSeq": 12 }. Streaming uses SSE and accepts afterSeq or the standard Last-Event-ID header.

Event types are status, archive_progress, stdout, stderr, artifact_collected, artifact_error, heartbeat, terminal, and error.

Terminal
curl -N "https://api.crownest.dev/v1/workspace-runs/wsr_abc123/events?stream=true" \
  -H "Authorization: Bearer $CROWNEST_API_KEY"

Status, list, cancel, and evidence

GET /v1/workspace-runs/{workspaceRunId} — requires workspace_run:read.

GET /v1/workspace-runs — requires workspace_run:read.

POST /v1/workspace-runs/{workspaceRunId}/cancel — requires workspace_run:cancel. Cancel is idempotent by state.

GET /v1/workspace-runs/{workspaceRunId}/evidence — requires workspace_run:read.

The Evidence Bundle is durable run proof: command, template fields, archive checksum, timing, exit code, artifact IDs and errors, failure classification, cleanup status, metadata, and source metadata. It is available only after the run reaches a terminal state and evidence persistence succeeds.

Dashboard inspection

The signed-in dashboard includes a Workspace Runs inspection surface at /workspace-runs. Use it after a run is created through the API, CLI, SDK, or Crabbox to list runs, open a detail page, inspect Evidence Bundle fields, copy Artifact IDs, and cancel active runs.

Next steps

On this page