Anyone can compute a contribution value once. What we built is the system that computes them continuously, at scale, on live spend, records every prediction before anyone acts, and grades itself after. This page says exactly how, including the parts we refuse to claim.
The system does two different jobs and does not let them blur.
Measurement answers: over this trailing window, what did each part of the spend actually contribute to deposits, relative to its cost? That is an attribution of observed value, not a forecast.
Prediction answers: if you move the next dollar, what happens? That is a model fit on top of the measured contributions, and it ships with its uncertainty attached.
Keeping them separate means a bad forecast never rewrites what was measured, and you can always check the measurement layer independently of any model we fit on it.
We treat the units of spend you can act on as players in a cooperative game: partners, data segments, supply paths, creative lanes, whatever level the decision lives at. The value function is your outcome over the window, deposits against cost. The contribution score for each player is its Shapley value: its average marginal contribution across orderings of the players.
Two properties matter in practice. The decomposition is exhaustive: by the efficiency axiom the parts sum exactly to the observed total, so nothing is invented and nothing is left over. And it is interaction-aware: a segment that only works when another one is present gets credited for that, which last-touch logic structurally cannot do.
Exact enumeration is used when the player set is small. Above roughly twenty players we switch to complementary contribution sampling, which scales to hundreds of interacting players and returns each estimate together with its sampling variance. That variance is not decoration; it feeds the intervals in section 04.
Overlapping segments are handled explicitly with intersection data rather than assumed away. And alongside the coalition family we run a second attribution family with different assumptions, Markov removal effects over path data, as a cross-check. Where the two families disagree, the disagreement is reported as a finding, not averaged into a single number.
On top of the measured contributions we fit response curves per unit: contributed outcome against spend over the trailing window. The number we report as marginal cost per deposit is the local slope at your current spend level, not the blended average. Blended tells you what you paid; marginal tells you what the next dollar costs, and those diverge exactly where a channel is saturating.
When more than one outcome matters, the objectives are weighted the way you declare, not the way a model finds convenient, and the allocation recommendation is solved as a constrained optimization over the levers you actually control. Budgets, floors, minimums, and anything you fence off stay fenced off.
Uncertainty enters twice and we carry both: sampling variance from the contribution estimator, and fit uncertainty from the response curve on the window. The interval printed next to an estimate is the combination, at a declared level. The working dashboards print 80% central bands so the ranges stay honest at a glance; formal reads run at 95% where a decision warrants it. The level is always stated on the surface that shows the number.
This is the part that is not in a paper, and it is the reason the system gets better on your data instead of just describing it.
Every analysis run is an ablation: same data, one thing changed or removed, difference measured. Every run is recorded with its inputs, settings, window, estimate, and band. When the system recommends a move, the predicted result is written down before anyone acts. Then the action that actually happened is logged, including "did nothing." Then the mature outcome is measured, against a holdout slice where the design allows one, and the prediction is graded against it. The grade feeds the next run.
The loop runs at every altitude at once: channel, partner, segment, supply path. As the record compounds, the same loop extends to decisions above and below media, including which market goes in front of which person once the after-the-click data is in reach.
A property of coalition attribution worth being straight about: the grand total is preserved at any granularity, but the per-player values at a coarse level are not the rollup of the values at a finer level. Partner-level, segment-level, and path-level runs are different games with different coalition structures. So we do not quietly pick a level. Every read states the level it was run at, and when a decision needs a finer level, we run that level rather than dividing a coarse answer.
Your geo holdouts and lift tests answer whether a channel works at all. They are slow by design and they cost you a dark cell. This system answers a different question: inside the spend you are already running, which parts are earning their price right now. The two compose. A lift test sets the ceiling and the weight for a channel; the decomposition allocates underneath that ceiling, and the built-in holdout slice keeps grading us while you keep every channel live.
An NDA and DPA, log-level exports from the platforms you already buy through, your deposit table keyed however you key it, and one trailing window. The first read is checkable against what you already believe before you act on anything. The working question list is at /questions, with a suggested path from first read to earned authority. What to demand from partners whose logs are thin is at /logs.