Every run, no matter the surface, validates the input against the workflow’s schema and is recorded in run history.
Run workflows from triggers
In production, most workflows run from a trigger. You attach a source (a webhook, schedule, poll, or app event) to a workflow, and each matching event starts a run.src/triggers/signup.ts
transform maps the source payload to the workflow’s input. See triggers for webhooks, schedules, and polling.
Run workflows from a form
Publish a workflow form to get a public URL. Anyone with the link can fill in the workflow’s inputs and start a run — no CLI or API key required.Run workflows from the CLI
The CLI is the most practical way to run a workflow while you build. Deploy your project, then invoke the workflow against the deployed project:signup-pipeline value is the workflow slug from defineWorkflow(), and --input is JSON validated against the workflow’s input schema.
--wait returns when the run finishes or the bounded timeout elapses. Choose the duration with --timeout <seconds>; without it, workflow waits default to 60 seconds. A timeout means the run is still active, not failed. Continue waiting with:
luno workflows runs against your deployed cloud project:
Run workflows as an agent tool
Import a workflow into an agent’stools array and it becomes a tool automatically. The agent calls it like any other tool, and the workflow runs with its normal step recording.
.sleep(), hookStep) normally. Child runs count toward your organization’s concurrency, but do not incur an additional workflow-run dispatch fee; model, web, and sandbox usage is still metered normally. See workflows as tools.
Run workflows via API
You can also invoke a deployed workflow over HTTP. The route validates the input, enqueues the run, and returns arunId to inspect later:
Resume a suspended run
A workflow with ahookStep suspends until something resumes it. The step’s onSuspend callback receives the token and the resumeUrl. Resume the run with POST for structured payloads, or GET for simple link/button flows (Slack, email). No API key or session is required — the hook token in the URL is the credential:
POST, the JSON body becomes the hook step’s output and the route returns 202 with the runId. With GET, query params become the payload (shallow) and the route returns a minimal HTML confirmation page. Query values arrive as strings, but if the hook declared a schema they are coerced to the schema’s primitive types first — so ?approved=true resolves to the boolean true. Values that can’t be coerced (e.g. ?approved=banana) are rejected with 400 and the run stays suspended.
If the hook declared a schema, the resume endpoint validates the payload against it first. An invalid payload is rejected with 400 and the run stays suspended — you can fix the payload and resume again, instead of failing the run. (Validation is structural; the hook step’s schema.parse remains the authoritative parse for coercion and refinements.)
Hooks with responders do not accept the raw token (403): each responder answers through the signed link from responderLinks, a hosted form at /api/projects/<project-id>/hooks/respond/<link>. Expired hooks answer 410 on both routes.
Runs waiting on a hook show Waiting for a response in run history. Runs paused by .sleep() / .sleepUntil() show Sleeping and resume on their own when the timer is due, so you don’t resume those manually. A parent waiting for queued agent or sub-workflow children shows Waiting on child runs and resumes automatically when they reach a terminal outcome.
Find the resume token for a suspended run
When a run’s status iswaiting_hook, run detail already includes pending hooks (token, status, and resumeUrl) — including lean polls like luno workflows runs get <run-id> --summary.
If you need every hook for a run (including resumed ones), or you didn’t look at run detail:
token, status, and a ready-to-use resumeUrl.
Restart a run
A finished run can run again under the same run id, so its history stays in one place:- Failed run — after fixing the cause (a missing credential, a down API, a code fix you deployed), restart it. It resumes from the step that failed; steps that already completed keep their results and do not run again.
- Any finished run, from a step (time travel) — re-run from a step you choose, optionally with new input for that step. Steps before it keep their results; that step and everything after run again. Hooks after that point ask again instead of reusing old answers.
POST /workflows/{slug}/runs/{runId}/restart with { "step"?, "input"? }. A run that is still running, or still has a retry queued, cannot be restarted (409).
Only the person who started the run, or a project admin (the project Admin role, or an org owner/admin), can restart it (403 otherwise). Runs nobody started by hand (triggers, schedules) restart only by a project admin. When an admin restarts someone else’s run, it runs as the admin, with the admin’s own credentials, never as the original user. Restarts are recorded in the audit log.
Review workflow runs
Every surface that runs a workflow creates a workflow run you can review later. Open Runs (/history) in the web app and filter Type to Workflow. The detail panel shows the input, output or error, steps, usage, trigger context, timing, and trace data.
From the CLI, use run commands while debugging:
Next steps
Triggers
Attach webhooks, schedules, and polls to start workflows.
Workflow forms
Publish a public form that starts a run from a shareable link.
Workflow runs
Inspect input, output, steps, errors, and traces.
Test workflows
Run workflows in tests before deploying changes.
Deploy a project
Ship workflow changes to the platform.