Zernio
APIFor you
Zernio
APIFor you
Overview

Guides

ProfilesConnecting accountsMedia uploadsQueue schedulingTimezones & schedulingIdempotency & safe retriesPost lifecycleError handlingRate limitsPixels and tracking tagsAutomated ad rulesCommerceManyChat-style automationsReport bugs & requestsPlatform settings
Dashboard
OverviewPlatformsAPI ReferenceResources
Guides

Automated ad rules

Pause, reactivate or rebudget campaigns and ad sets automatically when their metrics cross a threshold, or get a webhook when they do.


An ad rule checks the campaigns or ad sets of one ad account on a schedule, and acts on each one that meets every condition. Rules work on Meta, Google, TikTok, LinkedIn, Pinterest, X and Reddit. The dashboard has them under Ads > Rules (Reddit is API only for now).

What a rule is made of

FieldWhat it does
accountIdThe ads connection: the account from GET /v1/accounts whose platform is metaads, googleads, tiktokads, linkedinads, pinterestads, xads or redditads. Never a posting account.
adAccountIdThe ad account inside the connection, from GET /v1/ads/accounts?accountId=<accountId>. It must have selected: true there.
levelcampaign or adset. Each object at that level is checked on its own.
campaignIdsOptional. Only these campaigns, or their ad sets. Leave it out to check the whole ad account.
conditions.all1 to 10 conditions. Every one must hold.
actionsWhat to do with each matching object.
schedule.everyMinutesHow often the rule runs: 60, 180, 360, 720 or 1440.
cooldownMinutesHow long the rule leaves an object alone after acting on it. Defaults to 1440.

A condition compares one metric over one window with a number:

{ "metric": "cpa", "window": "last_7d", "op": ">", "value": 25 }
  • Metrics: spend, impressions, clicks, conversions, ctr, cpc, cpm, cpa, roas. ctr is a percentage. Money is in the ad account currency.
  • Windows: today, yesterday, last_3d, last_7d, last_14d, last_30d. Days follow the ad account's own timezone, and last_7d includes today.

Actions

ActionWhat it does
notifySends the ad_rule.triggered webhook with the matched objects. Subscribe an endpoint to that event with POST /v1/webhooks/settings first, or a notify-only rule shows nothing but its run history.
pausePauses the campaign or ad set.
activateReactivates a campaign or ad set that a rule paused, once the cooldown has passed.
adjust_budgetRaises or lowers the daily budget by percent, never past limit.

A rule takes notify, plus at most one of pause, activate and adjust_budget. A rule that pauses, activates or adjusts budgets needs cooldownMinutes at least as long as its schedule.

adjust_budget takes direction (increase or decrease), percent (up to 100 on an increase, 90 on a decrease) and limit. On an increase the budget never goes above limit. On a decrease it never goes below it.

Create a rule

This rule pauses every ad set that spent at least 50 over the last 7 days at a cost per conversion above 25, checking every hour:

curl -X POST https://zernio.com/api/v1/ads/rules \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pause expensive ad sets",
    "accountId": "64f1c2e8a9b3d4e5f6a7b8c9",
    "adAccountId": "act_1234567890",
    "level": "adset",
    "conditions": { "all": [
      { "metric": "cpa", "window": "last_7d", "op": ">", "value": 25 },
      { "metric": "spend", "window": "last_7d", "op": ">=", "value": 50 }
    ] },
    "actions": [{ "type": "pause" }, { "type": "notify" }],
    "schedule": { "everyMinutes": 60 },
    "enabled": false
  }'

The response is 201 with the rule. Create it disabled, check it with a preview, then enable it:

curl -X PATCH https://zernio.com/api/v1/ads/rules/RULE_ID \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'

Preview before you enable

POST /v1/ads/rules/{ruleId}/preview runs the conditions against current metrics and changes nothing. For each campaign or ad set it returns whether it matches, and the actual value of every condition. The response also names the timezone the windows used.

Run history

GET /v1/ads/rules/{ruleId}/runs lists the latest runs, newest first, from the last 31 days. Each run has an outcome:

OutcomeMeaning
triggeredAt least one object matched and the rule acted. actedObjectIds lists them.
no_matchNo object met every condition.
cooldownObjects matched, but all were still inside their cooldown.
failedThe metrics could not be read, every action failed, or the webhook could not be sent on a notify-only rule. error says why.

How it behaves

  • Metrics are the ones Zernio syncs from the ad platform, so they can trail the platform's own reporting.
  • A rate with no denominator never matches. A cpa condition skips objects with no conversions.
  • activate never touches an object you paused yourself. If you reactivate and then pause such an object between two runs, Zernio cannot tell your pause from the rule's, and an activate rule may reactivate it.
  • Google ad groups have no budget of their own. On Google, adjust_budget needs a campaign-level rule.
  • A run pauses, reactivates or rebudgets at most 20 objects. The rest wait for the next run.
  • An object whose action failed gets no cooldown, so the next run retries it.
  • Rules stop running while the team has no ads access, and resume when it is back.
  • Past the free live-ads allowance with no payment method, reactivations and budget increases are skipped with the reason ads_allowance_exceeded.
  • Disabling a rule stops its runs until you enable it again.

If it fails

ErrorCauseFix
403 ads_addon_requiredThe team has no ads access.Enable ads on the plan.
403 ad_account_not_selectedThe ad account is not selected on the connection.Add it in the dashboard ad account picker, or with GET /v1/connect/{platform}/ads and adAccountIds (the full list, since it replaces the selection).
400 invalid_field_value on cooldownMinutesA rule that changes objects has a cooldown shorter than its schedule.Raise cooldownMinutes to at least schedule.everyMinutes.
400 invalid_field_value on actionsadjust_budget on a Google ad set rule.Use level: "campaign".
403 ads_allowance_exceededA rule that reactivates or raises budgets, on a team past its free live-ads allowance with no payment method.Add a payment method. Rules that pause or lower budgets still work.
404 resource_not_foundThe rule does not exist or belongs to another team.Check the ruleId.

Related

  • List ad rules and create an ad rule
  • Preview an ad rule
  • Ads webhooks
Was this page helpful?

Pixels and tracking tags

One API for every ad platform's pixel or site tag: list, create, update, read stats, share, manage users and conversion events, and install on Shopify, WordPress, Wix or Webflow.

Commerce

One API over Shopify and WooCommerce stores: products, variants, inventory, collections, discounts, channels, markets, metafields, pages and menus, orders, plus syncing a store into a Meta catalog.

On this page

What a rule is made ofActionsCreate a rulePreview before you enableRun historyHow it behavesIf it failsRelated