Skip to content

Events

Every meaningful change is recorded as an event with a name, a sequence number, an occurred time, a resource (run, task_run, flow, schedule, rule, or custom), related resources, and a JSON payload. Rules match on events, the Events page and GET /api/events list them, and new ones arrive on the SSE stream as event.created.

The names below are the whole catalogue. It is declared once, in crates/core/src/events.rs, and every site that records an event names it from there, so this page is generated rather than maintained. GET /api/vocabulary serves the same list to the UI, and cereyan.events exposes it to Python: events.run.failed is the string "run.failed".

Run events

Resource run; related flow and the run's tags. Offline the payload is state and message only.

Event Payload When
run.scheduled state, state_type, message, flow, project, parameters, created_by The run is created, or re-enters Scheduled for a crash rerun
run.pending state, state_type, message, flow, project, parameters, created_by An engine accepted the run
run.running state, state_type, message, flow, project, parameters, created_by User code started
run.completed state, state_type, message, flow, project, parameters, created_by The run finished without error
run.failed state, state_type, message, flow, project, parameters, created_by The run raised, timed out, or was set failed
run.crashed state, state_type, message, flow, project, parameters, created_by The engine died while the run was executing
run.cancelled state, state_type, message, flow, project, parameters, created_by The run was cancelled
run.late state, state_type, message, flow, project, parameters, created_by, scheduled_time, name The scheduled time passed 15 seconds ago and the run has not started
run.retrying state, state_type, message, flow, project, parameters, created_by A retry attempt started
run.skipped state, state_type, message, flow, project, parameters, created_by, reason The run ended Skipped: on_overlap="skip", a backfill value already done, a catch-up drop, a fire a person skipped (reason user), or an upstream run skipped that way (reason upstream)
run.paused state, state_type, message, flow, project, parameters, created_by The run is waiting on wait_for_input
run.resumed state, state_type, message, flow, project, parameters, created_by The run was answered and its next attempt scheduled

AwaitingRetry, AwaitingResource, and Cancelling record no event.

Task run events

Resource task_run (id is the task run's external id, name its dynamic key); related run and flow. Offline the payload is state and task_run.

Event Payload When
task_run.running task, dynamic_key, state, message, flow, project The task started
task_run.completed task, dynamic_key, state, message, flow, project The task returned
task_run.failed task, dynamic_key, state, message, flow, project The task raised or timed out (after its retries)
task_run.cancelled task, dynamic_key, state, message, flow, project The task was cancelled with its run
task_run.skipped task, dynamic_key, state, message, flow, project The task's output= target already existed
task_run.cached task, dynamic_key, state, message, flow, project The task returned a persisted result

Flow events

Resource flow.

Event Payload When
flow.registered flow, project, module The server registered the flow at start or on handoff
flow.disabled failures, window_seconds, until disable_after tripped; the flow's schedules are paused until until
flow.enabled empty The disable window ended and the schedules resumed
flow.fan_in key, value, upstream, run_id Every upstream completed a run for the key value and the downstream run was created

Schedule events

Resource schedule, related flow.

Event Payload When
schedule.paused schedule_id, reason A schedule was paused from the UI, the API, an MCP tool, a rule, or a disable window
schedule.resumed schedule_id A schedule was resumed
schedule.catchup schedule_id, policy, missed, created, dropped The server started and applied the catch-up policy to fires missed while it was down
schedule.skips_dropped schedule_id, dropped An edit, or a restart that restored a code declaration, left skipped fires the schedule no longer produces, and they were forgotten

Resource events

Event Payload When
resource.exhausted resource A run waited for a resource that had no capacity; recorded once per wait

Rule events

Resource rule, related the run and flow of the triggering event.

Event Payload When
rule.fired rule_id, rule, event, event_id A rule matched an event and its actions started
rule.action.completed rule_id, action, index, detail One action finished
rule.action.failed rule_id, action, index, error One action failed, including a template that did not render
expectation.armed id, rule_id, key, run_id, deadline A proactive rule's when event armed an expectation
expectation.met id, rule_id, key The expected event arrived before the deadline
expectation.lapsed rule_id, rule, flow, project, run, run_name, expected, deadline, armed_at, expectation_id The deadline passed, or a clock-armed rule's tick found no matching event; the rule's actions run against this event

Runs created by a rule record created_by = rule:<id>, and a rule never fires on events of runs it created unless allow_self is set.

Custom events

cereyan.emit_event(name, payload=None, resource=None) records any name of your own. Inside a run the resource defaults to that run and the task run is recorded; outside a run the event goes to the store, or to the server's POST /api/events when one holds the store.

Names with a dot-separated prefix, such as orders.table_empty, match rules with events: ["orders.*"].

The prefixes run., task_run., flow., schedule., resource., rule., expectation. are the engine's. A name under one of them that is not in the catalogue above is rejected by emit_event, by @app.rule, and by the rules API, because nothing would ever emit it — a rule matching one could only ever sit silent. Every other name is yours and is never checked.

Stream messages

The SSE stream at GET /api/stream carries live notifications for the UI. They are not stored events and rules cannot match them, even where a name is shared with one: run.updated is a stream message, so a rule naming it is rejected.

Message Data Sent when
hello latest, since The connection opens, before any backlog
run.updated The run A run was created or changed state
task_run.updated The task run A task run was created or changed state
log.appended run_id, last_id, count New log lines arrived
event.created The event Any event was recorded
flow.registered The flow A flow was registered or re-registered
rule.updated The rule, or id and deleted A rule was created, edited, fired, or deleted
variable.updated The variable, or name and deleted A variable was set or removed
artifact.updated The artifact A run published or updated an artifact
schedule.updated The schedule, or id and deleted A schedule was created, edited, paused, resumed, or deleted
backfill.created backfill_id, flow_id, count A backfill created its runs
backfill.updated backfill_id, cancelled A backfill was cancelled
expectation.armed, expectation.met, expectation.lapsed id, rule_id, and the key or the event A proactive rule armed, disarmed, or lapsed an expectation
resync latest The client asked for a sequence number older than the replay buffer; refetch everything

Each message carries the sequence number as its SSE id. Reconnect with ?since=<seq> to replay what was missed, or receive resync when the buffer no longer reaches back that far.