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

gt

greater than

cpa gt 30

lt

less than

roas lt 1.5

gte

greater or equal

frequency gte 5

lte

less or equal

spend lte 100

eq

equal

purchases eq 0

neq

not equal

status neq "active"

between

inside [min, max]

roas between [1.5, 2.5]

not_between

outside [min, max]

cpa not_between [10, 30]

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

increased_pct

rose by ≥ N% vs prior period

cpa increased_pct 30 / last_3d → CPA rose 30%+ in last 3 days vs the 3 days before

decreased_pct

fell by ≥ N% vs prior period

roas decreased_pct 25 / last_7d → ROAS dropped 25%+ in last 7 days vs prior week

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

today

Midnight today → now

yesterday

Midnight to midnight (full day)

last_3d

Last 3 full days

last_7d

Last 7 full days

last_14d

Last 14 full days

last_30d

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 N guard.

  • 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 gt minimum.

  • between / not_between with bad array order: must be [min, max]. [30, 10] evaluates wrong.

Related