Conditions, operators, time ranges
Last updated: May 19, 2026
Conditions, operators, time ranges
Conditions are the IF part of an if-then rule. Each condition is a tuple {metric, operator, value, time_range}. Combine multiple conditions with AND (all must match) or OR (any matches). 8 standard operators + 2 trend operators (extensions). 6 time ranges.
Who is this for
Anyone designing a rule beyond a single condition. Reference for the builder's condition row UI.
The condition tuple
A condition has 4 fields:
{metric: "roas", operator: "lt", value: 1.5, time_range: "last_7d"}
In English: "ROAS less than 1.5 over the last 7 days."
Operators (8 standard)
Operator | Meaning | Example |
|---|---|---|
| greater than |
|
| less than |
|
| greater or equal |
|
| less or equal |
|
| equal |
|
| not equal |
|
| inside |
|
| outside |
|
between and not_between take an array of two numbers (inclusive bounds).
Trend operators (extensions, 2)
Behind the Rules Engine extensions feature set. Compare current time_range vs the immediately preceding equal-length period.
Operator | Meaning | Example |
|---|---|---|
| rose by ≥ N% vs prior period |
|
| fell by ≥ N% vs prior period |
|
Use case: catch performance drift (sudden CPA increase, ROAS collapse) early instead of waiting for absolute thresholds to break.
Time ranges (6)
The window over which the metric is computed. Aligned to workspace timezone.
Time range | Window |
|---|---|
| Midnight today → now |
| Midnight to midnight (full day) |
| Last 3 full days |
| Last 7 full days |
| Last 14 full days |
| Last 30 full days |
Shorter windows = faster reaction, noisier signal. Longer windows = slower reaction, more stable. For postback-fed metrics (purchases / ROAS / CPA): use last_7d minimum to avoid acting on incomplete data (see rul-103).
Combining conditions: AND vs OR
Per rule, choose condition_logic:
AND — all conditions must match for the entity to qualify
OR — any one condition matches
AND example (kill losers)
condition_logic: AND
conditions:
- roas lt 1.5 / last_7d
- spend gt 50 / last_7d
actions: pause
Pauses only entities with both bad ROAS AND meaningful spend (avoids killing low-traffic tests that haven't proved anything).
OR example (frequency alarm)
condition_logic: OR
conditions:
- frequency gt 5 / last_7d
- cpa increased_pct 50 / last_3d
actions: notify_only
Alerts on either creative fatigue OR sudden cost spike.
Per-condition entity matching
Each condition is evaluated per entity (campaign / adset / ad depending on level). The rule decides per-entity whether to act. Two different ad sets in the same scope may match differently — that's expected.
Examples
Pause adsets with bad ROAS
metric: roas, operator: lt, value: 1.5, time_range: last_7d
Single condition. Targets adsets where 7-day ROAS dropped below 1.5.
Scale winners with traffic
condition_logic: AND
- metric: roas, operator: gt, value: 3, time_range: last_3d
- metric: spend, operator: gt, value: 100, time_range: last_3d
Both must match. Excludes hot-but-tiny adsets where ROAS is unreliable due to low volume.
Protect daily spend
metric: budget_spent_pct, operator: gt, value: 80, time_range: today
Fires when more than 80% of today's daily budget is already spent.
Detect performance drift
condition_logic: OR
- metric: cpa, operator: increased_pct, value: 30, time_range: last_3d
- metric: roas, operator: decreased_pct, value: 20, time_range: last_3d
Trend operators. Alerts on either CPA spike OR ROAS drop vs prior 3-day period.
What you'll see in preview
POST /api/v1/rules/preview returns each evaluated entity with:
The metric values that the rule computed
Whether each condition matched (true / false)
Final match result based on AND / OR logic
Skip reason if applicable (cooldown active, daily cap, pending action)
Useful for debugging: if a known-bad adset is not matching, preview shows which condition failed and why.
Common mistakes
AND when you meant OR: condition too strict → no matches. Re-read the logic carefully.
OR when you meant AND: condition too loose → too many matches. Consider AND or add a
spend gt Nguard.Short time_range on slow metrics: postback metrics need
last_7d+. Otherwise rule fires on partial data.No spend guard on ROAS / CPA conditions: low-volume entities have wild metrics. Always pair with a
spend gtminimum.between / not_between with bad array order: must be
[min, max].[30, 10]evaluates wrong.
Related
Available metrics — what to measure
Actions overview — the THEN part
Preview / dry-run — test condition logic