Skip to main content
Automations are the parts of an app that run on their own — on a schedule, or when an outside service sends in an event. You declare them on a process component in kazzle.config.ts. One component can carry as many triggers as you need.

The shape

Two things are happening here:
  • processMode picks the lifecycle — long-running server, or one-off run per trigger.
  • triggers[] lists the events that should fire this component.
The two pieces are independent. A persistent server can have a cron. An ephemeral process can have a webhook. Pick the lifecycle that fits the workload, then attach as many triggers as you like.

processMode

Triggers

Each trigger has a name (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 declared path. 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 a triggered 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.
Triggered components have no idle machines on production — they spin up per call and shut down on exit.

Webhook URLs

The 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 a process_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 a 402. 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.