Attribution Accuracy
Which install matches are deterministic, the known failure modes, and the method and device checklist for measuring correct, wrong, and unmatched installs.
Android installs that go through the Play Store are matched deterministically with the Play Install Referrer. Every first install on iOS is matched probabilistically, because the App Store passes nothing through an install. We have not yet published measured match rates. This page publishes the method and the device test checklist first. Measured results will be published here, with counts.
For how the cascade works in full, read Install attribution and Deferred deep links. This page covers only what you need to judge accuracy.
Deterministic and probabilistic matches
The server tries four methods in order and stops at the first match: referrer, device ID, fingerprint, raw signals.
| Match | OS | Deterministic? | What it relies on |
|---|---|---|---|
| Referrer | Android | Yes | The Play Install Referrer carries the link's identity through the store |
| Device ID | iOS | Not an install match | Recognizes a device that already has an install. It returns that install's own result. |
| Fingerprint, raw signals | iOS and Android | No | The request IP, the device language, and the timezone, hashed |
Only the referrer match is deterministic. It requires that the visitor was sent to the https://play.google.com store address, so a link whose Android destination is a web page falls back to the probabilistic match.
Known failure modes
Each of these is a reason an install does not match, or matches the wrong person.
| Condition | Effect |
|---|---|
| The IP changes between the tap and the first launch (Wi-Fi to cellular, or the reverse) | No match. The IP is part of every probabilistic key. |
| IPv6 at the tap and IPv4 at the launch, or the reverse | No match. Same network, different address. |
| Several people share one public IP, such as an office, a household, or a carrier gateway, and tap links in the same window | The most recent claimable tap wins, so the install can be attributed to another person's link. The confidence score is reduced when this is likely, but it is not zero. |
| The device uses iCloud Private Relay | Safari traffic leaves from a relay address while the app's own request does not, so the two IPs can differ. We treat this as a test condition and have not yet measured its effect. |
| The device uses a VPN | The IP changes when the VPN connects or switches, and many users can share one VPN exit address. We treat this as a test condition and have not yet measured its effect. |
| The install happens after the link's match window (6 hours by default, 24 at most) | No match. |
The confidence score is not a probability
A match returns a confidence between 0.0 and 1.0. It is built from how long ago the tap happened, which fingerprint variant the SDK could send, and whether the tap came from a shared IP. A deterministic match is always 1.0.
A score of 0.80 does not mean that 80 out of 100 such matches are right. We use it to route: go straight to content at the top of the range, ask for confirmation in the middle, show generic onboarding at the bottom. Do not use a match, or its match_guaranteed flag, to sign anyone in or to show personal data. Authenticate the user separately.
How we test
We count three outcomes for every test install.
| Outcome | Meaning |
|---|---|
| Correct | The install matched the link that the tester tapped |
| Wrong | The install matched a different link |
| Unmatched | The server answered matched: false |
For each condition we report the counts of all three, not just a percentage. From the counts we derive:
- Correct rate: correct divided by all runs.
- False match rate: wrong divided by all matched runs. This is the number that matters most for iOS.
- Unmatched rate: unmatched divided by all runs.
We report a 95 percent interval (Wilson) beside each rate, because a small number of runs cannot support a precise percentage.
Ground truth comes from the test itself. Each run uses its own link with a known slug, so the right answer is known before the install.
Conditions
| # | Condition | Runs |
|---|---|---|
| 1 | Same Wi-Fi at the tap and at the first launch | 30 |
| 2 | Tap on Wi-Fi, first launch on cellular | 30 |
| 3 | Tap on cellular, first launch on Wi-Fi | 30 |
| 4 | iCloud Private Relay on at the tap and the launch (iOS) | 30 |
| 5 | VPN on at both | 30 |
| 6 | VPN turned on or off between the tap and the launch | 30 |
| 7 | Dual-stack network where the tap and the launch may use different IP versions | 30 |
| 8 | First launch 30 minutes after the tap | 30 |
| 9 | First launch 2 hours after the tap | 30 |
| 10 | First launch 5 hours after the tap | 30 |
| 11 | First launch after the match window has passed (expect no match) | 30 |
| 12 | Two devices on one network tap different links, then install (collision check) | 30 pairs |
| 13 | Android, link opens the Play Store address (control, expect deterministic) | 30 |
| 14 | Android, link opens a web page first (referrer missing) | 30 |
Thirty runs per condition is the minimum. With 30 runs and no wrong matches, the upper end of the 95 percent interval for the false match rate is still about 11 percent, which is why we publish the interval and the count together. We add runs for conditions that need a tighter bound.
Device test checklist
Use this checklist to run the test on your own devices. You can follow it for your own app before you trust a match in production.
Before you start
- Create a dedicated test organization or a separate app, so test installs do not mix with real data.
- Use a release build installed from the store path: TestFlight for iOS, an internal testing track on Google Play for Android. A debug build installed from a cable does not go through the store, so it does not test the real path.
- Record the SDK version, the device model, and the OS version for every run.
- Use at least two iOS versions and one Android version on real devices.
- Set the link's match window deliberately and write it down.
- Create a spreadsheet with one row per run and these columns: run id, condition, device, OS version, SDK version, expected link slug, tap time, launch time, network at tap, network at launch, matched link slug, match type, confidence, outcome.
For each run
- Delete the app from the device. If another app from the same developer account is still installed on an iPhone, the device ID tier can answer with an earlier install instead of a new match. Record the match type, and count a device ID answer as a repeat, not as a match.
- Create a new link for this run with a unique slug. Write the slug in the sheet.
- Set the network condition for the tap (Wi-Fi, cellular, Private Relay on, VPN on).
- Tap the link from a message or a note, as a real user would. On iOS, use Safari.
- Follow it to the store page and install the app. Wait for the delay that the condition requires.
- Set the network condition for the first launch.
- Open the app and let the SDK run its attribution check. Read the result from your
onLinkcallback: matched link, match type, confidence. - Write the outcome in the sheet: correct, wrong, or unmatched.
- Check the same install in the dashboard. The install should appear with the matched link. The "Why installs don't match" page lists the reason for an unmatched run.
For the collision condition
- Put two test devices on the same Wi-Fi network.
- Create two links, one per device.
- Tap link A on device 1 and link B on device 2 within a minute of each other.
- Install on both and launch both.
- Record what each device matched. Any cross match is a wrong match.
Results
We have not published measured results yet. When we do, they appear in this section. Each result will state the SDK versions, the device models and OS versions, the date, and the counts of correct, wrong, and unmatched runs for each condition above.
Until then, treat every probabilistic match as a best guess, which is how the SDK documentation describes it. See Install attribution for how to route on a match safely.
Architecture and Failure Modes
How WarpLink serves redirects from an edge cache, records clicks through a queue, and what keeps working when the database, API, or click queue is down.
Data Portability and Leaving WarpLink
What you can export from WarpLink, why custom domains stay yours, what installed apps do after you leave, cancel versus delete, and a leaving checklist.