Triggers & Webhooks
Runs don't have to be started by a person or your own server. Triggers start runs automatically — on a schedule or when an external system calls a webhook — and event hooks notify your systems when runs change state.
Overview
| Mechanism | Direction & purpose |
|---|---|
| Webhook trigger | Inbound. An external system (Stripe, GitHub, your CRM…) POSTs to a unique Chatterfly URL → a run starts with the payload mapped into its input. |
| Cron trigger | Scheduled. Chatterfly starts a run on a cron schedule (with timezone support) using a fixed input. |
| Event hook | Outbound. Chatterfly POSTs to your URL when a run starts, completes, or fails — so your systems can react without polling. |
Triggers are created per deployment in the dashboard under Deployment → Triggers, or declared in the workflow definition itself.
Webhook triggers
Creating a webhook trigger generates a unique, unguessable token and a URL:
https://your-chatterfly.example.com/api/webhooks/<token>Any POST with a JSON body (up to 256 KB) to that URL starts a run. The response matches the regular run-creation API:
POST /api/webhooks/wht_3fa9c2...
Content-Type: application/json
{ "customer_email": "alice@example.com", "amount": 4900 }{ "run_id": "run_xyz789", "status": "pending" }Input mapping
By default the JSON body fields are not passed through blindly — you declare an input_mapping that picks values out of the request and assigns them to declared workflow inputs:
{
"input_mapping": {
"email": "customer_email",
"value": "amount"
}
}This maps the request body's customer_email field to the workflow input email, and so on. Mapped values are validated against the workflow's declared inputs — invalid payloads get a 422 response and no run is created.
Signature verification
To make sure only the intended sender can fire your trigger, configure a shared secret. Chatterfly then requires an HMAC-SHA256 signature of the raw request body in the X-Webhook-Signature header:
// Sender side (Node.js)
const crypto = require("crypto");
const signature = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
await fetch(webhookUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Webhook-Signature": signature,
},
body: rawBody,
});Requests with a missing or invalid signature are rejected with 401.
Scheduled (cron) triggers
Cron triggers start runs on a schedule. Configure a standard five-field cron expression, an optional timezone, and a fixed input payload:
{
"trigger_type": "cron",
"config": {
"schedule": "0 9 * * 1",
"timezone": "Europe/London",
"input": { "report_week": "current" }
}
}The example starts a run every Monday at 09:00 London time. The dashboard shows each trigger's last_fired_at and total fire count so you can confirm schedules are running.
Outbound event hooks
Event hooks are the reverse direction: Chatterfly calls your URL when something happens to a run. Hooks can be registered at three scopes:
- Workflow-level — fires for every run of every deployment of the workflow.
- Deployment-level — fires for runs of one deployment.
- Run-level — passed inline via the
hooksfield ofPOST /api/v1/runs; applies to that run only.
Supported events include run.started, run.completed, and run.failed. Each delivery is a POST to your URL with the run's ID, status, and final state — use it to sync results into your own database the moment a run finishes instead of polling GET /runs/:id.
