Every other trigger
Reference for the generic webhook, the CLI runner, scheduled runs, and the automatic Semgrep-to-tinfoil-bee path.
Most bees start from Slack, Jira, the dashboard, or a GitHub comment. This page covers the remaining four ways a run can start, so you can pick the right one and fire it with working syntax.
Generic webhook
A vendor-agnostic, HMAC-validated HTTP ingress. Any external system (Zendesk, Linear, PagerDuty, an internal tool, a Zapier step) can POST /webhook to dispatch a bee. No bespoke per-system trigger needed.
Use it when you want another system to start bees and there is no dedicated trigger for it. The body needs two required fields: eventId (stable id, used for dedup: the same eventId twice within the dedup window does not start a second run; the second delivery still gets a 200) and payload (your task description and context, opaque to the trigger). Every production request must be signed: HMAC-SHA256 of the raw body with the shared secret, sent as X-Hub-Signature: sha256=<hex>.
BODY='{"eventId":"zendesk:ticket-123:2026-06-16T10:00:00Z","payload":{"description":"Fix this"}}'
SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$GENERIC_WEBHOOK_SECRET" | sed 's/^.*= //')"
curl -X POST https://<your-swarm-host>/webhook \
-H "Content-Type: application/json" \
-H "X-Hub-Signature: $SIG" \
-d "$BODY"The endpoint returns 200 immediately with a pipelineId you can look up in the dashboard. Full payload contract, signing recipes in Node and Python, and response codes: docs/webhook-setup.md in the repo.
CLI
./scripts/run-agent.sh runs a recipe directly from your machine via Goose: no trigger services, no queue. It loads the repo's .env (it uses GITHUB_TOKEN to authenticate the clone and push), creates a temp working directory, and runs the recipe there; the bee clones the repo, makes its changes, and opens a PR.
Use it for local development: testing a recipe change, or a one-off run when you're already in the repo. Flags: --recipe, --repo, and --ticket are required; --scan-scope is optional (defaults to full).
./scripts/run-agent.sh \
--recipe a11y-bee \
--repo "https://github.com/3sidedcube/your-project" \
--ticket "Run accessibility audit on the homepage only" \
--scan-scope "src/app/page.tsx"Scheduled runs
Recurring runs on a fixed cadence. You create a schedule in the dashboard under a project: Triggers → Schedules → New, picking a schedulable recipe (currently cleaner-bee), a repo, and a daily, weekly, or monthly time in UTC.
Under the hood an EventBridge rule fires every minute at /api/scheduled/tick on the dashboard (authenticated with an API key), and any schedule whose next_run_at has passed dispatches a run. If the repo's HEAD hasn't moved since the last successful run, the tick records a skipped job (verdict: no_new_commits) instead of burning a run, so a daily cleaner-bee on a quiet repo costs nothing.
Use it for standing review work, like cleaner-bee sweeping recent commits for bugs and security issues. Infrastructure detail lives in docs/deployment.md §4.10.
Semgrep findings → tinfoil-bee
Fully automatic: you don't trigger anything. When Semgrep creates a ticket in the Backlog of the Support board (the project set by JIRA_SUPPORT_PROJECT_KEY) with a semgrep.dev finding URL in "Steps to Reproduce", the Semgrep-Jira trigger spawns tinfoil-bee immediately, skipping classification. The repo comes from the ticket title (Semgrep writes ... in org/repo ...), with the "Github Repo" custom field as fallback.
The bee remediates the vulnerability, writes regression tests, and opens a PR; on success the ticket moves to "Awaiting PR" and the outcome is threaded onto the ticket's message in #3sc-semgrep-jira-tickets. If the bee verifies the finding is a false positive, it says so with the reason instead of opening a PR. Either way the contract holds: No human writes code. A human always reviews.
To re-run a Semgrep fix manually, use the CLI with --recipe tinfoil-bee and paste the finding details as the --ticket text.