Attribution · definition

iOS attribution without ATT: what you can actually know

FolioKit · July 15, 2026

Short answer: Apple gives you three attribution systems, and they answer different questions. AdServices is deterministic and user-level, but only for Apple Search Ads. SKAdNetwork 4 covers every other ad network at the campaign level — aggregate postbacks, no users, ever. AdAttributionKit is SKAdNetwork's successor and keeps the same privacy model. No combination of the three gives you user-level paid-social attribution. Plan around that instead of against it.

The confusion here is mostly vocabulary. Three frameworks, three consent stories, three data shapes — and most explainers are written by MMP vendors with a subscription to sell. Here's the map as it stands in 2026, sized for a solo developer rather than a growth team.

The mental model: one deterministic island, everything else aggregate

Sort the three systems by the question they answer and the picture gets simple:

SystemCoversGranularityNeeds ATT?
AdServices Apple Search Ads only Per user: campaign, ad group, keyword No (consent adds click detail)
SKAdNetwork 4 Any registered ad network Aggregate: campaign + conversion value No
AdAttributionKit Successor to SKAdNetwork; adds alternative marketplaces, re-engagement Aggregate, same model No

AdServices exists because Apple owns both sides of a Search Ads install — the ad and the store — so it can attribute deterministically without tracking anyone across companies. Everyone else's ads go through the aggregate lane. That asymmetry is the whole landscape; the rest is detail.

AdServices: the half you can fully trust

Your app asks the framework for an attribution token, posts it to Apple's API, and gets back either attribution: false (organic) or the campaign, ad group, and keyword IDs behind the install. It's per-user, it's exact, and the standard payload needs no consent — only the click timestamp is held back for users who declined ATT. Attach the result to your user record and "which keyword produced subscribers" becomes an ordinary query.

Because this is the deterministic half, it deserves its own walkthrough — token retries, payload fields, the ID-to-name mapping — which we've written up separately. The one-sentence version: if Apple Search Ads is your only paid channel, AdServices alone replaces an MMP.

SKAdNetwork 4: what the aggregate lane actually delivers

For Meta, TikTok, Reddit, or any other network, attribution arrives as postbacks: signed messages from Apple to the ad network (with a copy to you, if you register for it) saying "an install from campaign X reached conversion value Y." No device ID, no user, deliberately delayed. The version-4 specifics that matter:

Two practical consequences for an indie budget. First, register to receive your own postback copies — add the NSAdvertisingAttributionReportEndpoint key to your Info.plist pointing at an endpoint you control, and Apple sends you a copy of what the ad network gets. Without it, your only view of your own attribution is the network's dashboard. Second, concentrate spend: crowd anonymity is per campaign, so five small campaigns can each fall below the thresholds while one consolidated campaign would have cleared them. Fewer, bigger campaigns buy you better data, which is backwards from how web advertisers structure things and worth internalizing early.

The honest summary: SKAdNetwork tells a small advertiser which campaigns produce installs that reach milestones you chose in advance. It does not tell you who, when exactly, or what they did next.

AdAttributionKit: same contract, new container

AdAttributionKit shipped in iOS 17.4, originally so attribution could work on alternative app marketplaces in the EU, and has been absorbing SKAdNetwork's role since. It adds re-engagement attribution (ads that reopen an installed app, from iOS 18) and better developer testing, and it interoperates with SKAdNetwork campaigns during the migration, so nothing breaks while ad networks move over.

What it pointedly does not change is the privacy model: postbacks, conversion windows, crowd anonymity, aggregate only. If you were hoping the successor framework would quietly return user-level data — it doesn't, and Apple's direction of travel makes that a safe long-term assumption. Cover AdAttributionKit in your planning because your ad networks will require it, not because it unlocks anything new.

What you cannot know, in writing

Worth stating plainly, because a lot of tooling is marketed as if these were still purchasable:

None of this blocks running ads profitably. It blocks pretending to precision — which, at indie scale, was mostly noise anyway. The same sample-size honesty we argued for in measuring onboarding against paid conversion applies double behind a privacy threshold.

The one lever you control: what conversion values mean

You can't widen the pipe, but you decide what flows through it. The 0–63 fine value and the coarse buckets are yours to define, and the common mistake is spending them on vanity milestones (opened the app twice) instead of money-correlated ones (started trial, finished onboarding, reached the value moment). Two rules from doing this on live apps:

  1. Encode the funnel steps that predict revenue, which you only know if behavior and purchases already join on one user record — the one-ID pattern again. Your own joined data tells you which early actions correlate with paying; the conversion value should encode those.
  2. Keep the mapping server-side. Conversion-value schemes need iteration, and an app-update round trip per tweak means you'll stop iterating. A config-driven mapping lets you retune what 0–63 means without shipping a build.
Where FolioKit fits: the SDK handles both halves without an MMP — Apple Search Ads attribution via AdServices, deterministic and ATT-free, and SKAdNetwork conversion values mapped from server config so you can retune them without an app update. Aggregate paid-social stays aggregate; we won't pretend otherwise. Details in the SDK docs.

FAQ

Do I need an MMP like AppsFlyer or Adjust?

Apple-only spend: no — AdServices covers it deterministically. Several non-Apple networks at once: an MMP's real job today is collecting and deduplicating SKAdNetwork/AdAttributionKit postbacks across networks, which is worth paying for at a scale most indies haven't reached.

Can SKAdNetwork tell me which users came from which campaign?

No, and no setting changes that. Campaign-level counts and conversion values are the entire product. Anything claiming user-level paid-social on iOS is either modeled (estimates) or fingerprinting (against the rules).

Is AdAttributionKit replacing SKAdNetwork?

Yes, gradually — same aggregate model, plus alternative marketplaces and re-engagement, with interoperability during the transition. Adopt it when your ad networks ask; expect no new user-level data from it.

Should I still show the ATT prompt?

If your measurement is AdServices plus conversion values, skipping the prompt costs you almost nothing — consent mainly adds click-level detail to the Search Ads payload. One less scary dialog in onboarding is usually worth more than the extra field.

FolioKit is analytics for indie iOS developers — Apple Search Ads attribution and SKAN conversion values built into the SDK, joined to RevenueCat revenue on one user record, no MMP and no ATT prompt.

Get early access