Create your first rule — step-by-step

Last updated: May 19, 2026

Create your first rule — step-by-step

/rules → New rule. Backed by POST /api/v1/rules (verified). Builder walks through 9 steps. New rules start with status paused — use preview first, then toggle to active. Allow first cron tick (up to 15 min) before expecting execution.

Who is this for

First-time rule builders. Anyone porting a manual workflow ("every morning I pause adsets with CPA > 30") into an automated rule.

Prerequisites

  • Active ad account connected (Meta / Google / TikTok / Taboola / Snapchat per connect cluster)

  • At least 7 days of insights data (rules need history to evaluate against)

  • Mediabuyer role or higher

How to create

Step 1: Open the builder

Sidebar → RulesNew rule. Or /rules/new directly.

Step 2: Name + description

Required. Use a descriptive name: Kill losers — CPA > 30 / 7d is better than Rule 1. Description is internal-only (your team sees it).

Step 3: Entity level

Pick one:

  • Campaign — evaluate campaign-level metrics, act on campaigns

  • Ad set — adset-level (more granular)

  • Ad — per-ad (most granular)

The level determines which entities the rule scans + which it acts on. Most rules sit at adset level — granular enough to act, coarse enough to be meaningful.

Step 4: Scope — accounts + entity filter

Pick ad accounts (multi-select). Then narrow further:

  • name contains — only entities matching pattern

  • name does not contain — exclude pattern

  • status in[active, paused, archived] (default: active)

Use cases: only act on a specific client by name prefix; exclude test campaigns; only scan active.

Step 5: Conditions

Add one or more conditions:

metric  operator  value  time_range
roas    lt        1.5    last_7d
spend   gt        50     last_7d

Combine with AND (all must match) or OR (any matches).

Available metrics: see rul-103. Operators: see rul-104.

Step 6: Actions

Pick one or more actions:

Action

What it does

pause

Stop the matching entity

activate

Resume

increase_budget_pct

Scale up by N%

decrease_budget_pct

Cut down by N%

relaunch

Meta-only — copy ad with new creative

notify_only

No entity change, just send a notification

For budget actions, set the % delta. Platform minimums apply (Google campaign $1, TikTok campaign $50, TikTok adset $20, others $2).

Step 7: Schedule

Two options:

  • Interval — every N minutes (min 15, aligned to cron cadence)

  • Daily at time (extensions) — once per day at HH:MM in workspace timezone, with day-of-week + hour-of-day picker

Most rules use interval. Daily-at-time is for end-of-day kills / start-of-day scales.

Step 8: Protections

Set the safety net:

  • Cooldown minutes — default 360 (6h), min 60 for destructive actions. Per-entity check within window.

  • Max executions per day — default 3, hard cap 50. Prevents runaway.

  • Budget change limit % — single-action cap (e.g. never change > 50% at once)

  • Budget daily cap — cumulative daily delta cap

See rul-108 protections for deep dive.

Step 9: Notifications

notify_on_execution toggle + channels: in_app, telegram, email.

Channel availability:

  • in_app — always available

  • telegram — requires bot connected (see team-116)

  • email — sent to billing email by default

Step 10: Save (status = paused)

Click Save. Rule created with status: paused. POST /api/v1/rules records to automation_rule table.

Step 11: Preview before activating

/rules/:idPreview button → POST /api/v1/rules/preview. Returns:

  • entities_evaluated — total scanned

  • entities_matched — matched the conditions (with metric values shown)

  • entities_skipped — why (cooldown, daily cap, pending)

Check the matches make sense. If scope is too broad or too narrow, edit + preview again.

Step 12: Activate

Once preview is clean: per-rule actions menu → Activate. POST /api/v1/rules/:id/toggle flips to status: active.

Next cron tick (within 15 min): rule evaluates for real. Watch execution history to confirm behavior.

Endpoint

POST /api/v1/rules (verified apps/backend/src/routes/api/rules.route.ts).

Body shape (validated TypeBox):

  • name, description

  • entity_level: campaign / adset / ad

  • ad_account_ids[], entity_filter

  • condition_logic: AND / OR

  • conditions[]: {metric, operator, value, time_range}

  • actions[]: {type, params}

  • schedule_type, interval_minutes (or schedule_config for daily_at_time)

  • cooldown_minutes, max_executions_per_day, budget_change_limit_pct, budget_daily_cap

  • notify_on_execution, notify_channels

  • platforms[] (default [meta])

Returns the created rule with id + status: paused.

RBAC + audit

Mediabuyer+ can create rules. Audit log entry: action: rule_create recorded in audit_log table with metadata (rule_id, name, scope).

Common issues

  • "Save button disabled": a required field missing — usually scope (no ad account selected) or conditions empty.

  • "No entities matched in preview": scope too narrow OR condition thresholds too strict for current data. Loosen + re-preview.

  • "Too many matches": scope too broad — add filters, raise thresholds, drop a condition.

  • "Activated rule never fires": see rul-118 troubleshooting.

Related