Ad Rules Engine

A central rule management service that helps you easily, efficiently and intelligently manage ads. Without it, you must query the Marketing API to monitor an ad's performance and manually take actions on certain conditions. Since we can express most conditions as logical expressions, we can automate management two ways: using Schedule or Trigger Based rules. New to this? try the rules-based notification quickstart in your App Dashboard, Quickstarts.

For questions or feedback: rulesengine@fb.com or Facebook Ads Rules Engine Page.

Ad Rules

Ad Rules are standalone objects created and stored in the Ad Rules Library and minimally contain a name, an evaluation_spec and an execution_spec. This is the basic structure of a rule:

curl \
-F 'name=Rule 1' \
-F 'evaluation_spec={
    ...
   }' \
-F 'execution_spec={
    ...
   }' \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Facebook evaluates Trigger Based Rules when an Insights metric or Object metadata field changes. We evaluate Schedule Based Rules on scheduled intervals.

Evaluation Spec

The main purpose of the evaluation_spec of a rule is to determine the objects upon which the rule should execute its action. The evaluation_type determines the type of evaluation method and has the following options:

Evaluation Type Description

SCHEDULE

Schedule Based Rule

TRIGGER

Trigger Based Rule

The evaluation_spec also contains a filters array, which allows us to further narrow the list of matched objects. For example, you can construct filters on Ad, Adset and Campaign metadata and Insights metrics. All filters are evaluated together using the AND operator.

The array contains a list of filter objects, which themselves are dictionaries with keys of field, value, and operator:

Filter Object Keys Required Description

field

Yes

Filter field (e.g. insights or metadata)

value

Yes

Static filter value for the field

operator

Yes

Logical operator for the field

Each filter has a list of supported logical operators. Here is a list of all the logical operators which are supported in SCHEDULE and TRIGGER rules:

Logical Operator Value (Example)

GREATER_THAN

numeric (100)

LESS_THAN

numeric (100)

EQUAL

numeric (100)

NOT_EQUAL

numeric (100)

IN_RANGE

tuple ([100, 200])

NOT_IN_RANGE

tuple ([100, 200])

IN

list (["1", "2", "3"])

NOT_IN

list (["1", "2", "3"])

CONTAIN

string ("ABC")

NOT_CONTAIN

string ("ABC")

ANY

list ([1, 2, 3])

ALL

list ([1, 2, 3])

NONE

list ([1, 2, 3])

The evaluation_spec also requires a trigger for the TRIGGER evaluation type. The trigger contains a type and an underlying filter specification (field, value, operator).

The difference is that the trigger dynamically determines whether or not we should evaluate a rule, and you can have only one. See the section under Trigger Based Rules for more information.

Below we define some special filters, as well as general groups of filters that one can use.

Special Filters

The time_preset filter determines the time period over which we aggregate Insights metrics. Currently, we only allow one time_preset, and it will apply to all stats filters in the rule, including the one used for the trigger if present. The only supported operator for time_preset is EQUAL, and this is required as long as any Insights filter or trigger is present. Trigger Based Rules only supports time presets that include TODAY because it performs real-time evaluation.

Note that time presets for rules can behave differently from other interfaces; some of the time presets here include today's data. This is because today's data is critical for rules that run more frequently than daily. For other interfaces, a preset value of LAST_N_DAYS generally would not include today's data. See the descriptions below for more details.

{
  "field": "time_preset",
  "value": "TODAY",
  "operator": "EQUAL"
}
Time Preset Values Description

LIFETIME

Lifetime of the object

TODAY

The current day starting from midnight in the ad account's timezone

LAST_2_DAYS

YESTERDAY and TODAY

LAST_3_DAYS

Last 2 full days and TODAY

LAST_7_DAYS

Last 6 full days and TODAY

LAST_14_DAYS

Last 13 full days and TODAY

LAST_28_DAYS

Last 27 full days and TODAY

LAST_30_DAYS

Last 29 full days and TODAY

THIS_MONTH

This month, including TODAY

THIS_WEEK_MON_TODAY

This week using Monday as first day of week, including TODAY

THIS_WEEK_SUN_TODAY

This week using Sunday as first day of week, including TODAY

YESTERDAY

The previous full day, excluding TODAY

LAST_2D

Last 2 full days, excluding TODAY

LAST_3D

Last 3 full days, excluding TODAY

LAST_7D

Last 7 full days, excluding TODAY

LAST_14D

Last 14 full days, excluding TODAY

LAST_28D

Last 28 full days, excluding TODAY

LAST_30D

Last 30 full days, excluding TODAY

LAST_ND_14_8

Last 14 days to Last 7 days, for ROAS

LAST_ND_30_8

Last 30 days to Last 7 days, for ROAS

LAST_ND_60_8

Last 60 days to Last 7 days, for ROAS

LAST_ND_120_8

Last 120 days to Last 7 days, for ROAS

LAST_ND_180_8

Last 180 days to Last 7 days, for ROAS

LAST_ND_LIFETIME_8

Lifetime to Last 7 days, for ROAS

LAST_ND_60_29

Last 60 days to Last 28 days, for ROAS

LAST_ND_120_29

Last 120 days to Last 28 days, for ROAS

LAST_ND_180_29

Last 180 days to Last 28 days, for ROAS

LAST_ND_LIFETIME_29

Lifetime to Last 28 days, for ROAS

The attribution_window filter determines the lookback window over which we aggregate Insights metrics. For more information, see the Insights documentation on Attribution Windows. Currently, we only allow one attribution_window, and it will apply to all stats filters in the rule. The only supported operator for attribution_window is EQUAL, and this is only supported by Schedule Based Rules. If this filter is not specified, it defaults to the ACCOUNT_DEFAULT value, which is the attribution window you dynamically set for your account.

{
  "field": "attribution_window",
  "value": "1D_VIEW_1D_CLICK",
  "operator": "EQUAL"
}
Attribution Window Values Description

ACCOUNT_DEFAULT

Use the account level attribution window setting

DEFAULT

The FB default attribution window is 1 day views, 28 day clicks

INLINE

Inline attribution only (0 day views, 0 day clicks)

1D_VIEW

1 day views, 0 day clicks

7D_VIEW

7 day views, 0 day clicks

28D_VIEW

28 day views, 0 day clicks

1D_CLICK

0 day views, 1 day clicks

7D_CLICK

0 day views, 7 day clicks

28D_CLICK

0 day views, 28 day clicks

1D_VIEW_1D_CLICK

1 day views, 1 day clicks

7D_VIEW_1D_CLICK

7 day views, 1 day clicks

28D_VIEW_1D_CLICK

28 day views, 1 day clicks

1D_VIEW_7D_CLICK

1 day views, 7 day clicks

7D_VIEW_7D_CLICK

7 day views, 7 day clicks

28D_VIEW_7D_CLICK

28 day views, 7 day clicks

7D_VIEW_28D_CLICK

7 day views, 28 day clicks

28D_VIEW_28D_CLICK

28 day views, 28 day clicks

Metadata filters

With metadata filters, you can filter objects based on the current state of their metadata fields. These also support multi-level filtering, which means you can use prefixes to apply a metadata filter on an object's parent or grandparent as well. This does not affect other filters; Insights filters will still apply to the normal object. All metadata filters are supported for Scheduled Rules, but only a subset are currently supported for Trigger Rules.

For instance, if you want a rule that applies to Ad Sets of Campaigns whose objective is WEBSITE_CLICKS, you can include two filters:

 "filters" : [
  {
    "field": "entity_type",
    "value": "ADSET",
    "operator": "EQUAL",
  },
  {
    "field": "campaign.objective",
    "value": "WEBSITE_CLICKS",
    "operator": "EQUAL"
  }
]

Below is a list of metadata filters supported by Trigger and Schedule Based rules:

Metadata FieldDescriptionSupported PrefixesSupported ValuesSupported Operators

id*

Specific static objects for which the rule is applied.

ad, adset, campaign

int, array(int)

EQUAL, IN, NOT_IN

entity_type*

The object level for which the rule is applied.

none

AD, ADSET, CAMPAIGN

EQUAL

name

Name of the object, by partial or complete match

ad, adset, campaign

string

EQUAL, CONTAIN, NOT_CONTAIN

effective_status**

Effective statuses of the object

ad, adset, campaign

array(ACTIVE, PAUSED, ADSET_PAUSED, CAMPAIGN_PAUSED, PENDING_REVIEW, ARCHIVED, DELETED, DISAPPROVED, PREAPPROVED, PENDING_BILLING_INFO)

IN, NOT_IN

adlabel_ids

Ad label ids of the object

ad, adset, campaign

array(int)

ANY, ALL, NONE

objective

Objective of the campaign of the object

campaign

array(APP_INSTALLS, BRAND_AWARENESS, CONVERSIONS, EVENT_RESPONSES, LINK_CLICKS, ...)

IN, NOT_IN

start_time

Start epoch time of the object

adset, campaign

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

stop_time

Stop epoch time of the object

adset, campaign

int

GREATER_THAN, LESS_THAN

buying_type

Buying type of the campaign of the object

campaign

array(AUCTION, FIXED_CPM, RESERVED)

IN, NOT_IN

billing_event

Billing event of the adset of the object

adset

array(APP_INSTALLS, LINK_CLICKS, IMPRESSIONS, ...)

IN, NOT_IN

optimization_goal

Optimization goal of the adset of the object

adset

array(APP_INSTALLS, LINK_CLICKS, IMPRESSIONS, ...)

IN, NOT_IN

is_autobid

Autobid status of the adset of the object

adset

array(bool)

IN, NOT_IN

daily_budget

Daily budget of the adset of the object

adset

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

lifetime_budget

Lifetime budget of the adset of the object

adset

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

spend_cap

Spend cap of the campaign of the object

campaign

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

bid_amount

Bid amount of the object

ad, adset

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

created_time

Created epoch time of the object

ad, adset, campaign

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

updated_time

Updated epoch time of the object

ad, adset, campaign

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

Below is a list of additional metadata filters supported only in Schedule Based rules:

Metadata FieldDescriptionSupported PrefixesSupported ValuesSupported Operators

placement.page_types

Page types for placement of the adset of the object

adset

array(DESKTOPFEED, HOME, INSTAGRAMSTREAM, INSTAGRAMSTORY, ...)

ANY, ALL, NONE

budget_reset_period

Budget reset period of the adset of the object

adset

array(DAY, LIFETIME)

IN, NOT_IN

hours_since_creation

Hours since created_time of the object

ad, adset, campaign

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

estimated_budget_spending_percentage

Estimated percentage of your adset's budget to be spent by the end of its schedule. This uses the same mechanism as our Ad Sets Budget Rebalancing feature, so this would work with any budget type but requires 10 hours of delivery per day.

adset

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

audience_reached_percentage

Estimated percentage of your adset's reach against its audience size

adset

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

active_time

Seconds since the object had an effective status of ACTIVE. If the object is not currently ACTIVE, this returns 0

ad, adset, campaign

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE

current_time

Current epoch time

none

int

GREATER_THAN, LESS_THAN, IN_RANGE, NOT_IN_RANGE


*For every rule of evaluation type SCHEDULE or TRIGGER, we require you to specify either an entity_type or id filter.

By specifying an entity_type filter, you specify a dynamic object level for which to apply the rule. For example, if the entity_type is AD, this means that the rule will automatically evaluate every new Ad that is added under the account regardless of when you create the rule. By specifying an id filter instead, the rule will only apply to this static list of objects.

By specifying an id filter with no prefix, we will automatically compute the object level for which to apply the rule. For example, if you wanted to apply a rule to the Ads [123, 456], you only need one filter: a filter with field id, value [123, 456], and operator IN. An entity_type filter would not be required, as you provided an initial static list of objects, and we can compute the object level from those objects.

Note that you can use these in conjunction with multi-level filtering. For example, if you want a rule that applies to all Ads under some specified Ad Sets, you would have an entity_type filter of AD and an adset.id filter with the specified Ad Sets.

**By default, if you do not specify an effective_status filter, we implicitly add an effective_status filter when evaluating the rule. This default filter has an operator of IN and a value of ['ACTIVE', 'PENDING_REVIEW'] for all execution types that act upon active objects, which means the rule will only evaluate objects that have or will have active delivery. This is an internal optimization for our execution types. For execution types that do not act upon active objects (UNPAUSE), we instead add this filter with an operator of NOT_IN and a value of ['DELETED', 'ARCHIVED'].

Insights Filters

We evaluate insights filters against the current values returned from Insights API for a given time_preset.

Note that these filters will apply directly to the list or level of objects, and do not support multi-level filtering.

Also note that the units represented here are based on the currency's base in the Ads API. For example, for USD, the base unit is the cent, which means that a value of 1000 for spent would be equivalent to $10.00.

For a description of each of the fields below, see the Insights API docs.

All Insights filters support the following operators: GREATER_THAN, LESS_THAN, EQUAL, IN_RANGE, NOT_IN_RANGE

All of these filters are supported by Schedule Based Rules. Below is a list of Insights filters and whether they are supported by Trigger Based Rules:

Insights Field Allowed for Trigger Based Rules?

mobile_app_purchase_roas (Example)

No

website_purchase_roas (Example)

No

impressions

Yes

social_impressions

Yes

unique_impressions

Yes

clicks

Yes

social_clicks

Yes

unique_clicks

Yes

spent

Yes

results

Yes

cost_per

Yes

cpc

Yes

cpm

Yes

ctr

Yes

cpa

Yes

cpp

Yes

reach

Yes

actions

Yes

frequency

Yes

leadgen

Yes

link_ctr

Yes

cost_per_unique_click

Yes

result_rate

Yes

mobile_app_install

Yes

cost_per_mobile_app_install

Yes

app_custom_event

Yes

app_custom_event.fb_mobile_achievement_unlocked

Yes

app_custom_event.fb_mobile_activate_app

Yes

app_custom_event.fb_mobile_add_payment_info

Yes

app_custom_event.fb_mobile_add_to_cart

Yes

app_custom_event.fb_mobile_add_to_wishlist

Yes

app_custom_event.fb_mobile_complete_registration

Yes

app_custom_event.fb_mobile_content_view

Yes

app_custom_event.fb_mobile_initiated_checkout

Yes

app_custom_event.fb_mobile_level_achieved

Yes

app_custom_event.fb_mobile_purchase

Yes

app_custom_event.fb_mobile_rate

Yes

app_custom_event.fb_mobile_search

Yes

app_custom_event.fb_mobile_spent_credits

Yes

app_custom_event.fb_mobile_tutorial_completion

Yes

app_custom_event.other

Yes

cost_per_mobile_achievement_unlocked

Yes

cost_per_mobile_activate_app

Yes

cost_per_mobile_add_payment_info

Yes

cost_per_mobile_add_to_cart

Yes

cost_per_mobile_add_to_wishlist

Yes

cost_per_mobile_complete_registration

Yes

cost_per_mobile_content_view

Yes

cost_per_mobile_initiated_checkout

Yes

cost_per_mobile_level_achieved

Yes

cost_per_mobile_purchase

Yes

cost_per_mobile_rate

Yes

cost_per_mobile_search

Yes

cost_per_mobile_spent_credits

Yes

cost_per_mobile_tutorial_completion

Yes

offline_conversion

No

offline_conversion.add_payment_info

No

offline_conversion.add_to_cart

No

offline_conversion.add_to_wishlist

No

offline_conversion.complete_registration

No

offline_conversion.initiate_checkout

No

offline_conversion.lead

No

offline_conversion.other

No

offline_conversion.purchase

No

offline_conversion.search

No

offline_conversion.view_content

No

cost_per_offline_conversion

No

cost_per_offline_add_payment_info

No

cost_per_offline_add_to_cart

No

cost_per_offline_add_to_wishlist

No

cost_per_offline_complete_registration

No

cost_per_offline_initiate_checkout

No

cost_per_offline_lead

No

cost_per_offline_other

No

cost_per_offline_purchase

No

cost_per_offline_search

No

cost_per_offline_view_content

No

offsite_conversion

Yes

offsite_conversion.fb_pixel_add_payment_info

Yes

offsite_conversion.fb_pixel_add_to_cart

Yes

offsite_conversion.fb_pixel_add_to_wishlist

Yes

offsite_conversion.fb_pixel_complete_registration

Yes

offsite_conversion.fb_pixel_initiate_checkout

Yes

offsite_conversion.fb_pixel_lead

Yes

offsite_conversion.fb_pixel_purchase

Yes

offsite_conversion.fb_pixel_search

Yes

offsite_conversion.fb_pixel_view_content

Yes

offsite_conversion.fb_pixel_other

Yes

cost_per_add_payment_info_fb

Yes

cost_per_add_to_cart_fb

Yes

cost_per_add_to_wishlist_fb

Yes

cost_per_complete_registration_fb

Yes

cost_per_initiate_checkout_fb

Yes

cost_per_lead_fb

Yes

cost_per_purchase_fb

Yes

cost_per_search_fb

Yes

cost_per_view_content_fb

Yes

link_click

Yes

cost_per_link_click

Yes

like

Yes

offsite_engagement

Yes

post

Yes

post_comment

Yes

post_engagement

Yes

cost_per_post_engagement

No

post_like

Yes

post_reaction

Yes

view_content

Yes

video_play

Yes

video_view

Yes

cost_per_video_view

No

vote

Yes

unique_social_clicks

No

unique_social_impressions

No

lifetime_impressions

No

lifetime_spent

No

today_spent

No

yesterday_spent

No

Advanced Filters

We offer ways to customize and derive advanced fields based off the insights and metadata filters above. For more information on how to do this, see our doc on Evaluation Spec - Filters.

These advanced filters support the following operators: GREATER_THAN, LESS_THAN, EQUAL, IN_RANGE, NOT_IN_RANGE

They are also only supported by Schedule Based Rules at the moment. For some of the most commonly used advanced filters, we also added support for an alias as the filter:

Advanced Field Alias Derived From

daily_ratio_spent

today_spent / adset.daily_budget

lifetime_ratio_spent

lifetime_spent / adset.lifetime_budget

Execution Spec

The execution_spec of a rule determines the action that applies to all objects that pass evaluation. Schedule and Trigger Based Rules support different actions, and we denote the action in the execution_type field.

Execution Type Description Supported Evaluation Types

NOTIFICATION

Sends a jeweled notification to this rule's creator, or the list of users specified in user_ids if this option is provided.

SCHEDULE, TRIGGER

PAUSE

Pauses the objects.

SCHEDULE, TRIGGER

UNPAUSE

Unpauses the objects.

SCHEDULE, TRIGGER

CHANGE_BUDGET

Changes the budgets based on a defined change_spec. This applies to Ad Sets only.

SCHEDULE

CHANGE_BID

Changes the bids based on a defined change_spec. This applies to Ad Sets only.

SCHEDULE

ROTATE

Pauses the currently active Ad and activates the next Ad by id in the Ad Set. Requires an id filter of Ad Sets, and an entity_type filter of AD.

SCHEDULE

REBALANCE_BUDGET (Example)

Pauses the objects that match the evaluation criteria, and rebalances their budgets towards the rest based on a defined rebalance_spec. This applies to Ad Sets only.

SCHEDULE

PING_ENDPOINT

Sends a ping to the application's subscription via Webhooks. See Trigger Based Rules for more details on setup.

TRIGGER

Additional information may be required in order to perform some of these actions. The execution_spec provides an optional execution_options array for users to specify these additional parameters. The array contains a list of execution_option objects, which themselves are dictionaries with keys of field, value, and operator just like the filter objects above.

Below, we define the supported execution options that one can use, which execution_type values they support, and how to structure them. Currently, the only supported operator for all options is EQUAL. Note that Trigger Based Rules do NOT require any execution options.

Execution Option Field Description Supported Execution Types Value (Example)

user_ids*

Jeweled notification recipients for NOTIFICATION, or recipients for Schedule Based Rules summary emails for each execution_type.

ALL execution_type supported by Schedule Based Rules

array ([123, 456])

change_spec

Specifies the amount, limit, unit, and target_field. Required as a dictionary for the supported types. If the target_field exists, the bid or budget will scale based on the difference between the current value of the target field and the target value specified in amount. The target_field must be a valid Insights filter.

CHANGE_BUDGET, CHANGE_BID

Ad Rules Examples - Change Spec

rebalance_spec

Supports different options that determine how budgets will be rebalanced. Please see the example for more details.

REBALANCE_BUDGET

Ad Rules Examples - Rebalance Budget

execution_count_limit

Specifies the max number of times a budget/bid change action is taken for each individual ad object for the rule. Default is no limit if not specified.

CHANGE_BUDGET, CHANGE_BID

int (123)

action_frequency

Specifies the minimum amount of minutes until the same action can be taken on an object by a rule. For example, say the value is 10080 for a CHANGE_BUDGET rule and budget was just increased by that rule for object A. That rule will not increase the budget for object A for at least a week, even if object A passes the rule evaluation during that week.

CHANGE_BUDGET, CHANGE_BID

int (123)

*If user_ids are provided for Schedule Based Rules, we generate a daily email to summarize all the actions performed by the rule within the last 24 hours, and send it to the list of users specified by user_ids at 12:30AM of the ad account's time zone. This summary email will aggregate notifications for all rules to which each user is subscribed. If no actions are performed by any of the subscribed rules, the user will not get an email for that day.

Status

The status of a rule determines whether the rule should be running. There are two statuses: ENABLED and DISABLED. To temporarily turn off a rule, edit the rule and set its status to DISABLED. To reactivate a rule, edit the rule and set its status back to ENABLED. To permanently remove a rule, delete it.

Schedule Based Rules

Monitor the state of your ads by checking them at a set interval to see if they meet the evaluation_spec criteria. For Schedule Based Rules, an additional schedule_spec is required in the rule spec:

curl \
-F 'name=Rule 1' \
-F 'evaluation_spec={
    ...
   }' \
-F 'execution_spec={
    ...
   }' \
-F 'schedule_spec={
     "schedule_type": "DAILY"
   }' \

-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Schedule Spec

The schedule_spec of a rule determines how frequently to run it. We denote this interval in the schedule_type field.

Schedule Type Description

DAILY

Run the rule at midnight in the ad account's timezone.

HOURLY

Run the rule at the start of every hour.

SEMI_HOURLY

Run the rule at the start of every half-hour.

CUSTOM (Example)

Run the rule at customized schedules.

If the schedule_type is CUSTOM, you must also specify the list of custom schedules, or times when the rule will run. In the schedule list, each individual specification can be composed of a combination of the following fields, with the only requirement that at least one of start_minute or days must exist in each entry.

Field Description

start_minute

Time in minutes after 12:00AM. Must be a multiple of 30 minutes. If this is set and there is no end_minute, this will determine the exact time to run the rule. Else, it would determine with end_minute the range of time to run the rule. If this is not set, the rule will run SEMI_HOURLY for each day specified in days.

end_minute

Time in minutes after 12:00AM. Must be a multiple of 30 minutes and after start_minute. If set, this will determine with start_minute the range of time to run the rule. If the end_minute is the same as the start_minute, it would also determine the exact time to run the rule.

days

List of days to run the rule. Each day must be a value from 0-6. 0 is Sunday, 1 is Monday, ..., 6 is Saturday. If this is not set, the rule will be run on all 7 days based on the start_minute and, if exists, the end_minute.

For more information on how to use CUSTOM schedule types, please reference Ad Rules Examples - Advanced Scheduling.

Here's an example of an evaluation_spec. This rule applies to all objects in the initial list of ids that, in the last 7 days, have had more than 10000 impressions. Note that in this case, we do not need the entity_type filter since we defined a static list of initial objects using an id filter with no prefix.

curl \
-F 'name=Rule 1' \
-F 'schedule_spec={
    ...
   }' \
-F 'evaluation_spec={
      "evaluation_type" : "SCHEDULE",
      "filters" : [
       {
         "field": "time_preset",
         "value": "LAST_7_DAYS",
         "operator": "EQUAL"
       },
       {
         "field": "effective_status",
         "value": ["ACTIVE"],
         "operator": "IN"
       },
       {
         "field": "id",
         "value": [101, 102, 103],
         "operator": "IN"
       },
       {
         "field": "impressions",
         "value": 10000,
         "operator": "GREATER_THAN"
       }
     ]
   }' \
-F 'execution_spec={
    ...
   }' \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Here is another example. This rule applies to all Ad Sets under the Campaigns with ID 101, 102, 103 that use only lifetime budgets, and have been created for less than 48 hours. Note that in this case, we do not need the time_preset filter since there are no Insights filters.

curl \
-F 'name=Rule 1' \
-F 'schedule_spec={
    ...
   }' \
-F 'evaluation_spec={
      "evaluation_type" : "SCHEDULE",
      "filters" : [
       {
         "field": "entity_type",
         "value": "ADSET",
         "operator": "EQUAL"
       },
       {
         "field": "campaign.id",
         "value": [101, 102, 103],
         "operator": "IN"
       },
       {
         "field": "budget_reset_period",
         "value": ["LIFETIME"],
         "operator": "IN"
       },
       {
         "field": "hours_since_creation",
         "value": 48,
         "operator": "LESS_THAN"
       },
     ]
   }' \
-F 'execution_spec={
    ...
   }' \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Here is an example of an execution_spec. This rule increases the budget of all matching objects by 10%, with a maximum execution limit of 5 times. This means that for every object that could potentially be matched, it could individually only have a 10% increase in budget at most five times.

curl \
-F 'name=Rule 1' \
-F 'schedule_spec={
    ...
   }' \
-F 'evaluation_spec={
    ...
   }' \
-F 'execution_spec={
     "execution_type": "CHANGE_BUDGET",
     "execution_options": [
       {
         "field": "change_spec",
         "value": {
           "amount": 10,
           "unit": "PERCENTAGE"
         },
         "operator": "EQUAL"
       },
       {
         "field": "execution_count_limit",
         "value": 5,
         "operator": "EQUAL"
       }
     ]
   }' \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Here is another example. This rule pauses all matching objects and sends an email to the list of users.

curl \
-F 'name=Rule 1' \
-F 'schedule_spec={
    ...
   }' \
-F 'evaluation_spec={
    ...
   }' \
-F 'execution_spec={
     "execution_type": "PAUSE",
     "execution_options": [
       {
         "field": "user_ids",
         "value": [1001, 1002],
         "operator": "EQUAL"
       }
     ]
   }' \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Trigger Based Rules

Monitor the state of your ads in real-time. A Trigger Based Rule is evaluated as soon as its pertinent ad objects' metadata or insights data are changed. The latency for metadata changes is usually a few seconds, and the latency for insights changes is usually within a few minutes (current p99 is about 7.5 minutes).

For Trigger Based Rules, schedule_spec is not supported since they are always checked in real-time.

Note Trigger Based Rules are only available in API at this point, they are not accessible through Ads Manager.

Trigger Object

The trigger object defines how a rule is evaluated. All trigger types except METADATA_CREATION require a trigger field, and a Trigger Based Rule only checks its condition when this field is changed.

A Trigger Based Rule can only have one trigger. If you have conditions or restraints on multiple metrics, you can add the remaining ones as filters. The filters field is used the same way as it is in Schedule Based Rules, and a Trigger Based Rule only passes its evaluation when the trigger and all the filters satisfy the comparisons. As such, a trigger and a filter is interchangeable if the change of one field leads to the change of the other. For instance, if you want a rule to trigger when cost_per_mobile_app_install > X AND spent > Y, you can use either cost_per_mobile_app_install or spent as the trigger, and the other as one of the filters, because the two fields are dependent.

The trigger object has the following structure, and belongs in the evaluation_spec:

Trigger Object Keys Description

type

The type of Trigger Based Rule. The current supported options are:

METADATA_CREATION: Triggers when an ad object is created

METADATA_UPDATE: Triggers when the metadata field is updated

STATS_CHANGE: Triggers when the insights field changes to satisfy the comparison

STATS_MILESTONE: Triggers when the insights field reaches a multiple of the value

field

The underlying field. Not in use for METADATA_CREATION

value

The underlying filter value. Not in use for METADATA_CREATION. Optional for METADATA_UPDATE.

operator

The underlying filter operator. Not in use for METADATA_CREATION. Optional for METADATA_UPDATE.

You can create Ad Rules that are triggered in four different ways:

  • Metadata related: METADATA_CREATION or METADATA_UPDATE
  • Insights related: STATS_MILESTONE or STATS_CHANGE

Creating a Metadata Creation Rule

This rule is used to monitor when an ad objects is created. Only type is required within the trigger spec. For the filters, you need to specify the entity_type that you wish to monitor.

Here is an example of a metadata creation rule for monitoring the creation of all ads falling into a certain objective. Every time a new ad is created under a campaign of APP_INSTALLS objective, a ping will be sent.

curl -i -X POST \
-F 'name=Metadata Creation Example 1' \
-F 'evaluation_spec={
      "evaluation_type" : "TRIGGER",
      "trigger" : {
        "type": "METADATA_CREATION",
      },
      "filters" : [
       {
         "field": "entity_type",
         "value": "AD",
         "operator": "EQUAL",
       },
       {
         "field": "campaign.objective",
         "value": ["APP_INSTALLS"],
         "operator": "IN",
       },
     ]
   }' \
-F 'execution_spec={
      "execution_type": "PING_ENDPOINT"
   }' \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library"

Creating a Metadata Update Rule

This rule is used to monitor when an ad object's metadata is changed. Refer to here for the list of supported metadata fields. Within trigger spec, field is required while value and operator are optional. If you are interested in a field's change no matter what its value is, you only need to specify the field option. Here is an example to send you a Facebook Notification whenever an ad set's daily budget is changed.

curl -i -X POST \
-F 'name=Metadata Update Example 1' \
-F 'evaluation_spec={
      "evaluation_type" : "TRIGGER",
      "trigger" : {
        "type": "METADATA_UPDATE",
        "field": "daily_budget",
      },
      "filters" : [
       {
         "field": "entity_type",
         "value": "ADSET",
         "operator": "EQUAL",
       },
     ]
   }' \
-F 'execution_spec={
      "execution_type": "NOTIFICATION"
   }' \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library"

If you are only interested in a subset of the events, you can provide operator and value options to refine the trigger condition. Here is an example to be notified when an ad gets disapproved.

curl -i -X POST \
-F 'name=Metadata Update for Ad' \
-F 'evaluation_spec={
      "evaluation_type" : "TRIGGER",
      "trigger" : {
        "type": "METADATA_UPDATE",
        "field": "effective_status",
        "value": ["DISAPPROVED"],
        "operator": "IN"
      },
      "filters" : [
       {
         "field": "entity_type",
         "value": "AD",
         "operator": "EQUAL",
       },
     ]
   }' \
-F 'execution_spec={
      "execution_type": "PING_ENDPOINT"
   }' \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library"

Creating a Stats Milestone Rule

With STATS_MILESTONE as type the evaluation_spec triggers when the field reaches a multiple of the value for the objects matching the conditions in the filters array.

For this specific type of rule, the trigger operator must be EQUAL, and the time_preset filter must have a value of LIFETIME.

We also have a more restrictive set of supported fields; any field not listed below is not supported as a trigger field, but can still be used as a filter in the list of filters. In addition, there are required minimum values for the trigger's value depending on the field.

Supported Trigger Field Values Minimum Value

impressions

1000

social_impressions

1000

unique_impressions

1000

reach

1000

clicks

10

social_clicks

10

unique_clicks

10

spent

1000 (cents)

results

5

actions

5

app_custom_event

1

app_custom_event_fb_mobile_achievement_unlocked

1

app_custom_event_fb_mobile_activate_app

1

app_custom_event_fb_mobile_add_payment_info

1

app_custom_event_fb_mobile_add_to_cart

1

app_custom_event_fb_mobile_add_to_wishlist

1

app_custom_event_fb_mobile_complete_registration

1

app_custom_event_fb_mobile_content_view

1

app_custom_event_fb_mobile_initiated_checkout

1

app_custom_event_fb_mobile_level_achieved

1

app_custom_event_fb_mobile_purchase

1

app_custom_event_fb_mobile_rate

1

app_custom_event_fb_mobile_search

1

app_custom_event_fb_mobile_spent_credits

1

app_custom_event_fb_mobile_tutorial_completion

1

app_custom_event_other

1

leadgen

1

like

1

link_click

1

mobile_app_install

1

offsite_conversion

1

offsite_conversion_add_to_cart

1

offsite_conversion_checkout

1

offsite_conversion_fb_pixel_add_payment_info

1

offsite_conversion_fb_pixel_add_to_cart

1

offsite_conversion_fb_pixel_add_to_wishlist

1

offsite_conversion_fb_pixel_complete_registration

1

offsite_conversion_fb_pixel_initiate_checkout

1

offsite_conversion_fb_pixel_lead

1

offsite_conversion_fb_pixel_other

1

offsite_conversion_fb_pixel_purchase

1

offsite_conversion_fb_pixel_search

1

offsite_conversion_fb_pixel_view_content

1

offsite_engagement

1

post

1

post_comment

1

post_engagement

1

post_like

1

post_reaction

1

view_content

1

video_play

1

video_view

1

vote

1

Here is an example of a stats milestone rule, which sends a ping whenever someone comments on your post.

curl \
-F 'name=Rule 1' \
-F 'evaluation_spec={
      "evaluation_type" : "TRIGGER",
      "trigger" : {
        "type": "STATS_MILESTONE",
        "field": "post_comment",
        "value": 1,
        "operator": "EQUAL"
      },
      "filters" : [
       {
         "field": "entity_type",
         "value": "CAMPAIGN",
         "operator": "EQUAL",
       },
       {
         "field": "time_preset",
         "value": "LIFETIME",
         "operator": "EQUAL",
       },
     ]
   }' \
-F 'execution_spec={
      "execution_type": "PING_ENDPOINT"
   }' \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Creating a Stats Change Rule

When using STATS_CHANGE as the trigger type, the execution_spec will be triggered when the logical AND of the trigger and all filters is evaluated from false to true in the given time frame determined by the time_preset. If subsequent evaluations of the logical AND are also true, the execution_spec does not execute. However, if the evaluation of the logical AND changes from true to false, the execution_spec executes when it changes back to true again.

For this specific type of rule, the trigger operator can be any of GREATER_THAN, LESS_THAN, IN_RANGE, or NOT_IN_RANGE.

Here is an example of a stats change rule. Every time when an ad has reached more than 5000 people and it is over $10 per purchase for the last 3 days, pause it.

curl \
-F 'name=Rule 1' \
-F 'evaluation_spec={
      "evaluation_type" : "TRIGGER",
      "trigger" : {
        "type": "STATS_CHANGE",
        "field": "cost_per_purchase_fb",
        "value": 1000,
        "operator": "GREATER_THAN",
      },
      "filters" : [
       {
         "field": "entity_type",
         "value": "AD",
         "operator": "EQUAL"
       },
       {
         "field": "time_preset",
         "value": "LAST_3_DAYS",
         "operator": "EQUAL"
       },
       {
         "field": "reach",
         "value": 5000,
         "operator": "GREATER_THAN"
       }
     ]
   }' \
-F 'execution_spec={
      "execution_type": "PAUSE"
   }' \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Creating a Delivery Insights Change Rules (beta)

When using DELIVERY_INSIGHTS_CHANGE as the trigger type, the rule will be triggered when all the filters defined in evaluation_spec are evaluated to be true, and the trigger defined in evaluation_spec just changes from false to true. If subsequent evaluations, if the filters and trigger continue being evaluated to true, the rule will not be triggered again.

You can find more examples on Delivery Insights Rule Examples.

Set Up Webhooks

In order to use the supported execution type PING_ENDPOINT, you will need to set up a subscription for your application through Webhooks.

Set up a callback URL, a Facebook App and Webhooks to get notifications from Rules API.

1. Set up a callback URL

See Webhooks Guide and create a callback URL that can handle the challenge and response during verification. The callback URL handles the data structure sent when a rule is triggered:

{
  object: 'application',
  entry: [{
    id: '<APPLICATION_ID>',
    time: 1468938744,
    changes: [{
      field: 'ads_rules_engine',
      value: {
        'rule_id': 1234,
        'object_id': 5678,
        'object_type': 'ADSET',
        'trigger_type': 'STATS_CHANGE',
        'trigger_field': 'COST_PER_LINK_CLICK',
        'current_value': '15.8',
      }
    }],
  }],
}

Note that the current_value field is a JSON-encoded string, its value can be a string in double quotes, or a number, or an array begins with [ (left bracket) and ends with ] (right bracket).

2. Add ads_rules_engine Webhook to your app

Once the callback URL handles the challenge and response for verification, register it in your app when a rule is triggered:

  • Create a new Facebook App or use an existing one.
  • Add the Webhooks Product.
  • Create a New Subscription for an Application and select the ad_rules_engine.

Alternatively this can be done through the Graph API using an App access token and not a user access token:

curl \
-F "object=application" \
-F "callback_url=<CALLBACK_URL>" \
-F "fields=ads_rules_engine" \
-F "verify_token=<VERIFY_TOKEN>" \
-F "access_token=<APP_ACCESS_TOKEN>" \
"https://graph.facebook.com/<VERSION>/<APP_ID>/subscriptions"

See the Subscriptions Reference for details on APP_ID/subscriptions.

API Calls

Read All Rules of an Account

curl -G   \
-d 'fields=name,evaluation_spec,execution_spec,status'   \
-d 'access_token=<ACCESS_TOKEN>'   \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_library

Read a Rule

curl -G   \
-d 'fields=name,evaluation_spec,execution_spec,status'   \
-d 'access_token=<ACCESS_TOKEN>'   \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>

Update a Rule

In order to update a spec, you must provide all fields including those that are unchanged. Here is an example updating the rules trigger to instead be for every 1000 impressions. Updating a rule's status requires no spec changes.

curl \
-F 'evaluation_spec={
      "evaluation_type": ...,
      "trigger" : {
        "type": "STATS_MILESTONE",
        "field": "impressions",
        "value": 1000,
        "operator": "EQUAL"
      },
      "filters": ...
     ]
   }' \
-F 'access_token=<ACCESS_TOKEN>'   \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>

Here is an example updating the filters to instead select all Ads who have more than 200 clicks. The other filters such as entity_type and time_preset must still be in this update.

curl \
-F 'evaluation_spec={
      "evaluation_type": ...,
      "filters" : [
       {
         "field": "clicks",
         "value": 200,
         "operator": "GREATER_THAN",
       },
       {
       ...
     ]
   }' \
-F 'access_token=<ACCESS_TOKEN>'   \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>

Delete a Rule

curl -X DELETE \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>

Access a Rule's Execution History

We provide an endpoint to access history data for each rule's executions. By default, this endpoint provides relevant data such as results and actions. You can also check the state of the rule at each execution to track edits.

curl -G   \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>/history

In addition, this endpoint supports three filtering mechanisms on the data: object_id, action, and hide_no_changes. You can filter the results by an object_id or an action to see results for only that object_id or action type. You can also filter the results using the hide_no_changes flag to exclude all executions for which there are no changes at all. You can combine these filters to further narrow your results.

curl -G   \
-d 'object_id=123' \
-d 'action=CHANGED_BID' \
-d 'hide_no_changes=true' \
-d "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>/history

Access an Account's Execution History

We provide an endpoint to access aggregated history data for all rules under your account. By default, this endpoint provides the same relevant data as the rule's execution history, but also the id of the rules for each entry. Entries in this endpoint are ordered by newest to oldest. This endpoint also supports the same filtering mechanisms as above: object_id, action, and hide_no_changes.

curl -G   \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<VERSION>/<AD_ACCOUNT_ID>/adrules_history

Preview a Rule

We provide an endpoint to preview the evaluation of a Schedule Based Rule. When a POST request is sent, this endpoint will return a list of objects that satisfy all specified filters of the rule at that time.

curl \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>/preview

Manually Execute a Rule

We provide an endpoint to manually execute a Schedule Based Rule. When a POST request is sent to this endpoint, the rule will be immediately scheduled to run. Results can be fetched from the execution history when the rule execution is complete.

curl \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<VERSION>/<AD_RULE_ID>/execute

Read Governing Rules for an Object

We provide endpoints from each Ad, Ad Set, and Campaign to read all the rules that govern it. By default, a rule governs an object if it statically references it by the id filter or dynamically references it by the entity_type filter. This endpoint also supports optionally specifying a pass_evaluation flag, to further limit the list of rules by whether or not the object would pass the rule's filters at that time. If pass_evaluation is true, we equivalently return all rules that, when previewed, would return the object. If it is false, we return all rules that would not.

curl \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<VERSION>/<AD_OBJECT_ID>/adrules_governed