Deeplinkly

Glossary/Android platform

Play Install Referrer

Definition

The Play Install Referrer is a Google Play API that lets a newly installed Android app read the referrer string and click timestamps recorded when the user arrived at its Play Store listing.

It is the closest thing mobile has to a deterministic install signal, and it needs no advertising identifier and no user consent, because Google Play is passing the app data about its own install. That makes it the backbone of deferred deep linking on Android: the referrer string can carry your own link identifier, so the first launch after install knows which link the user came from.

Where the string comes from

Play preserves the referrer query parameter from the Play Store URL the user arrived on. Everything downstream depends on that parameter being set on the outbound link — if the link has no referrer, the API works perfectly and returns nothing useful.

The link, and the string it produces
# The outbound Play Store URL. The referrer value must be URL-encoded.
https://play.google.com/store/apps/details
  ?id=com.example.shop
  &referrer=utm_source%3Dnewsletter%26utm_campaign%3Dspring%26dl_id%3Dabc123

# What getInstallReferrer() returns on first launch:
utm_source=newsletter&utm_campaign=spring&dl_id=abc123

The string is opaque to Play — it is whatever you put there, up to a length limit, conventionally formatted as URL-encoded key-value pairs. dl_id above is a first-party click identifier: your server generated it when the link was clicked, so resolving it on first launch gives you the full deep link destination without matching on any device signal at all.

This is a first-party signal, not tracking

You are reading a parameter you set on your own link, returned by the store that served your own app. No cross-app identifier is involved, nothing is joined to a third party's graph, and no ATT-equivalent consent applies — which is why Android's deferred deep linking is deterministic where iOS's is probabilistic.

The implementation

build.gradle.kts
dependencies {
    implementation("com.android.installreferrer:installreferrer:2.2")
}
Reading the referrer on first launch
val client = InstallReferrerClient.newBuilder(context).build()

client.startConnection(object : InstallReferrerStateListener {
    override fun onInstallReferrerSetupFinished(responseCode: Int) {
        when (responseCode) {
            InstallReferrerClient.InstallReferrerResponse.OK -> {
                val details: ReferrerDetails = client.installReferrer
                val referrer = details.installReferrer          // the string
                val clickTs  = details.referrerClickTimestampSeconds
                val beginTs  = details.installBeginTimestampSeconds
                val instant  = details.googlePlayInstantParam   // Instant App?

                handleReferrer(referrer, clickTs, beginTs, instant)
            }
            // Play Store too old, or no Play Store at all.
            InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED,
            // Transient: Play services unavailable right now.
            InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE ->
                scheduleRetry()
        }
        client.endConnection()   // one-shot connection; always close it
    }

    override fun onInstallReferrerServiceDisconnected() = scheduleRetry()
})
The fields on ReferrerDetails.
FieldWhat it tells you
installReferrerThe referrer string you set on the Play Store link
referrerClickTimestampSecondsWhen the user clicked — the basis of click-to-install time
installBeginTimestampSecondsWhen the install began
googlePlayInstantParamWhether the user previously ran the Instant App
*ServerTimestampSeconds variantsGoogle's server-side clock, immune to device clock skew

Use the server timestamps for fraud checks

The device-clock timestamps are trivially manipulable. Any click injection or click-spam detection that compares click time to install time must use the server-side variants, or the signal you are validating against is one the attacker controls.

The failure modes worth knowing

Why the referrer comes back empty or wrong.
SymptomCauseFix
Empty string, OK responseThe Play Store link carried no referrer parameterAdd it, URL-encoded, to every outbound store link
FEATURE_NOT_SUPPORTEDSideloaded, or an alternative store, or Play Store too oldFall back to your own click-resolution path
SERVICE_UNAVAILABLETransient Play services stateRetry with backoff; do not treat as terminal
Referrer present but stale on reinstallPlay returns the original install's referrerKey on installBeginTimestampSeconds, not on first-launch flag
Params mangledDouble-encoded or unencoded & in the referrerEncode once, at link-generation time
Nothing after 90 daysPlay retains the referrer for 90 days from installRead it on first launch and persist it yourself
  1. Read the referrer on the very first launch, before anything can consume it, and persist the parsed result immediately.
  2. Never block your UI on the API. It is asynchronous and can fail; render the default experience and route when the referrer resolves.
  3. Call endConnection() after each attempt — the client is one-shot and leaks a service binding otherwise.
  4. Send the raw string to your server unparsed as well, so a parsing change does not require the referrer again.
  5. Treat the referrer as untrusted input. It arrives from a URL a stranger can construct; validate the click ID against your own records before honouring the destination.

Meta ads are the one common case where the referrer is present but not directly readable — see the Meta install referrer, which arrives encrypted inside the same string.

Android SDK documentation

Our Android SDK reads the install referrer for you, handles the retry and one-shot connection lifecycle, and resolves a first-party click ID into the deep link destination on first launch — with the raw string still available if you want to parse it yourself.

Open the android sdk documentation

Frequently asked questions

What is the Play Install Referrer API?
It is a Google Play API that lets a freshly installed Android app read the referrer string and click timestamps recorded when the user reached its Play Store listing. Because Google Play is handing the app information about its own install, no advertising identifier and no user consent are involved, which makes it a deterministic install signal rather than a probabilistic match.
How long is the install referrer available?
Google Play retains it for 90 days from the install. In practice you should read it on the app's first launch and persist the result yourself, because the retention window is a backstop rather than a store you can query later, and any analysis that needs the referrer months afterwards must rely on your own copy.
Why is my install referrer empty?
Most often because the Play Store link the user clicked had no referrer query parameter, in which case the API returns a successful response with an empty string. The other common causes are a sideloaded or alternative-store install, which returns FEATURE_NOT_SUPPORTED, and a transient SERVICE_UNAVAILABLE response that should be retried rather than treated as terminal.
Can the install referrer be used for deferred deep linking?
Yes, and it is the standard mechanism on Android. Put a first-party click identifier in the referrer parameter of the Play Store URL, read it on first launch, and resolve it against the click record your server created, which yields the exact deep link destination with no device fingerprinting and no probabilistic matching.
Should I trust the install referrer timestamps?
Use the server-side timestamp variants for anything security-relevant. The device-clock values can be manipulated by an attacker, so click-injection and click-spam detection that compares click time against install time must read the server timestamps, which come from Google's clock rather than the handset's.

Related terms

  • Meta Install ReferrerThe Meta Install Referrer is an encrypted campaign payload that Meta places in the Google Play install referrer string, allowing an advertiser's Android app to decrypt deterministic attribution data for installs driven by Facebook and Instagram ads.
  • GAIDThe GAID, or Google Advertising ID, is a resettable per-device identifier that Android provides for advertising and analytics, and which is replaced by a string of zeros for users who opt out of ads personalisation.
  • Deferred deep link not workingA deferred deep link fails when the signal meant to carry the pre-install destination across the app store — an install referrer, a stored token, or a server-side match — is absent, expired, or never read on first launch.
  • Android Instant AppAn Android Instant App is a small subset of an Android app that Google Play streams and runs directly from a URL, without the user installing the full app first.