Implementation of Deferred Deep Linking in Mobile Application
Normal deep link works only if app installed. User taps link, app not installed — link goes to store, context lost. Deferred deep linking solves exactly this: user installs app and on first launch lands on screen they tapped. Critical for ad campaigns, referral programs and content sharing.
How it technically works
Deferred deep linking mechanics built on several layers.
Layer 1: parameter passing before install. Classic approach — fingerprinting: on link transition server saves parameters (campaign, content, referrer) together with browser fingerprint (IP, user agent, screen resolution). After install app makes request to server with its fingerprint — server matches and returns saved parameters.
Fingerprinting accuracy — 70–85%. Sufficient for most marketing tasks, but not for financial operations.
Layer 2: Google Play Referrer (Android). More reliable than fingerprinting. On link transition with &referrer= parameter Google Play saves it and sends to app on first install via InstallReferrerClient:
val referrerClient = InstallReferrerClient.newBuilder(context).build()
referrerClient.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(responseCode: Int) {
if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) {
val referrer = referrerClient.installReferrer.installReferrer
// parse UTM parameters from referrer string
}
}
override fun onInstallReferrerServiceDisconnected() {}
})
Layer 3: SKAdNetwork / StoreKit AdNetwork (iOS). Apple closed fingerprinting on iOS 14.5+ through App Tracking Transparency. For iOS deferred deep linking works only through:
- Clipboard — copy parameters to buffer on landing page, app reads on first launch (requires
UIPasteboard.general.string, iOS 16+ shows system prompt) - Third-party SDK (Branch, AppsFlyer, Adjust) using deterministic matching via IDFA (with permission) and SKAdNetwork for attribution without it
Implementation through Branch.io
Branch — most complete deferred deep linking tool. Supports Android (Play Referrer + fingerprint), iOS (clipboard + SKAdNetwork + deterministic), web fallback.
Android SDK:
// Application.onCreate()
Branch.getAutoInstance(this)
// Activity.onStart()
Branch.sessionBuilder(this)
.withCallback { referringParams, error ->
if (error == null && referringParams != null) {
val screen = referringParams.getString("screen")
val itemId = referringParams.getString("item_id")
if (referringParams.getBoolean("+clicked_branch_link", false)) {
// navigate to right screen
navigateTo(screen, itemId)
}
}
}
.withData(intent?.data)
.init()
iOS SDK:
Branch.getInstance().initSession(launchOptions: launchOptions) { params, error in
guard error == nil, let params = params else { return }
if let clicked = params["+clicked_branch_link"] as? Bool, clicked {
let screen = params["screen"] as? String
self.navigateTo(screen: screen)
}
}
Universal links (iOS) and App Links (Android) configured in parallel — Branch generates needed apple-app-site-association and assetlinks.json via dashboard.
Custom implementation without third-party SDK
If Branch/AppsFlyer excessive (no budget for enterprise plan or policy against third-party SDK), can implement simplified version:
- Create endpoint
/deferred?screen=product&id=123— saves parameters + fingerprint in Redis with TTL 24 hours - On Android: install referrer via
?referrer=screen%3Dproduct%26id%3D123in Play Store link - On first launch: read via
InstallReferrerClient(Android) or make request with fingerprint (iOS) - Navigate to right screen
Limitation: on iOS accuracy ~70–75%, Android via Play Referrer — ~95%.
Testing
Deferred deep linking extremely difficult to test in dev environment: need real install from store or test track (Firebase App Distribution / TestFlight). For Branch — testMode allows emulating clicks in debug build.
Required test cases:
- Install on clean device from link
- Transition via link with already installed app (normal deep link)
- Transition via link, delete and reinstall (parameters shouldn't apply again)
- Transition without Branch link click (organic install — no parameters)
What's included
Choose strategy by platforms and budget (Branch/AppsFlyer vs custom implementation), configure Universal Links and App Links, implement SDK integration with navigation to right screens, test all install scenarios on real devices. Document parameter scheme for marketing team.
Timeline: 5–10 days including domain setup, testing all install scenarios and navigation integration.







