Deeplinkly

Glossary/Attribution mechanics

Cross-platform attribution

Definition

Cross-platform attribution is the practice of measuring one advertising campaign across iOS, Android and the web, where each platform supplies a different attribution signal at a different level of granularity and the results cannot be directly summed.

The instinct is to treat platform as a dimension you can group by, the way you group by country. It is not, because the number in each row was produced by a different measurement system: iOS reports installs in aggregate through SKAdNetwork with a delay and a privacy threshold, Android reports them deterministically and immediately through the Play install referrer, and the web reports them from your own server. Averaging those is arithmetic without meaning. This is a separate problem from cross-device attribution, which is about one person using two devices.

Three regimes, one campaign

What each platform can actually tell you about an install.
iOSAndroidWeb
Primary signalSKAdNetwork / AdAttributionKitPlay install referrerFirst-party click ID
GranularityAggregatePer installPer session
User-level identityNoYes, if consentedYes, first-party
LatencyHours to daysImmediateImmediate
Campaign dimensionsConstrained ID spaceFree-form stringFree-form string
Conversion detailConversion value, coarseAny eventAny event
Suppressed when smallYes — [crowd anonymity](/glossary/what-is-crowd-anonymity)NoNo
Re-attribution of existing usersLimitedYesYes

Two rows make blending indefensible. Aggregate granularity means an iOS row is a count with no rows behind it, so it cannot be filtered, joined or deduplicated after the fact. Suppression means an iOS row can be *absent* rather than zero when volume is below the privacy threshold — so a naive platform comparison reports Android outperforming iOS partly because Android tells you about small campaigns and iOS declines to.

The iOS double count

An iOS install can appear twice: once in a SKAdNetwork postback and once in a click-based attribution from your measurement partner's own matching. They describe the same install through two systems with different windows. Pick one as the source of truth per platform and report the other as a cross-check, or your iOS totals will exceed your actual install count.

The one thing that must be identical everywhere

You cannot normalise granularity, latency or identity — those are properties of the platforms. You can normalise the campaign key, and it is the only thing standing between you and a report where the same campaign appears as four rows. Decide the taxonomy once, encode it in every link regardless of platform, and mirror it into the constrained iOS campaign ID space with an explicit mapping table rather than an ad-hoc convention.

One campaign identifier, three destinations
# The campaign key is generated once and reused verbatim. Same
# cid on every platform is what makes a single GROUP BY possible.
CID="spring_launch_2026"
CREATIVE="hero_v3"

# Android and web: the key travels in the link as-is.
echo "https://example.com/product/42?cid=${CID}&creative=${CREATIVE}&utm_source=meta"

# iOS: SKAdNetwork campaign IDs are a small integer space, so the
# mapping has to be stored, not encoded. Keep it in version control
# next to the taxonomy — an undocumented mapping is unrecoverable
# once the person who chose it leaves.
echo "skan_campaign_id=37  ->  ${CID}"

# Verify the key survives to the landing page on every platform.
for ua in "iPhone; CPU iPhone OS 18_0" "Linux; Android 15"; do
  curl -s -o /dev/null -w "%{url_effective}\n" -L -A "Mozilla/5.0 ($ua)"     "https://links.example.com/l/abc?cid=${CID}&creative=${CREATIVE}"
done
Union the platforms, and carry the granularity with the number
-- The grain column is not decoration. It is what stops someone
-- averaging an aggregate row with a per-install row six months
-- from now, and it travels with the data into every downstream view.
WITH unified AS (
  SELECT campaign_id, 'ios'     AS platform, 'aggregate'   AS grain,
         installs, NULL::NUMERIC AS revenue, TRUE AS may_be_suppressed
  FROM skan_postback_rollup

  UNION ALL
  SELECT campaign_id, 'android' AS platform, 'per_install' AS grain,
         COUNT(*) AS installs, SUM(first_day_revenue), FALSE
  FROM android_attributed_install
  GROUP BY campaign_id

  UNION ALL
  SELECT campaign_id, 'web'     AS platform, 'per_session' AS grain,
         COUNT(*) AS installs, SUM(first_day_revenue), FALSE
  FROM web_attributed_conversion
  GROUP BY campaign_id
)
SELECT
  campaign_id,
  platform,
  grain,
  installs,
  revenue,
  -- Report per platform. Deliberately no SUM() across platforms:
  -- a total here would be three incompatible measurements added up.
  revenue / NULLIF(installs, 0) AS revenue_per_install
FROM unified
ORDER BY campaign_id, platform;

The absence of a grand total in that query is the design, not an omission. A cross-platform report answers "how did this campaign do on each platform", and the honest answer is three numbers with three provenances. If a stakeholder needs one number, the defensible construction is spend against revenue per platform, compared to each platform's own eCPI — never a blended install count.

What you can and cannot compare

Comparisons that hold, and comparisons that do not.
ComparisonValid?Why
iOS campaign A vs iOS campaign BYesSame regime, same suppression rules
Android week-over-weekYesDeterministic and stable
iOS installs vs Android installsNoAggregate vs per-install, and iOS suppresses low volume
Blended CPI across platformsNoDenominators were produced differently
Retention by platformQualifiedOnly for cohorts each platform can identify
Revenue per install per platformYesBoth terms come from the same platform
Total installs, all platformsNoSums incompatible measurements

The qualified row is worth expanding. Cohort analysis on iOS can only use cohorts SKAdNetwork is able to describe, which is a coarser grouping than the install-level cohorts Android gives you. Comparing a coarse iOS cohort's retention to a precise Android one is a comparison of measurement precision as much as of user behaviour, so state the grain alongside the figure whenever both appear in the same chart.

Deep linking is the part that genuinely is cross-platform

The measurement diverges, but the link does not have to. One https:// URL, verified through assetlinks.json on Android and the AASA file on iOS, routes correctly on both and falls back to the web everywhere else. Keeping one URL per destination across all platforms is also what makes the campaign key consistent, so the routing decision and the reporting decision are the same decision.

Where a genuine unified view is required — a board slide, a channel budget decision — the practical approach is to hold the taxonomy identical, report per platform, and reconcile at the spend level rather than the install level. Spend is the one quantity measured the same way everywhere, because you paid it. Everything downstream of it is platform-specific, and pretending otherwise is how a campaign gets cut on iOS for underperforming when it was only being measured more conservatively.

UTM builder

Consistent campaign keys are the only part of cross-platform reporting you fully control. The builder generates identically encoded parameters for every platform, so one campaign produces one row rather than four near-duplicates.

Open the utm builder

Frequently asked questions

What is cross-platform attribution?
It is measuring one advertising campaign across iOS, Android and web, where each platform provides a different attribution signal. iOS reports installs in aggregate through SKAdNetwork or AdAttributionKit, Android reports them per install through the Play install referrer, and web reports them from your own server, so the results describe the same campaign through three incompatible measurement systems.
Why can't I add iOS and Android installs together?
Because the two numbers were produced differently. The iOS figure is an aggregate with no underlying rows, arrives on a delay, and is suppressed entirely when volume falls below a privacy threshold, so an absent row does not mean zero installs. The Android figure is a deterministic per-install count with none of those properties. Summing them yields a number that describes neither platform.
What is the difference between cross-platform and cross-device attribution?
Cross-platform attribution is about reconciling incompatible measurement regimes for one campaign running on iOS, Android and web. Cross-device attribution is about one person using two devices, where the difficulty is that every advertising identifier is scoped to a single device and only a shared login identity can bridge them. They are different problems with different solutions.
How do I keep campaign names consistent across platforms?
Decide the taxonomy once and generate every link from it rather than typing parameters per platform. Android and web can carry the campaign key verbatim in the URL, while SKAdNetwork uses a small integer campaign ID space, so that mapping has to be stored explicitly and kept in version control alongside the taxonomy. An undocumented mapping becomes unrecoverable when its author leaves.
Can the same iOS install be counted twice?
Yes, and it commonly is. One install can appear in a SKAdNetwork postback and again in a click-based attribution produced by a measurement partner's own matching, because the two systems use different windows and different evidence. Choose one as the source of truth per platform and treat the other as a cross-check, otherwise iOS totals will exceed the real install count.

Related terms

  • Cross-device attributionCross-device attribution is the practice of crediting a conversion that happens on one device to an advertising touch that happened on a different device belonging to the same person, which requires an identity that both devices share.
  • SKAdNetworkSKAdNetwork is Apple's StoreKit framework that attributes app installs to advertising campaigns without exposing a device identifier, by having the operating system send a delayed, aggregated postback to the ad network that won the install.
  • Play Install ReferrerThe Play Install Referrer is a Google Play API that lets a newly installed Android app read the referrer string and click timestamps recorded when the user arrived at its Play Store listing.
  • Crowd AnonymityCrowd anonymity is Apple's privacy mechanism that decides how much campaign and conversion detail an attribution postback may contain, based on whether the install cohort is large enough that the report cannot identify an individual.
  • eCPIEffective cost per install is total marketing spend divided by all installs attributable to that spend, including organic uplift and referred installs, rather than only the installs a network claims.