Appfiliate Docs
appfiliate.io

Attribution

Called by the SDK on first app launch to attribute the install to a prior tracking link click. Returns whether a match was found and the confidence score.

POST/v1/attribution

Matches an app install to a recorded click using deterministic or probabilistic strategies.


Headers

ParameterTypeRequiredDescription
X-API-KeystringRequiredYour app's API key from the Appfiliate dashboard.
X-App-IDstringRequiredYour app's unique identifier.
X-Forwarded-ForstringOptionalThe end user's real IP address. Used for fingerprint matching when the request passes through a proxy.

Request Body

ParameterTypeRequiredDescription
app_idstringRequiredYour app ID. Can also be provided via the X-App-ID header.
platformstringRequiredThe device platform: "ios" or "android".
device_modelstringOptionalThe device model (e.g. "iPhone", "Pixel 8"). Used for fingerprint matching.
os_versionstringOptionalThe OS version string (e.g. "iOS 18.0", "Android 15"). Used for fingerprint matching.
idfvstringOptionaliOS Identifier for Vendor. Stored with the install record for deduplication.
af_click_idstringOptionalThe Appfiliate click ID extracted from the Android Install Referrer. When present, enables deterministic matching with 100% confidence.
referrerstringOptionalThe raw install referrer string (Android only).
sdk_versionstringOptionalThe version of the Appfiliate SDK making the request.

Example Request

curl
curl -X POST https://us-central1-appfiliate-5a18b.cloudfunctions.net/api/v1/attribution \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key" \
  -H "X-App-ID: app_myapp" \
  -d '{
    "app_id": "app_myapp",
    "platform": "ios",
    "device_model": "iPhone",
    "os_version": "iOS 18.0",
    "idfv": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890"
  }'

Responses

Successful match

200 OK
{
  "matched": true,
  "attribution_id": "m1abc123_x9f2k4p1",
  "confidence": 0.8,
  "method": "contextual_dedup",
  "click_id": "m0xyz789_a3b4c5d6"
}

No match found

200 OK
{
  "matched": false,
  "attribution_id": null,
  "confidence": 0,
  "method": "no_clicks",
  "click_id": null
}

Authentication error

401 Unauthorized
{
  "error": "Invalid API key"
}

Matching Strategies

The attribution endpoint uses two matching strategies depending on the platform and available data.

Deterministic matching (Android)

On Android, the Google Play Install Referrer can pass the af_click_id directly from the tracking link through to the installed app. When this parameter is present, the API looks up the exact click by ID. This produces a confidence of 1.0 and a method of referrer.

Probabilistic matching (iOS / fallback)

On iOS (and Android when no referrer is available), the API uses fingerprint-based matching. It queries recent unmatched clicks from the same IP address and scores them based on:

  • IP match (50 points) -- base requirement, already filtered by the query
  • Device model (15 points) -- device type matches between click and install
  • OS version (5 points) -- major OS version matches
  • Time decay -- scores decrease linearly over 48 hours
  • Contextual dedup boost -- if only one unmatched click exists from that IP, confidence is boosted by 15%

Matching windows

The API first searches a 2-hour window with a minimum score threshold of 50. If no clicks are found, it expands to a 24-hour window but requires a higher minimum score of 80 to reduce false positives.

Confidence scores

The confidence field is a value between 0 and 1. A score of 1.0 indicates a deterministic match (Android referrer). Probabilistic matches typically range from 0.5 to 0.9 depending on the available signals and time elapsed.

Match Methods

MethodDescription
referrerDeterministic match via Android Install Referrer. Confidence is always 1.0.
contextual_dedupProbabilistic match where only one unmatched click existed from the IP. Higher confidence due to lack of ambiguity.
strong_fingerprintProbabilistic match with multiple candidate clicks. The highest-scoring click was selected.
no_clicksNo unmatched clicks found from the user's IP within the matching window.
no_matchClicks were found but none met the minimum score threshold.