Measuring iOS app ads after ATT: SKAdNetwork, AdAttributionKit and why MMP numbers differ
Updated October 2026.
AdAttributionKit is the attribution framework Apple now recommends: the SKAdNetwork documentation page opens with advice to use AdAttributionKit for app campaigns on the App Store and on alternative app marketplaces (Apple Developer, SKAdNetwork). Since ATT, measuring iOS app ads relies on two sources: device-level data from users who agree to tracking, and aggregated postbacks from Apple’s two frameworks for everyone else. This article walks through SKAdNetwork and AdAttributionKit, how to set them up with an MMP, how to read numbers that do not match, incrementality testing, a sample conversion value table and a checklist to run before you increase your user acquisition budget.
ATT and the IDFA: the change that started with iOS 14.5
Since iOS 14.5, an app must ask permission through App Tracking Transparency (ATT) before it tracks users or reads the IDFA (the identifier for advertisers). If the user declines, the IDFA returns all zeros (Apple Developer, advertisingIdentifier).
Apple’s User Privacy and Data Use page spells out a few points that are often misread. You may not use a hashed email address or phone number to track someone who has not agreed. Session IDs, fingerprint IDs and device graph IDs are also identifiers that need permission. The IDFV may only be used for analytics across apps from the same developer.
The result: device-level mobile attribution now works only for the group that opts in. The group that declines is measured through Apple’s aggregated frameworks, which are slower and less detailed. The APIs of both frameworks can be called without an ATT request (Apple Developer, AdAttributionKit). How to ask for permission correctly is covered in our article on Apple’s ATT rules.
SKAdNetwork 4: postbacks, conversion values and crowd anonymity
SKAdNetwork attributes installs from ads without the IDFA. The current version is 4.0, which runs on iOS 16.1 and later (SKAdNetwork 4 release notes).
1. Three conversion windows, counted from the first app open: days 0 to 2, days 3 to 7 and days 8 to 35. Each conversion window produces at most one postback. Postback 1 arrives after a random delay of 24 to 48 hours; postbacks 2 and 3 arrive after 24 to 144 hours. The app can lock the value to receive the postback sooner, but any later events in that conversion window are then ignored. AdAttributionKit uses exactly the same windows (Apple Developer, AAK conversion windows).
2. Conversion values. The fine value is a 6-bit number from 0 to 63, and it appears only in postback 1. The coarse value has three levels, low, medium and high, and is used in postbacks 2 and 3, and in postback 1 when data is limited (Apple Developer, postback parameters). The app decides what each level means.
3. Crowd anonymity. Version 4 replaces the campaign ID (up to 100 values) with a 4-digit source identifier. Apple assigns each install to a postback data tier based on the crowd size of the app that showed the ad, the advertised app, the country and the source identifier. Fewer installs mean a postback with less information (Apple Developer, Receiving postbacks in multiple conversion windows):
| Tier | Postback 1 | Postbacks 2 and 3 |
|---|---|---|
| Tier 3 | 2 to 4 digit source identifier, fine value, source app, country code | 2-digit source identifier, coarse value |
| Tier 2 | 2 to 4 digit source identifier, fine value | Same as above |
| Tier 1 | 2-digit source identifier, coarse value | Same as above |
| Tier 0 | 2-digit source identifier only | None |
This table explains a common mistake: splitting iOS spend into too many small campaigns. Each campaign gets few installs, drops to Tier 0 or 1, and loses the fine value entirely. Google Ads also advises limiting the number of iOS campaigns, because many campaigns blur SKAdNetwork data (Google Ads Help, iOS App campaigns).
AdAttributionKit: where it stands in 2026
AdAttributionKit (AAK) arrived with iOS 17.4 (early 2024) and measures ads for both the App Store and alternative app marketplaces. Apple Ads help now says “SKAdNetwork is now called AdAttributionKit” (Apple Ads, App ad attribution overview).
Re-engagement: measuring people who already have the app
SKAdNetwork cannot measure re-engagement. AAK can. A re-engagement counts when someone who already has the app taps a custom-rendered ad, or taps the Open button on a StoreKit-rendered ad (Apple Developer, Receiving ad attributions and postbacks). Things to know:
- Only taps count; views do not. Networks that lose the attribution get no postback.
- From iOS 18, an ad can open the app’s universal link, with the AdAttributionKitReengagementOpen parameter attached.
- The app has only 2 days to send its first conversion value update, compared with 60 days for an install.
- Apple caps the number of re-engagements per app per month and per device per year.
- The conversion-type field reads download, redownload or reengagement.
AAK handles measurement only. Sending a list of your app users to an ad network for retargeting still counts as tracking, and you can do it only for users who agreed to ATT.
The AdAttributionKit Updates page (checked October 17, 2026) lists the most recent update as June 2025 (Apple Developer, AdAttributionKit Updates). The newest features:
- Custom attribution windows: the default is 30 days for clicks and 1 day for views; an app can set 1 to 30 days for clicks and 1 to 7 days for views.
- Cooldown of 0 to 720 hours between two conversions, and conversion tags (iOS 18.4) for overlapping re-engagements.
- Development postbacks: generate test postbacks in the iPhone’s Developer settings and choose the postback data tier (Apple Developer, developer settings).
How the two frameworks relate: Apple recommends AAK, SKAdNetwork keeps running alongside it, and both share the same ad network IDs. Impressions from both frameworks are ranked together, a click beats a view, and only one impression wins. An SDK that integrates both calls the update APIs of both (Apple Developer, interoperability).
Platform support is still uneven. Google Ads (checked October 2026) does not yet support AAK. Apple Ads has registered for SKAdNetwork since April 10, 2025 (Apple Ads Help), and AppsFlyer notes that from iOS 26.2, Apple Ads sends postbacks through AAK (AppsFlyer, updated May 2026). You should receive postback copies from both frameworks.
SKAdNetwork vs AdAttributionKit compared
| Criterion | SKAdNetwork 4 | AdAttributionKit |
|---|---|---|
| Minimum iOS | 16.1 | 17.4; re-engagement from 18 |
| Install source | App Store | App Store and alternative app marketplaces |
| Re-engagement | No | Yes, clicks only |
| Attribution window | Fixed: 30 days for clicks, 24 hours for views | Same default as SKAN, customizable in Info.plist |
| Cooldown, conversion tags | No | Yes |
| Key for receiving postback copies | NSAdvertisingAttributionReportEndpoint | AttributionCopyEndpoint |
What an MMP does in UA measurement
An MMP (mobile measurement partner) such as AppsFlyer, Adjust, Branch or Singular sits between your app and the ad networks and does four jobs:
- Device-level attribution for users who agree to ATT, and for sources outside ad networks such as links, QR codes and deep linking.
- Collecting SKAN and AAK postbacks from every network, decoding conversion values according to your schema, and deduplicating them against device-level data.
- Receiving postback copies for cross-checking, because the conversion value is not part of Apple’s signature and the numbers a network reports back can be altered (according to AppsFlyer).
- Filtering out install fraud before networks get paid.
Postback copies: developers receive them directly since iOS 15
In 2021, advertisers often complained that Apple sent postbacks only to ad networks. Since iOS 15, if the app registers for it, the device also sends the developer a copy of the winning postback, identical to the one the network receives and sent at the same time (Apple Developer, SKAdNetwork postbacks). The registration keys are in the table above. To receive postback copies for re-engagement as well, turn on the “Opt in for Reengagement Postback Copies” option (Apple Developer, Configuring an advertised app).
Setting up AdAttributionKit with an MMP
- Upgrade the MMP SDK to a version that supports both SKAdNetwork 4 and AAK. If old code still calls registerAppForAdNetworkAttribution(), remove it: the function was deprecated in iOS 15.4, and Apple points to updatePostbackConversionValue instead (Apple Developer, registerAppForAdNetworkAttribution()); the AAK equivalent is updateConversionValue. The app has to call the update function at least once, ideally on first open, or the conversion window never starts.
- Declare both postback copy keys using the domain your MMP gives you.
- Server-to-server events sent to the MMP should not use the IDFA as the matching key; use the IDFV, the MMP’s own ID or your internal user ID.
- Enter the conversion value schema (see below), then test it with development postbacks across several postback data tiers.
Why Meta and Google numbers differ from your MMP
Do not aim for a 100% match between the two sides, because each one uses a different attribution model (AppsFlyer, Meta ads discrepancies, updated November 2025; AppsFlyer, iOS metrics dashboard, updated May 2025):
| Cause | What happens | What to do |
|---|---|---|
| Attribution window | Meta defaults to 7-day click, 1-day view; the MMP lets you set 1 to 30 days | Set the MMP window to match Meta |
| Self-attribution | Meta claims the install regardless of other sources; the MMP uses last click across sources | A network total higher than the MMP total is normal |
| Modeling | Meta uses a probabilistic model (AEM) on iOS, so some installs show up on only one side; Google uses conversion modeling | Label clearly which columns are modeled numbers |
| Time zone, install date | Meta defaults to PST, SKAN uses UTC; the SKAN install date is inferred from when the postback arrives; Google Ads data in SKAN can lag by up to 13 days | Use one time zone; look at a range of at least 7 days that ends 3 to 5 days before today |
| Event lifetime | Meta counts events within 7 days of the click, AppsFlyer up to 180 days | Compare revenue on the same day cutoff |
| Duplicate events | The same event is sent from both the Facebook SDK and the MMP, and Meta does not deduplicate it | Send each event from one source only |
I track the ratio, not the raw number. A hypothetical example: Meta reports 1,000 installs and the MMP credits 700 to Meta, a ratio of 0.70. Three weeks in a row around 0.70 is the gap caused by different models. If week five drops to 0.40 with an unchanged budget, something has broken: a new SDK, a changed schema, duplicate events. To find out which channel actually brings in additional users, run incrementality testing instead of arguing over which number is right.
Reading SKAN and AAK reports
As the share of installs attributed through postbacks grows, what drops first is your ability to measure, not necessarily performance. I look at four things:
- The most recent days are always incomplete, because postback 1 can arrive about 4 days after the first app open.
- The share of postbacks with a fine value, with only a coarse value, or empty, broken down by source. A rising empty share usually comes from splitting campaigns too thin.
- If the source identifier is down to 2 digits, ask the ad network whether those 2 digits encode the campaign or the creative.
- Blended CPA and ROAS across all of iOS as the baseline while per-channel numbers are still fuzzy.
For users who have not agreed, ads cannot be personalized based on the behavior they leave in your app, so your product feed should favor best sellers. A/B tests run slower because you wait for postbacks, so test fewer variants.
Running an incrementality test for an iOS app
Without the IDFA, user-level tests are hard, but a geo test only compares totals, so it does not need the IDFA:
- Split provinces and cities into two groups with similar install and revenue history; the control group turns off the channel you want to measure.
- Measure with total iOS installs, organic included, and revenue by region from the MMP or your internal data, because postbacks carry no province-level detail.
- Keep creative, pricing and promotions the same across regions.
- Compare the gap between the two groups with the gap before the test, and convert it into cost per incremental install.
Google Ads offers Conversion Lift based on geography, which supports App campaigns too, but you have to contact a Google representative and the campaign must target a single country (Google Ads Help, Conversion Lift based on geography). A hypothetical example: Meta reports 1,000 installs and the test finds 400 incremental installs, so you apply a 0.4 multiplier to Meta’s numbers when allocating budget.
A quick comparison with Android
Android has no permission layer like ATT yet. The Install Referrer API returns referral data straight from Google Play (Android Developers, updated July 2025), so Android numbers usually match better than iOS numbers. Privacy Sandbox, once seen as “Android’s ATT”, was discontinued by Google in an announcement on October 17, 2025, Attribution Reporting API included (Privacy Sandbox, October 17, 2025).
Setting up a SKAdNetwork conversion value schema for an e-commerce app
A schema is the table that defines what each conversion value means. Without one, a postback is just a number, so this is the part that decides the quality of your iOS app ad measurement:
- Pick events that reflect value within the first 48 hours, because only postback 1 carries a fine value.
- Order values from least to most important. For ads signed with SKAN 3 or earlier, the 24-hour timer only restarts when the new value is higher than the old one.
- Assign coarse values that mean something, because Tiers 0 and 1 and postbacks 2 and 3 carry only coarse values.
- Choose between locking early (data reaches the algorithm faster) and waiting for the conversion window to close (fuller measurement).
- Enter the schema in your MMP and use one version for every network; review it after 2 weeks of live traffic.
A sample table, a hypothetical example for a cosmetics app with an average order value of about VND 350,000:
| Fine value | Meaning (postback 1, days 0 to 2) | Coarse |
|---|---|---|
| 0 | First app open | low |
| 1 | Account sign-up | low |
| 2 | Add to cart | medium |
| 3 | Checkout started | medium |
| 10 to 19 | First order, 10 revenue bands of VND 100,000 each (10 is under 100,000; 19 is 900,000 or more) | medium if under 300,000, high if 300,000 or more |
| 30 to 39 | 2 or more orders, same bands applied to cumulative revenue | high |
Postback 2 (days 3 to 7) and postback 3 (days 8 to 35) carry only coarse values: low means the user returned to the app, medium means 1 order, high means 2 or more orders or cumulative revenue of VND 700,000 or more. Postback 3 is the closest signal to LTV that SKAN gives you; the share of high values by source helps you estimate day-35 ROAS.
Do not spend all 64 values on 64 events, because fine values only exist from Tier 2 up. Do not change the schema mid-campaign. Do not set “app open” as coarse high, or the algorithm will optimize for people who install and leave. The events in your schema should match the set of app marketing KPIs your team already reports internally.
iOS app ad measurement checklist before you scale UA spend
Answer each item yes or no. If any item is still a no, hold off on increasing the budget.
- The MMP SDK is current and supports both SKAdNetwork and AdAttributionKit; the code no longer calls registerAppForAdNetworkAttribution().
- Info.plist has both postback copy keys pointing to the MMP, and the postback copy report already shows data.
- The conversion value schema is documented and identical across the MMP, Meta and Google.
- Development postbacks have been tested at Tier 0 and Tier 3, and the server reads them correctly.
- The ATT opt-in rate is tracked weekly.
- The attribution window and time zone in the MMP match each platform.
- Each event reaches Meta from one source only.
- There are few enough iOS campaigns that most postbacks carry a fine value.
- You have at least 3 weeks of history for the platform to MMP ratio.
- Fraud protection is on; AAK re-engagement links open the right screen.
- You have recorded your baseline organic install level, so you can see whether ads are eating into organic installs.
Only then choose channels and budgets according to the app marketing strategy for each stage; if the app is about to launch, go back over the steps for an app launch on the App Store first. If you need a review of your iOS measurement setup or a UA plan for your app, Adtek’s App User Acquisition team (Apple Ads certified) can work through it with you via the Adtek contact page.
Want to apply this to your business?
Send your question or situation. The Adtek team reads every question and gets back to you.
Prefer to chat? Message us on Zalo