How Attribution Works
Attribution is the process of connecting an app install (or purchase) back to the affiliate click that caused it. This page explains how Appfiliate solves the click-to-install matching problem on both Android and iOS.
The problem
When a user clicks an affiliate link, they leave the browser and enter an app store. The app store installs your app in a completely separate context -- there is no shared session, no query string, and (on iOS) no reliable device identifier. Appfiliate bridges that gap by capturing signals at click time and matching them against signals collected at install time.
Attribution flow
Every attribution follows the same five-step lifecycle, regardless of platform.
Creator shares a tracking link
Each creator gets unique links per platform (TikTok, Instagram, YouTube, etc.) in the format https://track.appfiliate.io/c/{code}
User clicks link -- Cloudflare Worker captures fingerprint
The worker records IP address, User-Agent, Accept-Language, Referer, TLS fingerprint (JA3 hash), and country. Then it redirects the user to the appropriate app store via 302.
User installs the app from the store
This step happens entirely inside the App Store or Google Play. On Android, the Play Store preserves a referrer string that Appfiliate uses for deterministic matching.
App launches -- SDK calls the attribution endpoint
On first launch, the SDK sends device signals (IP, device model, OS version, and on Android the install referrer) to POST /v1/attribution.
Backend matches the install to a click
The server finds the best matching click and creates an attribution record, linking the install to the creator who drove it. Revenue from future purchases is attributed to that creator.
Android attribution
On Android, Appfiliate uses the Google Play Install Referrer API for deterministic matching. When the Cloudflare Worker redirects an Android user to the Play Store, it appends a referrer string to the URL:
utm_source=appfiliate&af_click_id={clickId}&af_link_id={code}Google Play preserves this referrer string through the install process. After the user installs and opens the app, the SDK reads the referrer via the Install Referrer API and extracts the af_click_id. It then sends this click ID directly to the attribution endpoint.
Because the click ID is passed through a first-party channel (Google Play itself), this match is deterministic -- there is no ambiguity about which click led to the install.
| Property | Value |
|---|---|
| Match type | referrer |
| Confidence | 100% |
| Availability | ~88-93% of Android installs |
Gold standard for attribution
The remaining 7-12% of installs where the referrer is unavailable (sideloaded APKs, certain OEM app stores, or referrer API failures) fall back to the same probabilistic fingerprinting used for iOS.
iOS attribution
iOS does not have an install referrer API. Apple's App Tracking Transparency (ATT) framework means most users decline cross-app tracking, and the IDFA is unavailable without an ATT prompt. Appfiliate does not use the IDFA or trigger an ATT prompt. Instead, it uses probabilistic fingerprint matching to connect clicks to installs.
No IDFA, no ATT prompt required
Fingerprint scoring
When the SDK calls the attribution endpoint on first launch, the backend queries recent unmatched clicks from the same IP address and scores each one against the install's device signals:
| Signal | Points | Notes |
|---|---|---|
| IP address match | 50 | Required -- clicks are pre-filtered by IP |
| Device model family | 15 | Matches on device family (iPhone vs iPhone, iPad vs iPad) |
| OS version (major) | 5 | Major version comparison (e.g. iOS 17 vs iOS 17) |
| Time decay | multiplier | Score degrades linearly to zero over 48 hours |
The raw score is multiplied by a time decay factor: decay = max(0, 1 - hoursElapsed / 48). A click that happened 24 hours ago has its score halved; a click from 48+ hours ago scores zero and is never matched.
Matching thresholds
A click is only matched to an install if it meets one of these conditions:
- Score 70+ and the click happened within the last 2 hours
- Score 60+ and the click happened within the last 1 hour
- Single-IP contextual dedup -- if there is only one unmatched click from this IP, the minimum score threshold is lowered (50 in the standard 2-hour window)
There is also a broader 24-hour window that requires a higher score threshold of 80+ points, used as a fallback when no clicks are found in the standard 2-hour window.
Confidence scores
The attribution response includes a confidence value from 0 to 1 (0% to 100%). This is derived from the decayed fingerprint score, normalized to a 0-100 scale. When only one click exists from the same IP, a 15% contextual dedup boost is applied (capped at 100%).
Match methods
The method field in the attribution response tells you how the match was made:
| Method | Description |
|---|---|
referrer | Deterministic match via Android Install Referrer or iOS cookie recovery. 100% confidence. |
strong_fingerprint | Multiple clicks from the same IP -- matched by highest fingerprint score above threshold. |
contextual_dedup | Only one unmatched click from this IP exists, so the match threshold is relaxed and a confidence boost is applied. |
Cookie recovery (iOS)
When the Cloudflare Worker handles a click, it sets a first-party cookie called af_click containing the click ID (7-day TTL). On iOS, the SDK can open a lightweight SFSafariViewController to the cookie recovery endpoint. Because SFSafariViewController shares the Safari cookie jar, the endpoint can read the af_click cookie and pass the click ID back to the app via a URL scheme callback.
When cookie recovery succeeds, the SDK sends the recovered click ID to the attribution endpoint, resulting in a deterministic referrer match at 100% confidence -- the same path as Android. If the cookie is not available (cleared, expired, or different browser), the SDK falls back to fingerprint-based matching.
Privacy
Appfiliate is designed to attribute installs without invasive tracking:
- No cross-app tracking. Attribution is scoped to your app. Appfiliate does not track users across other apps or websites.
- No IDFA collection. The SDK never reads or transmits the Advertising Identifier, so it never triggers the ATT prompt.
- IDFV is vendor-scoped. The Identifier for Vendor is only visible to apps from the same developer and resets when all of that developer's apps are uninstalled. It cannot be used for cross-developer tracking.
- IP address used only for matching. IP addresses are used during the fingerprint matching window (up to 48 hours) and are not retained for long-term analytics or profiling.