--- title: 'workflows' description: 'List the durable workflows an agent installation exposes, read the input/output JSON Schema each declares, and start a run by name' position: 14 --- # stackbone workflows > With no `--agent`, these verbs talk to the runtime `stackbone dev` boots, so > `dev` must be running. See > [target resolution](/docs/cli/reference/conventions#target-resolution). > Every verb accepts `--json` and emits the > [standard envelope](/docs/cli/reference/conventions#json-output). None of the > three needs `--yes`: `start` begins a run and destroys nothing. Inspect the durable [workflows](/docs/sdk/workflows/overview) the targeted installation's workspace exposes, read the input/output JSON Schema each one declares, and start a run by name. A workflow declares its IO by exporting sibling `inputSchema` / `outputSchema` Zod objects next to the `'use workflow'` function. `workflows schema` is how you read a workflow's per-call contract. When a workflow declares neither, the schema reads `{ input: null, output: null }` and callers fall back to a raw JSON field. | Command | Purpose | | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `stackbone workflows list` | List the workflows the workspace exposes. Each row shows the workflow name and its trigger; `◆` marks one that declares an input/output schema (`◇` if it does not). | | `stackbone workflows schema ` | Print one workflow's input/output JSON Schema. Falls back to a message when the workflow declares no schema. | | `stackbone workflows start ` | Start a durable run of the workflow. Input from `--input ` or `--input-file `, validated server-side against the declared `inputSchema`. | Every verb takes `--agent ` to target a deployed box instead of the local-dev installation. Both serve the same workflow routes: the runtime `stackbone dev` boots for a local install, the deployed runtime for a cloud one. A deployed box needs a registered deployment first (see [target resolution](/docs/cli/reference/conventions#target-resolution)). ## stackbone workflows list List the durable workflows the installation exposes. Each row shows whether the workflow declares input/output schema (`◆` = has schema, `◇` = none) and its trigger. | Flag | Type | Description | | --------- | ------ | ------------------------------------------------------------- | | `--agent` | string | Installation id to target. Defaults to the local-dev install. | This list is not paginated: it takes no `--limit` / `--cursor`, and the payload carries `items` with no `nextCursor`. A workspace exposes few enough workflows to return in one read. Human mode prints `◆ onboarding POST /api/workflows/onboarding/start`; an empty list prints `No workflows exposed by this installation.` The `trigger` is the HTTP entry point that starts a fresh durable run of the workflow (a `POST /api/workflows/:name/start`). It is a route. The `trigger` field on a run row ([`stackbone runs list`](/docs/cli/reference/runs#stackbone-runs-list)) is a different field with a different vocabulary. The result of calling the route is a durable run you inspect with [`stackbone runs`](/docs/cli/reference/runs). **JSON payload** ```jsonc { "schema_version": 1, "items": [ { "name": "onboarding", "trigger": "POST /api/workflows/onboarding/start", "hasSchema": true }, { "name": "reconcile", "trigger": "POST /api/workflows/reconcile/start", "hasSchema": false }, ], } ``` ## stackbone workflows schema Print one workflow's input/output JSON Schema (derived from the sibling `inputSchema` / `outputSchema` Zod exports next to the workflow). Use it to drive a typed `start` payload. ```bash stackbone workflows schema onboarding stackbone workflows schema onboarding --json ``` | Flag | Type | Description | | --------- | ------ | ------------------------------------------------------------- | | `--agent` | string | Installation id to target. Defaults to the local-dev install. | A workflow with no schemas prints `Workflow "" declares no input/output schema (the Playground falls back to a raw JSON field).` **JSON payload** ```jsonc { "schema_version": 1, "schema": { "input": { /* JSON Schema or null */ }, "output": { /* JSON Schema or null */ }, }, } ``` ## stackbone workflows start Start a durable run of a workflow **by name**, the external trigger path. The name resolves on the runtime, so the workflow does not have to be bundled into the CLI; you can start any workflow the installation exposes. The input comes from one of two flags (else `{}`), and the runtime validates it server-side against the workflow's declared `inputSchema` before it creates any run. | Flag | Type | Description | | -------------- | ------ | -------------------------------------------------------------------------- | | `--input` | string | Inline JSON object passed as the workflow input. Wins over `--input-file`. | | `--input-file` | string | Path to a JSON file with the workflow input. | | `--agent` | string | Installation id to target. Defaults to the local-dev install. | ```bash stackbone workflows start onboarding --input '{"userId":"u_123","plan":"pro"}' stackbone workflows start onboarding --input-file ./payload.json ``` `start` needs no `--yes`, because it begins a run and destroys nothing. The command reports invalid JSON or an unreadable file before it enqueues anything, and an unknown name fails with "workflow not found". The receipt is the new run; track it with [`stackbone runs get `](/docs/cli/reference/runs#stackbone-runs-get) and [`stackbone logs tail --run `](/docs/cli/reference/logs). To trigger a workflow **from inside another workflow** instead, use `stackbone.workflows.start(name, input)` / `stackbone.workflows.startAndWait(name, input)` from the ambient `stackbone` client (see [Workflows](/docs/sdk/workflows/building-workflows#3-triggering-a-run)). **JSON payload** ```jsonc { "schema_version": 1, "workflowName": "onboarding", "status": "started", "runId": "9b1c7f42-3f6a-4a71-9c2e-8d4f0b6a1e33", "worldRunId": "...", "trigger": "POST /api/workflows/onboarding/start", } ``` `runId` is the durable run id, the same uuid [`stackbone runs`](/docs/cli/reference/runs) prints. `worldRunId` is the engine's own id for the run, which the run record carries as its `traceId`. `trigger` on the receipt is the same route string `workflows list` reports for that workflow. A **serial** workflow has one more shape. If a run is already active when you start it, the runtime queues the trigger instead of starting it: `status` is `"queued"` and `runId` / `worldRunId` are absent until its turn comes up. Human mode prints `Queued workflow "" — an earlier run is still active; it starts automatically when the queue frees.` See [Serial execution](/docs/sdk/workflows/serial-execution#triggering-a-serial-workflow). ## Exit codes `0` ok · `3` no target (no project and no `--agent`, or `stackbone dev` is not running) · `4` not found (unknown workflow, or a targeted box with no registered deployment) · `1` generic. An input that fails the declared `inputSchema`, a guardrail that refuses the payload, and a workflow that failed to compile all exit `1` with the reason on stderr. Full table: [Conventions → exit codes](/docs/cli/reference/conventions#exit-codes).