Skip to content
CodeOnAir
← All posts

Deferred deep linking on iOS without IDFA: how matching works

After App Tracking Transparency, how does a link survive the App Store install on iOS? Signal matching, the clipboard, attribution windows, accuracy and Apple's privacy rules.

CodeOnAir team25 October 20269 min read

Deferred deep linking means a new user taps a link, installs your app, and lands on the screen the link pointed to on the very first open. On Android there's a clean way to do it. On iOS there isn't: the App Store passes nothing from the tap to the app, and since App Tracking Transparency (ATT), the advertising identifier is usually unavailable too.

So how does deferred deep linking work on iOS today? This post explains the methods that work without the IDFA, how accurate each one is, where they fail, and what Apple's privacy rules say. It also describes exactly how CodeOnAir does it, so you can judge it yourself. If you're new to the idea, start with what deferred deep linking is.

Why iOS is harder than Android

On Android, the Play Store hands the newly installed app an install referrer: a string your link service set when it sent the user to the store. If that string carries a click ID, the first open can be matched to the exact click. No guessing.

On iOS, the App Store has no equivalent. The user taps your link in Safari or WhatsApp, the App Store opens, they install, and your app starts with no information about where they came from. Whatever connects the tap to the first open has to happen outside the store.

What changed with ATT and the IDFA

The IDFA (identifier for advertisers) is a per-device ID that apps could once read freely. Since iOS 14.5, apps must ask permission through ATT before reading it. Apple's advertisingIdentifier documentation says it returns all zeros (00000000-0000-0000-0000-000000000000) if the app hasn't requested authorization, or if the user declined.

The IDFA was never available on a web page anyway, so it couldn't link a tap in Safari to an install by itself. It mattered for ad networks that could see it on both sides. For deferred deep linking from your own links, today's methods don't use it at all.

Apple's own attribution framework, AdAttributionKit, attributes ad campaigns in a privacy-preserving way. It's for measuring campaigns, not for telling your app which screen to open for one user, so it doesn't replace deferred deep linking.

Method 1: Matching on device signals

This is what most services use by default. When the link is tapped, the service records a few properties of the request. When the app opens for the first time, the SDK sends the same kinds of properties. If they line up within a short time, the install is credited to that click.

Typical signals:

  • IP address, the strongest signal, since the phone usually has the same public IP for both requests.
  • Operating system and its version, for example iOS 18.1.
  • Language and time zone.
  • Time since the click. The closer together, the more likely they're related.
  • Device model, which is weak on iOS: Safari's user agent only says "iPhone".

How CodeOnAir scores a match

Here's what our matching code does, in order:

  1. Clicks are recorded with the platform, OS version, device type, language, country and a hashed IP address. The raw IP isn't stored. The landing page also reports the browser's time zone.
  2. On first open, the SDK sends a random install ID it creates itself, plus OS version, model, language and time zone. No IDFA, and no IDFV.
  3. Candidates are recent clicks on your own app's links from the same hashed IP and the same OS that haven't been matched yet.
  4. Each candidate gets a score. The same IP and OS are required. A matching language, time zone and OS version raise the score; a mismatch lowers it. Older clicks score slightly lower.
  5. The best score wins if it's above a minimum and the click is inside the link's attribution window. Each click can be matched to at most one install.

The SDK then hands your app the link's path and parameters with isDeferred: true, the method used (probabilistic) and the score as confidence. Exact methods report a confidence of 1.

Choosing the attribution window

The window is how long after a tap an install can still be credited to it. It's a trade-off:

  • Short windows (minutes to an hour) mean fewer wrong matches, but a user who installs the next morning won't get the deep link.
  • Long windows (a day or more) catch slow installers, but give more room for a different person on the same network to be matched.

In CodeOnAir you can set the window per link: up to 1 hour on Free, 24 hours on Starter and Growth, and 7 days on Scale (pricing). Referral and invite links often suit longer windows; paid campaign links usually suit shorter ones.

Where signal matching goes wrong

Be clear-eyed about its failure modes:

  • Shared IP addresses. Office Wi-Fi, college networks and mobile carriers that put many users behind one address make two people on the same iOS version look alike. That's the main source of wrong matches.
  • Network changes. Tap on Wi-Fi, install and open on mobile data: the IPs differ and there's no match.
  • iCloud Private Relay. For iCloud+ users with Private Relay on, Safari connects to websites through a temporary IP address (Apple Support). The tap may then arrive from a different IP than the app's first request.
  • VPNs, for the same reason.
  • Slow installers who open the app after the window has closed.

None of these produce an error. You just get no match, or occasionally the wrong one. That's why the next method exists.

Method 2: The clipboard

The clipboard is the one thing that survives the trip through the App Store. The idea:

  1. The link opens a small landing page with a Get the app button.
  2. When the user taps it, the page copies a short one-time token to the clipboard, then sends them to the App Store.
  3. On first launch, the app reads the clipboard. If it finds the token, it sends it to the service, which looks up the exact click.

That's an exact match, with no dependence on IP addresses. The costs:

  • iOS shows the user a paste prompt. Apple's UIPasteboard docs say that since iOS 14 the system notifies the user when an app reads pasteboard content from another app without user intent, and current iOS versions ask the user to allow the paste. If they tap Don't Allow, there's no clipboard match.
  • An extra tap. The landing page needs a button, because a page can only write to the clipboard after a user gesture.
  • The clipboard can be overwritten if the user copies something else before opening the app.

In CodeOnAir this is opt-in. Turn on clipboard matching (Advanced deferred deep linking) in your app's settings, and iOS links show the landing page with a Get the app button that copies a dlclick: token. In the app, pass clipboardMatching: true to the iOS SDK's DeepLinkConfiguration, or a clipboard getter to the React Native SDK. The SDK only reads the clipboard on the first launch, and clears it after it finds a token. If there's no token, signal matching still runs as a fallback.

Use the confidence in your app

You don't have to treat every deferred link the same. A product page can open on a probable match; a referral reward with money attached deserves more certainty:

import DeepLink from "@codeonair/deeplink-react-native";

DeepLink.init();

DeepLink.onLink((link) => {
  if (!link.isDeferred) return navigate(link.path, link.params);

  const exact = link.matchMethod === "install_referrer" || link.matchMethod === "clipboard";
  if (link.path === "/invite" && !exact && link.confidence < 0.8) {
    // Probably right, but ask before crediting anyone.
    return navigate("/confirm-invite", link.params);
  }
  navigate(link.path, link.params);
});

The 0.8 is your choice, not a magic number. A "Were you invited by Asha?" screen costs one tap, and protects your referral programme from crediting the wrong person.

Privacy: what Apple's rules say

This part matters, so here are Apple's words rather than ours. Apple's User Privacy and Data Use page:

  • Defines tracking as "linking user or device data collected from your app with user or device data collected from other companies' apps, websites, or offline properties for targeted advertising or advertising measurement purposes", and sharing data with data brokers.
  • On fingerprinting: "you may not derive data from a device for the purpose of uniquely identifying it."
  • On deferred deep linking tools: ATT permission is needed "if your application uses any third-party services that pass unique identifiers or create a shared identity of the user between applications from different companies for ad targeting, ad measurement, or sharing with a data broker."

What we take from that, and how CodeOnAir is built around it:

  • Keep it first-party. Matches only use clicks on your own app's links. We don't build a profile across other companies' apps, and we don't sell or share click data.
  • Don't keep identifiers you don't need. IP addresses are hashed, never stored raw. The SDKs don't read the IDFA, the IDFV or the Android advertising ID; the install ID is a random value the SDK creates.
  • Keep windows short for anything to do with advertising, and prefer exact methods (Android's install referrer, the opt-in clipboard) when certainty matters.
  • Disclose it. Mention link attribution in your privacy policy and App Store privacy details.

We're not your lawyers, and Apple's rules can change. If you use deferred deep links for ad measurement, or combine link data with data from other companies, review it with your privacy team. Whether you need the ATT prompt depends on what you do with the data, not on the link service alone.

A testing checklist

  • Delete the app, tap the link in Notes or Messages on the iPhone, install from TestFlight or the App Store, and open it. The deferred link should arrive on the first launch.
  • Repeat on mobile data after tapping on Wi-Fi, to see a missed match.
  • With clipboard matching on, check both answers to the paste prompt.
  • Log matchMethod and confidence during testing so you know which method fired.
  • Make sure DeepLink.init() runs on the very first launch, before any onboarding screen. A late init can miss the moment the app is still "first open".

FAQ

Does deferred deep linking work on iOS without the IDFA?

Yes. It uses either device signals (IP address, OS version, language, time zone and timing) within a short window, or an opt-in clipboard token. Neither needs the IDFA.

Do I need to show the ATT prompt for deferred deep links?

Apple says you do if the service passes unique identifiers or creates a shared identity across different companies' apps for ad targeting, ad measurement or data brokers. For first-party routing, such as opening an invite screen, it depends on how you use the data. Check Apple's guidance with your privacy team.

How accurate is probabilistic matching on iOS?

It depends on your users' networks and your attribution window. Shared IPs cause wrong matches; network changes and Private Relay cause missed ones. Measure it on your own traffic, and use confidence to decide what to trust.

Why does my app show "Allow Paste" on first launch?

Because clipboard matching is on and the app read the clipboard. iOS asks the user before an app reads content copied in another app. Turn clipboard matching off if you'd rather not show it.

Is Android deferred deep linking also probabilistic?

Not when the Play Install Referrer is available. It carries the click ID through the install, so the match is exact. CodeOnAir falls back to signals only if there's no referrer.

Get deferred deep links that say how sure they are

CodeOnAir AppLinks gives you exact matching on Android, signal matching and opt-in clipboard matching on iOS, per-link attribution windows, and the method and confidence on every link your app receives. How AppLinks work follows one link from tap to screen. Moving from Firebase? See our Firebase Dynamic Links alternative page. Sign-ups are currently by invitation: request access.


Apple quotes checked on 25 October 2026 against Apple's User Privacy and Data Use page, the advertisingIdentifier and UIPasteboard documentation, and the iCloud Private Relay support article.

Your first AppLink in five minutes.

Create an app, pick a subdomain, and share a link that opens your app. Try Growth free for 30 days — no card needed.