Triggers

A workflow declares at least one trigger on meta.triggers. Triggers only start runs; once running, every run behaves the same regardless of what started it.

Cron

triggers: [
  { kind: "cron", expr: "0 9 * * 1-5", timezone: "America/New_York" },
],

expr takes standard 5-field cron (or 6 fields with seconds). timezone is optional and defaults to UTC; daylight saving is handled for you. A workflow may declare several cron triggers.

Webhook

triggers: [
  { kind: "webhook", auth: "token" },
],

Deploying a webhook-triggered workflow provisions an inbound URL, shown in the dashboard. The request body becomes the run's input. auth picks how callers prove themselves:

  • token: the secret is part of the URL path (/v1/workflows/<id>/<token>). Paste that one URL into any app that sends webhooks (Linear, GitHub, Stripe); there is no header to set and no separate secret to copy. The full URL is shown once when you generate it, so save it then.
  • signature: the caller signs the raw request body with HMAC-SHA256 and sends it as X-Boardwalk-Signature: sha256=<hex>. Use this when you control the sender and want the payload cryptographically verified.

Either way the URL is unguessable and the secret is regenerable from the dashboard. Treat a token URL like a password: anyone who has it can start a run.

Manual

triggers: [{ kind: "manual" }],

Run it on demand: the Run button in the dashboard, boardwalk run from the CLI, or another workflow via workflows.call(). Workflow-to-workflow calls are manual triggers under the hood; the parent run is recorded on the child.

Reading the trigger payload

import { input } from "@boardwalk-labs/workflow";

// input is a value, not a function: the webhook body, run() --input, or call() input.
console.log(input);

Whatever started the run, its payload is available to the program as the input binding (a value, not a function call). Locally, pass one with boardwalk dev . --input '{...}'.