A trigger starts a run of a Worker’s published revision on its own: on a cron schedule, or when a signed webhook arrives. It does nothing else. There is no step engine behind a trigger. Every fire goes through the same start-run path as a manual start, with the same pinned revision, cost acknowledgement, plan limits and failure reasons (ADR-0107, extended by ADR-0135).
A Workflow still starts nothing on its own. Triggers belong to Workers.
Plans
Schedules and webhooks need a paid plan. Read the flags from your entitlement:
The Free plan also caps a run at 30 minutes and includes 5 environment-hours a month. Both caps refuse a start at admission rather than cutting a run short.
Create a schedule
A trigger stores the hard stop you were shown, the same acknowledgement a manual start carries. A trigger that cannot present a current acknowledgement refuses to start runs rather than skipping the cost card.
cron has five fields: minute, hour, day of month, month, day of week. 0 and 7 both mean Sunday.
timezone is an IANA name. The schedule is evaluated in that zone, so 0 7 * * 1-5 is 07:00 London time on weekdays, across daylight-saving changes. A local time that does not exist on a spring-forward day is skipped. One that happens twice on the fall-back day fires twice.
overlap_policy is skip, queue or cancel_previous, and decides what happens when the previous run is still going.
default_inputs are fixed inputs every fire starts with. They are validated against the Worker’s input schema (below).
Day of month and day of week both have to match. When both fields are restricted, Obol fires only on days that satisfy both. For example, 0 9 1 * 1 fires at 09:00 on a first of the month that is also a Monday. Standard Unix cron fires when either matches. Restrict only one of the two fields if you want the usual behaviour.
Preview before you save
The response lists the next three fire times, computed with the same matching rule the scheduler uses. A saved trigger also shows its next three fire times.
Create a webhook
The response carries the webhook’s URL and its signing secret. Send events to POST /api/v1/worker-webhooks/{trigger_id}, signed in the Stripe-shaped t=<unix seconds>,v1=<hex HMAC-SHA256 of "{t}.{raw body}"> form, in the x-obol-signature header (stripe-signature is also read). A signature more than five minutes old is refused.
input_mapping maps an input field to an RFC 6901 JSON Pointer into the signed body. The body is parsed only after the signature verifies, and only when a mapping exists.
- A mapped value that looks like a credential is refused. Credentials never travel as run inputs.
- An error names the field and the rule, never the value.
- The chosen fields become the run’s inputs, so they reach the model. Map only what the job needs.
A Worker revision may declare a small, closed input schema: at most 20 flat fields, each a string, number, integer or boolean. Every start is validated against it before the run exists: a manual start, an API start, a schedule, a webhook, a demo or a retry. A start whose inputs fail is refused with 422 run_input_invalid.
When a trigger stops firing
Publishing a revision can change what a run may cost. A schedule or webhook whose stored acknowledgement no longer matches the current hard stop refuses to start runs, with schedule_estimate_stale or webhook_estimate_stale. Trigger lists show this as needs_acknowledgement: true, and publishing warns you which schedules will need it.
Re-acknowledge in place. There is no need to delete and recreate the trigger:
The same route re-enables, reschedules, changes the timezone or overlap policy, or re-maps inputs. Every field is optional, and sending null for input_mapping or default_inputs clears it.
Retiring or disabling a Worker disables its triggers. Creating, changing and deleting a trigger are audited.
Starting runs from your own scheduler
You can still start runs from your own scheduler through the API. Each start echoes a fresh estimate:
Obol pins each run to an immutable revision and stores its inputs. A scheduler that fires twice starts two runs, and Obol does not deduplicate scheduled intent it never received. With your own scheduler, check for an in-flight run first; a built-in trigger applies its overlap_policy instead.