REST API
Everything in Boardwalk is an HTTP call. The dashboard, the CLI, and the MCP server all sit on the same REST surface, so anything they do, your own server can do too: fire a run when an event happens in your product, read its status, or manage workflows from CI. The hosted API lives at https://api.boardwalk.sh (self-hosted is your own host). Requests and responses are JSON; auth is a bearer token.
Authentication
For server-to-server calls, use an API key. Create one in the dashboard under Settings → API keys (key minting needs a logged-in session, so it is not something a key can do to itself). The full key (it begins with bwk_) is shown once at creation; store it as a secret. Send it as a bearer token:
curl https://api.boardwalk.sh/v1/orgs/acme/workflows \
-H "Authorization: Bearer bwk_your_key_here"A key belongs to one org. The CLI and CI both read the same value from the BOARDWALK_API_KEY environment variable.
Key scopes
A key is least-privilege: leave its scopes empty for full access at its role, or list scopes to restrict it to exactly the actions you need. For a key that only kicks off runs from your app, grant run:trigger and nothing else. Scopes are <resource>:<action> strings; the common ones:
| Scope | Allows |
|---|---|
run:trigger | Start a run of an existing workflow. |
run:read | Read run status, events, and listings. |
run:cancel | Cancel a queued or in-flight run. |
workflow:read / workflow:create / workflow:update | List or inspect, then create or version workflows (CI deploys). |
audit_log:read / billing:read | Read-only access to the audit log and billing balance. |
Credential-minting actions (secrets, API keys, inference providers, member and invitation management) are never reachable by an API key at any scope; they require a logged-in session in the dashboard.
Trigger a run from your app
This is the call you want when your own server or web app needs to start a workflow on demand. POST to the workflow's runs collection; the optional input body becomes the run's trigger payload, available to the program as input.
curl -X POST \
https://api.boardwalk.sh/v1/orgs/acme/workflows/wf_123/runs \
-H "Authorization: Bearer bwk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "input": { "pr_url": "https://github.com/acme/app/pull/42" } }'Or from your application code:
const res = await fetch(
"https://api.boardwalk.sh/v1/orgs/acme/workflows/wf_123/runs",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BOARDWALK_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ input: { pr_url: prUrl } }),
},
);
const { run } = await res.json(); // 201 Created
console.log(run.id, run.status); // the new run's id + "queued"The trigger returns immediately with the new run's id and status; the run executes asynchronously. To react to a workflow event instead of polling, point a workflow webhook at it, or have the workflow itself call back out when it finishes.
Read a run
Poll the run by id for its terminal status, and read its event log for the full timeline (phases, agent turns, output):
GET /v1/runs/{runId} # status, timing, token + cost totals
GET /v1/runs/{runId}/events # the run's event log (phases, agent, output)
POST /v1/runs/{runId}/cancel # stop a queued or in-flight runA run's status moves through queued, running, then one of completed, failed, or cancelled. The value passed to output() in the program lands in the run's events under the output channel.
Endpoint reference
The public surface, grouped. All paths are under /v1 and require a bearer token. Org-scoped routes take your org slug in the path.
| Area | Routes |
|---|---|
| Workflows | GET|POST /orgs/:slug/workflows, GET|PATCH|DELETE /workflows/:id |
| Runs | POST|GET /orgs/:slug/workflows/:id/runs, GET /orgs/:slug/runs, GET /runs/:id, GET /runs/:id/events, POST /runs/:id/cancel, POST /runs/:id/retry |
| Webhooks | GET /orgs/:slug/workflows/:id/webhook, POST /orgs/:slug/workflows/:id/webhook/rotate |
| Schedules & usage | GET /orgs/:slug/schedules, GET /orgs/:slug/usage, GET /orgs/:slug/workflows/:id/usage |
| Artifacts | GET /orgs/:slug/runs/:id/artifacts, GET /artifacts/:id, GET /artifacts/:id/download-url |
| Secrets | GET|POST /orgs/:slug/secrets (names only, never values), DELETE /secrets/:id, POST /secrets/:id/rotate |
| Inference providers | GET|POST /orgs/:slug/inference-providers, DELETE /orgs/:slug/inference-providers/:name |
| API keys | GET|POST /orgs/:slug/api-keys, PATCH|DELETE /api-keys/:id |
| Billing & audit | GET /orgs/:slug/billing/balance, GET /orgs/:slug/billing/transactions, GET /orgs/:slug/audit |
| Org, members, invitations | POST /orgs, GET|PATCH /orgs/:slug, GET /orgs/:slug/members, POST|GET /orgs/:slug/invitations |
| You | GET|PATCH /me, GET|PATCH /me/notifications |
The /runner/v1/* surface is internal: it is authorized by a short-lived per-run token the platform mints for a running workflow, not by your API key, and is not for general use.
Inbound webhooks
The trigger endpoint above is for code you control. When a third-party system you don't control needs to start a run (a GitHub push, a Stripe event), give it a workflow webhook instead: Boardwalk provisions a per-workflow URL and secret, and verifies the incoming request (a shared token or an HMAC signature) before firing. Fetch the URL and auth mode with GET /v1/orgs/:slug/workflows/:id/webhook, or rotate its secret with the /rotate route.