Impression-level ad revenue

When an impression occurs, the Google Mobile Ads SDK provides ad revenue data associated with that impression. You can use the data to calculate a user's lifetime value, or forward the data downstream to other relevant systems.

This guide is intended to help you implement the impression-level ad revenue data capture in your Android app.

Prerequisites

Each ad format has an OnPaidEventListener. During the lifecycle of an ad event, the Google Mobile Ads SDK monitors impression events and invokes the handler with an earned value.

The code below demonstrates how to handle paid events for a rewarded ad:

Java

import com.google.android.gms.ads.rewarded.RewardedAd;

public class MainActivity extends Activity {
  private RewardedAd rewardedAd;
  private final String TAG = "MainActivity";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    AdRequest adRequest = new AdRequest.Builder().build();

    RewardedAd.load(this, "AD_UNIT_ID",
      adRequest, new RewardedAdLoadCallback(){
        @Override
        public void onAdLoaded(@NonNull RewardedAd ad) {
          rewardedAd = ad;
          // Set paid event listener
          rewardedAd.setOnPaidEventListener(new OnPaidEventListener() {
            @Override
            public void onPaidEvent(AdValue adValue) {
              // TODO: Send the impression-level ad revenue information to your
              //preferred analytics server directly within this callback.

              // Extract the impression-level ad revenue data.
              long valueMicros = adValue.getValueMicros();
              String currencyCode = adValue.getCurrencyCode();
              int precision = adValue.getPrecisionType();

              // Get the ad unit ID.
              String adUnitId = rewardedAd.getAdUnitId();
              
              AdapterResponseInfo loadedAdapterResponseInfo = rewardedAd.getResponseInfo().
                  getLoadedAdapterResponseInfo();
              String adSourceName = loadedAdapterResponseInfo.getAdSourceName();
              String adSourceId = loadedAdapterResponseInfo.getAdSourceId();
              String adSourceInstanceName = loadedAdapterResponseInfo.getAdSourceInstanceName();
              String adSourceInstanceId = loadedAdapterResponseInfo.getAdSourceInstanceId();

              Bundle extras = rewardedAd.getResponseInfo().getResponseExtras();
              String mediationGroupName = extras.getString("mediation_group_name");
              String mediationABTestName = extras.getString("mediation_ab_test_name");
              String mediationABTestVariant = extras.getString("mediation_ab_test_variant");
            }
          });
        }
    });
  }
}

Kotlin

import com.google.android.gms.ads.rewarded.RewardedAd

class MainActivity : AppCompatActivity() {
  private var rewardedAd: RewardedAd? = null
  private final var TAG = "MainActivity"

  override fun onCreate(savedInstanceState: Bundle?) {
    AdRequest adRequest = new AdRequest.Builder().build()

    RewardedAd.load(this, "AD_UNIT_ID",
      adRequest, object: RewardedAdLoadCallback() {
        override fun onAdLoaded(ad: RewardedAd) {
          rewardedAd = ad
          // Set paid event listener
          rewardedAd.onPaidEventListener = OnPaidEventListener { adValue ->
            // TODO: Send the impression-level ad revenue information to your preferred
            // analytics server directly within this callback.

            // Extract the impression-level ad revenue data.
            val valueMicros = adValue.valueMicros
            val currencyCode = adValue.currencyCode
            val precision = adValue.precisionType

            // Get the ad unit ID.
            val adUnitId = rewardedAd.adUnitId

            val loadedAdapterResponseInfo = rewardedAd.responseInfo.loadedAdapterResponse
            val adSourceName = loadedAdapterResponseInfo.adSourceName
            val adSourceId = loadedAdapterResponseInfo.adSourceId
            val adSourceInstanceName = loadedAdapterResponseInfo.adSourceInstanceName
            val adSourceInstanceId = loadedAdapterResponseInfo.adSourceInstanceId
            val extras = rewardedAd.responseInfo.responseExtras
            val mediationGroupName = extras.getString("mediation_group_name")
            val mediationABTestName = extras.getString("mediation_ab_test_name")
            val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
          }
        }
    })
  }
}

For more information on the winning ad source, see Retrieve information about the ad response.

App Attribution Partners (AAP) integration

For complete details on forwarding ads revenue data to analytics platforms, refer to the partner's guide:

Partner SDK
Adjust
AppsFlyer
Singular
Tenjin

Implementation best practices

  • Set the listener immediately once you create or get access to the ad object, and definitely before showing the ad. This ensures that you don't miss any paid event callbacks.
  • Send the impression-level ad revenue information to your preferred analytics server immediately at the time the onPaidEvent() method is called. This ensures you don't accidentally drop any callbacks and avoids data discrepancies.

AdValue

AdValue is a class that represents the monetary value earned for an ad, including the value's currency code and its precision type encoded as below.

PrecisionType Description
UNKNOWN An ad value that's unknown. This gets returned when LTV pingback is enabled but there isn't enough data available.
ESTIMATED An ad value estimated from aggregated data.
PUBLISHER_PROVIDED A publisher provided ad value, such as manual CPMs in a mediation group.
PRECISE The precise value paid for this ad.

In case of mediation, AdMob tries to provide an ESTIMATED value for ad sources that are optimized. For non-optimized ad sources, or in cases where there aren't enough aggregated data to report a meaningful estimation, the PUBLISHER_PROVIDED value is returned.