Android deferred deep links
When someone on Android opens your Unolink link, Unolink sends them to Google Play and attaches a referrer. After they install and open your app, Google Play hands that referrer to the app. It tells you which link they came from, plus the deep link and parameters you set on that link. This page does it by hand, with no Unolink SDK, on every plan. With the SDK it's one listener.
1. Give the link a deep link
In the dashboard, open your app, go to Links, and choose ⋯ → Edit on a link. Set:
- Deep link: where the app should open, as a path (
/promo/3for2) or a URI (myapp://promo/3for2). - Parameters (optional): up to ten name/value pairs, for example
offer=3for2.
Edits apply to new clicks within seconds.
2. Add the Install Referrer library
// app/build.gradle.kts
dependencies {
implementation("com.android.installreferrer:installreferrer:2.2")
}
3. Read the referrer once, on first launch
Kotlin:
import android.content.Context
import android.net.Uri
import com.android.installreferrer.api.InstallReferrerClient
import com.android.installreferrer.api.InstallReferrerStateListener
fun readUnolinkReferrer(context: Context, onLink: (deepLink: String?, params: Map<String, String>) -> Unit) {
val prefs = context.getSharedPreferences("unolink", Context.MODE_PRIVATE)
if (prefs.getBoolean("referrer_read", false)) return
val client = InstallReferrerClient.newBuilder(context).build()
client.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(code: Int) {
if (code == InstallReferrerClient.InstallReferrerResponse.OK) {
val referrer = client.installReferrer.installReferrer
val query = Uri.parse("https://unolink.invalid/?$referrer")
if (query.getQueryParameter("unolink_click_id") != null) {
val params = query.queryParameterNames
.filter { it.startsWith("unolink_p_") }
.associate { it.removePrefix("unolink_p_") to query.getQueryParameter(it).orEmpty() }
onLink(query.getQueryParameter("unolink_deep_link"), params)
}
}
prefs.edit().putBoolean("referrer_read", true).apply()
client.endConnection()
}
override fun onInstallReferrerServiceDisconnected() = Unit
})
}
Java:
InstallReferrerClient client = InstallReferrerClient.newBuilder(context).build();
client.startConnection(new InstallReferrerStateListener() {
@Override public void onInstallReferrerSetupFinished(int code) {
if (code == InstallReferrerClient.InstallReferrerResponse.OK) {
try {
String referrer = client.getInstallReferrer().getInstallReferrer();
Uri query = Uri.parse("https://unolink.invalid/?" + referrer);
String clickId = query.getQueryParameter("unolink_click_id");
String deepLink = query.getQueryParameter("unolink_deep_link");
// Route to deepLink if clickId != null; parameters are unolink_p_<name>.
} catch (RemoteException e) {
// Play Store unavailable: try again on the next launch.
}
}
client.endConnection();
}
@Override public void onInstallReferrerServiceDisconnected() { }
});
React Native or Expo (Android only), with react-native-device-info:
import DeviceInfo from "react-native-device-info"
const referrer = await DeviceInfo.getInstallReferrer() // e.g. "unolink_click_id=clk_…&unolink_deep_link=%2Fpromo"
const query = new URLSearchParams(referrer)
const deepLink = query.get("unolink_click_id") ? query.get("unolink_deep_link") : null
Call it once after the first launch and remember that you did. Google Play keeps the referrer for 90 days after the install, so a second read returns the same values: don't open the deep link twice.
With the SDK (0.3.3+), that's done for you: the link waits on the device
until you consume it, even if the app is closed in between (up to 30 days), so you can open it after onboarding or
sign-in and call consumeDeferredDeepLink() once you have.
What the referrer contains
| Key | Value |
|---|---|
unolink_click_id | The click's ID, e.g. clk_01JA…. Always present for Unolink installs. |
unolink_link | The campaign link's path, e.g. tiktok. Absent for your app's main link. |
utm_source, utm_medium, utm_campaign, utm_term, utm_content | The UTM tags on the link someone tapped, when present. |
unolink_deep_link | The link's deep link. |
unolink_p_<name> | Each of the link's parameters. |
The referrer is limited to 1,000 characters. If a link's deep link and parameters are longer, parameters are left out first, then the deep link. The click lookup always returns everything.
If your Google Play URL in Unolink already has its own referrer=, Unolink leaves it alone and adds nothing.
Installs that didn't come through Unolink have no unolink_click_id. Google Play then reports something like
utm_source=google-play&utm_medium=organic.
Optional: look up the click
With an API key (Pro plan and up), send the click ID to Unolink to get the link's current deep link and parameters, even if they were too long for the referrer or changed after the click:
curl https://api.unolink.dev/v1/clicks/clk_01JA… -H "X-Unolink-Key: ulk_…"
See the SDK API reference.
Testing it
Google Play only passes a referrer for installs from Google Play, so test with a real install:
- Upload a build to Google Play Console → Testing → Internal testing, and add yourself as a tester.
- On the phone, uninstall the app, then open your Unolink link (for example
go.unolink.dev/yourapp/test) and install from the Play listing it opens. - Open the app. The referrer should contain your
unolink_click_id, and the deep link callback should run.
To test your parsing code without installing, pass it a string such as
unolink_click_id=clk_01JA0000000000000000000000&unolink_deep_link=%2Fpromo%2F3for2.
iPhone
There's no deferred deep link on iPhone. Apple has no install referrer, and the workarounds rely on fingerprinting, which Unolink never does. iPhone visitors still go straight to the App Store, and their clicks are counted.
Counting what happens after the install is a different matter: with the Unolink SDK, iPhone installs, onboarding, paywall views, trials and purchases are counted, the same as on Android, and the dashboard matches iPhone installs to the link they came from, without fingerprinting. What iPhone can't do is hand the link to your app on first open. For Apple's own per-campaign download numbers in App Store Connect, set the App Store provider token on your app.