Skip to content

Predicate reference

The lookup. Segments is the story.

Field Type Required Meaning
match "all" | "any" no (all) How the list combines. Deliberately flat: one list, no nested groups.
predicates array yes Trait and event predicates, in any order.

A definition names no app. The segment row carries the one app it belongs to, and both sides of every rule read that app’s profiles and events. There is no filter on the source an event arrived through either.

{ "kind": "trait", "name": "plan", "op": "eq", "value": "free" }
Op Reads value Matches
eq, neq yes Equal, or not.
gt, gte, lt, lte yes Ordered comparison.
contains yes Membership in an array trait, substring in a string.
exists, notExists no Whether the trait is set at all.

Comparison coerces form-friendly values first: "150" matches 150 numerically, and " TRUE " matches true for eq and neq, trimmed and case-insensitive. Ordering never coerces booleans.

{ "kind": "event", "name": "signed_up", "op": "performed", "withinDays": 30, "atLeast": 2 }
Field Required Meaning
op yes performed or notPerformed.
atLeast no (1) How many times.
withinDays no A rolling window relative to evaluation time. Absent means all history.

Events merged in from an anonymous identity count, so a visitor who signed up keeps the history they built before they had a name. See Identity.

Time-decaying states are journeys, not predicates

Section titled “Time-decaying states are journeys, not predicates”

“Active in the last 30 days” evaluated by the wall clock is deliberately not an evaluator feature: nothing would recompute it when the clock passes, only when the person is written. Express it as a journey with a durable timer that sets and unsets a trait, then point a segment at that trait. See Journey composition and the activity-decay template.