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 job runner 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.

They are intentionally not a provider picker. Public responses expose CrowNest templates and resources, not Cloudflare, E2B, VM class, image, or provider IDs.

The launch path is release-gated on the python-node template in CrowNest-managed Cloudflare Sandboxes. Run the release smoke before changing public launch language:

Terminal
CROWNEST_WORKSPACE_RUN_E2E=1 \
CROWNEST_API_URL=https://api.crownest.dev \
CROWNEST_API_KEY=$CROWNEST_API_KEY \
pnpm live:workspace-runs

The API key needs workspace_run:create, workspace_run:read, workspace_run:cancel, sandbox:read, sandbox:kill, 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. Environment variables are not accepted on Workspace Runs yet; use committed files or a future secret-backed path instead.

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.

Implemented upload limit

The current API route accepts archives up to 8 MiB. The staged-transfer contract is already public, but it currently uses the same Worker-backed upload route and limit.

Staged archive transfer

Use staged transfer when you want the transfer contract explicitly, or when future durable-storage upload targets are available.

  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. If the upload URL is a CrowNest API URL, authenticate normally with your API key. If it is an external storage URL, do not attach the CrowNest bearer token unless the transfer headers explicitly include an auth mechanism.

  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.

The dashboard does not create Workspace Runs, upload archives, start runs, build Templates, open live terminals, or expose provider/runtime placement.

Next steps

Workspace Runs do not yet include self-serve Dockerfile templates, E2B-backed core runtime behavior, SSH/devbox access, desktop, GPU, pause/resume, browser automation, artifact globs, full CI replacement, or public provider selection.

On this page