Deferred Deep Linking

Deferred deep linking that survives the install

WarpLink carries the link's destination through the store install and delivers it on first launch, with a confidence score built from the match's signal type and the time since the tap. It works on iOS, Android, React Native, and Flutter through one SDK, with no advertising identifier and no App Tracking Transparency prompt.

What is deferred deep linking?

Deferred deep linking sends a new user to the screen a link named, even when they had to install the app first. The link cannot travel through the App Store or the Play Store, so WarpLink records the tap, matches the first app open back to it, and hands your app the original link with a confidence score.

How it works

  1. Someone without the app taps the link. We record the click with the signals a browser exposes: the request address, the device language, and the timezone. The visitor then goes to the App Store, the Play Store, or the fallback set on the link.

  2. The store install drops the URL. The new app never receives the tapped URL. On Android, a Play Store destination carries an install referrer naming the link through the install. On iOS nothing travels with it, so the click waits inside the link's match window.

  3. The app opens for the first time. The SDK detects first launch and sends the device language and timezone, plus the install referrer on Android or the identifier for vendor (IDFV) on iOS. The server reads the request address itself, because an app cannot see its own public IP.

  4. The server matches the install to a click. We read the install referrer first, then the IDFV for a check this install already made, then a probabilistic match on address, language, and timezone. The first rung that matches wins.

  5. The SDK delivers the original link. The result reaches your onLink callback with isDeferred set, the link's destination and deep link URL, a match type, a confidence score from 0.0 to 1.0, and matchGuaranteed.

  6. Your app routes by confidence. Open the exact screen on a strong match and a welcome on a weak one. The check runs once per install, and later launches make no extra request.

Key facts

  • A Play Install Referrer match on Android is exact: it scores 1.0 and sets matchGuaranteed.
  • Probabilistic matches score up to 0.85 inside the first hour and lower as the hours pass.
  • The match window is 6 hours by default and can be set from 1 to 24 hours per link.
  • No advertising identifier (IDFA or GAID) and no App Tracking Transparency prompt.
  • The iOS, Android, React Native, and Flutter SDKs are all at version 1.1.1, open source under the MIT license.
  • Included on every plan with deep linking, install attribution, and real-time analytics.
  • Plans start at Free ($0, 10K clicks a month) and run through Starter ($19), Growth ($49), and Scale ($99) to Unlimited ($149, no click ceiling).

Matching and confidence referencePlans and pricing

A standard deep link opens a screen in an app that is already installed: the operating system hands the URL straight to the app. A deferred deep link covers the visitor who has to install first. The URL cannot pass through the store, so a server matches the first open back to the tap and returns the link then.

Compared onStandard deep linkDeferred deep link
App installed at the tapYesNo, the tap leads to the store
Install stepNoneAn App Store or Play Store install comes first
How the app gets the linkUniversal Links or App Links hand over the URLThe SDK asks the server on first launch
Context preservedThe full URL, including its queryThe destination and the deep link URL, with any query on it
CertaintyExact: the operating system delivers the URLExact with the Play Install Referrer, a scored match otherwise

How iOS and Android match an install

Android can name the click exactly, because the Play Store carries a referrer through the install. On iOS, a first install is matched probabilistically on network, language, and timezone, and comes back with a confidence score from 0.0 to 1.0.

Compared onAndroidiOS
What survives the storeThe install referrer we add to the Play Store URLNothing
First-install matchExact: the referrer names the linkProbabilistic match on request address, language, and timezone
When the exact path is missingThe probabilistic match covers sideloaded builds, devices without the Play Store, and destinations that are not a Play Store URLProbabilistic matching is the first-install match path.
A repeat check from the same installThe referrer answers it againThe IDFV returns the result the install already got
Confidence1.0 with the referrer, up to 0.85 on the probabilistic matchUp to 0.85, lower as the hours pass
matchGuaranteedTrue for a referrer matchFalse: a probabilistic match carries a confidence score
Permission promptNone, no advertising IDNone, no IDFA and no ATT prompt

Confidence, privacy, and match windows

A probabilistic match is scored from the time since the tap: 0.85 at the top inside the first hour, lower as the hours pass. The match key is a one-way hash. Each tap can be matched only within the link's match window (6 hours by default, 1 to 24 per link), and pending entries expire automatically.

Time since the tapTop probabilistic scoreWhat it is good for
Under 1 hour0.85Open the exact public screen
1 to 3 hours0.65Open the screen, or name it on a welcome
3 to 6 hours0.50Suggest the content on a welcome screen
6 to 24 hours0.30A hint only, for links set past the 6 hour default

Set it up on your stack

  1. Register your app

    Add your iOS bundle ID and team ID, your Android package name, or both. Every organization registers an app before it creates links, and a link tied to that app falls back to its store listings for visitors without it, so the Play Store visit carries the install referrer.

  2. Create a link

    Set the web destination and the in-app path, then choose the match window: 6 hours by default, anywhere from 1 to 24, set per link in the dashboard. It only governs probabilistic matches, so the Android referrer path is unaffected by it.

  3. Ship the SDK and route

    Add the SDK for iOS, Android, React Native, or Flutter and call configure once at launch. The first-launch check runs on its own and delivers a match to your onLink callback with isDeferred set. Keep sign-in on your own authentication.

Handle the first open in each SDK

iOS (Swift)
import WarpLink

WarpLink.configure(
    // SDK key from Keys > SDK
    apiKey: "wl_live_yoursdkkeyhere000000000000000000",
    options: WarpLinkOptions(onLink: { result in
        guard case .success(let deepLink) = result, let deepLink else { return }

        if deepLink.isDeferred {
            // Survived the App Store install.
            navigate(to: deepLink.deepLinkUrl ?? deepLink.destination)
        } else {
            navigate(to: deepLink.destination)
        }
    })
)
Android (Kotlin)
WarpLink.configure(
    context = this,
    // SDK key from Keys > SDK
    apiKey = "wl_live_yoursdkkeyhere000000000000000000",
    options = WarpLinkOptions(onLink = { result ->
        result.onSuccess { deepLink ->
            if (deepLink.isDeferred) {
                // Survived the Play Store install.
                navigateTo(deepLink.deepLinkUrl ?: deepLink.destination)
            } else {
                navigateTo(deepLink.destination)
            }
        }
    })
)
React Native
import { WarpLink } from '@warplink/react-native'

WarpLink.configure({
  // SDK key from Keys > SDK
  apiKey: 'wl_live_yoursdkkeyhere000000000000000000',
  onLink: ({ deepLink }) => {
    if (!deepLink) return

    if (deepLink.isDeferred) {
      // Survived the store install.
      navigateTo(deepLink.deepLinkUrl ?? deepLink.destination)
    } else {
      navigateTo(deepLink.destination)
    }
  },
})
Flutter
import 'package:warplink_flutter/warplink_flutter.dart';

// Call from your root widget's initState
WarpLink.configure(
  // SDK key from Keys > SDK
  apiKey: 'wl_live_yoursdkkeyhere000000000000000000',
  onLink: (event) {
    if (event is! LinkEvent) return;
    final deepLink = event.deepLink;

    if (deepLink.isDeferred) {
      // Survived the store install.
      navigateTo(deepLink.deepLinkUrl ?? deepLink.destination);
    } else {
      navigateTo(deepLink.destination);
    }
  },
);
Sub-10ms redirects·Never blocked·Open source SDKs·MCP server, free on all plans

Frequently Asked Questions

It sends a new iOS user to the screen a link named after they install from the App Store. WarpLink records the tap, then matches the first launch to it on the request address, the device language, and the IANA timezone name. A first install on iOS comes back with a confidence score. It needs no IDFA and no App Tracking Transparency prompt.

Through the Play Install Referrer. WarpLink adds a referrer naming the link when it sends a visitor to a play.google.com store URL, the Play Store carries it through the install, and the SDK reads it on first launch for an exact match at confidence 1.0. The SDK uses the probabilistic match as a second path.

Three kinds matter on mobile. A custom URL scheme such as myapp://item/7 opens an installed app and fails when the app is missing. Universal Links on iOS and App Links on Android are verified https links that open the app when it is installed and the website when it is not. A deferred deep link adds the install case: it carries the destination through the store so the first launch lands on the right screen.

It is true for a deterministic match, such as the Play Install Referrer on Android, and that always scores 1.0. Use matchGuaranteed and the confidence score to choose how specific a screen to open, and keep sign-in on your own authentication.

Nothing on top of your plan. Deferred deep linking, install attribution, and real-time analytics are included on every plan, starting with Free at $0 a month and 10K clicks. Paid plans run from $19 a month for 100K clicks to $149 a month with no click ceiling, and redirects are never blocked at any limit.

Your links should open the app.
Your data should tell you why.

Set up deep linking, attribution, and analytics in minutes. Free to start.

Start building, free

Have a question?