Runs & observability

Every run is a permanent record. While it's in flight you can watch it live; after it ends the same timeline replays, with its phases, agent turns, tool calls, output, artifacts, and token and cost totals. This page is the model behind that: what a run is, the event log it streams, and the ways to read it.

The run lifecycle

A run is one execution of a workflow. Its status moves forward through a small set of states:

queuedpendingrunningcompletedfailedcancellingcancelled

queued is waiting for a runner, pending is a claimed runner starting up, running is executing, and the three terminal states are final. A cancel flips a live run to cancelling while it shuts down gracefully, then cancelled. A run that crashes restarts from the top rather than failing outright, so a transient blip doesn't end it. Cancel a run from the dashboard, boardwalk cancel <runId>, or POST /v1/runs/:id/cancel; re-run one with the same input from the Retry button or POST /v1/runs/:id/retry.

A run can also suspend partway through and resume later: it shows sleeping during a long sleep, awaiting_input while a human-input gate waits on a person, and waiting_for_child while a workflows.call() child runs. A suspended run holds its place without burning compute, then continues where it left off.

The event log

A run emits a stream of events as it executes: lifecycle transitions, the phase() markers your program sets, each agent turn and the tools it calls, anything the program logs, and the final output(). That stream is the run log, stored durably and replayable. Read a snapshot of it over REST for a first paint:

GET /v1/runs/{runId}/events
// → { "events": [ { "cursor": 1, "type": "...", "data": { ... } }, ... ], "done": false }

Each event carries a monotonic cursor; pass the last one you saw back as ?since=to read only what's new, which is how a resumed stream avoids replaying the whole log.

Channels

Every event belongs to exactly one channel, so you can ask for just the altitude you want:

ChannelCarries
lifecycleStatus transitions: queued, running, terminal.
phaseThe phase() markers your program sets, for grouping the timeline.
outputThe value passed to output(): the run's result.
logProgram stdout and stderr.
agentAgent turns, streamed text, reasoning, and every tool call and result.

The default view is the quiet trio (lifecycle, phase, output): enough to follow what a run is doing without the firehose. Ask for agent and log when you want to see the model think and the tools fire.

Watching a run

The same log, four ways to read it:

  • Dashboard: the run page live-tails by default and replays afterward, with the channels as toggles.
  • CLI: boardwalk runs <id> --logs prints a snapshot; --follow live-tails until the run ends. Add --verbose or --stream agent,log to widen the channels. While running a workflow with boardwalk dev or boardwalk run, the same stream prints to your terminal.
  • API: GET /v1/runs/:id/events for a snapshot, or the live stream for a tail.
  • MCP: get_run_output returns the same snapshot to a connected agent client.

Live tail

The live view is Server-Sent Events: events arrive as they happen, and a reconnect resumes from the last cursor rather than from the top, so a dropped connection never loses or duplicates the timeline. The CLI's --follow and the dashboard both use it; you rarely build a poll loop, but a conditional GET on the run row (see polling) is there if you need one.

Output & artifacts

A run's result is whatever it passed to output(): a single JSON-serializable value, shown on the run page, sent to watchers, and returned to a parent that called the workflow with workflows.call(). For files a run produces (a report, an image, a diff), write an artifactinstead: artifacts are listed on the run, downloadable with a signed URL, and outlive the run's working directory.

Watches & notifications

A watchsubscribes you to a run's or a workflow's terminal outcome, so you hear when it finishes without polling. Set one from the dashboard, or over the API:

PUT /v1/runs/{runId}/watch        # this run's outcome
PUT /v1/workflows/{id}/watch      # every run of this workflow

Manage all of yours under GET /v1/me/notifications. A workflow can also notify on its own terms by declaring notifications in meta(email or webhook on completion, failure, cancellation, or a breached budget), which is the right tool when the workflow's author, not a watcher, owns who gets told.

Usage metrics

Across runs, the usage view rolls up what your org spent: runs, compute minutes, tokens in and out, credit, the share of work that ran without a human, and the cache-hit rate. Read it for the whole org or one workflow:

boardwalk usage --org acme --days 30
GET /v1/orgs/acme/usage?days=30
GET /v1/orgs/acme/workflows/{id}/usage?days=30

Per-run token and cost totals sit on the run row itself, so the number you see on a run is the number that was metered. See Pricing for how a run is priced.