# Android Install Referrer Referral Code in Kotlin

> Pass a referral code through a Google Play install with the Play Install Referrer API in Kotlin, then let the WarpLink SDK read it and credit the inviter.

_Last updated: 2026-10-26_

A referral code survives a Google Play install when it rides in the `referrer` parameter of the Play Store link. Google Play keeps that string through the install and returns it to your app on first launch through the Play Install Referrer API. Your app reads it once, parses the code, and credits the inviter.

This guide shows the plain Kotlin version first, so you see exactly what Google gives you. Then it shows what the WarpLink Android SDK does with the same signal, and how `claimReferral` turns it into a credited, exact referral. It uses SDK 1.2.0.

## How the code travels through the Play Store

A friend taps an invite link on an Android phone that does not have your app. They land on your Google Play listing, tap Install, and open the app. Nothing in that path carries your app's query string. The one channel that does is the `referrer` parameter on the Play Store URL:

```text
https://play.google.com/store/apps/details?id=com.example.app&referrer=ref%3DANA123
```

The value must be URL-encoded, so `ref=ANA123` becomes `ref%3DANA123`. Google Play stores it with the install, and the app can ask for it on first launch. The Play Store app, not the phone's browser or a clipboard, is the carrier. That is why Android needs no paste step.

## Read the referrer in Kotlin

Add Google's library to the app module. This is the version Google documents at [developer.android.com](https://developer.android.com/google/play/installreferrer/library):

```kotlin
dependencies {
    implementation("com.android.installreferrer:installreferrer:2.2")
}
```

Then connect, read, and close. The call is asynchronous, so everything happens inside `onInstallReferrerSetupFinished`:

```kotlin
import android.content.Context
import android.net.Uri
import com.android.installreferrer.api.InstallReferrerClient
import com.android.installreferrer.api.InstallReferrerStateListener

fun readReferralCode(context: Context, onResult: (code: String?, readable: Boolean) -> Unit) {
    val client = InstallReferrerClient.newBuilder(context).build()
    client.startConnection(object : InstallReferrerStateListener {
        override fun onInstallReferrerSetupFinished(responseCode: Int) {
            if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) {
                val referrer = client.installReferrer.installReferrer
                onResult(Uri.parse("?$referrer").getQueryParameter("ref"), true)
            } else {
                // SERVICE_UNAVAILABLE is worth a retry on a later launch.
                val unavailable =
                    responseCode == InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE
                onResult(null, !unavailable)
            }
            client.endConnection()
        }

        override fun onInstallReferrerServiceDisconnected() {
            // Retry on the next request to Google Play.
        }
    })
}
```

`client.installReferrer` returns a `ReferrerDetails` object. Its `installReferrer` property is the string you put in the link, for example `ref=ANA123`. It also carries `referrerClickTimestampSeconds` and `installBeginTimestampSeconds`.

### Read it only once

Google's guidance is to call the API only once, during the first execution after install, because the value does not change unless the app is reinstalled. Keep a flag in `SharedPreferences` and skip the connection when it is set. Set the flag once Google Play answers, and leave it unset when the service is unavailable so the next launch tries again:

```kotlin
val prefs = context.getSharedPreferences("referral", Context.MODE_PRIVATE)
if (!prefs.getBoolean("referrer_read", false)) {
    readReferralCode(context) { code, readable ->
        if (readable) prefs.edit().putBoolean("referrer_read", true).apply()
        if (code != null) pendingReferralCode = code
    }
}
```

Hold the code until the person signs up, then send it with the new account to your backend. That is a complete referral on Android with no third-party code. What it does not give you is a record of the tap, a check that the code belongs to a live invite, a duplicate guard, or a report.

## What the WarpLink SDK does with the same signal

With WarpLink, the referral link is the thing that puts the code in the referrer, and the SDK reads it for you. A WarpLink referral link redirects to Google Play with the link id and a per-tap token inside the install referrer. On first launch, SDK 1.2.0 reads it through the same Google library, which the SDK brings in as a dependency, and matches it to the tap.

Three steps replace the code above.

**1. Create a referral link.** Any link that belongs to an app can be a referral link. Turn on **Referral link** in the dashboard, or send `is_referral` over REST:

```bash
curl -X POST https://api.warplink.app/v1/links \
  -H "Authorization: Bearer wl_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "YOUR_APP_ID",
    "slug": "invite-ana",
    "destination_url": "https://example.com/invite",
    "is_referral": true
  }'
```

Store the returned link id with the user who shares it. The webhook names that link later, and the id tells you whose invitation earned the credit.

**2. Configure the SDK.** Register the signing certificate SHA256 fingerprint on the app in the dashboard, then configure once in `Application.onCreate()`:

```kotlin
WarpLink.configure(
    context = this,
    apiKey = "wl_live_yoursdkkeyhere000000000000000000",
    options = WarpLinkOptions(onLink = { result ->
        result.onSuccess { deepLink ->
            if (deepLink.isDeferred) showWelcomeFromInvitation(deepLink)
        }
    })
)
```

The referrer read happens at first launch with no code of yours. The match arrives in `onLink` like any other deferred link, and the SDK keeps the evidence for the claim.

**3. Claim the install when the person signs up.** Pass an installer id: a dedicated random id for the new user, 1 to 128 characters. Do not use a primary key, an email address, or a phone number.

```kotlin
import android.util.Log
import app.warplink.WarpLink
import app.warplink.referral.ReferralClaimStatus

WarpLink.claimReferral(user.warplinkId) { result ->
    result.onSuccess { claim ->
        when (claim.status) {
            ReferralClaimStatus.CLAIMED -> Unit // credited inside the window
            ReferralClaimStatus.FLAGGED -> Unit // credited after the window
            ReferralClaimStatus.IGNORED -> Unit // already credited: see claim.duplicateOf
            ReferralClaimStatus.NONE -> Unit    // no referral link brought this install
        }
    }.onFailure { error ->
        Log.w("Referral", error)
    }
}
```

`claimReferral(installerId, callback)` is safe to repeat. The first valid claim for an app and installer id wins.

## What the claim records

A referral read from the Play install referrer is an exact match: `matchMethod` is `android_referrer` and `isExact` is true. The tap time, the install time, the link, and the installer id are stored with the referral. Your backend receives a signed `referral.claimed` webhook, grants the reward from its own rules, and the credited install shows in the Referrals report next to the rest of your link analytics.

[Exact versus estimated referral matches](https://warplink.app/blog/referral-attribution-exact-vs-estimated) defines every evidence field. [Verify a referral before you grant the reward](https://warplink.app/blog/verify-referral-before-reward) shows what to check on the server.

## Common problems

**The read returns nothing on a debug build.** The install referrer exists only when Google Play installs the app. An install by `adb install` or a direct APK has none. Install from a Google Play internal testing track, as [How to test the install referrer and referral links](https://warplink.app/blog/test-install-referrer-and-referral-links) shows.

**The second launch returns nothing, or a repeat test finds the old value.** The value is tied to the install. Delete the app and install it again for a fresh run.

**The code is empty after parsing.** The `referrer` value was not URL-encoded, or the parameter name differs from the one you read. Log the raw `installReferrer` string and compare.

**`claimReferral` answers `NONE`.** No referral link brought this install. Check that the link is a referral link and that the tap was after `referral_since`.

## Frequently Asked Questions

### How do I pass a referral code through a Google Play install?

Add the code to the `referrer` parameter of the Play Store link, for example `&referrer=ref%3DANA123`. Google Play keeps the value through the install. On first launch, the Play Install Referrer library returns it as a string your app parses.

### Is the Play install referrer reliable enough for rewards?

It is a strong signal because Google Play delivers it through the install, not the clipboard or the browser. It exists only for installs from Google Play, and your app reads it once. For a reward, claim the install on your server and treat it as one input next to your own rules.

### How many times can I read the install referrer?

Google says to call the API only once, on the first execution after install, because the value does not change unless the app is reinstalled. Store a flag after the first read and skip the call on later launches.

### Does the WarpLink SDK read the install referrer for me?

Yes. SDK 1.2.0 reads the referrer on first launch through Google's library, which it brings in for you. The match arrives with the method `android_referrer` and exact set to true, and you call `claimReferral` after sign-up to credit the inviter.

### Do Android referrals need a paste step like iPhone?

No. Google Play carries the invitation inside the install referrer, so the new person sees no extra screen.

## Related Guides

- **Quickstart:** [Android referral quickstart](https://warplink.app/docs/guides/referrals/android) and the full [referrals guide](https://warplink.app/docs/guides/referrals).
- **Code or link:** [Referral code vs referral link](https://warplink.app/blog/referral-code-vs-referral-link) shows how to combine a code with a link that survives the install.
- **Test it:** [How to test the install referrer and referral links](https://warplink.app/blog/test-install-referrer-and-referral-links).
- **Other platforms:** [React Native referral program](https://warplink.app/blog/react-native-referral-program), [Flutter referral system](https://warplink.app/blog/flutter-referral-system), and [referral links on iPhone](https://warplink.app/blog/ios-referral-link-after-install).
- **The general mechanism:** [Deferred deep linking on Android](https://warplink.app/blog/deferred-deep-linking-android).
- **The rules:** [App Store and Google Play referral reward rules](https://warplink.app/blog/app-store-referral-rewards-rules).

## How WarpLink Helps

The plain Kotlin version reads a string. The parts around it are what make a referral usable: the link that writes the code into the install, the record that joins a tap to a first launch, the duplicate guard, and the signed event your backend can trust. That is our job. You create a referral link, configure the SDK, and call `claimReferral` after sign-up. The reward and its rules stay in your system.

One workflow, three pillars. Deep linking carries the invitation, install attribution credits the link that produced the new user, and real-time analytics shows referrals beside every other link. Sub-10ms redirects on the way in, one SDK on the way out.

[Create a free WarpLink account](https://dash.warplink.app/auth/signup) and get deep linking, install attribution, and real-time analytics in one SDK, with 10,000 clicks a month on the free plan.
