Skip to main content

Matching Architecture

This page describes how Detour matches first app open with a previously recorded click, and how scoring/threshold settings affect attribution results.

How matching starts

When app opens for the first time, SDK calls Detour match API. Runtime selects one of two matching modes depending on payload shape.

Matching modes

  1. Deterministic (preferred) — when an exact clickId is present (Android install referrer), the server performs a simple lookup and returns the link if the click exists and is unmatched. Deterministic matching is exact and fast.

  2. Probabilistic (fallback) — when clickId is not available (typical on iOS), Detour computes a similarity score between the device fingerprint sent by the SDK and recent unmatched click beacons.

Probabilistic payload fields

The probabilistic payload includes:

  • platform, model, manufacturer, systemVersion — device identity signals. Not all are available in every browser.
  • screenWidth, screenHeight, scale — display metrics.
  • locale[] (languageTag used for scoring) - language/region.
  • timezone — timezone string.
  • userAgent — raw user agent for more granular device signature.
  • timestamp — when the fingerprint was captured (used for time-window filtering).
  • pastedLink (optional) — the clipboard content if the user had a link copied prior to first open. Platform checks equality of token generated by server which was added as search param and url string.

Scoring weights

The server scores each candidate click using separate scoring functions. The weights used by Detour today:

SignalWeight
IP exact500
Model + system version exact450
User-agent device signature match350
Timezone200
Screen match200
Pasteboard URL/token match (iOS)350
Language match100

Important runtime rules:

  • model + systemVersion has priority; user-agent signature is used when model/version match is unavailable.
  • Screen comparison uses tolerance (±1 width/height, ±0.01 scale).
  • Pasteboard score on iOS:
    • 350 when token matches and pasted URL starts with click URL
    • 175 when only URL prefix matches

Why these weights? weights prioritize signals that are harder to spoof or coincidental (IP, user-agent/device signature, clipboard) and treat softer signals (language) as weaker evidence.

Threshold and time window

Both values are app-level settings from Link settings -> Matching configuration:

  • Matching threshold - default: 850 (allowed range: 700..1200)
  • Matching time window - default: 15 minutes (allowed range: 5..180)

Customizing the Matching Threshold

While the default threshold of 850 is optimized for a balance of accuracy and recall, you can customize this value.

  • Lowering the threshold (e.g., to 700) increases the likelihood of finding a match, but raises the risk of false positives (attributing an install to the wrong link). This may be acceptable for general marketing links.
  • Raising the threshold (e.g., to 1000) makes matching stricter, reducing false positives but potentially missing legitimate matches. This is recommended if you are linking to sensitive content.

Clicks outside the configured time window are ignored. The default window in the matching logic is 15 minutes between click timestamp and fingerprint timestamp. This reduces false positives and focuses on near-in-time installs.

Customizing the Time Window

The default time window of 15 minutes is configurable.

  • A shorter window (e.g., 5–10 minutes) increases confidence in matches, as the click and app open happen closely together. However, users may not finish downloading and installing the app within this shortened window, which can cause legitimate installs to be missed.
  • A longer window (e.g., 30–60 minutes) can help capture users who are interrupted or take longer to download the app. However, significantly extending the window increases the pool of potential clicks, which can lead to a higher rate of false positives.

Candidate selection

In probabilistic mode, runtime:

  1. Load unmatched clicks for app within configured time window.
  2. Compute score for each candidate.
  3. Keep highest score.
  4. If score tie occurs, choose newer click.
  5. Accept only if best score is >= threshold.

After successful match

When match succeeds:

  • click is marked as matched,
  • install is stored as non-organic in analytics install stream,
  • API returns resolved link URL.

When no match is found, install is recorded as organic and API returns 404.

Example score scenarios

  • Strong deterministic evidence: IP + exact pasteboard token/url -> 500 + 350 = 850 -> accepted with default threshold
  • Weak signals: Timezone + language + screen -> 200 + 100 + 200 = 500 -> rejected
  • IP + user-agent signature: 500 + 350 = 850 -> accepted with default threshold

Tuning guidance

Start with defaults and tune only after observing real traffic patterns in analytics. If you see too many missed matches, consider lowering threshold slightly or extending time window. If you see suspicious cross-attribution in dense traffic, move in the opposite direction.

For practical edge cases that affect tuning decisions, see Limitations & Known Issues.