Custom Audiences from Your Mobile App

Build audiences based on peoples' actions in your app that meet your criteria. For example, define audiences who "Passed Level 8 in the last 10 days", "Used app in the last 8 days but hasn't purchased anything". "Added to cart but not purchased", and so on.

This solution uses logged named events through our Facebook SDKs or via Mobile Measurement Partners. Examples include "Installed", "Added to Cart", "Purchased", or "Achieved a Level".

Create an Audience

To create Custom Audiences from your mobile app, the ad account must accept the Terms of Service for Custom Audiences, in Ads Manager.

Notes:

  • You need to be an Admin, Developer, or Insights User for the ad account.
  • The ad account should be listed as an Advertising account on your app settings.
curl -X POST \ -F 'name="My Test Website Custom Audience"' \ -F 'rule={ "inclusions": { "operator": "or", "rules": [ { "event_sources": [ { "id": "<APP_ID>", "type": "app" } ], "retention_seconds": 8400, "filter": { "operator": "and", "filters": [ { "field": "event", "operator": "eq", "value": "fb_mobile_purchase" } ] } } ] } }' \ -F 'prefill=1' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.1/act_<AD_ACCOUNT_ID>/customaudiences
const adsSdk = require('facebook-nodejs-ads-sdk'); const AdAccount = adsSdk.AdAccount; const CustomAudience = adsSdk.CustomAudience; let access_token = '<ACCESS_TOKEN>'; let app_secret = '<APP_SECRET>'; let app_id = '<APP_ID>'; let id = '<ID>'; const api = adsSdk.FacebookAdsApi.init(access_token); const showDebugingInfo = true; // Setting this to true shows more debugging info. if (showDebugingInfo) { api.setDebug(true); } const logApiCallResult = (apiCallName, data) => { console.log(apiCallName); if (showDebugingInfo) { console.log('Data:' + JSON.stringify(data)); } }; let fields, params; fields = [ ]; params = { 'name' : 'My Test Website Custom Audience', 'rule' : {'inclusions':{'operator':'or','rules':[{'event_sources':[{'id':'<appID>','type':'app'}],'retention_seconds':8400,'filter':{'operator':'and','filters':[{'field':'event','operator':'eq','value':'fb_mobile_purchase'}]}}]}}, 'prefill' : '1', }; let customaudiences = (new AdAccount(id)).createCustomAudience( fields, params ); logApiCallResult('customaudiences api call complete.', customaudiences);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\CustomAudience; use FacebookAds\Api; use FacebookAds\Logger\CurlLogger; $access_token = '<ACCESS_TOKEN>'; $app_secret = '<APP_SECRET>'; $app_id = '<APP_ID>'; $id = '<ID>'; $api = Api::init($app_id, $app_secret, $access_token); $api->setLogger(new CurlLogger()); $fields = array( ); $params = array( 'name' => 'My Test Website Custom Audience', 'rule' => array('inclusions' => array('operator' => 'or','rules' => array(array('event_sources' => array(array('id' => '<appID>','type' => 'app')),'retention_seconds' => 8400,'filter' => array('operator' => 'and','filters' => array(array('field' => 'event','operator' => 'eq','value' => 'fb_mobile_purchase'))))))), 'prefill' => '1', ); echo json_encode((new AdAccount($id))->createCustomAudience( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebookads.adobjects.adaccount import AdAccount from facebookads.adobjects.customaudience import CustomAudience from facebookads.api import FacebookAdsApi access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAdsApi.init(access_token=access_token) fields = [ ] params = { 'name': 'My Test Website Custom Audience', 'rule': {'inclusions':{'operator':'or','rules':[{'event_sources':[{'id':'<appID>','type':'app'}],'retention_seconds':8400,'filter':{'operator':'and','filters':[{'field':'event','operator':'eq','value':'fb_mobile_purchase'}]}}]}}, 'prefill': '1', } print AdAccount(id).create_custom_audience( fields=fields, params=params, )
import com.facebook.ads.sdk.*; import java.io.File; import java.util.Arrays; public class SAMPLE_CODE_EXAMPLE { public static void main (String args[]) throws APIException { String access_token = \"<ACCESS_TOKEN>\"; String app_secret = \"<APP_SECRET>\"; String app_id = \"<APP_ID>\"; String id = \"<ID>\"; APIContext context = new APIContext(access_token).enableDebug(true); new AdAccount(id, context).createCustomAudience() .setName(\"My Test Website Custom Audience\") .setRule(\"{\\"inclusions\\":{\\"operator\\":\\"or\\",\\"rules\\":[{\\"event_sources\\":[{\\"id\\":\\"<appID>\\",\\"type\\":\\"app\\"}],\\"retention_seconds\\":8400,\\"filter\\":{\\"operator\\":\\"and\\",\\"filters\\":[{\\"field\\":\\"event\\",\\"operator\\":\\"eq\\",\\"value\\":\\"fb_mobile_purchase\\"}]}}]}}\") .setPrefill(true) .execute(); } }
require 'facebook_ads' access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAds.configure do |config| config.access_token = access_token config.app_secret = app_secret end ad_account = FacebookAds::AdAccount.get(id) customaudiences = ad_account.customaudiences.create({ name: 'My Test Website Custom Audience', rule: {'inclusions':{'operator':'or','rules':[{'event_sources':[{'id':'<appID>','type':'app'}],'retention_seconds':8400,'filter':{'operator':'and','filters':[{'field':'event','operator':'eq','value':'fb_mobile_purchase'}]}}]}}, prefill: '1', })

This returns the id of the audience upon success. These parameters are most relevant:

Name Description Type Required

name

Name of your custom audience.

String

Yes

description

Description of your custom audience.

String

No

rule

Rule to define the audience. See [Audience Rules]

JSON object

No

Each ad account can create a maximum of 200 custom audiences via Custom Audiences from Your Mobile App. Make a HTTP POST to:

https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/customaudiences

Use these fields:

name type description required

name

string

name of your Custom Audience

yes

subtype

string

Set to APP

yes

retention_days

integer

How long someone is in this audience. 1 min, 180 max.


If retention_days is 14, and on day 13, an audience member triggers an app event matching your criteria, then Facebook extends their time in the audience 14 more days. Someone is in an audience N days from the last matching event they triggered.

yes

rule

JSON Object

Rules to define the audience. See Audience Rules

yes

Audience Rules

To determine who gets added to the Custom Audience, define a rule based on events in your app. A rule is a JSON object with key-value pairs and can reference multiple app events. You can define the rule based on specific events and their parameters and also the aggregation.

For for full examples of these components in action, see Example Custom Audience Rules.

Audience Rule Syntax

To define an audience rule, the following structure must be followed:

rule: {
   "inclusions": <RULE_SET>,
   "exclusions": <RULE_SET>,}
Name Description Type Required

inclusions

Rule Set JSON string that defines the inclusion

String

Yes

exclusions

Rule set JSON string that defines the inclusion

String

No

Audience Rules, deprecated

Use this section for audience rules prior to v3.0.

Rules determine whether a person should be added to this audience. They apply to Offline Events sent through the Offline Conversions API or uploaded manually with Offline Event Manager.

For example, build an audience with people who purchased in the past 30 days:

 curl \
-F 'name=30d Purchasers' \
-F 'subtype=OFFLINE_CONVERSION' \
-F 'retention_days=30' \
-F 'rule={"event":{"eq":"Purchase"}}' \
-F 'dataset_id=&lt;OFFLINE_EVENT_SET_ID>' \
-F 'access_token=&lt;ACCESS_TOKEN>' \      "https://graph.facebook.com/&lt;API_VERSION>/act_&lt;AD_ACCOUNT_ID>/customaudiences"

Rules can use Offline Event attributes in custom_data field called 'category'. This targets people who purchased a product from the footwear category in the past 60 days:

curl \
  -F 'name=60d Footwear Purchasers' \
  -F 'subtype=OFFLINE_CONVERSION' \
  -F 'retention_days=60' \
  -F 'rule={"and": [{"event":{"eq":"Purchase"}},{"custom_data.category":{"i_contains":"FOOTWEAR"}}]}' \
  -F 'dataset_id=&lt;OFFLINE_EVENT_SET_ID>' \
  -F 'access_token=&lt;ACCESS_TOKEN>' \
  "https://graph.facebook.com/&lt;API_VERSION>/act_&lt;AD_ACCOUNT_ID>/customaudiences"

Rules are based on these operators and data types:

Name Description

operator

  • i_contains - Contains substring, case insensitive
  • i_not_contains - Does not contain substring, case insensitive
  • contains - Contains substring, case sensitive
  • not_contains - Does not contain substring, case sensitive
  • eq - Equal to, case sensitive
  • neq - Not equal to, case sensitive
  • lt - Less than, numeric fields only
  • lte - Less than or equal to, numeric fields only
  • gt - Greater than, numeric fields only
  • gte - Greater than or equal to, numeric fields only
  • regex_match -
    Matches a regular expression, such as ".*shoes". Full PCRE grammar supported

data

  • event - Offline Event name. Examples: 'Purchase', 'Lead', 'Other'
  • value - Offline Event value
  • custom_data - Any attribute added to custom_data for an Offline Event. Examples: custom_data.category, custom_data.color.

Rule Set Syntax

{
  "operator": <BOOLEAN_OPERATOR>,
  "rules": <RULE_DEFINTION>,  
}
Name Description Type Required

operator

and or or

String

Yes

rules

Array of JSON objects of rules

String

Yes

Rule Syntax

{
    "event_sources": <EVENT_SOURCE_DEFINITION>,
    "retention_seconds": <SECONDS>,
    "filter": <FILTER>,
    "aggregation": <AGGREGATION>,
}
Name Description Type Required

event_sources

Array of JSON objects of event source objects of the format

{"id": APP_ID, "type": "app"}

String

Yes

retention_seconds

Integer in seconds for the retention window of the audience. MAX: 15552000 (180 days)

Integer

Yes

filter

JSON string of the filter. See more in Filters.

Integer

Yes

aggregation

JSON string of the aggregation rule. See more in Aggregation Functions.

String

No

Filter

Filtration follows this general format:

"filter": {
    "operator": <BOOLEAN_OPERATOR>,
    "filters": <FILTER_SET>,
}
Name Description Type Required

operator

and or or

String

Yes

filters

Array of JSON objects of filter rules

String

Yes

Filters

{
    "field": <FIELD>,
    "operator": <COMPARISON_OPERATOR>,
    "value": <VALUE>,
}
Name Description Type Required

field

Use "event" if the filter is to specify an event. Parameters that match App events sent by app; for example, "_appVersion", "_value", and so on.

String

Yes

comparison operator

=, !=, >=, >, <=, <, i_contains, i_not_contains, contains, not_contains, is_any, is_not_any, i_is_any, i_is_not_any, . If field set to event, must use =.

String

Yes

value

If the field attribute is set to "event", the value must be set to an event name. Use the App Event API to see app events and parameters reported by the pixel.

String

Yes

Aggregation Function

Create a Custom Audience based on the behavior frequency and intensity using aggregation in the rule field.

"aggregation": {
    "type": <AGGREGTION_FUNCTION>,
    "method" <AGGREGATION_METHOD>,
    "field": <EVENT_PARAMETER>,
    "operator": <COMPARISON_OPERATOR>,
    "value": <VALUE>,
}
Name Description Type Required

type

The aggregation function type: “count” “sum” “avg” “min” “max”

String

Yes

method

absolute, meaning add people that logged events in specified range, or percentile, meaning add people from a specified percentile range. If you select percentile the operator should only be in_range and not_in_range.

String

No

field

The parameter on which the aggregation function is applied.

String

No, if type is set to count; Yes, otherwise

comparison operator

=, !=, >=, >, <=, <, in_range, not_in_range

String

Yes

value

Expected value of the parameter

String

Yes

Comparison Operators

Operator Description

">" or "gt"

True if event's parameter value greater than specified value.

">=" or "gte"

True if event's parameter value greater than or equal to specified value.

"<" or "lt"

True if event's parameter value less than specified value.

"<=" or "lte"

True if event's parameter value less than or equal to specified value.

"=" or "eq"

True if event's parameter value equal to specified value. Note: This is equivalent to not specifying an operator at all; that is, "'x' : { 'eq' : 'y' }" is the same as "'x' : 'y' }.

"!=" or "neq"

True if event's parameter value not equal to specified value.

"contains"

True if event's parameter value, as string, contains specified string. Value of "shoe12345" fulfills 'contains' if specified value 'shoe'.

"not_contains"

True if event's parameter value, as string, does not contain specified string. Value "shoe12345" fulfills 'not_contains' if specified value is 'purse'.

"i_contains"

Contains, case-insensitive

"i_not_contains"

Not contains, case-insensitive

"is_any"

True if event's parameter value matches any strings in given array.

"is_not_any"

True if event's parameter value matches no strings in specified array.

"i_is_any"

'is_any', case-insensitive.

"i_is_not_any"

'is_not_any', case-insensitive

Example Custom Audience Rules

Standard event example: All mobile app purchasers in the last 30 days for app id 55064006:

{
    "inclusions: {
        "operator": "or",
        "rules": [    
            {
                "event_sources": [
                    {
                        "id": 55064006, 
                        "type": "app"
                    }
                ],
                "retention_seconds: 2592000,
                "filter": {
                    "operator": "and",
                    "filters": [
                        {
                            "field": "event",
                            "operator": "=",
                            "value": "fb_mobile_purchase"
                        }
                    ]
                }
            }
        ]
    }
}

Custom event with parameters example: All users who passed back custom “timeOnPanel” events in the last 30 days for app id 55064006:

{
    "inclusions: {
        "operator": "or",
        "rules": [    
            {
                "event_sources": [
                    {
                        "id": 55064006, 
                        "type": "app"
                    }
                ],
                "retention_seconds: 2592000,
                "filter": {
                    "operator": "and",
                    "filters": [
                        {
                            "field": "event",
                            "operator": "=",
                            "value": "timeOnPanel"
                        }
                    ]
                }
            }
        ]
    }
}

All users who passed back custom “timeOnPanel” events where event value is greater than 30, color is “red” or “blue”, and favorite dessert contains “banana”:

{
    "inclusions: {
        "operator": "or",
        "rules": [    
            {
                "event_sources": [
                    {
                        "id": 55064006, 
                        "type": "app",
                    }
                ],
                "retention_seconds: 2592000,
                "filter": {
                    "operator": "and",
                    "filters": [
                        {
                            "field": "event",
                            "operator": "=",
                            "value": "timeOnPanel",
                        },
                        {
                            "field": "_value",
                            "operator": ">",
                            "value": 30,
                        },
                        {
                            "field": "color",
                            "operator": "is_any",
                            "value": ["red", "blue"],
                        },
                        {
                            "field": "favoriteDessert",
                            "operator": "contains",
                            "value": "banana",
                        }
                    ]
                }
            }
        ]
    }
}

Aggregation example: Top 20% purchasers based on the purchases in the last 30 days:

{
    "inclusions: {
        "operator": "or",
        "rules": [    
            {
                "event_sources": [
                    {
                        "id": 55064006, 
                        "type": "app"
                    }
                ],
                "retention_seconds: 2592000,
                "filter": {
                    "operator": "and",
                    "filters": [
                        {
                            "field": "event",
                            "operator": "=",
                            "value": "fb_mobile_purchase"
                        }
                    ]
                }
                "aggregation": {
                    "type": "count",
                    "method": "percentile",
                    "operator": "in_range",
                    "from": 75,  
                    "to": 100,
                }
            }
        ]
    }
}

Exclusions example: Include people who added-to-cart but not purchased:

{
    "inclusions: {
        "operator": "or",
        "rules": [    
            {
                "event_sources": [
                    {
                        "id": 55064006, 
                        "type": "app"
                    }
                ],
                "retention_seconds: 2592000,
                "filter": {
                    "operator": "and",
                    "filters": [
                        {
                            "field": "event",
                            "operator": "=",
                            "value": "add_to_cart"
                        }
                    ]
                }
            }
        ]
    },
    "exclusions": {
        "operator": "or",
        "rules": [    
            {
                "event_sources": [
                    {
                        "id": 55064006, 
                        "type": "app"
                    }
                ],
                "retention_seconds: 2592000,
                "filter": {
                    "operator": "and",
                    "filters": [
                        {
                            "field": "event",
                            "operator": "=",
                            "value": "fb_mobile_purchase"
                        }
                    ]
                }
            }
        ]
    }
}

Aggregate Functions, deprecated

Use this section for aggregate functions prior to v3.0.

Create custom audiences based upon the frequency and intensity of a person's behavior through a rule_aggregation field. Provide functions with these fields:

Name Description

type

Type of function: count, sum, avg, max, min

config

Required by certain aggregation functions. See below

operator

  • =
  • >
  • >=
  • <
  • <=
  • !=
  • @> - Time between delivery and when the Offline Event took place is longer than the value, or now - pass-in-time > value
  • @< - Time between delivery when the Offline Event took place is shorter than the value, or now - pass-in-time < value

value

Integer. rule_aggregation value

The available functions are:

NameRequired ConfigDescription

count

Number of Offline Events satisfying the rule

sum

{“field”: “field_name”}

Accumulate values of given Offline Event's field

avg

{“field”: “field_name”}

Average of values in specified Offline Event's field

max

{“field”: “field_name”}

Maximum value for a Offline Event's field

min

{“field”: “field_name”}

Minimum value in a Offline Event's field

To target people who purchased more than 5 times in the past 110 days:

curl \
-F 'name=110d Returning Customers' \
-F 'subtype=OFFLINE_CONVERSION' \
-F 'retention_days=110' \
-F 'rule={"event":{"eq":"Purchase"}}' \
-F 'rule_aggregation={"type":"count", "operator":">", "value": "5"} ' \
-F 'dataset_id=&lt;OFFLINE_EVENT_SET_ID>' \
-F 'access_token=&lt;ACCESS_TOKEN>' \
"https://graph.facebook.com/&lt;API_VERSION>/act_&lt;AD_ACCOUNT_ID>/customaudiences"

App Events API

Query which app events and parameters an app reported to Facebook. You can use these events and parameters directly for creating Custom Audiences. You need an access token associated with the app_id with a admin, developer, or advertiser role.

Make a HTTP GET call:

https://graph.facebook.com/<API_VERSION>/<APP_ID>/app_event_types

The response is JSON containing a data array of JSON dictionaries having these fields:

Name Description Type

event_name

App event type to use in rule

string

display_name

Human-readable name of event type

string

description

Verbose description of standard event

string

parameters

array of JSON dictionaries describing parameters for this event { "parameter_name": "fb_currency", "display_name": "Currency", "description": "Currency for event" }


parameter_name - string, App param type to use in rule


display_name - string, Human readable name of event type


description - string, Verbose description of parameter, if a standard param

array


Managing Audiences

Resources