Cross-Platform Attribution: Stitching Web, iOS and Android

Cross-platform attribution is the work of proving that the person who tapped an ad on the mobile web, the person who installed your iOS app, and the person who logged in on Android are one user, not three. After ATT and Apple's fingerprinting crackdown, only one stitch method still holds up reliably: deterministic login stitching, where the same account identifier appears on every surface. Everything else has become a probability, an aggregate, or a policy violation.

I've shipped attribution SDKs into apps with tens of millions of installs, and the pattern I keep seeing is teams treating "cross-platform" as a checkbox their MMP handles. It doesn't, not anymore. So let's walk through what actually happens on each surface, which identifiers survive the trip, and where the legal line sits for each approach.

What "stitching" actually means on-device

Here's the mechanical version. A user exists as a different identity on every surface until something ties those identities together.

On the mobile web, they're a first-party cookie or a localStorage value scoped to your domain. On iOS, they're either an IDFA (only if they opted into tracking) or, more commonly, an IDFV that's unique to your developer account and useless across companies. On Android, they're the GAID, which the user can reset or zero out. And in your own backend, they're an account ID the moment they authenticate.

Stitching is the join. You're trying to write a row that says "web-cookie-abc123 and ios-idfv-def456 and account-99 are the same human." The question is what key you join on. That key determines everything downstream, including whether the whole thing is legal.

There are really three families of join key. One of them still works cleanly.

The three stitch methods, and what each can still do

Method Join key Post-ATT coverage Cross-app? Privacy-legality
Deterministic (login) Your own account ID / hashed email High, but only for logged-in users Yes, within your own properties Clean. First-party data you already control.
Deep link (deferred) Click token passed through the store Medium; drops without a device match on iOS Yes, for the click-to-install hop Fine if you don't fingerprint to match; shaky if you do
Probabilistic IP + device signals, statistically matched Low and falling on iOS; better on Android Yes, across publishers Banned on iOS by Apple; gray on Android

Deterministic login stitching

This is the durable one, and it's almost boring how well it works. When a user logs in on web and later logs in on your iOS app, you have the same account ID on both. You emit that ID with every event. Your analytics or warehouse joins on it. Done. No IDFA, no match window, no postback.

The catch is obvious: it only covers authenticated users. Everything before signup is anonymous, and that pre-login activity is exactly where the classic pitfall lives. If you don't alias the anonymous ID to the account ID at the identify moment, all that pre-signup behavior gets orphaned and your "new user" counts inflate. That merge step is its own topic, and I'd point you at the identity-resolution write-up for the read-time versus write-time tradeoffs, because getting it wrong quietly corrupts retention curves.

But for the join that matters here, login stitching is the only method that survived the last three years intact. Switchboard's 2025 identity-resolution analysis lands in the same place from the marketing-ops side: first-party authenticated data is now what keeps cross-platform coverage above roughly 60%, with deterministic matching as the foundation and probabilistic bolted on only as a reach extender.

Deep linking handles a narrower job: carrying context from a click to an app open. Regular deep links are easy because the app is already installed and the OS routes the URL. Deferred deep links are the hard case, where the app isn't installed yet, so you have to hold the click context through an App Store visit and hand it to the app on first launch.

On Android, this still works acceptably because Google's Install Referrer passes a referrer string through Play, deterministically, no fingerprinting required. On iOS, there's no equivalent public referrer for App Store installs. So historically, deep-link vendors matched the click to the install probabilistically, by fingerprinting the device on both ends. That's the part that broke.

If you own the click surface and the app, you can still do clean deferred deep linking with your own token passed through a universal link or a pasteboard handoff on first launch. If you're relying on a vendor matching an anonymous ad click to an install, you're back in probabilistic territory, with all its costs. I go deeper on the vendor trade-offs in our deep-linking platform comparison.

Probabilistic stitching

Probabilistic matching infers that two sessions are the same user from signals like IP address, screen resolution, OS version, timezone, and behavior timing. When it works, it extends coverage to users you could never identify deterministically. Airbridge's post-IDFA accuracy write-up puts controlled-condition accuracy at around 70 to 90 percent, and meaningfully lower on shared networks or when iCloud Private Relay is masking the IP. On a corporate wifi or a household behind one NAT, "same IP" means almost nothing.

And on iOS it's not just inaccurate. It's disallowed.

The Apple line nobody should be fuzzy about

Apple has banned fingerprinting since iOS 14.5, and the wording is unambiguous. Per Apple's own guidance, quoted in Mysk's May 2024 breakdown of the Required Reason API rollout, "regardless of whether a user gives your app permission to track, fingerprinting is not allowed." That last clause trips people up. Even a user who tapped "Allow" on the ATT prompt does not give you license to fingerprint. ATT consent covers using the IDFA. It does not resurrect device-signal matching.

The enforcement teeth arrived on May 1, 2024, when Apple began requiring a declared reason in the privacy manifest for a set of "required reason APIs" (disk space, system boot time, file timestamps, active keyboard, user defaults) that were the raw material for fingerprints. Ship an app that touches those APIs without a valid declared reason and it gets rejected. This isn't a knob you tune with consent copy. It's a policy floor.

So when a probabilistic vendor tells you they get you great iOS match rates, the honest question is what signals they're combining and whether that's a fingerprint by another name. The docs don't spell out every gray case, and testing is how you find the edges. But "we match iOS installs probabilistically" and "we don't fingerprint" cannot both be fully true.

Why the aggregate frameworks don't stitch anything

People sometimes assume SKAdNetwork or its successor solves cross-platform attribution. They don't, and it's worth being precise about why.

SKAN was built to attribute app installs to ad campaigns in aggregate, privately. It sends a postback, and per SplitMetrics' guide, those postbacks go directly to the individual ad networks, not to a centralized measurement partner. So your attribution data scatters across every network you ran on. SKAN also doesn't attribute owned or organic installs at all, only paid install campaigns. There's no user-level identifier in it by design, which is the whole point of the framework and also why it can't stitch a web session to an app open. You get a conversion value and a campaign, not a person.

AdAttributionKit, the successor Apple expanded at WWDC 2025 and shipped into iOS 18.4, adds re-engagement measurement and configurable windows on top of the same aggregate, privacy-preserving model. Useful for what it is. Still not a cross-platform identity graph. If your plan for stitching web to app leans on SKAN or AdAttributionKit, you've picked a tool built to prevent exactly the join you're trying to make.

And the postbacks, true to form, arrive whenever they feel like it. SKAN's timers are deliberately randomized, so you cannot use arrival time as a signal for anything. Plan around delays measured in hours to days, not seconds.

The coverage math, honestly

The reason deterministic login stitching wins isn't ideology. It's that the alternatives keep shrinking. ATT opt-in sits somewhere around 15 to 25 percent globally in Business of Apps' running 2026 dataset, with games near 19 percent and non-game apps closer to 12. Weather apps push 40 percent, news and medical often sit under 5. Singular reported opt-in rates dipping into the mid-teens through 2024. Whatever your category's number, it means the majority of your iOS users open the app with no IDFA available, so anything keyed on IDFA covers a minority and a declining one.

Login coverage moves in the opposite direction. Every user who signs up is deterministically stitchable from that point forward, on every surface where they authenticate, forever, with no consent prompt because it's your own first-party account relationship. The more of your product sits behind a login, the more of your funnel you can measure cleanly. That's the lever worth pulling: get users to authenticate earlier, and design the anonymous-to-identified merge so nothing gets orphaned.

Here's the practical hierarchy I'd give a team building this today:

  • Emit a stable first-party ID on every surface, and alias anonymous IDs to the account ID at login. This is your spine.
  • Use the Android Install Referrer and your own universal-link tokens for deterministic deep linking where you own the click.
  • Treat probabilistic matching as a labeled, low-confidence supplement on Android only, and keep it off iOS entirely.
  • Use SKAN / AdAttributionKit for what they're for: aggregate paid-install measurement, in their own reporting lane, never as your identity graph.

Where the tooling sits

Most mobile measurement partners now organize around this same reality. AppsFlyer, Adjust, Branch, and Singular all lead with deterministic, login-based identity and treat probabilistic matching as a shrinking fallback, because Apple gave them no other durable option. Analytics platforms that unify web and native under one first-party SDK, Kixo among them with its iOS, Android, and Web SDKs plus deferred deep links, land in the same design: the stitch happens on your own account identifier, not on a device fingerprint. The honest trade-off across all of them is coverage of anonymous, pre-login traffic, which no first-party approach fully solves. If a vendor claims otherwise for iOS, ask exactly which signals they match on.

For the deeper build, including how to lay out consent and the identity join so the whole thing stays defensible, I've written a privacy-first attribution reference architecture that maps the data flow end to end.

The uncomfortable summary

Cross-platform attribution used to be a modeling problem: how cleverly can we match devices we don't have permission to match? Apple answered that by removing the option. What's left is an infrastructure problem instead. Can you get a first-party identifier onto every surface, and can you merge anonymous to identified without corrupting your counts?

If yes, you have durable cross-platform attribution. If you're still chasing device matches on iOS to fill the gap, you're building on a signal Apple has spent five years dismantling, and it will keep getting worse. Pick the boring, deterministic spine. It's the only one that'll still be standing next year.