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:
- Audience creation in AppsFlyer: The advertiser creates a custom audience in AppsFlyer Audiences and connects it to a media partner.
- Custom audience sync between advertisers and ad platforms through PAAPI:
- Audience sync to the ad platform:
- 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.
- 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.
- Please note, for current testing purposes, partners will simulate the advertiser experience, creating and naming the custom audiences (see Ad platform-created custom audiences).
- AppsFlyer will initiate the creation of the custom audience entity on the ad platform through a designated API endpoint owned by the ad platform.
- On-device audience creation by AppsFlyer:
- 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.
- 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.
- 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 sync to the ad platform:
- Fetch of ads and bidding information from the ad platform:
- 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.
- 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
- 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. - 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:
- Audience creation in AppsFlyer (by ad platform):
- Ad platform access: Advertisers will grant their ad platform(s) access to audience creation in AppsFlyer UI.
- Custom audience creation: The ad platform will call AppsFlyer to create a new audience. The “create audience” call will include the:
- Audience name
- Audience filtering criteria: similar to how advertisers define the audience rulesets in the Audiences UI, ad partners could define audience rulesets through the API.
- 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.
- 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 method | PUT |
URI | https://hq1.appsflyer.com/api/audiences-external-api/create-custom-audience |
Header | Authorization: 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
Name | Description |
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
Name | Description |
filter type: String | Required event |
quantifier type: String | Required at_least at_most exactly |
times | Required 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
Name | Description |
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
Name | Description |
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..
Name | Description |
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)
Name | Description |
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
Name | Description |
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
Name | Description |
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
Name | Description |
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
- Once approved, AppsFlyer will provide ad partner with two keys that are required for testing:
- Implement Android’s Protected Audience APIs (FetchURI, DailyUpdateURL, etc..)
- Please follow Android dev documentation for details
- 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