Install Attribution
How WarpLink attributes app installs to the link clicks that drove them, using deterministic and probabilistic match strategies.
Install attribution connects an app install (or re-open) to the link that drove it. WarpLink uses a multi-tier match cascade to determine which link a user came from, with confidence scores that help you decide how to route the user.
What You Need
Attribution is recorded by a WarpLink mobile SDK, and the SDK must be configured with an SDK key. Create one in the dashboard under API Keys > SDK key, then pass it to configure().
An API key is not a substitute. It carries the scopes you pick for backend and CI work, and install attribution is never one of them. A mobile app configured with an API key still resolves deep links, which makes the integration look healthy, but every attribution call is rejected and no installs appear in your dashboard.
Match Cascade
The server tries matching methods in order. The first successful match wins.
| Priority | Method | Signal | Confidence | Platform |
|---|---|---|---|---|
| 1 | Referrer | Play Install Referrer | 1.0 | Android |
| 2 | Device ID | IDFV | 1.0 | iOS |
| 3 | Fingerprint | IP (server-derived) + normalized language + timezone | 0.20–0.85 | Both |
| 4 | Raw signals | accept_language + timezone + timezone_offset (IP added server-side) | 0.20–0.85 | Both |
The first two tiers are deterministic: they identify a specific device, so the response returns match_guaranteed: true. The last two are probabilistic, and their fingerprint is shaped by the network rather than the device.
The IP Gap Problem
The SDK cannot know its own public IP address, but WarpLink includes the request IP in fingerprint computation at click time. To solve this:
- The SDK sends raw device signals (not a pre-computed fingerprint) to the attribution endpoint
- The server computes the fingerprint hash using the request's IP address
- This ensures the SDK-originated fingerprint matches what WarpLink stored at click time
Confidence Scores
A deterministic match always scores 1.0. A probabilistic match starts from how long ago the click happened and which fingerprint variant the SDK could send:
| Time since click | enriched_tz | enriched | basic |
|---|---|---|---|
| < 1 hour | 0.85 | 0.80 | 0.70 |
| < 3 hours | 0.65 | 0.60 | 0.50 |
| < 6 hours | 0.50 | 0.45 | 0.35 |
| < 24 hours | 0.30 | 0.25 | 0.20 |
Past 24 hours there is no match at all. The link's match window can cut that shorter still: it defaults to 6 hours and is capped at 24.
enriched_tz is what current SDKs send: it hashes the IANA timezone name, for example America/Toronto. The name carries far more entropy than the minute offset (roughly 340 zones against 38 offsets) and it does not shift at a daylight-saving boundary, which used to break a click and install pair that straddled the change. enriched hashes the offset instead and is the fallback for SDKs that send no zone name. basic covers signals that carry neither.
Two multipliers then reduce the starting score:
| Condition | Multiplier |
|---|---|
| The bucket offered more than one distinct link | 0.6 |
| Click IP was carrier-grade NAT or private | 0.6 |
| Click IP was a household IPv4 address | 0.9 |
| Click IP was IPv6 | 1.0 |
Use the result to decide how far to lean on the match: route straight to content near the top of the range, show a suggestion or a confirmation in the middle, and fall back to generic onboarding at the bottom. For anything sensitive, gate on match_guaranteed rather than on a score threshold.
Confidence depends on four things: how much time passed between the click and the install, which fingerprint variant was used, how many clicks were claimable in the same bucket, and how shared the click's IP address was. When several clicks could match, the most recent claimable one wins and the ambiguity multiplier applies.
Click Deduplication
Click uniqueness is computed server-side at write time for perfect accuracy, never at the cache layer.
A click is considered unique per combination of link, IP address, and 24-hour window.
What attribution returns
When a match succeeds, the response identifies the link and how confident the match is:
- Matched link: the link the install is attributed to, with its resolved deep link and destination URLs and any custom parameters
- Match type:
deterministicfor an exact referrer or device ID match, orprobabilisticfor a fingerprint match - Match confidence: a score from 0.0 to 1.0 you can use to decide how to route the user (see Confidence Scores above)
- Match guaranteed:
trueonly for a deterministic match, exposed asmatchGuaranteedon the SDKs
Gate anything sensitive on match_guaranteed, not on a confidence threshold. Automatic sign-in and showing personal data belong behind a guaranteed match. A probabilistic match is a best guess from a fingerprint shaped by the network rather than the device, so it can name the wrong user however high the score reads.
Deterministic matches come from the Play Install Referrer on Android or the IDFV on iOS. If a user who previously installed the app taps a link, the IDFV gives an exact re-engagement match. When nothing matches, the response says so, and you can fall back to generic onboarding.
Reinstalls
A reinstall is an install. When someone deletes your app and installs it again, attribution runs again from scratch, on every platform, and the result counts in your install numbers like any other install. The install that follows a reinstall is the one most likely to have come from a link, so dropping it would lose exactly the campaigns you care about.
The SDK also labels it. Each platform keeps two separate markers:
| Marker | Survives an app delete? | Job |
|---|---|---|
| Attribution complete | No, and it is never restored from a backup | Stops a second attribution request inside one install |
| Device seen | Yes, and it does come back from a backup | Decides whether this install is a reinstall |
When the device-seen marker is present and the completion marker is not, the SDK sends is_reinstall: true on the attribution request. Anything else is a first install. The flag never gates the request: attribution runs either way. SDK versions older than the flag send nothing, which the server reads as a first install.
The dashboard counts installs and reinstalls together as one installs number. There is no separate reinstall metric.
Privacy
WarpLink's attribution is designed to be privacy-preserving:
- No IDFA (iOS) or GAID (Android): no advertising identifiers
- No cross-app tracking: IDFV is scoped to your vendor
- No ATT prompt: IDFV is exempt from App Tracking Transparency
- Hashed fingerprints: Probabilistic fingerprints are stored only as a one-way hash, never as raw signals
- HTTPS only: All signal transmission is encrypted
Deferred Deep Links
How deferred deep links preserve their destination and context through an app install, routing new users to the right place after first launch.
Social Previews
How WarpLink generates rich social previews with Open Graph and Twitter Card tags, so your links look right when shared on social media.