How to Reconcile Campaign Attribution Across Deep-Link and MMP Logs

Assign link delivery and campaign credit to separate owners, then compare shared IDs, attribution rules and privacy-limited results to explain mismatches.

Use one owner for each measurement job.

  • Let the deep-link system own link resolution and destination delivery.
  • Let one agreed attribution rule own campaign credit for attributed installs and events.
  • Carry stable campaign labels and available click IDs across the handoff.
  • Compare event records only when the systems expose a shared, permitted identifier.
  • Treat privacy-preserving aggregate results as a separate evidence set.

When a deep-link vendor says a user arrived through Campaign A and an attribution provider credits Campaign B, the two tools may be answering different questions. The link system can confirm which URL opened and which screen the app displayed. The attribution provider applies its own touchpoint, timing, and re-engagement rules to decide which campaign receives credit. A reconciliation starts by separating those jobs, then traces the shared identifiers and rules that connect them.

For a small subscription-app team, the practical outcome is a measurement contract: who owns link delivery, who owns campaign credit, which records can be joined, and what to do with unmatched results. Use that contract to understand a $2,000 campaign before changing links or trusting one dashboard total. The goal is a clear explanation of the difference, not identical totals by default.

1. Give each system a measurement job

A deep link and a mobile measurement partner (MMP) perform related but distinct work. A deep link carries a person toward a destination, such as a particular screen or offer. An MMP records eligible marketing touchpoints and applies configured rules to attribute installs and later events to campaigns.

AppsFlyer’s deep-link and attribution documentation makes the distinction visible: on iOS 14.5 and later, its Unified Deep Linking flow returns deep-link values such as deep_link_value, while attribution fields such as media_source and campaign return null in that flow. A destination-routing value and a campaign-credit value therefore serve different purposes, even when the same click starts both processes.

Assign ownership by outcome. The following division gives the marketer and developer one place to inspect each question.

Measurement questionOwnerEvidence to retain
Did the link resolve, open the app or store, and pass the person to the intended screen?Deep-link system and app routing codeLink ID, requested destination, actual destination, app state, and delivery result
Which source and campaign receive credit for an attributed install?The MMP or attribution method named in the measurement contractAttribution result, campaign labels, touchpoint type, applicable rule, and event time
Did the person start a trial, subscribe, renew, or refund?The system that records the subscription event, such as the app backend or billing platformEvent name, event ID, event time, and the chosen campaign attribution result where available
Which signal goes to an ad platform for optimization?The named conversion sender for that platform and eventDestination, event mapping, transaction or deduplication key, and send status
Why do two reports differ?Internal reconciliation owner, usually marketer plus developerThe relevant vendor records, field map, rule versions, and unmatched category

Keep product truth and campaign credit separate. The subscription system establishes whether a payment or renewal happened. The attribution system applies the agreed campaign-credit rule to that event. A product analytics tool can describe behavior across the funnel, while the attribution owner answers the acquisition question.

Write down the owner before checking a total. If the link vendor reports opens and destination delivery while the MMP reports attributed installs, compare those metrics as different outcomes. If both systems report campaign credit, identify the specific metric, attribution method, and event each report means before choosing a number for a budget decision.

2. Choose a source of truth for each decision

Choose the system whose rule matches the decision, then use that system consistently for the same metric. A campaign dashboard can guide paid acquisition, a link report can diagnose owned-link engagement, and the billing record can establish subscription revenue. One universal source of truth is unnecessary when each metric answers a different operating question.

DecisionSource of truth to nameWhat the team should compare
Which paid campaign receives credit for an attributed install?The chosen MMP or platform attribution methodCampaign, touchpoint type, eligible window, and attribution timestamp
Did a campaign link send people to the right app destination?Link platform plus app-routing resultRequested destination, final screen, and app-installed or store path
Did the user start a trial or pay?Subscription event sourceEvent definition, event ID, and event timestamp
Which signal should optimize a paid campaign?The destination ad platform’s accepted conversion signal, using the agreed senderEvent mapping, attribution basis, deduplication behavior, and postback result
Matched, unmatched, and rule-difference recordsReconciliation log with both systems’ resultsThe relevant records, match status, and applicable rule

Attribution windows are one common cause of different credit. AppsFlyer’s lookback-window guide says a non-self-reporting-network setup can configure click-through and view-through windows, and its selected time appears in the attribution link. If one system accepts a click for a longer period, it can credit an install that another system treats as outside its window.

Re-engagement rules also change what a campaign report counts. AppsFlyer’s retargeting attribution guide documents app launches reported as new re-engagements and explains how its SDK uses the launch timestamp in that case. For a subscription app, decide whether a returning user’s purchase belongs in an acquisition report, a re-engagement report, or both under separately named metrics. Keep the same definition in weekly reporting so a shift in attribution settings does not look like a sudden change in subscriber demand.

Before comparing totals, record each system’s click-through and view-through settings, re-engagement definition, event mapping, timezone, and the date the settings took effect. Compare attributed installs with attributed installs, trial starts with trial starts, and revenue with revenue under the same currency and event window.

Make a shared field map before launching a campaign. Use human-readable campaign labels to align reporting, and preserve the click identifiers that the ad platform or attribution provider supplies for its own matching. A label such as spring_trial_us can help people compare reports. A click ID such as gclid carries a platform-generated value that should retain its original form.

Google Analytics’ campaign URL guidance defines utm_source as the referrer, utm_medium as the marketing medium, utm_campaign as the campaign or promotion, utm_id as a campaign ID, and utm_content as a creative identifier. Google Analytics’ campaign URL guidance recommends using utm_source, utm_medium, and utm_campaign in tagged URLs. Treat these as shared descriptive labels, then keep platform-specific click IDs as separate fields.

Google Ads’ auto-tagging documentation says auto-tagging adds a Google Click Identifier, or GCLID, to the URL a customer clicks. This gives the team a concrete redirect test: inspect the landing URL at each hop and verify the GCLID and approved campaign fields remain available to the intended receiver. Google’s auto-tagging details also explain that GA4 prioritizes auto-tagging over manual tagging, so teams should document when they rely on platform identifiers and when they rely on manually added UTM values.

Build the campaign map around fields your actual tools expose:

  • Campaign identity: agreed source, medium, campaign name, and stable campaign ID.
  • Ad breakdown: ad set, placement, or creative label when the ad platform provides it.
  • Click evidence: link ID, click ID, and click timestamp when each system makes those fields available.
  • Routing instruction: the deep-link destination key, such as a product screen or offer identifier.
  • Install and event evidence: install timestamp, event name, event ID, and attribution result when available.
  • Collection context: platform, app version, timezone convention, and the campaign-map version used for the test.

Use separate fields for routing and attribution. A routing key tells the app which screen or content to open. An attribution key describes the marketing touchpoint or a provider’s matching token. AppsFlyer’s iOS privacy documentation is a useful example: it separates deep-link fields from attribution fields in Unified Deep Linking. A link can deliver the right screen while the attribution result follows a different, privacy-eligible path.

Inspect the complete redirect chain with one controlled test link. Save the original URL, each intermediate URL, the final store or app URL, and the app’s received routing values. Compare the map with the raw click or install fields your systems actually expose. Mark any field that changes spelling, disappears, becomes blank, or gets replaced by a default value. Update the campaign template or redirect configuration, then repeat the test with the same values.

4. Reconcile evidence from click to event

Use a controlled campaign and a short, defined date range for the first comparison. A campaign-wide month of data often mixes installs, returning users, privacy-limited reports, and several app versions. A small test keeps the diagnosis focused on the handoff and the configured credit rules.

  1. Write down the question. Choose one metric, such as attributed installs from one campaign or first subscription events from that campaign. Record its owner, date range, timezone, and attribution rule.
  2. Collect the available records. Export or inspect the click, link-open, install, event, and postback records each selected system makes available. Capture timestamps, campaign labels, link IDs, event names, and match results that the system exposes.
  3. Standardize timestamps, labels, and source values. Use one timezone for sorting, map synonymous event names to one internal label, and retain the original values beside each normalized value. Keep click time, install time, and event time as different fields.
  4. Join on the strongest shared identifier available. Start with a shared event or click ID when both records contain it. Use stable campaign ID and a reasonable time relationship to classify records when no common event-level ID exists. Label those as inferred matches rather than exact joins.
  5. Classify every result. Mark records as matched, present only in the link system, present only in the attribution system, credited to different campaigns, delayed, or privacy-aggregated. Preserve the original record and the reason for the classification.
  6. Repeat after one change. Change one URL, event mapping, or attribution setting at a time. Run the same test again so the team can identify which change altered the result.

A simple comparison sheet can use these columns: record_type, link_id, click_id, campaign_id, event_id, event_name, click_time_utc, install_time_utc, event_time_utc, link_result, attribution_result, and reconciliation_status. Example values might be campaign_id=spring_trial_us, event_name=trial_started, and reconciliation_status=matched; these are sample labels, not required vendor field names. Keep vendor-native field names in a source column so that a renamed internal label never erases what the provider sent.

Android’s Google Play Install Referrer API exposes an install_referrer string and client- and server-side click and install-begin timestamps. The documentation says referrer information remains available for 90 days and recommends calling the API once during the first execution after install. For an Android test, those fields can help check whether the referrer reached the app and whether click and install timing look plausible.

An event-level join depends on a shared identifier that both systems expose and that the team is allowed to use. Apple’s AdAttributionKit documentation says its cryptographically signed postback contains no user- or device-specific data. Apple determines a data tier that controls the detail in a postback to help maintain crowd anonymity. Treat those postbacks as privacy-preserving aggregate evidence, then compare their campaign and conversion summaries at their supported level instead of trying to force a person-level join.

Keep the reconciliation data narrow. The Federal Trade Commission’s business guide to protecting personal information advises keeping sensitive personal information only as long as there is a legitimate business need, and recommends a written retention policy that states what to keep, how to secure it, how long to keep it, and how to dispose of it. Store the campaign and event fields needed to answer the measurement question, limit access, and set a review date for deletion.

5. Diagnose a broken handoff or a rule difference

A broken handoff changes what reaches the next system. A rule difference changes how a system interprets evidence it received. Use the record pattern to decide which team should investigate first.

PatternLikely explanationNext check
Link click exists, but the app opens the wrong screenDestination value or app routing mismatchCompare requested route with the value received by the app and the screen actually opened
The app opens the intended screen, while campaign fields are absent downstreamCampaign parameters dropped or transformed during redirect or deferred installCompare the initial URL, each redirect, store handoff, install referrer, and app receipt
Both providers credit a campaign, but to different touchpointsDifferent click or view-through windows, touchpoint priorities, or re-engagement rules can produce different creditThe credited touchpoint and timestamps identify which rule assigned each result
Link click is visible but no deterministic install match appearsInstall delay, missing shared key, platform privacy outcome, or a link-to-install handoff gapCheck referrer and timestamp evidence, then classify privacy-limited outcomes separately
Install credit matches, but subscription counts differDifferent event names, delivery, trial definitions, or date ranges can change countsEvent IDs and timestamps distinguish delivery gaps from differences in event mapping or date range
Daily totals shift around midnightReporting timezones can place the same event on different datesComparing event timestamps in UTC shows whether the underlying event timing matches
One report has campaign-level conversions without a user-level recordPrivacy-preserving aggregate attributionCompare the aggregate at its supported reporting level

Trace the evidence from the landing URL through app routing, campaign fields, and attribution settings. First, confirm that each redirect preserves the intended destination and campaign parameters, and that the app opens the requested screen. Then inspect each install or event record for the campaign ID, source, medium, campaign label, and any platform or provider click ID; compare those values with the original URL and campaign map. Finally, compare the recorded timestamps with each provider’s click and view-through windows, touchpoint priorities, and re-engagement settings. This prevents the team from changing attribution windows to fix a URL parameter that never arrived.

For a rule difference, capture both configurations and calculate how many records sit inside each system’s applicable window. For a handoff fault, locate the first redirect or event step where the expected field vanishes or changes. Change that step, rerun the same test, and keep a before-and-after record. A clear status such as parameter_missing, window_difference, or privacy_aggregate gives the founder a useful explanation for the discrepancy instead of a single unexplained total.

6. Keep conversion signals from counting twice

Choose one sender for each conversion event and destination, or write down the exact deduplication rule when two senders are required. Trace a conversion from the source event through each integration and postback. For a subscription app, define whether trial_started, subscription_started, renewal, and refund each send a signal, and identify which system owns the event ID.

Google Ads’ transaction ID guidance says that two conversions for the same conversion action with the same transaction ID are treated as duplicates, and the second is not counted. It also says each separate purchase needs its own unique transaction ID, and the ID from a second data source must match the original ID exactly for this deduplication path.

Test the event path with a known transaction or test event. Send the same event through the intended retries, inspect the delivery statuses, and verify the downstream conversion count follows the documented rule. Then send a second, distinct test event with a unique ID and confirm that it remains a separate conversion. Keep retries idempotent, meaning that resending the same event ID preserves one logical conversion rather than creating another.

Separate delivery duplicates from attribution differences. A duplicate occurs when the same conversion signal is accepted twice under a destination’s rules. Different campaign credit can occur when two tools apply different attribution rules to one conversion. The fixes differ: correct sender or deduplication for the first, and align the measurement contract or explain the rule boundary for the second.

7. Decide whether the split stack still fits

Keep separate vendors when each has a clear job, the team can preserve the required identifiers, and the recurring reconciliation produces an answer the team can use. A specialist link product may cover routing needs that differ from the attribution provider’s campaign-credit function. The price of that split is the integration work: someone must own field mapping, tests, event delivery, and changes to either vendor’s rules.

Consider a combined workflow when it removes a real handoff problem and includes the link behavior, campaign reporting, channels, and data access your team needs. A shared vendor can reduce the number of system boundaries to inspect, but the team still needs a source-of-truth rule and privacy-aware reconciliation.

Airbridge’s Core Plan documents mobile campaign attribution and reporting together with direct and deferred deep linking. It describes users with the app landing inside it and users without the app passing through the store before arriving at the destination. For a US consumer subscription app that wants campaign and subscription reporting alongside link routing, that documented combination is a reasonable fit to evaluate.

The plan’s available export level matters if the workflow depends on joining individual records. Airbridge’s Data Export page lists event-level attribution export to S3, BigQuery, or Snowflake as a Growth Plan feature, while Core includes report exports to Sheets and CSV. Core therefore suits teams that can make their campaign decisions from its reports; teams that require raw event records for an internal join should evaluate a plan with event-level export. The Core feature list also describes up to two third-party integrations, including subscription platforms such as RevenueCat, Adapty, or Superwall, which supports a subscription-platform-agnostic setup.

Make the decision from the reconciliation you have already done. If the unresolved rows mainly come from a route parameter disappearing, repair the routing or redirect contract. If the rows come from different windows, define which rule owns the decision. If the team needs raw event-level joins and its selected plan only offers report-level exports, data access is the actual selection criterion. Keep the split or evaluate a combined workflow according to that specific gap.

8. Put the agreement and repeatable QA in writing

Keep a short measurement contract beside the campaign setup documentation. The marketer owns campaign naming and the decision metric. The developer owns parameter receipt, app routing, event IDs, and the app-side test. One named person owns attribution settings, exports, and the reconciliation log. Small teams can share roles, but each task still needs a clear owner.

Use this checklist when a campaign launches or any part of its tracking changes:

  • Metric and owner: name the question, such as paid attributed installs, first trials, paid subscriptions, or renewal revenue, and name the system that owns it.
  • Credit rule: record click-through and view-through windows, re-engagement treatment, event definitions, reporting timezone, and effective date.
  • Campaign map: save the stable campaign ID, agreed UTM labels, supported platform click IDs, deep-link route, and the expected value at each handoff.
  • Event path: name the event source, event ID, sender, destinations, retry behavior, and destination-specific deduplication rule.
  • Evidence fields: list which click, install, event, postback, or aggregate fields each system makes available to the team.
  • Mismatch categories: record the accepted labels for route failure, missing parameter, rule difference, delayed event, duplicate signal, and privacy aggregate.
  • Escalation and retention: name who investigates each category, who can access the reconciliation data, and when the team reviews or deletes it.
  • Repeat trigger: rerun the test after a link template, campaign taxonomy, SDK, event mapping, attribution setting, or app-release change.

Run one end-to-end test before scaling spend: click a controlled link, check the destination, verify the values received by the app, trigger the test event, and confirm the chosen attribution and postback path. Save the test date, app version, link ID, campaign ID, and outcome. Repeat that same path after a material change so a later mismatch can be compared with a known working state.

During routine review, group unresolved records by category rather than escalating a headline total. A dozen missing routing keys point to a different owner than a cohort of installs credited outside a chosen click window. The contract gives both the marketer and developer a repeatable way to decide whether the fix belongs in a URL, an app release, an attribution rule, an event integration, or the reporting interpretation.

FAQS

FAQ

Should the deep-link vendor or the MMP own campaign credit?

The MMP or attribution method named in the measurement contract should own the paid campaign-credit metric. The deep-link system owns link resolution and destination delivery, while the subscription event source establishes whether a trial, payment, renewal, or refund occurred.

Should the two dashboards show the same number?

Only when they report the same event under the same attribution rules, window, timezone, and reporting scope. Different link outcomes, campaign credit, and privacy-limited aggregate reports answer different questions, so document the reason for a difference before treating it as a tracking fault.

Can we join every install or conversion to a click?

No. A record-level join requires a shared identifier that both systems expose and that the team is permitted to use. Privacy-preserving postbacks can provide campaign-level evidence without user- or device-specific fields.

When does raw event export change the vendor decision?

When the team needs to join individual click, install, and subscription event records in its own storage or analysis workflow. Airbridge Core includes report-level Sheets and CSV exports, while Airbridge’s Data Export page places event-level export in Growth Plan.

Get Started Free

See how these criteria hold up on the real thing.

Get Started Free