Deeplinkly

Glossary/Android platform

Meta Install Referrer

Definition

The 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.

It solves a specific problem: Meta will not publish campaign identifiers in a plaintext referrer that any party could read, but advertisers legitimately need deterministic attribution for their own installs. The compromise is that the data rides in the standard Play install referrer, encrypted with a key only the advertiser holds. Decrypt it and you get click-through versus view-through, campaign, ad set and ad IDs, and a trustworthy click timestamp.

What arrives, and where

There is no separate API. You read the ordinary Play install referrer, and if the install came from a Meta ad the string contains a utm_content value holding a small JSON object.

The utm_content payload, after URL-decoding
{
  "source": "apps.facebook.com",
  "data": "1f3a9c...",
  "nonce": "9b2e7d41c0a5..."
}
The wrapper fields.
FieldMeaning
sourceThe Meta surface — e.g. apps.facebook.com, apps.instagram.com. Check it before decrypting
dataHex-encoded AES-GCM ciphertext plus authentication tag
nonceHex-encoded initialisation vector for this payload

Branch on `source`, do not assume

The same referrer string carries your own utm_* parameters for non-Meta traffic. Treating any utm_content as an encrypted payload will throw on ordinary campaign links, so gate the decryption path on a recognised source value and fall through to normal parsing otherwise.

Decrypting it

The key is per-app and comes from Meta's app dashboard, under the app's install referrer settings. It is a secret: it belongs on your server, not compiled into the APK where anyone can extract it.

AES-256-GCM decryption
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec

fun decryptMetaReferrer(dataHex: String, nonceHex: String, keyHex: String): String {
    val cipher = Cipher.getInstance("AES/GCM/NoPadding")
    cipher.init(
        Cipher.DECRYPT_MODE,
        SecretKeySpec(keyHex.hexToByteArray(), "AES"),
        // 128-bit auth tag; the tag is appended to the ciphertext in `data`.
        GCMParameterSpec(128, nonceHex.hexToByteArray())
    )
    return String(cipher.doFinal(dataHex.hexToByteArray()))
}

private fun String.hexToByteArray(): ByteArray =
    chunked(2).map { it.toInt(16).toByte() }.toByteArray()
The decrypted payload
{
  "ad_id": "23851234567890123",
  "adset_id": "23851234567890000",
  "campaign_id": "23851234560000000",
  "campaign_group_id": "23851234500000000",
  "publisher_platform": "facebook",
  "is_ct": true,
  "actual_timestamp": 1755500000
}
The decrypted fields and what to do with them.
FieldUse
campaign_group_idMeta campaign — the top level of their hierarchy
campaign_idAd set in Meta's UI naming
adset_id / ad_idThe finer splits, for creative-level reporting
publisher_platformfacebook, instagram, audience_network, messenger
is_ctClick-through when true, view-through when false. Never merge the two
actual_timestampMeta's server-side click time — the input to click-to-install time

`is_ct` is the field people drop

View-through installs attributed as clicks is the single most common way Meta reporting ends up disagreeing with an advertiser's own numbers, in Meta's favour. Store is_ct and segment every metric by it, because the two populations do not behave alike and paying click prices for view-through volume is a real budgeting error.

Where this fits against the alternatives

Meta attribution options on Android.
ApproachDeterminismNeeds consentGives you
Meta install referrerDeterministicNo — first-party install dataCampaign, ad set, ad, CT/VT, click time
GAID matchingDeterministic when availableEffectively yes — opt-out zeroes itDevice-level match
Meta's own dashboardDeterministic, but self-reportedNoTheir numbers, unverifiable by you
Probabilistic matchingNoNoAn estimate, and a policy problem

The referrer's advantage over the dashboard is not accuracy but independence: it is the same event, recorded in your own infrastructure, which is what lets you audit a self-attributing network rather than accept its claims. Discrepancies then become answerable questions rather than a negotiation.

  1. Enable the install referrer for your app in Meta's dashboard and copy the decryption key into your server's secret store.
  2. Read the Play install referrer on first launch and forward the raw string to your server without parsing it on-device.
  3. Server-side, check source, decrypt, and store the raw ciphertext alongside the decrypted result so a key rotation or parsing change is replayable.
  4. Reconcile against Meta's dashboard weekly, segmented by is_ct. Persistent gaps in one direction point at instrumentation, not at Meta.
  5. Keep a non-Meta path in the same pipeline, since your own dl_id links flow through the identical referrer field.

Android SDK documentation

Our Android SDK forwards the raw install referrer to your server so the Meta payload can be decrypted where the key belongs, and keeps your own first-party click IDs flowing through the same path without a second integration.

Open the android sdk documentation

Frequently asked questions

What is the Meta install referrer?
It is an encrypted campaign payload that Meta places inside the standard Google Play install referrer string, letting an advertiser's Android app obtain deterministic attribution data for installs driven by Facebook and Instagram ads. The advertiser decrypts it with a per-app key from Meta's dashboard, so the campaign identifiers are not exposed to any other party reading the referrer.
How do I decrypt the Meta install referrer?
Read the Play install referrer, URL-decode the utm_content value, and parse the JSON object containing source, data and nonce fields. Then decrypt the hex-encoded data using AES-256 in GCM mode with the hex-encoded nonce as the initialisation vector, a 128-bit authentication tag, and the per-app decryption key from Meta's app dashboard.
Where do I get the Meta install referrer decryption key?
From your app's install referrer settings in Meta's app dashboard. Treat it as a server-side secret: embedding it in your APK makes it extractable by anyone who downloads your app, which would let a third party read the campaign data Meta encrypted specifically to keep it between you and them.
What does is_ct mean in the Meta install referrer?
It distinguishes click-through from view-through attribution — true means the user clicked the ad, false means they only saw it. Merging the two is the most common cause of Meta-attributed installs looking better than they are, since view-through volume behaves differently from clicked volume and should not be valued or bid on identically.
Do I need the GAID if I have the Meta install referrer?
No. The install referrer is a first-party signal delivered by Google Play about your own app's install, so it works regardless of the advertising ID's availability and needs no opt-in. That makes it more reliable than GAID matching on modern Android, where the identifier is zeroed for users who opt out of ads personalisation.

Related terms

  • Play Install ReferrerThe 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.
  • 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.
  • Unattributed installsAn install is unattributed when no signal linking it to a prior ad click or link tap survived the journey through the app store, which can mean the install was organic or that the signal existed and was lost.