Skip to main content

Manual Integration

Track ad events from any mediation platform that provides ILRD

AIAsk AIChatGPTClaude

Track ad events from any mediation platform that provides impression-level revenue data (ILRD) by calling AdTracker methods from your SDK callbacks. Ad impressions, clicks, and revenue appear alongside your subscription data in RevenueCat Charts.

⚠️Beta Feature - Opt-in Required

This feature is currently in beta. To enable it, visit the Ads page in your RevenueCat dashboard to opt in.

Overview

Manual integration gives you full control over ad event tracking and works with any mediation platform that supports ILRD, including:

  • AppLovin MAX
  • ironSource
  • Unity Ads
  • Any custom mediation setup

Hook into your mediation platform's callbacks and call the appropriate AdTracker methods.

How it works

  1. Your mediation platform fires a callback (e.g., ad loaded, ad displayed, revenue generated)
  2. You call the corresponding AdTracker method with the event data
  3. RevenueCat records the event and makes it available in Charts

Prerequisites

  • SDK Version:
    • Android: purchases-android 8.0.0+
    • iOS: purchases-ios 5.0.0+
    • Flutter: purchases_flutter 10.2.0+
    • Unity: purchases-unity 9.1.0+
    • React Native: react-native-purchases 10.2.0+
  • iOS Availability: Ad tracking requires iOS 15.0+ / tvOS 15.0+ / macOS 12.0+ / watchOS 8.0+. On older OS versions, calls are silently ignored and a warning is logged.
  • ILRD Support: Your mediation platform must provide impression-level revenue data. If using Google AdMob, you must enable "Impression-level ad revenue" in your AdMob dashboard under Settings.
  • Experimental API: Ad monetization APIs are marked as experimental

Android integration

1. Access the AdTracker

import com.revenuecat.purchases.ExperimentalPreviewRevenueCatPurchasesAPI
import com.revenuecat.purchases.Purchases

@OptIn(ExperimentalPreviewRevenueCatPurchasesAPI::class)
val adTracker = Purchases.sharedInstance.adTracker

2. Import event types

import com.revenuecat.purchases.ads.events.types.*

3. Track events from mediation callbacks

All track methods follow a similar pattern. Here are the two main examples:

Track ad loaded

Call when an ad successfully loads:

@OptIn(ExperimentalPreviewRevenueCatPurchasesAPI::class)
fun onAdLoaded(ad: YourAdType) {
adTracker.trackAdLoaded(
AdLoadedData(
networkName = ad.networkName, // e.g., "Google Ads"
mediatorName = AdMediatorName.APP_LOVIN, // or custom: AdMediatorName.fromString("YourMediator")
adFormat = AdFormat.REWARDED, // BANNER, INTERSTITIAL, etc.
placement = "home_screen", // Your custom placement ID
adUnitId = ad.adUnitId, // Ad unit identifier
impressionId = ad.impressionId // Unique impression ID
)
)
}

Track ad revenue

Call when your mediation platform reports revenue for an impression:

@OptIn(ExperimentalPreviewRevenueCatPurchasesAPI::class)
fun onAdRevenue(ad: YourAdType, revenue: Double, currency: String) {
adTracker.trackAdRevenue(
AdRevenueData(
networkName = ad.networkName,
mediatorName = AdMediatorName.APP_LOVIN,
adFormat = AdFormat.REWARDED,
placement = "home_screen",
adUnitId = ad.adUnitId,
impressionId = ad.impressionId,
revenueMicros = (revenue * 1_000_000).toLong(), // Convert to micros
currency = currency, // e.g., "USD"
precision = AdRevenuePrecision.EXACT // Or ESTIMATED, PUBLISHER_DEFINED
)
)
}

Other track methods

The remaining methods follow the same pattern as trackAdLoaded:

  • trackAdDisplayed(AdDisplayedData) - Call when ad impression is recorded (ad shown on screen)
  • trackAdOpened(AdOpenedData) - Call when user clicks/taps the ad
  • trackAdFailedToLoad(AdFailedToLoadData) - Call when ad fails to load (doesn't require networkName or impressionId)

See the Event data reference section below for complete parameter details.

iOS integration

1. Access the AdTracker

@_spi(Experimental) import RevenueCat

let adTracker = Purchases.shared.adTracker
📘iOS availability

Ad tracking requires iOS 15.0+, tvOS 15.0+, macOS 12.0+, and watchOS 8.0+. On older OS versions, calls are silently ignored and a warning is logged.

2. Track events from mediation callbacks

All track methods follow a similar pattern. Here are the two main examples:

Track ad loaded

Call when an ad successfully loads:

@_spi(Experimental)
func onAdLoaded(ad: YourAdType) {
Purchases.shared.adTracker.trackAdLoaded(.init(
networkName: ad.networkName, // e.g., "Google Ads"
mediatorName: .appLovin, // or custom: .init(value: "YourMediator")
adFormat: .rewarded, // .banner, .interstitial, etc.
placement: "home_screen", // Your custom placement ID
adUnitId: ad.adUnitId, // Ad unit identifier
impressionId: ad.impressionId // Unique impression ID
))
}

Track ad revenue

Call when your mediation platform reports revenue for an impression:

@_spi(Experimental)
func onAdRevenue(ad: YourAdType, revenue: Double, currency: String) {
Purchases.shared.adTracker.trackAdRevenue(.init(
networkName: ad.networkName,
mediatorName: .appLovin,
adFormat: .rewarded,
placement: "home_screen",
adUnitId: ad.adUnitId,
impressionId: ad.impressionId,
revenueMicros: Int64(revenue * 1_000_000), // Convert to micros
currency: currency, // e.g., "USD"
precision: .exact // Or .estimated, .publisherDefined
))
}

Other track methods

The remaining methods follow the same pattern as trackAdLoaded:

  • trackAdDisplayed(_:) - Call when ad impression is recorded (ad shown on screen)
  • trackAdOpened(_:) - Call when user clicks/taps the ad
  • trackAdFailedToLoad(_:) - Call when ad fails to load (doesn't require networkName or impressionId)

See the Event data reference section below for complete parameter details.

Flutter integration

1. Add the dependency

# pubspec.yaml
dependencies:
purchases_flutter: ^10.2.0

2. Access the AdTracker

import 'package:purchases_flutter/purchases_flutter.dart';

// ignore: experimental_member_use
final adTracker = Purchases.adTracker;
📘iOS availability

Ad tracking requires iOS 15.0+, tvOS 15.0+, macOS 12.0+, and watchOS 8.0+. On older OS versions, calls are silently ignored and a warning is logged. Android has no version restriction.

3. Track events from mediation callbacks

All track methods follow a similar pattern. Here are the two main examples:

Track ad loaded

Call when an ad successfully loads:


void onAdLoaded(YourAdType ad) {
Purchases.adTracker.trackAdLoaded(
AdLoadedData(
networkName: ad.networkName, // e.g., "Google Ads"
mediatorName: AdMediatorName.adMob, // or custom: AdMediatorName('YourMediator')
adFormat: AdFormat.rewarded, // .banner, .interstitial, etc.
placement: 'home_screen', // Your custom placement ID
adUnitId: ad.adUnitId, // Ad unit identifier
impressionId: ad.impressionId, // Unique impression ID
),
);
}

Track ad revenue

Call when your mediation platform reports revenue for an impression:


void onAdRevenue(YourAdType ad, double revenue, String currency) {
Purchases.adTracker.trackAdRevenue(
AdRevenueData(
networkName: ad.networkName,
mediatorName: AdMediatorName.adMob,
adFormat: AdFormat.rewarded,
placement: 'home_screen',
adUnitId: ad.adUnitId,
impressionId: ad.impressionId,
revenueMicros: (revenue * 1_000_000).toInt(), // Convert to micros
currency: currency, // e.g., "USD"
precision: AdRevenuePrecision.exact, // or .estimated, .publisherDefined
),
);
}

Other track methods

The remaining methods follow the same pattern as trackAdLoaded:

  • trackAdDisplayed(AdDisplayedData) - Call when ad impression is recorded (ad shown on screen)
  • trackAdOpened(AdOpenedData) - Call when user clicks/taps the ad
  • trackAdFailedToLoad(AdFailedToLoadData) - Call when ad fails to load (doesn't require networkName or impressionId)

See the Event data reference section below for complete parameter details.

Unity integration

1. Add the dependency

Import com.revenuecat.purchases 9.1.0 via the Unity Package Manager.

2. Access the AdTracker

using RevenueCat;

// Experimental API — may change in a future release
var adTracker = purchases.AdTracker; // 'purchases' is the Purchases MonoBehaviour on a GameObject
📘iOS availability

Ad tracking requires iOS 15.0+. On older iOS versions, calls are silently ignored and a warning is logged. The C# code compiles and runs on all platforms — the guard is applied in the native bridge layer.

3. Track events from mediation callbacks

All track methods follow a similar pattern. Here are the two main examples:

Track ad loaded

Call when an ad successfully loads:

// Experimental API — may change in a future release
void OnAdLoaded(YourAdType ad)
{
purchases.AdTracker.TrackAdLoaded(new AdLoadedData(
mediatorName: AdTracker.MediatorName.AdMob, // or new AdTracker.MediatorName("YourMediator")
adFormat: AdTracker.Format.Rewarded, // .Banner, .Interstitial, etc.
adUnitId: ad.adUnitId, // Ad unit identifier
impressionId: ad.impressionId, // Unique impression ID
networkName: ad.networkName, // e.g., "Google Ads" (optional)
placement: "home_screen" // Your custom placement ID (optional)
));
}

Track ad revenue

Call when your mediation platform reports revenue for an impression:

// Experimental API — may change in a future release
void OnPaidEvent(YourAdType ad, double revenue, string currency)
{
purchases.AdTracker.TrackAdRevenue(new AdRevenueData(
mediatorName: AdTracker.MediatorName.AdMob,
adFormat: AdTracker.Format.Rewarded,
adUnitId: ad.adUnitId,
impressionId: ad.impressionId,
revenueMicros: (long)(revenue * 1_000_000), // Convert to micros
currency: currency, // e.g., "USD"
precision: AdTracker.Precision.Exact // or .Estimated, .PublisherDefined
));
}

Other track methods

The remaining methods follow the same pattern as TrackAdLoaded:

  • TrackAdDisplayed(AdDisplayedData) - Call when ad impression is recorded (ad shown on screen)
  • TrackAdOpened(AdOpenedData) - Call when user clicks/taps the ad
  • TrackAdFailedToLoad(AdFailedToLoadData) - Call when ad fails to load (doesn't require networkName or impressionId)

See the Event data reference section below for complete parameter details.

React Native integration

1. Add the dependency

npm install react-native-purchases@^10.2.0
# or
yarn add react-native-purchases@^10.2.0

2. Access the AdTracker

/** @beta — this API is experimental and may change in a future release */
import Purchases, {
AdMediatorName,
AdFormat,
AdRevenuePrecision,
} from "react-native-purchases";

const adTracker = Purchases.adTracker;
📘Web and iOS availability

Ad tracking is not supported on web — calls are silently ignored. On iOS < 15.0, calls are also silently ignored and a warning is logged. Android has no version restriction.

3. Track events from mediation callbacks

All track methods follow a similar pattern. Here are the two main examples:

Track ad loaded

Call when an ad successfully loads:

/** @beta */
async function onAdLoaded(ad: YourAdType) {
await Purchases.adTracker.trackAdLoaded({
networkName: ad.networkName, // e.g., "Google Ads" (optional)
mediatorName: AdMediatorName.adMob, // or any string
adFormat: AdFormat.rewarded, // AdFormat.banner, .interstitial, etc.
placement: "home_screen", // Your custom placement ID (optional)
adUnitId: ad.adUnitId, // Ad unit identifier
impressionId: ad.impressionId, // Unique impression ID
});
}

Track ad revenue

Call when your mediation platform reports revenue for an impression:

/** @beta */
async function onAdRevenue(ad: YourAdType, revenue: number, currency: string) {
await Purchases.adTracker.trackAdRevenue({
networkName: ad.networkName,
mediatorName: AdMediatorName.adMob,
adFormat: AdFormat.rewarded,
placement: "home_screen",
adUnitId: ad.adUnitId,
impressionId: ad.impressionId,
revenueMicros: Math.round(revenue * 1_000_000), // Convert to micros
currency: currency, // e.g., "USD"
precision: AdRevenuePrecision.exact, // or .estimated, .publisherDefined
});
}

Other track methods

The remaining methods follow the same pattern as trackAdLoaded:

  • trackAdDisplayed(AdDisplayedData) - Call when ad impression is recorded (ad shown on screen)
  • trackAdOpened(AdOpenedData) - Call when user clicks/taps the ad
  • trackAdFailedToLoad(AdFailedToLoadData) - Call when ad fails to load (doesn't require networkName or impressionId)

See the Event data reference section below for complete parameter details.

Event data reference

Common parameters

All event types share these common parameters:

ParameterTypeDescriptionRequired
networkNameStringAd network that served the ad (e.g., "Google Ads", "Meta Audience Network")No (null allowed)
mediatorNameAdMediatorNameYour mediation platformYes
adFormatAdFormatType of adYes
placementStringYour custom placement identifierNo (null allowed)
adUnitIdStringAd unit identifier from mediation platformYes
impressionIdStringUnique identifier for this ad instanceYes (except for failed events)

AdFormat values

FormatAndroidiOSFlutterUnityReact Native
BannerAdFormat.BANNER.bannerAdFormat.bannerAdTracker.Format.BannerAdFormat.banner
InterstitialAdFormat.INTERSTITIAL.interstitialAdFormat.interstitialAdTracker.Format.InterstitialAdFormat.interstitial
RewardedAdFormat.REWARDED.rewardedAdFormat.rewardedAdTracker.Format.RewardedAdFormat.rewarded
Rewarded InterstitialAdFormat.REWARDED_INTERSTITIAL.rewardedInterstitialAdFormat.rewardedInterstitialAdTracker.Format.RewardedInterstitialAdFormat.rewardedInterstitial
NativeAdFormat.NATIVE.nativeAdFormat.native_AdTracker.Format.NativeAdFormat.native
App OpenAdFormat.APP_OPEN.appOpenAdFormat.appOpenAdTracker.Format.AppOpenAdFormat.appOpen
OtherAdFormat.OTHER.otherAdFormat.otherAdTracker.Format.OtherAdFormat.other
CustomAdFormat.fromString("x").init(value: "x")AdFormat("x")new AdTracker.Format("x")any string

AdMediatorName values

MediatorAndroidiOSFlutterUnityReact Native
Google AdMobAdMediatorName.AD_MOB.adMobAdMediatorName.adMobAdTracker.MediatorName.AdMobAdMediatorName.adMob
AppLovin MAXAdMediatorName.APP_LOVIN.appLovinAdMediatorName.appLovinAdTracker.MediatorName.AppLovinAdMediatorName.appLovin
CustomAdMediatorName.fromString("x").init(value: "x")AdMediatorName("x")new AdTracker.MediatorName("x")any string

AdRevenuePrecision values

PrecisionAndroidiOSFlutterUnityReact Native
ExactAdRevenuePrecision.EXACT.exactAdRevenuePrecision.exactAdTracker.Precision.ExactAdRevenuePrecision.exact
EstimatedAdRevenuePrecision.ESTIMATED.estimatedAdRevenuePrecision.estimatedAdTracker.Precision.EstimatedAdRevenuePrecision.estimated
Publisher DefinedAdRevenuePrecision.PUBLISHER_DEFINED.publisherDefinedAdRevenuePrecision.publisherDefinedAdTracker.Precision.PublisherDefinedAdRevenuePrecision.publisherDefined
UnknownAdRevenuePrecision.UNKNOWN.unknownAdRevenuePrecision.unknownAdTracker.Precision.UnknownAdRevenuePrecision.unknown

Revenue in micros

The revenueMicros parameter expects revenue in micros (millionths of the currency unit). Multiply the revenue value from your mediation platform by 1,000,000:

  • $1.50 USD → 1,500,000 micros
  • €0.25 EUR → 250,000 micros

The conversion in each platform's code examples above shows the exact formula for that language.

Best practices

Placement naming

Use consistent, descriptive placement names:

  • ✅ Good: "home_banner", "level_complete_interstitial", "bonus_coins_rewarded"
  • ❌ Avoid: "ad1", "test", timestamps, or dynamic values

Impression IDs

  • Use unique IDs provided by your mediation platform
  • Use the same impression ID across all events for a single ad instance (loaded → displayed → opened → revenue)

Error handling

Track failed ad loads to understand fill rate issues:

adTracker.trackAdFailedToLoad(
AdFailedToLoadData(
mediatorName = AdMediatorName.fromString("YourMediator"),
adFormat = AdFormat.REWARDED,
placement = "home_screen",
adUnitId = adUnitId,
mediatorErrorCode = errorCode // Include platform error code
)
)

When to track each event

EventWhen to Call
trackAdLoadedAfter ad successfully loads in memory
trackAdDisplayedWhen ad impression is recorded (ad shown on screen)
trackAdOpenedWhen user clicks/taps the ad
trackAdRevenueWhen mediation platform reports ILRD for the impression
trackAdFailedToLoadWhen ad request fails

Example projects

Complete working examples are available:

These examples use AdMob's helper methods, but the event tracking patterns apply to manual integration with any mediation platform.

View your data

See the Ad Monetization overview for details on where your ad data appears in the dashboard.

Troubleshooting

Testing your integration

Before troubleshooting, verify your events are being tracked:

  1. Run your app in debug mode
  2. Navigate to the Ads page in your RevenueCat dashboard
  3. Toggle on "Sandbox data"
  4. Trigger some ads in your app
  5. Check that events appear in the sandbox events table

RevenueCat automatically marks events from debug builds as sandbox, so you can verify your integration without affecting production data.

Events not appearing in Charts

  1. Verify you've opted in via the Ads page in your RevenueCat dashboard
  2. Check that you're calling the correct track* methods with all required parameters
  3. Ensure impressionId is unique for each ad instance
  4. Verify your mediation platform is providing ILRD callbacks
  5. Check that revenueMicros is calculated correctly (multiply by 1,000,000)
  6. Use the sandbox data view (above) to confirm events are being received

Revenue values seem incorrect

  • Ensure you're converting to micros: multiply by 1,000,000
  • Verify the currency code is correct (e.g., "USD", "EUR")
  • Check that the revenue value from your mediation platform is already in the correct currency unit

Next steps

Was this page helpful?