AdMob SDK integration
Track AdMob events on iOS, legacy Android, and Google Mobile Ads Next-Gen with RevenueCat
The RevenueCat AdMob integration wraps standard AdMob loading calls with automatic event tracking. Use it with the Google Mobile Ads SDK on iOS, the legacy SDK on Android, or the Google Mobile Ads Next-Gen SDK on Android.
This feature is currently in beta.
Before integrating, install the AdMob Adapter SDK that matches your platform and Google Mobile Ads SDK generation. The legacy adapters require purchases-ios 5.89.0+ (iOS 15+) or purchases-android 10.19.0+; see the installation guide for the Next-Gen requirements.
The loadAndTrack methods automatically track the following events, captured from AdMob's callbacks with no additional code required:
- Ad Loaded — Ad successfully loads
- Ad Displayed — Ad impression is recorded
- Ad Opened — Customer clicks the ad
- Ad Revenue — Ad generates revenue (via AdMob's paid event handler)
- Ad Failed to Load — Ad fails to load
The adapter can't track Rewarded Ad Prompt Shown and Rewarded Ad Prompt Accepted, because only your app knows when it offers a rewarded ad. Call trackRewardedAdPromptShown and trackRewardedAdPromptAccepted yourself when you show and when the user accepts the prompt (requires purchases-ios 5.92.0+ or purchases-android 10.24.0+). See Track rewarded ad prompts.
Choose an adapter
Choose one adapter for your platform and Google Mobile Ads SDK generation:
| Platform | Google Mobile Ads SDK | Code tab |
|---|---|---|
| iOS | Google Mobile Ads SDK | Swift |
| Android | Legacy Google Mobile Ads SDK (play-services-ads) | Kotlin (Legacy AdMob) |
| Android | Google Mobile Ads Next-Gen SDK (ads-mobile-sdk) | Kotlin (Next-Gen AdMob) |
The two Android adapters are mutually exclusive. The Next-Gen adapter is Kotlin-only; Java apps can use the base AdTracker APIs directly.
Quick start
1. Import the module
- Swift
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
import RevenueCatAdMob
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.admob.* // AdMob helper extensions
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.admob.nextgen.* // AdMob Next-Gen helper extensions
2. Replace load calls with loadAndTrack
Replace standard AdMob load calls with loadAndTrack methods. On iOS, every loadAndTrack method offers both an async/await and a completion-handler variant — pick whichever matches your code style:
- Swift (async/await)
- Swift (completion handler)
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
// Before
let ad = try await InterstitialAd.load(with: adUnitID, request: Request())
ad.fullScreenContentDelegate = self
self.interstitialAd = ad
// After
self.interstitialAd = try await InterstitialAd.loadAndTrack(
withAdUnitID: adUnitID,
request: Request(),
placement: "level_complete",
fullScreenContentDelegate: self
)
// Before
InterstitialAd.load(with: adUnitID, request: Request()) { ad, error in
ad?.fullScreenContentDelegate = self
self.interstitialAd = ad
}
// After
InterstitialAd.loadAndTrack(
withAdUnitID: adUnitID,
request: Request(),
placement: "level_complete",
fullScreenContentDelegate: self
) { ad, error in
self.interstitialAd = ad
}
// Before
InterstitialAd.load(context, adUnitId, adRequest, callback)
// After
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
context = context,
adUnitId = adUnitId,
adRequest = adRequest,
placement = "level_complete",
loadCallback = callback
)
val adRequest = AdRequest.Builder(adUnitId).build()
// Before
InterstitialAd.load(adRequest, callback)
// After
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
adRequest = adRequest,
placement = "level_complete",
loadCallback = callback,
)
Implementation examples
Banner ads
- Swift
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
import RevenueCatAdMob
let bannerView = BannerView(adSize: AdSize(size: CGSize(width: 320, height: 50), flags: 0))
bannerView.adUnitID = "ca-app-pub-3940256099942544/2435281174"
bannerView.loadAndTrack(
request: Request(),
placement: "home_banner"
)
@Composable
fun BannerAdView() {
AndroidView(
factory = { context ->
AdView(context).apply {
adUnitId = "ca-app-pub-3940256099942544/9214589741"
setAdSize(AdSize.BANNER)
// Load with tracking
Purchases.sharedInstance.adTracker.loadAndTrackBannerAd(
adView = this,
adRequest = AdRequest.Builder().build(),
placement = "home_banner"
)
}
}
)
}
@Composable
fun BannerAdView() {
AndroidView(
factory = { context ->
AdView(context).apply {
val adRequest = BannerAdRequest.Builder(
"ca-app-pub-3940256099942544/9214589741",
AdSize.BANNER,
).build()
loadAndTrackAd(
adRequest = adRequest,
placement = "home_banner",
)
}
},
)
}
Interstitial ads
- Swift (async/await)
- Swift (completion handler)
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
import RevenueCatAdMob
class MyViewController: UIViewController, FullScreenContentDelegate {
private var interstitialAd: InterstitialAd?
func loadInterstitial() async {
do {
self.interstitialAd = try await InterstitialAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/4411468910",
request: Request(),
placement: "level_complete",
fullScreenContentDelegate: self
)
} catch {
// Handle error
}
}
func showInterstitial() {
interstitialAd?.present(from: self)
}
}
import RevenueCatAdMob
class MyViewController: UIViewController, FullScreenContentDelegate {
private var interstitialAd: InterstitialAd?
func loadInterstitial() {
InterstitialAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/4411468910",
request: Request(),
placement: "level_complete",
fullScreenContentDelegate: self
) { [weak self] ad, error in
if let error { return }
self?.interstitialAd = ad
}
}
func showInterstitial() {
interstitialAd?.present(from: self)
}
}
class MyActivity : AppCompatActivity() {
private var interstitialAd: InterstitialAd? = null
fun loadInterstitial() {
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
context = this,
adUnitId = "ca-app-pub-3940256099942544/1033173712",
adRequest = AdRequest.Builder().build(),
placement = "level_complete",
loadCallback = object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) {
interstitialAd = ad
}
override fun onAdFailedToLoad(error: LoadAdError) {
interstitialAd = null
}
}
)
}
fun showInterstitial() {
interstitialAd?.show(this)
}
}
class MyActivity : AppCompatActivity() {
private var interstitialAd: InterstitialAd? = null
fun loadInterstitial() {
val adRequest = AdRequest.Builder(
"ca-app-pub-3940256099942544/1033173712",
).build()
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
adRequest = adRequest,
placement = "level_complete",
loadCallback = object : AdLoadCallback<InterstitialAd> {
override fun onAdLoaded(ad: InterstitialAd) {
interstitialAd = ad
}
override fun onAdFailedToLoad(error: LoadAdError) {
interstitialAd = null
}
},
)
}
fun showInterstitial() {
interstitialAd?.show(this)
}
}
Rewarded ads
- Swift (async/await)
- Swift (completion handler)
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
import RevenueCatAdMob
func loadRewardedAd() async {
do {
self.rewardedAd = try await RewardedAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/1712485313",
request: Request(),
placement: "bonus_coins",
fullScreenContentDelegate: self
)
} catch {
// Handle error
}
}
func showRewardedAd() {
rewardedAd?.present(from: self) {
// User earned reward
}
}
import RevenueCatAdMob
func loadRewardedAd() {
RewardedAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/1712485313",
request: Request(),
placement: "bonus_coins",
fullScreenContentDelegate: self
) { [weak self] ad, error in
if let error { return }
self?.rewardedAd = ad
}
}
func showRewardedAd() {
rewardedAd?.present(from: self) {
// User earned reward
}
}
fun loadRewardedAd(context: Context) {
Purchases.sharedInstance.adTracker.loadAndTrackRewardedAd(
context = context,
adUnitId = "ca-app-pub-3940256099942544/5224354917",
adRequest = AdRequest.Builder().build(),
placement = "bonus_coins",
loadCallback = object : RewardedAdLoadCallback() {
override fun onAdLoaded(ad: RewardedAd) {
// Ad loaded successfully
ad.show(activity) { reward ->
// User earned reward
grantCoins(reward.amount)
}
}
override fun onAdFailedToLoad(error: LoadAdError) {
// Handle error
}
}
)
}
fun loadRewardedAd() {
val adRequest = AdRequest.Builder(
"ca-app-pub-3940256099942544/5224354917",
).build()
Purchases.sharedInstance.adTracker.loadAndTrackRewardedAd(
adRequest = adRequest,
placement = "bonus_coins",
loadCallback = object : AdLoadCallback<RewardedAd> {
override fun onAdLoaded(ad: RewardedAd) {
ad.show(activity) { reward ->
grantCoins(reward.amount)
}
}
override fun onAdFailedToLoad(error: LoadAdError) {
// Handle the error.
}
},
)
}
Rewarded interstitial ads
- Swift (async/await)
- Swift (completion handler)
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
import RevenueCatAdMob
func loadRewardedInterstitialAd() async {
do {
self.rewardedInterstitialAd = try await RewardedInterstitialAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/6978759866",
request: Request(),
placement: "between_levels",
fullScreenContentDelegate: self
)
} catch {
// Handle error
}
}
func showRewardedInterstitialAd() {
rewardedInterstitialAd?.present(from: self) {
// User earned reward
}
}
import RevenueCatAdMob
func loadRewardedInterstitialAd() {
RewardedInterstitialAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/6978759866",
request: Request(),
placement: "between_levels",
fullScreenContentDelegate: self
) { [weak self] ad, error in
if let error { return }
self?.rewardedInterstitialAd = ad
}
}
func showRewardedInterstitialAd() {
rewardedInterstitialAd?.present(from: self) {
// User earned reward
}
}
fun loadRewardedInterstitialAd(context: Context) {
Purchases.sharedInstance.adTracker.loadAndTrackRewardedInterstitialAd(
context = context,
adUnitId = "ca-app-pub-3940256099942544/5354046379",
adRequest = AdRequest.Builder().build(),
placement = "between_levels",
loadCallback = object : RewardedInterstitialAdLoadCallback() {
override fun onAdLoaded(ad: RewardedInterstitialAd) {
ad.show(activity) { reward ->
// User earned reward
}
}
override fun onAdFailedToLoad(error: LoadAdError) {
// Handle error
}
}
)
}
fun loadRewardedInterstitialAd() {
val adRequest = AdRequest.Builder(
"ca-app-pub-3940256099942544/5354046379",
).build()
Purchases.sharedInstance.adTracker.loadAndTrackRewardedInterstitialAd(
adRequest = adRequest,
placement = "between_levels",
loadCallback = object : AdLoadCallback<RewardedInterstitialAd> {
override fun onAdLoaded(ad: RewardedInterstitialAd) {
ad.show(activity) { reward ->
grantCoins(reward.amount)
}
}
override fun onAdFailedToLoad(error: LoadAdError) {
// Handle the error.
}
},
)
}
App open ads
- Swift (async/await)
- Swift (completion handler)
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
import RevenueCatAdMob
func loadAppOpenAd() async {
do {
self.appOpenAd = try await AppOpenAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/5575463023",
request: Request(),
placement: "app_launch",
fullScreenContentDelegate: self
)
} catch {
// Handle error
}
}
import RevenueCatAdMob
func loadAppOpenAd() {
AppOpenAd.loadAndTrack(
withAdUnitID: "ca-app-pub-3940256099942544/5575463023",
request: Request(),
placement: "app_launch",
fullScreenContentDelegate: self
) { [weak self] ad, error in
if let error { return }
self?.appOpenAd = ad
}
}
fun loadAppOpenAd(context: Context) {
Purchases.sharedInstance.adTracker.loadAndTrackAppOpenAd(
context = context,
adUnitId = "ca-app-pub-3940256099942544/9257395921",
adRequest = AdRequest.Builder().build(),
placement = "app_launch",
loadCallback = object : AppOpenAd.AppOpenAdLoadCallback() {
override fun onAdLoaded(ad: AppOpenAd) {
// Ad loaded successfully
}
override fun onAdFailedToLoad(error: LoadAdError) {
// Handle error
}
}
)
}
fun loadAppOpenAd() {
val adRequest = AdRequest.Builder(
"ca-app-pub-3940256099942544/9257395921",
).build()
Purchases.sharedInstance.adTracker.loadAndTrackAppOpenAd(
adRequest = adRequest,
placement = "app_launch",
loadCallback = object : AdLoadCallback<AppOpenAd> {
override fun onAdLoaded(ad: AppOpenAd) {
appOpenAd = ad
}
override fun onAdFailedToLoad(error: LoadAdError) {
appOpenAd = null
}
},
)
}
Native ads
- Swift
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
import RevenueCatAdMob
let adLoader = AdLoader(
adUnitID: "ca-app-pub-3940256099942544/3986624511",
rootViewController: self,
adTypes: [.native],
options: nil
)
adLoader.delegate = self
adLoader.loadAndTrack(
Request(),
placement: "feed",
nativeAdDelegate: self
)
val adLoader = AdLoader.Builder(context, "ca-app-pub-3940256099942544/2247696110")
// Use forNativeAdWithTracking in place of the standard forNativeAd
.forNativeAdWithTracking(
adUnitId = "ca-app-pub-3940256099942544/2247696110",
placement = "feed",
) { nativeAd ->
// Use the loaded native ad
}
.build()
// Load as usual with the standard AdLoader.loadAd() call
adLoader.loadAd(AdRequest.Builder().build())
val adRequest = NativeAdRequest.Builder(
"ca-app-pub-3940256099942544/2247696110",
listOf(NativeAd.NativeAdType.NATIVE),
).build()
Purchases.sharedInstance.adTracker.loadAndTrackNativeAd(
adRequest = adRequest,
placement = "feed",
loadCallback = object : NativeAdLoaderCallback {
override fun onNativeAdLoaded(nativeAd: NativeAd) {
loadedNativeAd = nativeAd
}
override fun onAdFailedToLoad(error: LoadAdError) {
loadedNativeAd = null
}
},
)
Placement parameter
The placement parameter identifies where ads appear in your app and is used for reporting and segmentation in Ad Charts.
Use consistent, descriptive names like "home_banner" or "level_complete_interstitial". Avoid dynamic values or timestamps.
Show-time placement override
For full-screen ads, you can set the placement when showing the ad instead of at load time. This is useful when you preload an ad before knowing where it will be shown:
- Swift
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
// Load once, without a specific placement
InterstitialAd.loadAndTrack(
withAdUnitID: adUnitID,
request: Request(),
fullScreenContentDelegate: self
) { [weak self] ad, error in
self?.cachedAd = ad
}
// Show with placement depending on where the user is
cachedAd?.present(from: self, placement: "level_complete")
// Load once, without a specific placement
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
context = context,
adUnitId = adUnitId,
adRequest = AdRequest.Builder().build(),
loadCallback = object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) {
cachedAd = ad
}
}
)
// Show with placement depending on where the user is
cachedAd?.show(activity, "level_complete")
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
adRequest = AdRequest.Builder(adUnitId).build(),
loadCallback = object : AdLoadCallback<InterstitialAd> {
override fun onAdLoaded(ad: InterstitialAd) {
cachedAd = ad
}
},
)
// Later, override the placement based on where the ad is shown.
cachedAd?.show(activity, placement = "level_complete")
The show-time placement applies to Ad Displayed, Ad Opened, and Ad Revenue events. Ad Loaded and Ad Failed to Load always use the load-time placement.
Optional parameters and callbacks
Beyond placement, the loadAndTrack methods accept the load and lifecycle callbacks provided by each Google Mobile Ads SDK:
- Swift
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
InterstitialAd.loadAndTrack(
withAdUnitID: adUnitID,
request: Request(),
placement: "level_complete", // Optional: for reporting
fullScreenContentDelegate: self, // Optional: ad lifecycle callbacks
paidEventHandler: { adValue in
// Optional: your custom paid event handling
}
) { ad, error in
// Optional: your load completion handler
}
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
context = context,
adUnitId = adUnitId,
adRequest = adRequest,
placement = "level_complete", // Optional: for reporting
loadCallback = callback, // Optional: your load callback
fullScreenContentCallback = contentCallback, // Optional: for ad lifecycle
onPaidEventListener = paidListener // Optional: your paid event listener
)
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
adRequest = adRequest,
placement = "level_complete", // Optional: for reporting
loadCallback = loadCallback,
adEventCallback = eventCallback, // Optional: your lifecycle callback
)
RevenueCat wraps your lifecycle callback at load time and forwards events to your handler after tracking them. If you change the callback after loading, use the tracking-aware setter instead of assigning it directly:
- Swift
- Kotlin (Legacy AdMob)
- Kotlin (Next-Gen AdMob)
// Pass the full-screen content delegate when loading the ad.
InterstitialAd.loadAndTrack(
withAdUnitID: adUnitID,
request: Request(),
placement: "level_complete",
fullScreenContentDelegate: self
) { ad, error in }
// Or replace it later with the tracking-safe setter.
ad?.setTrackingFullScreenContentDelegate(myDelegate)
// Don't assign it directly. This replaces RevenueCat's tracking wrapper.
ad?.fullScreenContentDelegate = myDelegate
import com.revenuecat.purchases.admob.setTrackingFullScreenContentCallback
// Pass the full-screen content callback when loading the ad.
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
context = context,
adUnitId = adUnitId,
adRequest = adRequest,
placement = "level_complete",
fullScreenContentCallback = myCallback
)
// Or replace it later with the tracking-safe setter.
ad.setTrackingFullScreenContentCallback(myCallback)
// Don't assign it directly. This replaces RevenueCat's tracking wrapper.
ad.fullScreenContentCallback = myCallback
import com.revenuecat.purchases.admob.nextgen.setTrackingAdEventCallback
// Pass the event callback when loading the ad.
Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
adRequest = adRequest,
placement = "level_complete",
loadCallback = loadCallback,
adEventCallback = myCallback,
)
// Or replace it later with the tracking-safe setter.
ad.setTrackingAdEventCallback(myCallback)
// Don't assign it directly. This replaces RevenueCat's tracking wrapper.
ad.adEventCallback = myCallback
Use setTrackingFullScreenContentDelegate on iOS or setTrackingFullScreenContentCallback with the legacy Android adapter. The Android Next-Gen adapter uses setTrackingAdEventCallback for every supported ad type and setTrackingBannerAdRefreshCallback for banner refresh events.
The delegate/callback parameter on loadAndTrack methods is optional and defaults to none, so you can omit it at load time and set it later with the tracking-aware setter.
Android Next-Gen features
The Android Next-Gen adapter supports additional Google Mobile Ads Next-Gen loading workflows. These APIs are only available in the Kotlin (Next-Gen AdMob) integration.
Suspending loads
Interstitial, rewarded, rewarded interstitial, app open, and native helpers have suspending overloads. They return Google's original result with RevenueCat tracking installed on successful ads:
- Kotlin (Next-Gen AdMob)
lifecycleScope.launch {
when (
val result = Purchases.sharedInstance.adTracker.loadAndTrackInterstitialAd(
adRequest = AdRequest.Builder("AD_UNIT_ID").build(),
placement = "game_interstitial",
)
) {
is AdLoadResult.Success -> interstitialAd = result.ad
is AdLoadResult.Failure -> interstitialAd = null
}
}
Direct banner loading remains callback-based because Google doesn't provide a supported suspending AdView.loadAd API.
Preloading
All six supported formats work with Google's preloaders. Track preload success or failure with startAndTrack, then install lifecycle tracking on a buffered ad with pollAndTrackAd:
- Kotlin (Next-Gen AdMob)
val preloadConfiguration = PreloadConfiguration(
request = AdRequest.Builder("AD_UNIT_ID").build(),
bufferSize = 2,
)
InterstitialAdPreloader.startAndTrack(
preloadId = "game-interstitial-buffer",
preloadConfiguration = preloadConfiguration,
placement = "game_interstitial_preload",
preloadCallback = object : PreloadCallback {},
)
// Later, adopt a buffered ad. Polling doesn't emit another loaded event.
interstitialAd = InterstitialAdPreloader.pollAndTrackAd(
preloadId = "game-interstitial-buffer",
placement = "game_interstitial",
adEventCallback = interstitialAdEventCallback,
)
interstitialAd?.show(this)
The placements supplied to startAndTrack and pollAndTrackAd are independent. Polling doesn't emit another loaded event. Use the corresponding preloader extensions for banner, app open, native, rewarded, and rewarded interstitial ads.
Other loading workflows
The Next-Gen adapter also supports server-to-server ad responses for every format and single or batched native-ad loading. See the Android Next-Gen advanced loading guide for complete examples.
Migrate from the legacy Android adapter
The Next-Gen adapter isn't a drop-in binary replacement for the legacy adapter. Migrate the Google Mobile Ads SDK and RevenueCat adapter together:
- Replace the legacy dependencies with
purchases-admob-next-genandads-mobile-sdk. - Change RevenueCat imports from
com.revenuecat.purchases.admobtocom.revenuecat.purchases.admob.nextgen. - Update Google imports from
com.google.android.gms.adstocom.google.android.libraries.ads.mobile.sdk. - Update requests and callbacks to the Next-Gen types shown in this guide.
- Keep existing placement values when they identify the same ad slots so reporting remains consistent.
Next-Gen requests own the ad unit ID. BannerAdRequest also owns the banner size that the legacy SDK stored on AdView. Next-Gen callbacks may run on a background thread, so dispatch to the main thread before updating UI-confined state.
Review Google's Next-Gen migration guide for SDK and mediation changes.
Troubleshooting
Testing your integration
Before troubleshooting, verify your events are being tracked:
- Run your app in debug mode
- Navigate to the Ads page in your RevenueCat dashboard
- Toggle on "Sandbox data"
- Trigger some ads in your app
- Check that events appear in the sandbox events table
Events from debug builds are automatically marked as sandbox. This lets you verify your integration without affecting production data.
Note on event timing: Ad events are not synced to the dashboard in real-time. The SDK batches and sends events periodically. If you've triggered several ads and don't see events immediately, try putting your app in the background and bringing it back to the foreground to trigger a sync. This is normal behavior and doesn't indicate an integration issue.
Events not appearing in charts
- Verify that "Impression-level ad revenue" is enabled in your AdMob account (instructions)
- Verify you've opted in via the Ads page in your RevenueCat dashboard
- Check that you're using
loadAndTrackmethods (not standard AdMob methods) - Ensure
placementparameter is provided - Verify ads are actually loading and showing (check AdMob callbacks)
- Use the sandbox data view (above) to confirm events are being received
Next steps
- Explore the example projects: iOS, legacy Android, and Android Next-Gen
- Grant ad rewards when users complete rewarded ads, verified server-side
- View your ad data in Ad Charts, and see the Ad Monetization overview for where it appears across the dashboard
- Connect your Google AdMob account to sync ad unit names for more readable charts — no code changes required
- Learn about Manual Integration for other mediation platforms