AppsFlyer support for custom audience management through the Android Protected Audience API

Before you begin

To understand the full context of custom audience targeting through Android’s Protected Audience API (PAAPI) and to gain a deeper understanding of AppsFlyer’s proposed solutions, we advise reading the publicly available guides for Android Privacy Sandbox and Protected Audience API available on the Android for Developers website.

Overview

The Protected Audience API (PAAPI) on Android (formerly known as FLEDGE), part of the Android Privacy Sandbox, is Android’s new framework for custom audience targeting that is not reliant on cross-app device IDs such as the Google Advertising ID (GAID).

AppsFlyer enables advertisers and ad platforms (on the advertiser’s behalf) to create, manage, and access on-device custom audiences for personalized ad targeting.

This is made possible with the use of the AppsFlyer SDK, designated ad partner integrations, and the AppsFlyer Audiences platform, as detailed below.

Who is this document for?

This document is for ad tech platforms that want to build their integration to receive advertiser-side Android custom audiences for ad targeting, and Android app developers who want to have a better understanding of how custom audience targeting is achieved within this new privacy-preserving framework.

Advertiser-created custom audiences

Custom audience management

Advertiser-created custom audiences

Custom audiences created by AppsFlyer advertiser accounts in AppsFlyer Audiences will be able to sync with advertising partners through PAAPI. This includes both audiences that are defined in the audience builder as well as imported audiences. 

The process:

  1. Audience creation in AppsFlyer: The advertiser creates a custom audience in AppsFlyer Audiences and connects it to a media partner
  2. Custom audience sync between advertisers and ad platforms through PAAPI: 
    1. Audience sync to the ad platform: 
      1. AppsFlyer will initiate the creation of the custom audience entity on the ad platform through a designated API endpoint owned by the ad platform.
        • The “create audience” call will include the name of the audience as specified by the advertiser. 
      2. The ad platform will respond with a unique ID that will be encrypted and used within an audience-level verification token. This token will allow the ad platform to identify the audience in API calls received from Android’s PAAPI.
      3. Please note, for current testing purposes, partners will simulate the advertiser experience, creating and naming the custom audiences (see Ad platform-created custom audiences).
    2. On-device audience creation by AppsFlyer: 
      1. Unlike ID-based custom audience sync, which consists of uploading a list of hashed IDs that represent the audience members to the ad platform, PAAPI audience sync will happen on-device by the AppsFlyer SDK. 
      2. For each device that is part of the audience and per each ad platform that was set as an audience connection (a destination for the audience), the AppsFlyer SDK will communicate the device’s audience membership to Android via the PAAPI by triggering a fetchAndJoinCustomAudience call. This call will include:
        • FetchURI: an endpoint on the ad platform server that responds with the required parameters of the custom audience such as ads and bidding information. The Fetch URI will include the:
          • Audience verification token: an audience-level verification token that represents the audience on the ad platform, as received by AppsFlyer from the ad platform upon audience creation.
          • App-level user ID (optional): an advertiser-side, app-level user ID (such as CUID, an ID that represents the user within the advertiser app, but isn’t available to 3rd party apps) to be sent to the ad platform, to enable user-level bidding. 
        • Audience name: The audience name and/or ID for reporting purposes.
        • Activation and expiration time: The times when the audience is set to become active and expire. 
  1. Fetch of ads and bidding information from the ad platform:
    1. PAAPI custom audiences require that ads and bidding information for custom audience members be pre-set as part of the on-device audience. This information is added to the custom audience by responding to the FetchURI.
    2. The ad platform will respond to the FetchURI call with:
      • Ads: A list of candidate ads intended to be served for the custom audience
      • Trusted bidding data: a URL and set of predefined keys that enable the retrival of buy-side information that is needed to execute the ad auction in real time (e.g. available budget) 
      • User Bidding Signals: advertiser-side signals for the specific device that will enable the  determination of bids (e.g. revenue or churn scores to determine user value) 
      • Bidding Logic URL: a URL used to fetch bidding code from the ad platform upon ad auction to determine the bid
      • Daily Update URL: A URL that refreshes audience data (such as ads) on a daily basis 
  1. Targeting ads to an on-device audience:
    Publisher apps (or ad monetization platforms on their behalf) could initiate an on-device “ad selection” call to PAAPI whenever they want to display an ad within a publisher app. The ad selection call will include sell-side signals for the buyer and decision logic by which a winning ad could be selected from within the on-device custom audiences.
  2. Impression reporting
    Beyond Android Privacy Sandbox’s Attribution API, designated AppsFlyer features for reporting and attribution of PAAPI ads is still under active design.

Ad platform-created custom audiences

Ad platform-created custom audiences

Advertisers who wish to delegate custom audience creation and management to the ad platform could grant them access to create custom audiences in AppsFlyer on their behalf, with the ad platform itself set as a destination for the audience. 

The process:

  1. Audience creation in AppsFlyer (by ad platform):
    1. Ad platform access: Advertisers will grant their ad platform(s) access to audience creation in AppsFlyer UI.
    2. Custom audience creation: The ad platform will call AppsFlyer to create a new audience. The “create audience” call will include the:
      1. Audience name
      2. Audience filtering criteria: similar to how advertisers define the audience rulesets in the Audiences UI, ad partners could define audience rulesets through the API. 
      3. DSP Audience ID: a UUID that is set by the ad platform and forwarded to AppsFlyer to allow the ad platform to identify the audience in API calls received from Android’s PAAPI.
  2. For Audience sync and targeting, see previous section (starting at 2.b.)

AppsFlyer Audience management API for Partners

1. Create Custom Audience API

This API endpoint enables AppsFlyer ad partners to create audiences on behalf of advertisers and make them available for targeting using PAAPI. An audience created by an ad platform through the Create Custom Audience API will only be available for targeting by the audience creator.

Http methodPUT
URIhttps://hq1.appsflyer.com/api/audiences-external-api/create-custom-audience
HeaderAuthorization: Bearer ${your V2 token}Content-Type: application/json
Body{
   “name”: “${audience-name}”,
   “dsp_audience_id”: “${audience-dsp-id}”
   “rules”: “${audience-rules}”
}
Response{
    “status”: ${status code},
    “message”: “${success\ error msg}”
}

Audience rules:

The audience rules schema is described as a tree of set operations and formatted as a JSON string.

The basic element of the criteria is the rule

Rules are grouped into rulesets and multiple rulesets can be grouped to describe the criteria.

Here’s a representation of a criteria containing two rulesets, each ruleset is comprised of two rules:

Operator (between rulesets)

and (operator between rules)

  Rule 1

  Rule 2

and (operator between rules)

  Rule 3

  Rule 4

The following operators are available between rulesets:

  • or – user corresponds to either ruleset1 or ruleset2
  • diff – user corresponds to ruleset1 minus ruleset2
  • and – user corresponds to ruleset1 and ruleset2 

An audience can hold up to 12 rulesets.

Audience rules examples:

  • Audience criteria structure examples:
{
  "or": [
    {
      "and": // Ruleset A Filters
[
        
      	]
    },
    {
      "and": // Ruleset B Filters
[
               ]
    }
  ]
}
// All the users of ruleset A OR ruleset B
{
  "diff": [
    {
      "or": [
        {
          "and": // Ruleset A
[
            
          	]
        },
        {
          "and": // Ruleset B
[
               
]
        }
      ]
    },
    {
      "and": // Ruleset C
[
              ]
    }
  ]
}
// All the users of (ruleset A OR ruleset B) EXCLUDE users of ruleset C
  • Rulesets examples:
{
      "and": [
        {
          "filter": "launch",
          "date": {
            "type": "last",
            "value": 30
          },
          "quantifier": "at_least",
          "times": 1,
          "app_id": "com.appsflyer.android_privacy_sandbox_sample"
        }
      ]
}
{ 
      "filter": "app_version",	
      "predicate": "is",
      "values": [
        "5.20.0"
      ],
      "app_id": "com.appsflyer.android_privacy_sandbox_sample"	
}
  • Audiences criteria real life example:
{
  "diff": [
    {
      "and": [
        {
          "filter": "launch",
          "date": {
            "type": "since_first"
          },
          "quantifier": "at_least",
          "times": 1,
          "app_id": "com.appsflyer.android_privacy_sandbox_sample"
        }
      ]
    },
    {
      "and": [
        {
          "filter": "launch",
          "date": {
            "type": "last",
            "value": 30
          },
          "quantifier": "at_least",
          "times": 1,
          "app_id": "com.appsflyer.android_privacy_sandbox_sample"
        }
      ]
    }]}

Audience filter  definition 

Date field

NameDescription
type

type: String
Required
last
between
since_first
value

type: Number or Object
Required if type is last or between 
For last:
Value is the amount of days to look back

For between:
Value is the date range in the format: 
{
  “$gte”: “YYYY-MM-DD”,
  “$lte”: “YYYY-MM-DD”
}

Did Event filter

Filter based on event done by the user

NameDescription
filter

type: String
Required
event
quantifier 

type: String
Required

at_least
at_most
exactly 
timesRequired

The amount of times the user did the event
event_name

type: String
Required

The event name as defined in AppsFlyer SDK
date

type: Date field
Required

See Date field 
event_values

Type: Event values array
Required an empty array or with values

See event value structure below

Event value structure

NameDescription
event_key

type: String
Required

The event key as defined in AppsFlyer SDK
predicate 

type: String
Required

is
is_not
greater_than (only for number value)
lower_than (only for number value) 
event_value

type: String or Number
Required

Did not do event filter

Filter based on event not done by the user in a specific date range

NameDescription
filter

type: String
Required

excluded_event
event_name

type: String
Required

The event name as defined in AppsFlyer SDK
date

type: Date field
Required

See Date field 

Dimension filter

Filter based on a dimension like device_model, os version etc..

NameDescription
filter

type: String
Required

device_model
brand
os_version
carrier
app_version
ad
adset_name
campaign
media_source
predicate

type: String
Required

isis_not
values

type: Strings array
Required

pre

Attribution filter

Filter based on the attribution type (organic or retargeting)

NameDescription
filter

type: String
Required

is_oragnic
is_retargeting
predicate

type: String
Required

is
values

type: Strings array
Required

true
false

Revenue filter

Filter based on the revenue 

NameDescription
filter

type: String
Required

total_iap_revenue – for in app revenue
total_ad_revneue
sum_total_revenue – for both revenues
predicate

type: String
Required

is
is_not
greater_than 
lower_than 
value

type: Number
Required

The revenue in USD
date

type: Date field
Required

See Date field 

Event occurrences filter

Filter based on the following events occurrences 

NameDescription
filter

type: String
Required

launch
install
click (clicked an add)
impression (viewed an ad)
quanitifier 

type: String
Required

at_least
at_most
exactly 
times

type: Number
Required

The amount of times the event happen 
date

type: Date field
Required

See Date field 

Event occurrences filter

Filter based on the following events occurrences 

NameDescription
filter

type: String
Required

uninstall
no_install
no_launch
date

type: Date field
Required

See Date field 

2. Audience verification token


The Audience verification token includes a UUID (dsp_audience_id) that is set by the ad platform and forwarded to AppsFlyer to allow the ad platform to identify the audience in API calls received from Android’s PAAPI.

Audience verification token would be in the following structure:

DSP Audience ID ; Appsflyer ID ; timestamp

  • DSP Audience ID – 128 bit UUID generated by the DSP
  • Appsflyer ID – An AppsFlyer ID is automatically created by AppsFlyer for every new install of an app
  • Timestamp – current unix epoch in seconds as unsigned 64 bit integer.

This will be hashed using a symmetric key that will be provided in the onboarding phase in AES128 hashing methodology and then turned to Base64.

Ad platform integration and testing

AppsFlyer support for custom audience management through the Android Protected Audience API is currently in testing stages. We welcome ad partners to test against AppsFlyer and Android APIs, validate their solutions and provide feedback to help shape our future integrations.
Testing is being done with the use of our partner facing APIs, and our testing app that imitates both the advertiser app for audience management and the publisher app for ad selection.
To begin testing, please follow the next steps.

  • Apply for AppsFlyer’s PAAPI testing
    • Testing is available for AppsFlyer ad partners that are already integrated with the AppsFlyer platform (for either Attribution or Audience management) 
    • To join AppsFlyer Protected Audience API testing, please reach out to your Partner Devepment Manager 
    • Once approved,  you will be granted access to the Create Custom Audience API. To authenticate, please use the AppsFlyer API Token V2 that is available within your AppsFlyer account login. 
  • Get Symmetric key for Audience verification token encryption and App Testing Key
    • Once approved, AppsFlyer will provide ad partner with two keys that are required for testing:
      • Symmetric key for encryption and decryption of the Audience verification token
      • App Testing Key that is used as an input within your testing app and identifies your test devices as belong to a specific ad partner
  • Implement Android’s Protected Audience APIs (FetchURI, DailyUpdateURL, etc..)
  • Share FetchURI with AppsFlyer
    • The FetchURI will be sent by the AppsFlyer SDK together with fetchAndJoinCustomAudience calls, to call the ad platforms servers for required audience data such as ads and bidding information
  • Download the AppsFlyer PAAPI Test app 
Background
Interested in measuring the ROI of your campaigns?