How to attribute ad revenue to user acquisition source in a mobile app
Your MMP shows zero revenue for every campaign because ad revenue arrives impression by impression through the mediation SDK, and this guide explains how to connect that revenue to the source that acquired each user, format by format.

In this article
- Ad revenue is invisible to purchase-based measurement
- Impression-level revenue is the foundation of source attribution
- Each ad format needs its own handling
- Cohort ad ROAS turns attribution into a budget decision
- Where ad revenue measurement lives is a contract question
- Ad revenue attribution will not fix your monetization strategy
You buy traffic, you monetize with ads, and your MMP dashboard shows zero revenue for every campaign. The UA team optimizes on installs and retention. The monetization team sees revenue by network, format and country in the mediation dashboard, but not by acquisition source. Nobody can answer the question that drives next month's budget: which campaigns bring users who generate more ad revenue than they cost.
Ad revenue is invisible to purchase-based measurement
Most MMP setups are built around events the app sends itself: install, registration, purchase with a price. Ad revenue does not work that way. No user pays anything. Revenue is the sum of many small impression values, set by an auction inside the mediation layer. The app does not know those values unless the mediation SDK reports them.
If nobody forwards those values, the MMP has nothing to attribute. The zero is not a bug. It is missing input. The fix is to connect two sources of truth at user level: revenue from mediation and attribution from the MMP. We covered why install counts alone fall short in [Beyond the install: what mobile teams actually need from measurement](/blog/beyond-the-install-mobile-measurement).
Impression-level revenue is the foundation of source attribution
Mediation platforms expose a per-impression revenue callback in their SDKs. AppLovin MAX, AdMob and IronSource each provide one. Forward every callback to the MMP as an ad revenue event. The MMP already knows which campaign the user came from, so each impression inherits that source automatically.
Forward more than the revenue value. You will need these fields later:
- Revenue value and currency, exactly as reported by the mediation SDK.
- Ad format and ad unit, so you can split rewarded, interstitial, banner and offerwall.
- Winning network, so you can compare demand sources per acquisition cohort.
- The precision flag. Mediation platforms mark whether a value is exact, estimated or publisher-defined. Keep that distinction.
The alternative is aggregate allocation. You pull daily revenue from network reporting APIs and split it across cohorts by their share of sessions or impressions. It works when you cannot change the SDK. But it is a model, not a measurement. It assumes users from every source earn the same per impression, which is exactly the assumption you want to test.
Each ad format needs its own handling
Rewarded video and interstitials
These produce fewer impressions with higher values. Revenue tends to concentrate in engaged users, so a small group can dominate a cohort's average. Look at the distribution per source, not only the mean.
Banners
Banner refresh creates a high volume of low-value impressions. Check that your MMP setup handles the event volume. If you aggregate locally per session before sending, keep the format and network attributes intact.
Offerwall
Offerwall revenue arrives when a user completes an offer, is often confirmed server-side later, and can be reversed. Treat it as a separate stream. Send it server-to-server with a stable user ID and accept revisions. Do not mix it with impression revenue in first-day reporting, or early cohorts will look worse than they are.
Cohort ad ROAS turns attribution into a budget decision
Once revenue carries a source, build cohorts by install date and source. Compare cumulative ad revenue per user at a chosen day against cost per install. That is ad ROAS, often called eROAS. In hybrid apps, add in-app purchase revenue net of store fees to the same view, but keep it in a separate column so each team can read its own number.
Payback windows depend on vertical and market. Set targets from your own observed curves, not from industry benchmarks.
On iOS, users who decline ATT tracking are not attributed at user level. Their ad revenue reaches you only in aggregate through SKAN conversion values, so your conversion value schema should encode ad revenue ranges. The details are in [SKAN in 2026: A Practical Measurement Playbook](/blog/skan-2026-measurement-playbook).
Reconcile before you trust the data. Pick one full day and, for each network, sum the forwarded ad revenue events in your MMP. Compare that with the mediation dashboard for the same day, timezone and currency. Gaps come from timezone mismatches, currency conversion, estimated values and events lost when the app closes before sending. Agree an acceptable gap with the monetization team, and repeat the check after every SDK update.
Where ad revenue measurement lives is a contract question
If you are evaluating or replacing an MMP, ask four questions. Is ad revenue attribution included in the plan or sold as an add-on? Which mediation integrations are supported natively? Can ad revenue be sent as postbacks to ad networks for ROAS-based bidding? How do ad revenue events count toward billing? If you are on Adjust, AppsFlyer or Kochava today, put the same questions to your account manager and get the answers in writing.
AdShift measures ad revenue in the same SDK as install attribution and deep links, priced per conversion instead of per MTU. Whichever platform you choose, the answers to those four questions matter more than the logo. For the wider context, see [Understanding MMPs and AdShift](/blog/understanding-mmps-and-adshift).
Ad revenue attribution will not fix your monetization strategy
Attribution answers one question well. It does not answer these:
- Optimal ad load. More ads can raise revenue per session and lower retention. Only controlled experiments settle that trade-off.
- eCPM swings caused by seasonality or advertiser demand. Attribution shows them per cohort but cannot prevent them.
- Mediation setup. Waterfall order, bidding configuration and floor prices are separate work.
- Estimated values. If the network reports an estimate, the attributed number is still an estimate.
- User-level iOS data for users who did not consent to tracking.
What it does give you is enough to move budget: a per-source view of whether acquired users earn back what they cost.
Frequently asked questions
Why does my MMP show zero ad revenue when the mediation dashboard shows revenue?+
The MMP only attributes events it receives. Ad revenue lives in the mediation SDK, and unless you forward the impression-level revenue callback to the MMP, it never arrives. Once forwarded, each impression inherits the acquisition source of the user who saw it.
Can I attribute ad revenue without changing the app SDK?+
You can allocate aggregate revenue from network reporting APIs to cohorts by sessions or impressions. That is a model, not a measurement. It assumes every source earns the same per impression, which hides the differences you are trying to find.
Should ad revenue and in-app purchase revenue be combined in ROAS?+
In hybrid apps, show both in the same cohort view so budget decisions reflect total value. Keep them in separate columns, and report purchases net of store fees. That way the UA and monetization teams can each read and challenge their own number.
How should offerwall reversals be handled?+
Send offerwall revenue server-to-server with a stable user ID and allow later corrections. Report it separately from impression revenue in early cohort views. Decisions made on first-day offerwall numbers alone tend to change once confirmations and reversals arrive.
About the author
Co-founder of AdShift, building a mobile measurement platform for app teams that need attribution, ROAS/LTV and ad revenue data they can defend.
See it on your data
Want attribution you can defend in a budget meeting?
We will walk through your current measurement setup, show where the signal is leaking, and map what AdShift would report differently.
Keep reading
Mobile MarketingBeyond the install: what mobile teams actually need from measurement
The real mobile measurement problem starts after the install: revenue lives in several systems, dashboards disagree, exports matter, and every migration from an existing MMP has to be low-risk.
Read moreWhy we built AdShift: a measurement layer mobile teams can trust
Mobile teams do not need another dashboard. They need a measurement layer they can trust. AdShift was built from our adtech experience to help app teams connect attribution, ROAS/LTV, fraud, deep links and ad revenue in one place.
Read more
Mobile MarketingUnderstanding MMPs and AdShift
Discover what a Mobile Measurement Platform is, how it works, and how AdShift helps you track user journeys, measure campaign performance, and drive meaningful growth for your app.
Read more