Documentation
Triggers and rules
How rule trees evaluate against incoming events, how conditions are scoped and composed, and why every evaluation explains itself.
A trigger watches the events from one or more providers and decides whether they matter. When it decides they do, it fires, and the workflows attached to it run.
What a trigger owns is a rule tree: nested groups combining conditions with AND or OR. What makes it worth using is that the tree explains itself — every condition returns a plain-language reason whether it matched or not.
Before anything else: enable it
A trigger is created disabled, as is a provider and a workflow. If nothing is happening, that is the first thing to check. It is the single most common reason a rule that looks correct never fires.
The same switch is how a trigger is paused: disable it and it stops firing, enable it and it resumes, with its rules and links untouched. On a phone the trigger's page carries Pause trigger and Resume trigger in the bar above the tabs; its rules are shown there but edited on a larger screen.
Groups and conditions
A condition is a leaf. It reads a field out of the event by dot-path, applies an operator, and compares against one or more values:
employee.status EQUALS "terminated"
employee.department IN ["engineering", "design"]
alert.count GT 5A group is a branch. It has an operator — AND or OR — and contains
conditions, other groups, or both. A trigger has exactly one root group, and
groups nest up to six levels deep.
AND
├── employee.status EQUALS "terminated"
└── OR
├── employee.department IN ["engineering", "design"]
└── employee.level GTE 5AND requires every child to match. OR requires one. Both short-circuit, so a
group stops evaluating as soon as the answer cannot change.
Two empty cases are worth knowing, because both fail closed rather than matching everything:
- A group with no children evaluates to false
- A trigger with no root group evaluates to false, with the reason
trigger has no root rule group configured
Every evaluation explains itself
This is the part that makes a trigger debuggable. Each condition returns a reason string alongside its verdict, and they are written to be read rather than parsed:
value "terminated" equals "terminated"
value "full_time" not found in [contractor intern]
no array element matched (checked 3 elements)You get these in three places: in the response to a webhook post, in the trigger's evaluation history, and in run history for the workflow that fired. When a trigger does not fire, you are not reduced to guessing which clause let you down — the tree tells you which one, and what it compared.
Rule operators lists all eighteen operators and the exact reason each one returns.
Field paths
A field path walks the event payload by dots. Given this event:
{
"employee": {
"id": "E-2231",
"roles": [{ "name": "admin" }, { "name": "billing" }]
}
}employee.id resolves to "E-2231", and employee.roles.name resolves to both
"admin" and "billing".
That second case is array traversal. When a path crosses an array, the values from every element are collected and the condition matches if any of them match. The reason says so, and counts what was checked:
array element matched: value "admin" equals "admin"
no array element matched (checked 2 elements)You do not have to know the shape of an event in advance. The rule builder learns it from the messages a provider has actually sent — the newest hundred, so a field a sender started including last week is there — and field paths and their observed values autocomplete as you type rather than coming from a schema somebody had to write down.
Scoping a condition to one provider
A trigger can listen to several providers at once, which raises an awkward question: what should a condition about a Workday field do when the event came from CloudWatch?
Scoping a condition to a provider answers it. When an event arrives from a different provider, the condition is skipped and counts as matched:
provider scope 4 does not match current provider 7; skippedSkipping to matched rather than false is deliberate. Inside an AND group, a
condition that failed simply because it was about somebody else's event would
veto the whole trigger, and a multi-provider trigger would never fire. This way a
scoped condition constrains the provider it names and stays out of the way
otherwise.
Composing triggers
The TRIGGER_MATCH operator lets one trigger reference another: the condition
matches when the referenced trigger fires for the same event.
This is how you avoid restating logic. If "is a production incident" is already a trigger you trust, every other trigger can ask for it by reference rather than copying its clauses and letting the copies drift.
Referenced triggers are evaluated once per event no matter how many conditions ask for them. A condition satisfied from that cache says so:
result from memoization cacheA trigger can't depend on itself. If references loop back, whether a trigger names itself or A references B and B references A, the reference that closes the loop evaluates as not matched and says why:
ref trigger 42 is already being evaluated: TRIGGER_MATCH cycle, treated as not matchedChains are also capped at 32 references deep. A reference past the cap is not evaluated and doesn't match.
Triggering on a correlation
A trigger can listen to the built-in Correlations provider like any other.
Its events are correlations, so its conditions test fields such as confidence,
rule.name and source.data.employee_id. See
Acting on a correlation.
What a trigger does when it fires
It runs each workflow attached to it once, and the event's payload travels with
it. That payload is what a step's input mappings and templates read from, via
paths like trigger.event.data.employee.email, so the data that decided the
trigger should fire is the same data the workflow acts on.
See Workflows and steps.
Deleting a trigger
Deleting a trigger deletes what is the trigger's: its rule tree, and its
history of firings. What it started is kept. Workflow runs it fired stay in the
run history with no trigger against them, the way a deleted workflow's runs
stay. A trigger node on a workflow canvas that pointed at it stays too, pointing
at nothing until you link it to another trigger; and a TRIGGER_MATCH condition
in another trigger that deferred to it now defers to nothing, and never matches,
which the evaluation's reason says.
Deleting a rule group deletes its conditions and the groups nested under it. Disable a trigger instead if you want to keep its history and rules.