Documentation · Attribution · Models + Reconciliation Panel

Attribution that works at every connection level

Seven attribution models — six heuristic credit-split rules plus the Reconciled · Total Impact blend (BETA) — three data sources, and one honest 3-way view. Pick the model that fits your funnel, set a window from 1-day to 90-day, connect what you have today, and let the Reconciliation Panel tell you why Meta, your pixel, and Shopify never quite agree.

The three-number problem 7 attribution models Reconciled · Total Impact (BETA) Reconciliation Panel FAQ

The three-number problem

Every DTC operator has been here. You open Meta Ads Manager and it says you spent $10,000 and made $40,000 — a clean 4x ROAS. You open your Admaxxer pixel and it says you spent $10,000 and tracked $20,000 of attributed revenue — 2x. You open Shopify Total Sales and it says you made $25,000 across all channels in the same window. Three numbers, three different stories. Which one is right?

The honest answer: all three are right, in their own coordinate system. Meta is reporting what Meta thinks Meta drove, including 7-day-click + 1-day-view conversions plus modeled (i.e., guessed) post-iOS-14.5 conversions. Your pixel is reporting what your pixel actually saw — strict client-side attribution against the visitor's UTM-tagged path. Shopify is reporting raw revenue across every channel, attributed to nobody in particular. Each number answers a different question:

Community consensus on the gap: Meta routinely overreports by 26%+ against pixel-side measurement, even before iOS 14.5. 30-60% Meta-vs-Shopify gap is normal for DTC stores spending more than $10K/mo on paid social. iOS 14.5 broke 30-50% of click-attribution — Meta backfills with modeled conversions; your pixel doesn't. The gap isn't a bug. It's structural. The right question isn't "which number is true?" but "what's the gap between them, and what does that gap tell me?"

That's what the Reconciliation Panel is built for.

7 attribution models

The active model determines how Admaxxer's pixel-side numbers split credit across the touches in a visitor's path. Six of the seven are heuristic credit-split rules; the seventh — Reconciled · Total Impact — is a BETA blend that produces one reconciled number per channel (covered in its own section below). Time-decay (H=7d) is the recommended default for DTC stores — it's the GA4 default and matches the typical 5-21 day consideration window. Switch models from the model-pill bar at the top of /marketing-acquisition. The change re-computes the table in <500ms (analytics pipeline params change, not a re-fetch).

Model Formula Best for Watch out for Min orders When to switch
Last-click 100% credit to the touch closest to conversion. Bottom-funnel optimization, retargeting, brand-search, anything where the last paid touch is the deciding push. Penalizes top-of-funnel campaigns (TOF prospecting, paid social, video views) that warm the visitor weeks before checkout. 20+ orders / mo Switch when paid-social ROAS reads below 1.5x and you suspect the model is undercrediting prospecting.
First-click 100% credit to the first touch in the visitor's journey. TOF prospecting, audience-building, podcast / influencer campaigns where discovery is the goal. Penalizes retargeting and brand-search; first-touch can be weeks-old and have nothing to do with the actual purchase. 30+ orders / mo Switch when retargeting ROAS reads below 2x and you suspect the model is overcrediting cold reach.
Linear (all touches) Credit split equally across every touch in the path: 1/n per touch. Long DTC funnels (skincare, supplements, considered-purchase apparel) where 5+ touches over 7-21 days is normal. Treats a 30-second video view the same as a brand-search click. Position and time information is discarded. 50+ orders / mo Use when you want a fairness-as-default baseline before reaching for time-decay or position-based.
Linear (paid only) Credit split equally across paid touches only; organic / direct touches get 0. Pure paid-traffic operators who want platform comparisons (Meta vs Google) uncontaminated by organic. Hides organic contribution entirely; useless for measuring brand health or content marketing. 50+ orders / mo Switch when comparing paid platforms head-to-head and organic is consistent enough to set aside.
Time-decay (H=7d) Credit weight = pow(0.5, days_since_touch / 7). Touch from yesterday gets ~0.91; touch 7 days back gets 0.5; 14 days back gets 0.25. Mid-funnel optimization where recency matters but you don't want to discard older awareness touches entirely. Half-life is fixed at 7 days (GA4 default). Long DTC funnels (subscription, B2B trial) may want 14d or 30d — coming in v1.5. 75+ orders / mo The recommended default for DTC stores with 5-21 day consideration windows. Industry standard.
Position-based (40/20/40) First touch + last touch each get 40%; middle touches share 20%. Single-touch = 100%; two-touch = 50/50; 3+ = 40/20/40. Stores that value both discovery (first touch) AND closing (last touch) and have meaningful middle-funnel campaigns. Middle 20% can dilute the picture when there are 5+ middle touches; consider time-decay if recency matters more than position. 100+ orders / mo Switch when you want to balance prospecting and retargeting credit explicitly without time-weighting.
Reconciled · Total Impact (BETA) Blends multi-touch attribution + marketing-mix modeling + incrementality + your post-purchase survey, then reconciles so the channel totals sum to your actual revenue. Returns one number per channel with a confidence range. When you want a single, trustworthy number per channel for a budget call — not three numbers to argue over. Opt-in, not the default. BETA. It's a modeled blend, so it carries a confidence range — read the band, not just the point estimate. Needs enough survey responses + spend history for the modeling layers to settle; thin data widens the band. 200+ orders / mo + survey running Turn it on as a single-number lens once your three sources keep disagreeing and you want a reconciled view that ties to ledger revenue.

The newest model is Reconciled · Total Impact (BETA) — an opt-in single-number lens detailed in the next section. The two industry-standard models time-decay (H=7d) and position-based (40/20/40) sit alongside the four originals (last-click, first-click, linear-all, linear-paid). Every heuristic model respects the existing attribution_window_days, paid_only, new_customers_only, and platforms filters; the underlying queries read from the deduplicated source so re-synced rows never double-count. Tooltips on each model pill explain "best for" + "watch out for" inline.

Reconciled · Total Impact (BETA)

The six models above each answer the same question a different way — and they rarely agree. Total Impact is a different kind of answer: one reconciled number per channel that you can take into a budget meeting without three tabs open. It is opt-in, not the default — you turn it on as a lens when you want a single trustworthy figure instead of a spread.

It blends four independent signals and then reconciles them:

The reconciliation step is what makes it usable: the channel totals are scaled so they sum to your actual revenue (your store ledger), so you never get a model that "adds up" to more than you actually made. The result is shown as a point estimate and a confidence range, plus a plain-English "how this was computed" breakdown so you can see which layer moved the number and by how much.

Worked example — Meta for one month

  1. Start: multi-touch attribution credits Meta with $5,000 of last-touch-weighted revenue.
  2. MMM adjusts down: the spend-response curve says Meta was into diminishing returns this month, so some of that $5,000 would have converted anyway → −$700.
  3. Incrementality adjusts down: the global paid-vs-organic lift test trims another −$450 as not-truly-caused-by-paid.
  4. Survey adds back: buyers who said "a friend told me" on the post-purchase survey move +$300 of credit toward word-of-mouth (and away from over-credited paid).
  5. Reconcile to ledger: totals are scaled so every channel sums to your real monthly revenue.

Total Impact for Meta: ~$4,150, with a confidence range of roughly $3,800–$4,500. One reconciled number instead of four arguing ones — and the band tells you how much to trust it.

Honest about the limits. Total Impact is a modeled estimate, not a deterministic count. The incrementality layer is a global paid-vs-organic lift (not yet a per-channel causal test), and the MMM + survey layers need enough history and responses to settle — thin data widens the confidence band. We keep it opt-in and clearly labeled BETA so it never quietly replaces the deterministic numbers you can audit. Use it as a single-number tiebreaker, and keep the six heuristic models + the Reconciliation Panel for the row-by-row audit trail.

Attribution windows

The window is the lookback period — how far back before a purchase a touch is still allowed to earn credit. It's independent of the model: pick the model (how credit is split) and the window (how far back to look) separately. A shorter window is stricter and more conservative; a longer window captures considered, slow-burn purchases.

The 90-day window is new — added alongside the existing 1 / 7 / 14 / 28-day and Lifetime windows specifically for considered, high-AOV catalogs where a buyer might see your ad in week one and not check out until week ten. If your 7-day window keeps under-crediting top-of-funnel because your customers take a month to decide, widen the window before you blame the model.

The Reconciliation Panel

This is the marquee feature of Phase 1. The Reconciliation Panel sits right below the AttributionDrilldownCard on /marketing-acquisition and shows you, per channel:

Pre-computed reasonings include:

The panel is built on a single analytics pipeline — an internal report — that does a FULL OUTER JOIN of pixel-side, platform-side, and Shopify-side rows per channel. FULL OUTER (not INNER) is critical: it means a channel that exists in only one source still shows up, with the missing columns marked as a "missing" data-coverage chip instead of silently dropping the row. That's the source-additive principle (GL#256 + GL#313) at the SQL layer.

The card UI is at client/src/components/marketing-acquisition/ReconciliationCard.tsx — premium card chrome matching AttributionDrilldownCard's vocabulary (rounded-2xl border + emerald gradient rail + framer-motion entrance + theme tokens). Mounted right below the AttributionDrilldownCard so it's the second card on the page after the model-pill bar.

The Meta first-conversion lens

One thing the Reconciliation Panel surfaces that nothing else can replicate from pixel alone: Meta's deterministic first-conversion data behind ATT and iOS 14.5. Meta operates the conversion API (CAPI) on the server side and has direct access to the deterministic match between an ad impression and a purchase event — a match that survives Apple's App Tracking Transparency framework because it never leaves Meta's infrastructure.

Concretely, the omni_purchase deduped action type from Meta's /v25.0/<ad-account-id>/insights endpoint is the canonical first-conversion count Meta itself uses internally. It's NOT what the Meta pixel would see if you installed it on your storefront — it's the Meta-internal deduped count that includes server-side matches you have no other way to access. The dailyAdSpendSync cron (GL#378) now captures this column on every level=ad pull and surfaces it in the Reconciliation Panel as the "Meta first-conversion" line within the Platform-reported column.

This is the Hyros-style match-rate signal done right: instead of forcing a 6-month server-side identity-stitching setup like Hyros does, Admaxxer pulls Meta's own first-conversion data via the same insights API every other tool already calls. Free signal, no extra integration, no customer setup work.

Source-additive philosophy

Most attribution tools force you into a binary: either a full setup before you see anything (Hyros: 6-month implementation, server-side identity stitching, custom domain) or a no-platform-data shrug (Datafast: UTM-only, doesn't ingest Meta or Google). Admaxxer is built on a third philosophy: source-additive.

Connect what you have today. See what's possible. Add more sources when ready.

Each source you add fills in another column. Each missing source shows a "missing" data-coverage chip instead of breaking the page. This is enforced at the code level by the source-additive guardrail canary (GL#381): every JOIN to a source-attached stream (ad spend, Shopify-reported metrics, enriched orders, visitor payments) must be a LEFT JOIN (or LEFT ANY / LEFT ASOF / FULL OUTER). INNER JOIN = build violation. The canary walks the query SQL and fails the postbuild if anyone accidentally writes an INNER JOIN against an ad-spend source; sister rule to GL#368/371 (token-chain canary) and GL#256/313 (source-additive principle).

You can never get into a state where adding more data makes things worse. That's the structural promise.

How to pick your model — 4 steps

  1. Step 1. Connect at least one source. Open /integrations and connect what you have today. Pixel-only works (UTM-driven). Add Shopify if you have it. Meta + Google unlock platform-side data and first-conversion (Meta's deterministic match data). Source-additive: each source fills in another column in the Reconciliation Panel — missing sources show a chip, not a break.
  2. Step 2. Open /marketing-acquisition and look at AttributionDrilldownCard. The Channel -> campaign -> adset -> ad drill-down is the first card on /marketing-acquisition. Above it is the model-pill bar with all six heuristic attribution models plus the Reconciled · Total Impact lens (BETA). Below it is the Reconciliation Panel showing the 3-way gap.
  3. Step 3. Pick a model that matches your funnel. Default to time-decay (H=7d) — GA4 default, fits 5-21 day DTC funnels. Switch to last-click for bottom-funnel-only, first-click for TOF-heavy (podcast / influencer), linear (all touches) for long consideration, position-based (40/20/40) when you want to credit discovery + closing equally.
  4. Step 4. Read the Reconciliation Panel reasoning. The panel surfaces the gap between Meta-reported, pixel-tracked, and Shopify-reconciled conversions per channel. Each row carries a pre-computed 'reasoning' line: 'Platform claims much more than pixel — likely iOS 14.5 view-through', 'High direct/untagged share — likely UTM hygiene issue', or 'Within 10% — reconciliation clean'. Trust the latter; investigate the former two.

FAQ

Why does Meta show 4x ROAS but my pixel shows 2x?
Two different coordinate systems, both technically correct. The platform uses modeled conversions plus view-through credit and a 7-day-click + 1-day-view default window — anyone who saw your ad and purchased within 7 days counts, even if the ad wasn't the deciding touch. Pixel relies on click-attribution and iOS 14.5+ ATT broke 30-50% of those signals deterministically. Both numbers are real, both are different lookback choices. Operators on Reddit (r/PPC, r/dtcecommerce) consistently land on the same answer: stop trusting one source and look at all of them — open the Reconciliation Panel on /marketing-acquisition to see platform-reported, pixel-tracked, and Shopify-reconciled side-by-side. The gap itself is the most useful signal: under 10% means your model is clean; over 30% almost always means iOS 14.5 view-through or UTM hygiene drift. Source: BloomAnalytics + EasyInsights research covering DTC-specific Meta attribution gaps.
What's iOS 14.5 attribution loss and how does Admaxxer handle it?
Apple's App Tracking Transparency (ATT) framework, shipped in iOS 14.5 (April 2021), prompts every iOS user with 'Allow [App] to track your activity across other companies' apps and websites?' — and ~70-80% of users decline. That decline blocks deterministic click-attribution for ~30-50% of all DTC traffic. The platform's response was to fill the gap with modeled conversions: ML extrapolation from a small consenting cohort to the broader audience. It's controversial because it's unverifiable from the outside, and operators argue it systematically over-credits the platform vs. earned/organic. Admaxxer's first-party pixel sidesteps the third-party-cookie path entirely, click-ID persistence (GL#361, 90-day cookie/localStorage retention) preserves attribution even after the platform's third-party cookies expire, and Meta CAPI _fbc synthesis recovers most of the iOS 14.5 deterministic gap server-side. The Reconciliation Panel still shows you the platform-vs-pixel gap so you can audit transparently — we don't try to hide the loss, we just give you a deterministic floor.
Hyros markets 'AI tracking' — does Admaxxer have something similar?
No, and that's intentional. Hyros's 'AI' is widely treated as marketing copy by the operator community — Reddit threads on r/PPC and r/dtcecommerce repeatedly flag the 6-month server-side identity-stitching setup, opaque pricing tiers (~$799/mo entry that climbs with revenue), and the lack of a documented public methodology paper. Admaxxer competes on transparency instead of unverifiable promises: every attribution model has a published formula (see the Models table above), every API endpoint is curl-testable (see the curl examples in our model-specific docs), every Reconciliation Panel row carries a pre-computed 'reasoning' string explaining the gap, and Markov-chain attribution ships natively with the same algorithm Northbeam publishes in their methodology paper. If a competitor needs you to take their 'AI' on faith, that's a feature for them; if you want to verify the math yourself, that's the surface we built.
Which attribution model should I pick?
Default to time-decay (H=7d) for most DTC stores — it's the GA4 default and matches the typical 5-21 day consideration window. Switch to last-click if you optimize for bottom-funnel only, first-click if you're a top-of-funnel-heavy operator (podcast, influencer), linear-all-touches if your customers do 5+ touches over weeks, or position-based if you explicitly want to credit both discovery and closing. If you'd rather have one reconciled number per channel than a spread to argue over, turn on the Reconciled · Total Impact lens (BETA) — it blends those models with marketing-mix modeling, incrementality, and your post-purchase survey and reconciles the totals to your actual revenue. The Reconciliation Panel works the same way regardless of which heuristic model is active — it always shows you the gap between sources, the model just changes how that gap is computed inside the pixel column.
What is the Reconciled · Total Impact model and is it the default?
No — it is opt-in, not the default, and it's currently in BETA. Total Impact is a single reconciled number per channel built by blending four signals: multi-touch attribution (your deterministic click-level baseline), marketing-mix modeling (the spend-vs-revenue curve including diminishing returns), incrementality (a global paid-vs-organic lift estimate), and your post-purchase survey (word-of-mouth and offline channels no pixel sees). The channel totals are then scaled so they sum to your actual store revenue, and the result is shown as a point estimate plus a confidence range with a plain-English 'how this was computed' breakdown. Worked example: multi-touch credits Meta with $5,000; marketing-mix modeling trims $700 for diminishing returns; incrementality trims $450 as not-truly-caused-by-paid; your survey moves $300 toward word-of-mouth; after reconciling to ledger revenue, Total Impact for Meta lands around $4,150 with a roughly $3,800-$4,500 band. Because it's a modeled blend, read the band — not just the point — and keep the six deterministic models for the audit trail.
What attribution windows can I choose, and why was a 90-day window added?
The window is the lookback period — how far back before a purchase a touch can still earn credit — and it's independent of the model. Admaxxer offers 1-day, 7-day (the DTC default), 14-day, 28-day, the new 90-day window, and Lifetime. The 90-day window was added for considered, high-AOV catalogs (furniture, electronics, jewelry, courses) where a buyer might see your ad in week one and not check out until week ten. If a shorter window keeps under-crediting top-of-funnel because your customers take a month or more to decide, widen the window before you blame the model. Shorter windows are stricter and more conservative; longer windows capture slow-burn purchases.
What if I haven't connected my ad accounts yet?
Admaxxer's attribution is source-additive — it works with any subset of (pixel, Meta, Google, Shopify). With pixel-only you get UTM-driven attribution and the 6 models against pixel-tracked conversions. Add Shopify and you unlock the pixel-vs-Shopify reconciliation. Add Meta and you unlock the platform-vs-pixel comparison plus Meta's first-conversion data (Meta's deterministic match data behind ATT/iOS 14.5 that no pixel can replicate). Add Google and the same expands to Google Ads. Each source you add fills in another column in the Reconciliation Panel; missing sources show a 'data coverage' chip instead of breaking the page. Datafast skips ad-platform data entirely (UTM-only); Hyros forces a 6-month full setup before you see anything. We ramp with you.
How does the reconciliation panel handle direct/untagged traffic?
The panel surfaces direct/untagged traffic as its own row with a pre-computed 'reasoning' column explaining the gap. Common reasonings: 'Platform claims much more than pixel — likely iOS 14.5 view-through' (Meta is reporting view-through conversions your pixel can't see), 'High direct/untagged share — likely UTM hygiene issue' (you're missing UTM tags on a paid surface and the click is landing as direct), 'Within 10% — reconciliation clean' (the three sources agree; trust the model). Direct traffic itself isn't a problem; high direct share when you're spending heavily on paid IS a problem (likely UTM hygiene). The Reconciliation Panel surfaces the latter explicitly.
Can I see different attribution models side-by-side?
Yes — the AttributionTab at the top of /marketing-acquisition has a model-pill bar with all six heuristic models, plus the Reconciled · Total Impact lens (BETA). Click any pill to switch the active model; the table below re-computes in <500ms (analytics pipeline params change, not a re-fetch from raw rows). To compare two models side-by-side, open /marketing-acquisition in two browser tabs and pick a different model in each. A future enhancement (v1.5) will let you pin two models for in-page comparison; for now the two-tab pattern is the canonical workflow.
How often does Meta data refresh?
Once per day. The dailyAdSpendSync cron runs at 04:00 UTC and pulls (a) campaign + adset + ad-level insights via level=ad with the immutable campaign_id / adset_id / ad_id columns, (b) three breakdown calls (age_gender, region, placement), and (c) Meta's omni_purchase deduped first-conversion data (the deterministic match data that survives ATT). Meta itself reports its insights with a ~24-48h lag (Meta-side limitation, not Admaxxer's), so today's spend isn't fully attributable until the day-after-tomorrow's sync. The Reconciliation Panel shows a small 'last sync' timestamp on the Meta column so you know which data freshness window you're working with.
What's 'time decay' and why H=7?
Time-decay is an attribution model that weights each touch by how recently it happened, on an exponential curve. The formula is weight = pow(0.5, days_since_touch / H), where H is the half-life — the number of days at which a touch's credit drops to 50%. We use H=7 days because that's GA4's default and matches the 5-21 day DTC consideration window most stores see. A touch from yesterday gets pow(0.5, 1/7) ~= 0.91; a touch from 7 days ago gets exactly 0.5; from 14 days ago, 0.25; from 30 days ago, ~0.05. The key property: the credit decays smoothly with time instead of stair-stepping, so the model never has a sharp 'before/after' edge. v1.5 will expose H as a per-workspace knob for stores with longer (subscription, B2B) or shorter (impulse-buy) consideration windows.
Does Admaxxer's attribution match TripleWhale's?
Yes by construction in many cases, no in some. TripleWhale defaults to a 7-day-click attribution window with last-click as the model; Admaxxer's default is also 7-day-click but with time-decay (H=7d) so the two will differ on multi-touch journeys. Set Admaxxer to last-click + 7-day window and the two should match within ~5% (residual differences come from Admaxxer's pixel CV vs TW's pixel CV — different parsers, different UTM normalization). For deterministic apples-to-apples: use last-click + 7-day on Admaxxer, last-click + 7-day on TW, and they'll converge. The reason we default to time-decay is it's the more accurate model for DTC funnels (TW's last-click default is a holdover from pre-iOS-14.5 conventions). The Reconciliation Panel exposes the gap regardless of which tool you compare against — it's an honest 3-way view.