Documentation · Attribution · Markov-chain attribution

Markov-chain attribution: causal-graph credit for every touch

The seventh model in Admaxxer's attribution lineup — the same rigorous causal-graph approach Northbeam ships in their Probabilistic 1.0, applied to your pixel paths in real time. Free on every plan, gated on >=1000 attributable paths.

What is Markov? Removal effect vs the field FAQ

What is Markov-chain attribution?

Every visitor's journey through your funnel is a sequence: Meta paid → Email → Brand search → Purchase. Multiply that across thousands of visitors and you get a graph — nodes are channels, edges are transitions, weights are empirical transition frequencies. Markov-chain attribution treats this graph as a first-order Markov chain (the next state depends only on the current state) and asks the deceptively simple question: "if I removed this channel from the graph entirely, by how much would the overall conversion rate drop?"

That drop is the channel's removal effect. Channels that consistently appear in successful paths but rarely in dead-end paths get a high removal effect — they're load-bearing. Normalize the removal effects across channels and you have credit assignment that uses the full path topology — not just position (last-click / first-click) or rule-of-thumb weights (linear / position-based / time-decay).

The removal effect is the gold standard among multi-touch models because it doesn't pre-bake any opinion about funnel shape. The data tells you which channels are critical.

The removal-effect intuition

Build the transition matrix from your path data: P[i,j] = empirical probability that a visitor in state i transitions to state j next. Two absorbing states matter: the conversion state (purchase) and the null state (drop-off). Compute the probability of reaching conversion from each non-absorbing state — that's a small linear-system solve against the transition matrix. Call this baseline conversion probability P*.

Now repeat the computation, but zero out all transitions involving a single channel C. The new conversion probability is P*_{-C}. The removal effect of C is RE(C) = (P* - P*_{-C}) / P*. High RE = channel is critical. Low RE = channel is replaceable in the visitor's path.

Normalize across channels (RE values typically sum to slightly less than 1 because there's interaction structure that doesn't fully decompose), and you have per-channel credit shares. Multiply by total conversion count = attributed conversions. Multiply by attributed revenue / conversion = attributed revenue. That's the MarkovChannelEffect row Admaxxer returns from /api/v1/analytics/attribution/markov.

Implementation note: path-graph algorithms are awkward in SQL at scale. The Tinybird pipes (attribution_breakdown.pipe, source_medium_breakdown.pipe) intentionally do NOT branch on markov. Instead a small pipe (p_markov_paths) returns the raw touch sequences; server/lib/attribution/markov.ts builds the transition matrix in TypeScript and solves the linear system. ~600 lines of Node, no Python deps.

When Markov works (and when it doesn't)

Use Markov when: you have >=1000 attributable paths per window (typically $40K+/mo ad spend); multi-touch funnels with most paths having 3+ touches across 5-21 days; you're comparing TOF (paid-social, podcast) vs MOF/BOF (retargeting, brand search) credit; you want a model that doesn't pre-bake an opinion about funnel shape; you're cross-checking last-click + time-decay and want a third triangulation point.

Don't use Markov when: you have <1000 paths in your window — empty state will surface; your funnel is single-touch dominated (Markov collapses to last-click in degenerate cases); you're optimizing for bottom-funnel only — last-click is the simpler, more interpretable model; compliance / explainability constraints require linear or position-based weights you can hand-trace.

Markov in DTC tools — Admaxxer vs the field

Markov attribution is the gold standard among multi-touch models, but only a handful of DTC tools ship it natively. Pricing is the more important axis — most tools that ship Markov are enterprise-priced. Admaxxer is the only sub-$200/mo tool with native Markov.

ToolShips MarkovNotes
Admaxxer Yes Markov ships native in the model picker alongside last-click, first-click, linear (all + paid), time-decay (H=7d), and position-based (40/20/40). Removal-effect computed in Node from pixel touch graph, gated on >=1000 paths. Free on every plan.
TripleWhale Limited TW's 'Multi-Touch Attribution' is a black-box weighted blend rather than a true Markov chain. No published removal-effect surface. $129+/mo with attribution as a paid add-on.
Hyros No Server-side identity stitching focused on first-click + view-through, no Markov. ~$799/mo with a 6-month full-setup requirement.
Northbeam Yes Ships a 'Probabilistic 1.0' model based on Markov + ML-blended priors. Enterprise pricing only (~$10k+/yr).
Polar Analytics Limited Surfaces last-click + first-click + linear primarily; Markov is on the v2 roadmap but not yet in product. ~$149+/mo.
Datafast No UTM-only attribution, doesn't ingest paid platforms. Markov isn't applicable.

How to switch your model to Markov — 4 steps

  1. Step 1. Confirm you have >=1000 attributable paths in your window. Markov needs path density. Below 1000 paths the transition-probability matrix becomes too sparse for stable removal-effect estimates. The Admaxxer pipe checks paths_observed >= MARKOV_MIN_PATHS (1000) and returns data_status='insufficient_data' below that.
  2. Step 2. Open /marketing-acquisition and pick Markov from the model dropdown. AttributionTab + ReconciliationCard both read the active model from the same AttributionModel enum. Switching to Markov refreshes both surfaces with the removal-effect channel ranking.
  3. Step 3. Compare the Markov ranking against last-click + time-decay. Heuristic models (last-click especially) systematically over-credit closing channels and under-credit warming channels. Markov's removal-effect rebalances. If your TOF channels jump 2-3x vs last-click, that's the signal.
  4. Step 4. Read the Reconciliation Panel with Markov as the model. ReconciliationCard accepts attribution_model='markov' and shows the same 3-way side-by-side (Platform-claimed / Pixel-attributed / Shopify-denominator) but with the pixel column computed under Markov.

Curl example

Every Markov call is a single GET against /api/v1/analytics/attribution/markov. Pass since, until, and attribution_window_days; get back the per-channel removal-effect ranking with attributed revenue. No SDK required — copy, paste, swap $TOKEN.

# Rank channels by Markov removal-effect for April 2026 (28-day window).
# Replace $TOKEN with a workspace API key from /settings/api.
curl -H "Authorization: Bearer $TOKEN" \
  "https://admaxxer.com/api/v1/analytics/attribution/markov?since=2026-04-01&until=2026-04-30&attribution_window_days=28" \
  | jq '.channels[] | {channel, removal_effect, attributed_revenue}'

# Sample response (truncated):
# {
#   "data_status": "ok",
#   "paths_observed": 1842,
#   "channels": [
#     { "channel": "meta_paid",   "removal_effect": 0.34, "attributed_revenue": 28450 },
#     { "channel": "google_paid", "removal_effect": 0.22, "attributed_revenue": 18420 },
#     { "channel": "email",       "removal_effect": 0.18, "attributed_revenue": 15080 },
#     { "channel": "organic",     "removal_effect": 0.15, "attributed_revenue": 12560 }
#   ]
# }

FAQ

What is Markov-chain attribution in one sentence?
Markov-chain attribution treats each visitor's path as a sequence of states (channels) and asks: 'if I removed this channel from the graph, by how much would the conversion probability drop?' That drop, normalized across channels, is the channel's credit. It's the textbook causal-graph approach to multi-touch attribution and is the same algorithm Northbeam ships in their Probabilistic 1.0 model.
Why is Markov better than last-click or linear?
Last-click and first-click only see one touch in the path. Linear gives every touch the same weight regardless of position or how often that channel converts on its own. Markov uses the actual conversion probabilities from the path graph - channels that consistently appear in successful paths but rarely in failed paths get more credit. It's the only model in our 7-model lineup that uses the FULL path topology, not just touch positions.
How many orders/paths do I need before Markov is reliable?
Admaxxer's threshold is 1000 attributable paths in the selected window. Below that, the transition-probability matrix is too sparse and the removal-effect estimates have high variance. The endpoint returns data_status='insufficient_data' and the UI shows an empty state. For a typical $200 AOV DTC store, 1000 paths is roughly 200-500 orders depending on multi-touch rate - workable for stores doing $40K+/mo in ad spend.
Does Markov replace the other attribution models?
No - it's an additional model, not a replacement. The 7 models are designed to be picked based on funnel shape: time-decay for typical DTC, last-click for bottom-funnel-only, first-click for TOF-heavy, position-based for both-discovery-and-closing, linear for fairness baselines, and Markov when you have the path density and want the most-rigorous causal-graph view.
How is Markov computed - Tinybird SQL or Node?
Node. The Tinybird pipes (attribution_breakdown.pipe, source_medium_breakdown.pipe) intentionally do NOT branch on markov because path-graph algorithms are awkward to express in SQL at scale. Instead, the dedicated /api/v1/analytics/attribution/markov endpoint pulls the touch-by-touch path data from a small Tinybird pipe (p_markov_paths), builds the transition matrix in Node (server/lib/attribution/markov.ts), runs the removal-effect computation, and returns MarkovAttributionResponse. ~600 lines of TypeScript total, no Python deps.
Does Markov respect attribution-window-days and paid-only filters?
Yes. The fetcher applies the same filters (attribution_window_days, paid_only, new_customers_only) as the SQL pipes - they shape the touch graph at the source. The removal-effect computation runs on whatever graph survives the filter.
Does TripleWhale or Hyros ship Markov attribution?
TripleWhale's 'Multi-Touch Attribution' is a weighted blend, not a true Markov chain. Hyros doesn't ship Markov at all. Northbeam ships a true Markov-based 'Probabilistic 1.0' model. Admaxxer is the only sub-$200/mo tool that ships Markov natively.
Can the Claude AI agent use the Markov ranking?
Yes. The query_metrics tool exposes attribution_model='markov' as a valid value. Asking the agent 'rank my channels by Markov removal-effect over the last 28 days' resolves to a single tool call against /api/v1/analytics/attribution/markov.
When does Markov stop working?
Below 1000 attributable paths in the selected window, the transition-probability matrix becomes too sparse for stable removal-effect estimates. We hard-gate the endpoint: under that threshold, /api/v1/analytics/attribution/markov returns data_status='insufficient_data' and the UI renders a premium empty-state pointing back at time-decay (H=7d) instead of showing noisy ranks that look authoritative but aren't. For a typical $200 AOV DTC store, 1000 paths is roughly 200-500 orders/month depending on multi-touch rate. Other Markov-failure modes: single-touch-dominated funnels (Markov collapses to last-click in degenerate cases), brand-search-heavy paths (the brand-search node attracts most removal-effect mass and the ranking inverts), and post-event windows that don't extend back far enough to capture the full path (we recommend at least 28 days for any Markov call).