This post used to be an explainer called "iOS attribution without ATT". The frameworks are still here (section three), but the question people bring to it is the one in the title, so that's what it answers now.
The decision in one table
| Your situation | MMP? | What covers it instead |
|---|---|---|
| No paid ads yet | No | App Store Connect's source and campaign-link reports |
| Apple Ads only | No | AdServices, per install; RevenueCat Charts for revenue by keyword |
| Apple Ads plus one social network, small budget | Usually no | AdServices for Apple; the network's own AdAttributionKit or SKAdNetwork reporting; RevenueCat's Meta Ads integration to send purchase events to Meta |
| Several non-Apple networks, real budgets, someone reallocating spend weekly | Probably yes | An MMP, for cross-network cost, deduplication, fraud checks and deep links |
The price objection has softened. AppsFlyer's free "Zero" plan includes 12,000 conversions for the first year but says it isn't suitable for apps with paid activity (pricing), and Singular's free plan covers up to 15,000 paid conversions (pricing). So the real question is whether you need the work an MMP does, not whether you can afford it.
What an MMP does, and what it can't
The fair version of the MMP pitch: AppsFlyer, Adjust, Singular and Branch pull spend from each ad network into one cost report, decide which network gets credit when two claim the same install, run fraud detection, handle deferred deep links, and decode SKAdNetwork conversion values into dashboards. With Meta, TikTok and Google running at the same time, that is a real job.
What an MMP can't do on iOS, whatever you pay:
- Name the user a Meta or TikTok install came from without ATT consent. It receives the same aggregate postbacks you could receive yourself.
- Make SKAdNetwork or AdAttributionKit faster. Postbacks arrive days after the install; that delay is Apple's.
- Tell you what those users did in your app, unless you send it your in-app events and revenue. At that point it's one more place holding a copy of your user data.
What Apple gives you for free
Apple ships three attribution systems. They answer different questions, and none needs the ATT prompt (AdAttributionKit docs: "Apps don't need to use App Tracking Transparency before calling ad attribution APIs").
| System | Covers | Granularity |
|---|---|---|
| AdServices | Apple Ads only | Per install: campaign, ad group, keyword, tap or view, joinable to your own user record |
| AdAttributionKit | Registered ad networks, on the App Store and alternative marketplaces; installs and re-engagement | Aggregate postbacks with a source ID and a conversion value |
| SKAdNetwork | Registered ad networks, App Store only | Aggregate, same model; interoperates with AdAttributionKit |
AdServices: the per-install answer for Apple Ads
Your app asks the framework for a token, posts it to Apple, and gets back
either attribution: false or the campaign, ad group and
keyword IDs behind the install, plus whether the person tapped the ad
(Click) or only saw it (Impression, since
March 2025). No user or device identifier is in the payload; you get
Apple's definite answer for this install, which you store on your own
user record. The full walkthrough, including what RevenueCat already
covers, is in
Apple Ads attribution
without an MMP.
AdAttributionKit and SKAdNetwork: the aggregate lane
For every other network, attribution arrives as postbacks: signed messages from the device to the ad network (and a copy to you, if you ask) saying that an install from a source reached a conversion value. The current rules, from Apple's conversion windows reference:
- Up to three postbacks per install, for days 0–2, 3–7 and 8–35 after first launch. The first is sent after a random delay of 24 to 48 hours; the second and third after 24 to 144 hours.
- Fine values only in the first postback. The 0–63 fine value can arrive in the first postback; the second and third carry at most a coarse low, medium or high.
- Crowd size decides what you get. Apple assigns each install a postback data tier. At Tier 0 you get only the first postback with a two-digit source ID. Country codes appear only at Tier 3. Small campaigns, which for an indie is most campaigns, sit in the low tiers.
- One winner. When an app has both AdAttributionKit and SKAdNetwork impressions, the system picks a single winner across both; taps beat views and newer beats older (interoperability doc). AdServices reports Apple Ads separately, so don't add Apple Ads installs to a network's postback counts and call it a total.
What AdAttributionKit added over SKAdNetwork: it launched in iOS 17.4, added re-engagement attribution (ads that reopen an installed app) in iOS 18, and in iOS 18.4 gained overlapping re-engagement windows, conversion tags, configurable attribution rules and country codes in postbacks, plus better developer-mode testing (WWDC25 session). WWDC 2026 brought no meaningful changes to AdAttributionKit or ATT, according to Kochava's review, so the iOS 18.4 feature set is still the current one.
Two habits for a small budget. First, receive your own
postback copies: add the
NSAdvertisingAttributionReportEndpoint key to your
Info.plist, pointing at an endpoint you control, and Apple sends it a
copy of each winning postback. Without it, the network's dashboard is
your only view. Second, concentrate spend: the tier
depends on crowd sizes that include the campaign's source identifier,
so five small campaigns can each stay in a low tier where one
consolidated campaign would have cleared a higher one.
What RevenueCat adds
If you already run RevenueCat, two of its integrations cover ground an MMP used to own:
- Apple Ads. With AdServices token collection enabled in the SDK, Charts can be filtered and segmented by campaign, ad group, keyword and claim type, which it has supported since March 27, 2025 (changelog).
- Meta Ads. RevenueCat can send trial and subscription events to Meta through the Conversions API, including renewals that happen while the app is closed (docs). That feeds Meta's optimization. It doesn't tell you which Meta ad a given subscriber came from.
What nobody can tell you
These are not for sale from any vendor, so plan without them:
- Which specific user came from which paid-social ad, without ATT consent. Fingerprinting workarounds break Apple's rules.
- Per-user lifetime value by campaign for non-Apple networks. The best you get is conversion-value distributions per source.
- Fast feedback. Conversion windows plus random delays mean paid-social signal is days old when it lands.
- Detail on small campaigns. Privacy tiers bite hardest at indie spend levels.
None of this stops you running ads profitably. It rules out a precision that, at indie volume, would mostly have been noise. The sample-size rules from measuring onboarding against paid conversion apply twice over behind a privacy threshold.
The one lever you control: what conversion values mean
Apple fixes how much comes back and when. What the conversion values encode is yours. The common mistake is spending them on vanity milestones (opened the app twice) instead of steps that predict money (started a trial, finished onboarding, reached the moment the app proves itself). Two rules from doing this on live apps:
- Encode the steps that predict revenue. You only know which those are if behavior and purchases share one user record, the one-ID pattern. Your own joined data shows which early actions go with paying; the conversion value should carry those.
- Keep the mapping on a server. Conversion-value schemes need a few rounds of tuning, and an App Review cycle per tweak means you'll stop tuning. A config-driven mapping lets you change what 0–63 means without shipping a build.
FAQ
Do I need an MMP if I only run Apple Ads?
No. AdServices gives you campaign, ad group and keyword per install without ATT, and RevenueCat can chart revenue by keyword. An MMP adds little for one Apple-only channel.
When does an MMP pay off for a small iOS app?
When you spend real budgets on several non-Apple networks at once and need one cost report across them, deduplication, fraud checks and deep links in one place. Below that, the networks' own reporting plus Apple's frameworks usually answer a solo developer's questions.
Are there free MMP plans?
Yes, with limits. AppsFlyer Zero includes 12,000 conversions for the first year and isn't meant for paid campaigns; Singular's free plan covers up to 15,000 paid conversions. Check each pricing page for current terms.
Can SKAdNetwork or AdAttributionKit tell me which user came from which campaign?
No. Postbacks name a source and carry a conversion value; Apple signs no user or device data into them. Anything claiming user-level paid-social on iOS without ATT is either modeled or against the rules.
Is AdAttributionKit replacing SKAdNetwork?
It's the successor, and the two interoperate: ad network IDs work in both, and the system picks one winner across them. Adopt it when your ad networks ask. It stays aggregate.
Did WWDC 2026 change iOS attribution?
No meaningful changes to AdAttributionKit or ATT, per Kochava's review. The iOS 18.4 additions announced at WWDC 2025 are still the current state.
Should I still show the ATT prompt?
If Apple Ads is your only paid channel, you can skip it: the AdServices payload arrives without consent and one less dialog in onboarding is usually worth more than the tap timestamp. If you run retargeting or meaningful spend on networks that optimize on consented users, decide on their terms.
Sources
- Apple, AdAttributionKit, conversion windows and data tiers, SKAdNetwork interoperability
- Apple, What's new in AdAttributionKit (WWDC25)
- Kochava, Your iOS attribution strategy: 2026 reality check
- RevenueCat, Charts keyword and claim type and Meta Ads integration
- AppsFlyer pricing and Singular pricing (checked September 2026)