A user taps a referral link from a friend, installs your app, opens it, and lands on the generic welcome screen. The referral code is gone. The promo that motivated them to download in the first place has vanished. You just lost your best conversion moment.
Contextual deep linking is the solution. It combines deep link routing with attached metadata so your app knows not just where to send a user, but who they are and why they came. Even if the app wasn't installed when they tapped the link.
This guide covers the mechanics, the use cases, the URL design, and the SDK code you need to actually build it.
What Makes a Deep Link "Contextual"
A plain deep link is a URL that routes a user to a specific screen inside an app. Something like myapp://products/42 opens the product detail page for item 42. That's routing.
A contextual deep link carries additional data alongside the destination. The same link might encode a referral user ID, a promo code, a campaign source, or a content share token. For a detailed look at how to structure these values, see our guide on deep link parameters. The app reads all of that on first open and acts on it immediately.
The destination and the context travel together. When the user taps the link, both pieces survive the journey through the App Store or Google Play and arrive in your app's first-launch callback.
The mechanism that makes this possible for users who don't yet have the app installed is called deferred deep linking. The "deferred" part just means the link fires after the install rather than immediately. Contextual deep linking is deferred deep linking with richer data attached.
How Context Survives the Install
When someone without your app taps a contextual deep link, the app isn't there to receive it. Here is how platforms bridge that gap.
Fingerprinting
The most widely used technique is probabilistic matching. When the user clicks the link, the platform records a fingerprint: IP address, device type, OS version, screen resolution, language, and timestamp. When the user installs and opens the app, the SDK sends the same set of signals. The platform compares them and, if they match within a short time window (typically under 15 minutes), attributes the install to that click and delivers the stored context.
Fingerprinting has no dependency on any persistent device identifier, which makes it work across platforms and survive user privacy settings. The tradeoff is accuracy. It is probabilistic, not certain. Shared IP addresses (corporate Wi-Fi, mobile carrier NAT) and short time windows increase match confidence; long delays or VPN use decrease it.
Clipboard-Based Matching
On iOS, some platforms briefly write an encoded token to the pasteboard at click time and read it back on first app open. iOS 16 introduced a privacy notice that appears whenever an app reads the clipboard without user interaction. Most well-maintained SDKs ask for explicit permission or have stopped using this method to avoid the notice. It's worth knowing it exists, but you shouldn't design your implementation around it.
SKAdNetwork and Privacy-Preserving Attribution (iOS)
Apple's SKAdNetwork provides install attribution without any device-level identifiers. It is useful for measuring campaign performance, but it does not deliver contextual data back to the app. SKAdNetwork tells you that a campaign produced an install; it does not tell your app what referral code was attached. For contextual data delivery, you still rely on fingerprinting or server-side matching.
Google Play Install Referrer (Android)
Android has a cleaner built-in option. The Play Install Referrer API lets you attach a referrer query parameter to any Play Store URL. When the user installs and opens the app, the InstallReferrerClient returns that parameter verbatim. You can encode your entire context payload in that string. It is deterministic, not probabilistic, which makes it the most reliable method on Android.
Use Cases
Referral Programs with Attribution
A referral link encodes the referring user's ID. When the new user installs and opens the app, the SDK callback fires with that ID. Your app creates the new account, credits the referrer, and shows the new user a confirmation screen: "You were referred by Alex. You both get a free month." That entire experience depends on the context surviving the install.
Without contextual deep linking, the new user arrives on a generic onboarding screen. They have to manually enter a referral code (most won't), and your conversion rate drops. For a complete walkthrough of building this kind of referral flow, see our referral deep links guide.
Personalized Onboarding
An email campaign targets users who browsed a specific product category on your website. Each link encodes the category. After install, the onboarding wizard skips generic questions and goes straight to content relevant to that interest. The user's first experience feels relevant rather than generic. Our guide on personalized onboarding flows covers how to design these context-aware first-run experiences in detail.
Promo Codes
A social media ad or influencer campaign uses a unique promo code per creator. The link encodes the code. After install, the app automatically applies it at checkout or prompts the user to use it. No manual entry required.
Content Sharing
A user in your app shares a piece of content with a friend who doesn't have the app. The share link encodes the content ID. When the friend installs, they land directly on that content instead of a home screen with nothing to orient them. This is one of the highest-value uses of contextual deep links because it turns every share into a guided install flow.
Designing the URL Parameters
The link your platform generates at click time needs to carry the context in a way that survives redirects, App Store visits, and URL encoding. A common approach is to put the contextual data in query parameters on the initial link and have the platform store them server-side, keyed to a short-lived token.
A minimal parameter set might look like this:
https://link.tolinku.com/ref?
ref_id=user_8821
&promo=SUMMER25
&content_id=article_557
&utm_source=email
&utm_campaign=summer_launch
Keep the parameter names short and consistent across campaigns. Avoid encoding personally identifiable information directly in the URL (more on that in the privacy section). Use opaque tokens or IDs that resolve server-side rather than embedding names, email addresses, or phone numbers in the link.
For the Play Store referrer on Android, the entire query string gets URL-encoded and appended to the Play Store URL:
https://play.google.com/store/apps/details?
id=com.yourapp
&referrer=ref_id%3Duser_8821%26promo%3DSUMMER25
The InstallReferrerClient will return the decoded string ref_id=user_8821&promo=SUMMER25 which you parse normally.
Reading Context on First App Open
iOS (Swift)
With Tolinku's iOS SDK, you call the context retrieval method in your app delegate or @main struct after the SDK initializes.
import TolinkuSDK
@main
struct MyApp: App {
init() {
Tolinku.configure(apiKey: "tolk_pub_your_key_here")
}
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
Tolinku.getFirstLaunchContext { result in
switch result {
case .success(let context):
if let refId = context.params["ref_id"] {
// Credit the referrer
ReferralService.credit(referrerId: refId)
}
if let promo = context.params["promo"] {
// Pre-apply promo code
CartService.applyPromo(code: promo)
}
if let contentId = context.params["content_id"] {
// Navigate to the shared content
NavigationService.navigate(to: contentId)
}
case .failure(let error):
// No context found or attribution expired
print("No launch context: \(error.localizedDescription)")
}
}
}
}
}
}
The getFirstLaunchContext method should only be called once, on first launch. Subsequent opens use getLinkContext from the scene or activity callbacks for standard Universal Link handling.
Mark the first-launch check as complete in UserDefaults or your app's preferences storage so you don't repeat it on every open:
if !UserDefaults.standard.bool(forKey: "hasCheckedInstallContext") {
UserDefaults.standard.set(true, forKey: "hasCheckedInstallContext")
Tolinku.getFirstLaunchContext { result in
// handle context
}
}
Android (Kotlin)
On Android, call the context check in your launcher Activity's onCreate after SDK initialization. The SDK checks both the Play Install Referrer API and fingerprint matching and returns whichever result is available.
import com.tolinku.sdk.Tolinku
import com.tolinku.sdk.model.LinkContext
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Tolinku.configure(this, apiKey = "tolk_pub_your_key_here")
val prefs = getSharedPreferences("app_prefs", MODE_PRIVATE)
if (!prefs.getBoolean("has_checked_install_context", false)) {
prefs.edit().putBoolean("has_checked_install_context", true).apply()
Tolinku.getFirstLaunchContext { result ->
result.onSuccess { context: LinkContext ->
context.params["ref_id"]?.let { refId ->
ReferralService.credit(referrerId = refId)
}
context.params["promo"]?.let { promo ->
CartService.applyPromo(code = promo)
}
context.params["content_id"]?.let { contentId ->
NavigationService.navigate(to = contentId)
}
}
result.onFailure {
// No install context found
}
}
}
// Also handle the standard deep link for returning users
intent?.data?.let { uri ->
Tolinku.handleLink(uri) { linkContext ->
// route to the destination
}
}
}
}
The Play Install Referrer check runs asynchronously but typically resolves within a second or two. The SDK handles the async lifecycle and delivers the result on the main thread.
Privacy Considerations
Contextual deep linking involves collecting and processing user data. A few things to keep in mind.
Don't put PII in URLs. Referral codes, content IDs, and campaign slugs are fine as URL parameters. Email addresses, phone numbers, and full names are not. Use opaque user IDs that only resolve to personal data server-side, behind authentication.
Fingerprinting and consent. Probabilistic matching uses IP address and device signals. In jurisdictions covered by GDPR or the CCPA, this may constitute processing of personal data. Review your privacy policy and, if required, collect consent before the SDK attempts a fingerprint match. Some platforms offer a consent-gated SDK initialization mode for this reason.
Attribution window expiry. Store link context server-side with a short TTL (time to live). If a user installs three weeks after clicking a link, the fingerprint match is unreliable and the data may be stale. Most platforms use a window of 7-30 days. Discard context outside that window rather than delivering potentially misleading attribution.
Android 12+ and the referrer API. The Play Install Referrer API does not require any special permissions and is not affected by the QUERY_ALL_PACKAGES restriction introduced in Android 11. It is the privacy-preserving choice on Android precisely because it avoids device identifiers entirely.
What to Do When There Is No Context
Not every install comes from a contextual link. Organic installs, App Store search, and direct brand awareness don't carry parameters. Your getFirstLaunchContext callback will return an error or an empty result in those cases.
Handle this gracefully. Show the default onboarding flow. Don't block on context retrieval. Set a timeout (the SDK should have one built in) and proceed without context if the check doesn't complete within a few seconds.
The zero-context case is your baseline experience. Contextual deep linking enhances that baseline for users who arrive through tracked links. It should never be required for the app to function.
Putting It Together
Contextual deep linking is not a single feature, it is a combination of URL design, server-side storage, attribution matching, and SDK callbacks. Get each layer right and you have a system that greets every link-driven install with a personalized experience.
The highest-leverage places to start are referrals and content sharing. Both have clear conversion impact, both are straightforward to instrument, and both make the difference between a user who immediately understands why they installed your app and one who has to figure it out from scratch.
For a full walkthrough of the deferred linking mechanics, see the deferred deep linking concepts doc.
Get deep linking tips in your inbox
One email per week. No spam.