Skip to content

Control API

The daemon's localhost HTTP API — every endpoint.

The daemon serves a control API on http://127.0.0.1:4319 (configurable via control.host / control.port). The CLI is one client; the browser UI is another. It binds to 127.0.0.1 and is unauthenticated locally; exposing it on a non-local host requires control.token, sent as Authorization: Bearer <token>.

{ "ok": true } — used by the CLI to detect a running daemon.

The daemon’s startup snapshot: pid, uptime, mode (global | project), registered projects and whether each contributed workflows, and the loaded workflow count.

All loaded workflows: name, triggerKind, scopeId, tags.

Run history, newest first. Query parameters:

ParamMeaning
limitmax rows (default 50)
offsetpagination offset
workflowonly this workflow’s runs
statusrunning | ok | error

{ "total": n } for the same workflow / status filters — pagination totals.

One run’s detail: { run, steps }, where each step carries status, timing, JSON output, error, and captured logs.

Files the run wrote: [{ path, size, mtime }], paths relative to the run’s artifact directory.

Download one artifact. Paths that escape the run’s directory are refused.

Fire a workflow once. The JSON body arrives as ctx.event.input. Optional ?project=<root> resolves duplicate workflow names to the intended scope. Returns { runId, status, error? } when the run settles.

Re-run a workflow against the stored event of a previous run. Bypasses dedup deliberately.

Abort an executing run via its AbortSignal (the same path as a timeout). 200 { "cancelled": true }, or 409 if the run isn’t currently executing.

All approvals across the daemon’s scopes, pending first, newest first: [{ scopeId, approval }], where approval carries id, status, the request text, payload, rounds, replies, and timestamps.

Record a human reply on a pending approval. Body: { "text": "...", "user"?, "scopeId"? } (scopeId disambiguates duplicate ids across scopes). The approvals.responded() trigger turns the reply into an event on its next poll. 404 for an unknown id, 409 when the approval is already resolved or expired.

Server-sent events. Pushes an update event whenever the (filtered) runs list changes; accepts the same limit / offset / workflow / status parameters as GET /runs, plus run=<id> to include that run’s live detail:

event: update
data: { "runs": [...], "detail": { "run": {...}, "steps": [...] } }

The browser UI uses this for live run watching; curl -N works too.

Webhook intake for connector triggers. The one route open without a token — protected by each connector’s HMAC signature verification instead; connectors fail closed when no webhookSecret is configured.

GET / serves the UI — the prebuilt app shipped in the package when present, with a dependency-free fallback page otherwise. Disable with control.ui: false.