Privacy Sandbox on Android Beta is here! Learn how to get started, and continue to provide feedback.

App install ads filtering

New mobile app installations are commonly driven by app install ads. To maximize your ad spend ROI, it's a good idea to not show an ad to install an app on devices that already have that same app installed. In this proposal, we refer to this practice as "app install ads filtering."

This proposal introduces how FLEDGE on Android will support contextual ads filtering, in particular app install ads filtering, in a privacy-preserving way. To participate, the app on the device needs to explicitly opt-in to app install ads filtering. During ad selection, ad candidates will be filtered out based on the list of apps installed on the device known by the adtech. The list of installed apps is only visible within the ad selection flow, and relies on the buy-side platform to signal that a particular ad should be filtered based on the existence of an app on the device.

To set up app install ads filtering, follow these steps:

Step 1: Register app for app install ads filtering

To opt-in to app install ads filtering, the app developer invokes the registerForAdFiltering app registration API from their app, or an adtech SDK, with a list of adtech buyer eTLD+1s. This allows the buyers on the list, and only those buyers, to filter ads based on the app’s install status, whether directly or via their adtech’s SDK. Registration gives complete control to the app developer on whether their app should participate or not in app install ads filtering.

void registerForAdFiltering(List<AdTechIdentifier> buyers);

Step 2: Request to filter out app install ads

When an ad is considered for bidding, buyers can choose to flag the ad to be filtered out based on an app's install status. This is done by including the app's package name in the ad's metadata. The app install ads filtering request is part of the ads data fed into the FLEDGE auction process. This ads data is created differently based on whether this is a contextual or remarketing ad.

  • For the contextual ad use case, which is the main use case for app install ads filtering, filtering information is included as part of the ads data that buyers can give to sellers when responding to a contextual bid outside of FLEDGE. FLEDGE will expect this filtering information to be returned as part of the contextual response, just like any other ad-specific metadata.

  • For the remarketing use case, FLEDGE will expect the filtering information to be included in the custom audience. There are 2 opportunities for this inclusion to happen: when joining the audience and when fetching new audience data as part of the update audience process

The request to filter out app install ads should look like the following within the AdData JSON object:

{
  "render_uri": "https://..",
  "metadata": {..},
  "filters": {
    "app_install": {
       "app_package_names": ["app1.package", "app2.package"]
    }
  }
}

Note: You can filter out app install ads for multiple apps at once. To do that, simply list all the app package names that should be evaluated. If ANY of the packages are found in the app install list, the ad will be filtered out .

We are currently exploring ways to enable encryption and/or signing of the contextual ads information, and we request your feedback on this topic.

Step 3: Filter out app install ads during ad selection

During an ad request, the buyer can pass multiple ads back to the seller with filtering information so that ads for installed apps can be filtered out. The sell-side is required to pass the filtering information as part of the selectAds function configuration in the adData field. Android will expect a message format similar to the one below. Note that for contextual ads the ads data is being passed into the function, as it is not already on the device, unlike for remarketing ads where the ads data is custom audience-based.

AdData myAdData = new AdData.Builder()
        .setRenderUri(Uri.parse("https://.."))
        .setMetadata("{...}")
        .setFilters(new AdFilters.Builder()
                .setAppInstalledFilter(new AppInstalledFilter.Builder()
                    .setPackageNames(ImmutableList.of("app1.package", "app2.package"))
                    .build())
                .build())
        .build();

AdSelectionConfig myAdSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(AdTechIdentifier.fromString("example-ssp1.com"))
    .setDecisionLogicUri(Uri.parse("https://..."))
    ...
    .setContextualAds(ImmutableList.of(new ContextualAd.Builder()
                      .setBuyer(AdTechIdentifier.fromString("example.com"))
                      .setReportingUri("https://example.com/reporting")
                      .setBid(20)
                      // myAdData could be taken from the JSON above
                      .setAd(myAdData)
                      .build()))
    .build();

// Invoke ad services API to initiate ad selection workflow.
selectAds(myAdSelectionConfig);

Filtering is processed within the selectAds API. FLEDGE will filter out the ad if the app specified in the message match the app in the adtech buyers’ specific app install list. Two outcomes are possible:

  • The app is not found in this list, meaning it is not installed and opened.
  • The app is found in this list, meaning it is installed and opened.

If FLEDGE detects that an app already exists, then the ad is excluded from the list of ads that the auction uses to run scoreAds on.

Considerations when contextual ads are involved

With app install ads filtering, the FLEDGE APIs start to support contextual ads filtering. A few things are important to specify in the situations where the auction is a mix of contextual and remarketing ads, or composed entirely only of contextual ads.

  • When a selectAd auction is run, the buyer will have the option to pass in a list of ContextualAd objects. These objects will contain the eTLD+1 of the ad buyer, the bid for the ad, a URL pointing to the reporting logic for the ad, and the AdData containing the actual ad content URL. Note that the AdData format is used in both contextual and remarketing ads.

  • At the beginning of the auction process, contextual and remarketing ads will be filtered based on the app they have listed that are visible to them. Then bid values will be decided for any remarketing ads, and both the remarketing and contextual ads will be scored using the provided scoreAds function. The ad with the highest score will win. Note that this process works even if no remarketing ads are present.

  • If a contextual ad wins the auction and impression reporting is triggered by the app, FLEDGE will download and execute a JS function named reportWin() from the reporting URL included in the contextual ad data. This is similar to how reporting is done for a remarketing ad winning the auction.

    Sample JavaScript reporting function:

    function reportWin(ad_selection_signals, per_buyer_signals, signals_for_buyer,
    contextual_signals) {
    let reporting_address = 'https://reporting.example.com';
    return {'status': 0, 'results': {'reporting_uri':
         reporting_address + '?some_signal=' + per_buyer_signals.some_signal} };
    }