Stay organized with collections
Save and categorize content based on your preferences.
When an impression occurs, Google Mobile Ads SDK calls the paid event
handler with its associated revenue data. By implementing this handler, 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 LTV data capture in your iOS app.
Each ad format has a paidEventHandler property of type
GADPaidEventHandler.
During the lifecycle of an ad event, Google Mobile Ads SDK monitors
impression events and invokes the handler with an earned value.
Swift
classViewController:UIViewController,FullScreenContentDelegate{varrewardedAd:RewardedAd?funcrequestRewardedAd(){RewardedAd.load(with:"AD_UNIT_ID",request:AdManagerRequest()){(ad,error)inifleterror=error{print("Rewarded ad failed to load with error: \(error.localizedDescription)")return}ifletad=ad{self.rewardedAd=adself.rewardedAd?.paidEventHandler={adValuein// TODO: Send the impression-level ad revenue information to your preferred analytics// server directly within this callback.// Extract the impression-level ad revenue data.letvalue=adValue.valueletprecision=adValue.precisionletcurrencyCode=adValue.currencyCode// Get the ad unit ID.letadUnitId=ad.adUnitIDletresponseInfo=ad.responseInfoletloadedAdNetworkResponseInfo=responseInfo?.loadedAdNetworkResponseInfoletadSourceId=loadedAdNetworkResponseInfo?.adSourceIDletadSourceInstanceId=loadedAdNetworkResponseInfo?.adSourceInstanceIDletadSourceInstanceName=loadedAdNetworkResponseInfo?.adSourceInstanceNameletadSourceName=loadedAdNetworkResponseInfo?.adSourceName}}}}}
Objective-C
@importGoogleMobileAds;@importUIKit;@interfaceViewController()@property(nonatomic,strong)GADRewardedAd*rewardedAd;@end@implementationViewController-(void)requestRewardedAd{__weakViewController*weakSelf=self;GAMRequest*request=[GAMRequestrequest];[GADRewardedAdloadWithAdUnitID:@"AD_UNIT_ID"request:requestcompletionHandler:^(GADRewardedAd*ad,NSError*error){if(error){NSLog(@"Rewarded ad failed to load with error: %@",[errorlocalizedDescription]);return;}self.rewardedAd=ad;self.rewardedAd.paidEventHandler=^void(GADAdValue*_Nonnullvalue){ViewController*strongSelf=weakSelf;// TODO: Send the impression-level ad revenue information to your preferred analytics// server directly within this callback.// Extract the impression-level ad revenue data.NSDecimalNumber*value;=value.value;NSString*currencyCode=value.currencyCode;GADAdValuePrecisionprecision=value.precision;// Get the ad unit ID.NSString*adUnitId=strongSelf.rewardedAd.adUnitID;GADAdNetworkResponseInfo*loadedAdNetworkResponseInfo=strongSelf.rewardedAd.responseInfo.loadedAdNetworkResponseInfo;NSString*adSourceName=loadedAdNetworkResponseInfo.adSourceName;NSString*adSourceID=loadedAdNetworkResponseInfo.adSourceID;NSString*adSourceInstanceName=loadedAdNetworkResponseInfo.adSourceInstanceName;NSString*adSourceInstanceID=loadedAdNetworkResponseInfo.adSourceInstanceID;};]};}
Identify a custom event ad source name
For custom event ad sources, adSourceName
property gives you the ad source name Custom event. If you use multiple custom
events, the ad source name isn't granular enough to distinguish between multiple
custom events. To locate a specific custom event, do the following steps:
Set the handler immediately once you create or get access to the ad object,
and definitely before showing the ad. This makes sure that you don't miss
any paid event callbacks.
Send the paid event information to your preferred analytics server
immediately at the time the paidEventHandler method is called. This
makes sure that you don't accidentally drop any callbacks and avoids data
discrepancies.
GADAdValue
GADAdValue is a class that represents the monetary value earned for an ad,
including the value's currency code and its precision type encoded as following.
GADAdValuePrecision
Description
GADAdValuePrecisionUnknown
An ad value that's unknown. This gets returned when LTV pingback is
enabled but there isn't enough data available.
GADAdValuePrecisionEstimated
An ad value estimated from aggregated data.
GADAdValuePrecisionPublisherProvided
A publisher provided ad value, such as manual CPMs in a mediation group.
GADAdValuePrecisionPrecise
The precise value paid for this ad.
Test impressions from Open Bidding
After an impression-level ad revenue event occurs for
an Open Bidding
ad source through a test request, you receive only the following
values:
GADAdValuePrecisionUnknown: indicates the precision type.
0: indicates the ad value.
Previously, you might have seen the precision type as a value other than
GADAdValuePrecisionUnknown and an ad value more than 0.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[],[],null,["When an impression occurs, Google Mobile Ads SDK calls the paid event\nhandler with its associated revenue data. By implementing this handler, you can\nuse the data to calculate a user's lifetime value, or forward the data\ndownstream to other relevant systems.\n\nThis guide is intended to help you implement LTV data capture in your iOS app.\n\nPrerequisites\n\n- Make sure you have [turned on the impression-level ad revenue\n feature](//support.google.com/admanager/answer/13404416) in the Ad Manager UI.\n\n\u003c!-- --\u003e\n\n- Import Google Mobile Ads SDK 9.10.0 or higher.\n- Complete the [Get started guide](/ad-manager/mobile-ads-sdk/ios/quick-start).\n- Before you can receive any impression-level ad revenue, you need to implement\n at least one ad format:\n\n - [Banner](/ad-manager/mobile-ads-sdk/ios/banner)\n - [Interstitial](/ad-manager/mobile-ads-sdk/ios/interstitial)\n - [Rewarded](/ad-manager/mobile-ads-sdk/ios/rewarded)\n - [Rewarded Interstitial](/ad-manager/mobile-ads-sdk/ios/rewarded-interstitial)\n - [Native](/ad-manager/mobile-ads-sdk/ios/native)\n\nImplement a paid event handler\n\nEach ad format has a `paidEventHandler` property of type\n[`GADPaidEventHandler`](/ad-manager/mobile-ads-sdk/ios/api/reference/Type-Definitions#gadpaideventhandler).\nDuring the lifecycle of an ad event, Google Mobile Ads SDK monitors\nimpression events and invokes the handler with an earned value. \n\nSwift \n\n class ViewController: UIViewController, FullScreenContentDelegate {\n var rewardedAd: RewardedAd?\n func requestRewardedAd() {\n RewardedAd.load(\n with: \"\u003cvar class=\"readonly\" translate=\"no\"\u003eAD_UNIT_ID\u003c/var\u003e\", request: AdManagerRequest()\n ) { (ad, error) in\n if let error = error {\n print(\"Rewarded ad failed to load with error: \\(error.localizedDescription)\")\n return\n }\n if let ad = ad {\n self.rewardedAd = ad\n self.rewardedAd?.paidEventHandler = { adValue in\n // TODO: Send the impression-level ad revenue information to your preferred analytics\n // server directly within this callback.\n // Extract the impression-level ad revenue data.\n let value = adValue.value\n let precision = adValue.precision\n let currencyCode = adValue.currencyCode\n // Get the ad unit ID.\n let adUnitId = ad.adUnitID\n let responseInfo = ad.responseInfo\n let loadedAdNetworkResponseInfo = responseInfo?.loadedAdNetworkResponseInfo\n let adSourceId = loadedAdNetworkResponseInfo?.adSourceID\n let adSourceInstanceId = loadedAdNetworkResponseInfo?.adSourceInstanceID\n let adSourceInstanceName = loadedAdNetworkResponseInfo?.adSourceInstanceName\n let adSourceName = loadedAdNetworkResponseInfo?.adSourceName\n }\n }\n }\n }\n }\n\nObjective-C \n\n @import GoogleMobileAds;\n @import UIKit;\n\n @interface ViewController ()\n @property(nonatomic, strong) GADRewardedAd *rewardedAd;\n @end\n\n @implementation ViewController\n - (void)requestRewardedAd {\n __weak ViewController *weakSelf = self;\n\n GAMRequest *request = [GAMRequest request];\n [GADRewardedAd\n loadWithAdUnitID:@\"\u003cvar class=\"readonly\" translate=\"no\"\u003eAD_UNIT_ID\u003c/var\u003e\"\n request:request\n completionHandler:^(GADRewardedAd *ad, NSError *error) {\n if (error) {\n NSLog(@\"Rewarded ad failed to load with error: %@\", [error localizedDescription]);\n return;\n }\n self.rewardedAd = ad;\n self.rewardedAd.paidEventHandler = \\^void(GADAdValue \\*_Nonnull value){\n ViewController \\*strongSelf = weakSelf;\n // TODO: Send the impression-level ad revenue information to your preferred analytics\n // server directly within this callback.\n // Extract the impression-level ad revenue data.\n NSDecimalNumber \\*value; = value.value;\n NSString \\*currencyCode = value.currencyCode;\n GADAdValuePrecision precision = value.precision;\n // Get the ad unit ID.\n NSString \\*adUnitId = strongSelf.rewardedAd.adUnitID;\n GADAdNetworkResponseInfo \\*loadedAdNetworkResponseInfo =\n strongSelf.rewardedAd.responseInfo.loadedAdNetworkResponseInfo;\n NSString \\*adSourceName = loadedAdNetworkResponseInfo.adSourceName;\n NSString \\*adSourceID = loadedAdNetworkResponseInfo.adSourceID;\n NSString \\*adSourceInstanceName = loadedAdNetworkResponseInfo.adSourceInstanceName;\n NSString \\*adSourceInstanceID = loadedAdNetworkResponseInfo.adSourceInstanceID;\n };\n \\]};\n }\n\nIdentify a custom event ad source name\n\nFor custom event ad sources, [`adSourceName`](/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GADAdNetworkResponseInfo#adsourcename)\nproperty gives you the ad source name `Custom event`. If you use multiple custom\nevents, the ad source name isn't granular enough to distinguish between multiple\ncustom events. To locate a specific custom event, do the following steps:\n\n1. Get the [`adNetworkClassName`](/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GADAdNetworkResponseInfo#adnetworkclassname) property.\n2. Set a unique ad source name.\n\nThe following example sets a unique ad source name for a custom event: \n\nSwift \n\n func uniqueAdSourceName(for loadedAdNetworkResponseInfo: AdNetworkResponseInfo) -\u003e String {\n var adSourceName: String = loadedAdNetworkResponseInfo.adSourceName ?? \"\"\n if adSourceName == \"Custom Event\" {\n if loadedAdNetworkResponseInfo.adNetworkClassName\n == \"MediationExample.SampleCustomEventSwift\"\n {\n adSourceName = \"Sample Ad Network (Custom Event)\"\n }\n }\n return adSourceName\n } \n https://github.com/googleads/googleads-mobile-ios-examples/blob/bce0771eb0fad1bb4179e3e95fcc53e32a9f9a83/Swift/advanced/APIDemo/APIDemo/Snippets/ResponseInfoSnippets.swift#L22-L32\n\nObjective-C \n\n - (NSString *)uniqueAdSourceNameForAdNetworkResponseInfo:\n (GADAdNetworkResponseInfo *)loadedAdNetworkResponseInfo {\n NSString *adSourceName = loadedAdNetworkResponseInfo.adSourceName;\n if ([adSourceName isEqualToString:@\"Custom Event\"]) {\n if ([loadedAdNetworkResponseInfo.adNetworkClassName isEqualToString:@\"SampleCustomEvent\"]) {\n adSourceName = @\"Sample Ad Network (Custom Event)\";\n }\n }\n return adSourceName;\n } \n https://github.com/googleads/googleads-mobile-ios-examples/blob/bce0771eb0fad1bb4179e3e95fcc53e32a9f9a83/Objective-C/advanced/APIDemo/APIDemo/Snippets/ResponseInfoSnippets.m#L27-L36\n\nFor more information on the winning ad source, see [Retrieve information about\nthe ad response](/ad-manager/mobile-ads-sdk/ios/response-info).\n\nImplementation best practices\n\n- Set the handler immediately once you create or get access to the ad object, and definitely before showing the ad. This makes sure that you don't miss any paid event callbacks.\n- Send the paid event information to your preferred analytics server immediately at the time the `paidEventHandler` method is called. This makes sure that you don't accidentally drop any callbacks and avoids data discrepancies.\n\nGADAdValue\n\n`GADAdValue` is a class that represents the monetary value earned for an ad,\nincluding the value's currency code and its precision type encoded as following.\n| **Key Point:** The value of [`GADAdValue.value`](/ad-manager/mobile-ads-sdk/ios/api/reference/Classes/GADAdValue#value) is a decimal number that represents each ad's worth. For example, a value of 0.005 means this ad is estimated to be worth $0.005.\n\n| GADAdValuePrecision | Description |\n|----------------------------------------|--------------------------------------------------------------------------------------------------------------------|\n| `GADAdValuePrecisionUnknown` | An ad value that's unknown. This gets returned when LTV pingback is enabled but there isn't enough data available. |\n| `GADAdValuePrecisionEstimated` | An ad value estimated from aggregated data. |\n| `GADAdValuePrecisionPublisherProvided` | A publisher provided ad value, such as manual CPMs in a mediation group. |\n| `GADAdValuePrecisionPrecise` | The precise value paid for this ad. |\n\n| **Key Point:** In the case of mediation, Ad Manager tries to provide a `GADAdValuePrecisionEstimated` first and falls back to `GADAdValuePrecisionPublisherProvided` if there isn't enough aggregated data to report a meaningful value.\n\nTest impressions from Open Bidding\n\nAfter an impression-level ad revenue event occurs for\nan Open Bidding\nad source through a test request, you receive only the following\nvalues:\n\n- `GADAdValuePrecisionUnknown`: indicates the precision type.\n\n\u003c!-- --\u003e\n\n- `0`: indicates the ad value.\n\nPreviously, you might have seen the precision type as a value other than\n\n`GADAdValuePrecisionUnknown` and an ad value more than `0`.\n\nFor details on sending a test ad request, see\n[Enable test devices](/ad-manager/mobile-ads-sdk/ios/test-ads#enable-test-devices)."]]