kazzle.config.ts. One component can carry as many triggers as you need.
The shape
processModepicks the lifecycle — long-running server, or one-off run per trigger.triggers[]lists the events that should fire this component.
processMode
Triggers
Each trigger has aname (unique within the component), a kind, and — depending on mode — a schedule and/or path.
Persistent mode — HTTP into the server
When a trigger fires for a persistent component, Kazzle POSTs to your server at the declaredpath. The request carries:
For webhook triggers, the original request body is forwarded as the POST body. For schedule triggers the body is empty.
Triggered mode — one-off per trigger
When a trigger fires for atriggered component, Kazzle spawns the entry script fresh and waits for it to exit. There is no path; the script learns which trigger fired from env vars.
Webhook URLs
triggerName segment must match a kind: 'webhook' entry in that component’s triggers[]. Unknown trigger names return 404.
Schedule resolution
Cron expressions are 5-field (minute, hour, day-of-month, month, day-of-week) and minute resolution is the floor. Sub-minute schedules are rejected at manifest validation time.How runs are recorded
Each trigger fire writes aprocess_runs row with the trigger_name, triggered_by, run_id, and the run’s exit status. You can query these from your own code or inspect them in the app’s runs view.
Running out of credits
A failing run is recorded and logged, but the schedule keeps running on its normal cadence — a flaky run never disables the trigger. The one thing that stops a run is credits: every trigger fire is checked against the space’s balance, and while the space is out of credits (or has no billing set up) runs are skipped with a402. This is self-recovering — the schedule stays armed and the next fire after you top up runs normally, with no manual resume.
Adding automations later
A simple app can start with no triggers and gain them later — add a daily summary, connect Stripe, run cleanup. The component’s lifecycle (processMode) and triggers (triggers[]) are independent, so you can change them without rewriting the rest of the app.