[object Object]

Attribution is the report most likely to start a fight and least likely to end it. Every model tells a different story, every team picks the model that makes their channel look best, and finance discovers six months in that the numbers do not reconcile to the P&L. The board deck quotes one number, the CMO dashboard quotes another, and the actual paying customers are unmoved by either.

You do not need a perfect model. You need a chosen model, documented, with known limitations.

What HubSpot actually offers

HubSpot’s attribution report supports first touch, last touch, last engagement, linear, U-shaped, W-shaped, full path, and several time-decay variants. They all run on the same underlying interaction data: page views, form fills, email engagements, chat sessions, meeting bookings.

The model is a weight function over those interactions. That is it. The interactions are the signal. The model is the politics.

The decision criteria

Pick by what question you are answering.

QuestionModel
Which channel discovers customers?First touch
Which channel closes them?Last touch
Which channels deserve credit holistically?Linear or W-shaped
Where did we lose them in the funnel that did not convert?Full path with negative weighting (manual)
What did marketing contribute to revenue?W-shaped (most honest balance)
What is finance willing to defend?First touch (auditable)

The finance row is the one most teams skip. Finance does not want a fair model. Finance wants a defensible model. First touch is defensible because there is exactly one first touch per deal. W-shaped is fair but harder to defend to an auditor.

Default recommendation

For most B2B teams: W-shaped for the marketing dashboard, first touch for the finance report, both visible and reconciled monthly. You are not “doing attribution twice.” You are answering two different questions.

Why time decay rarely wins

Time decay sounds smart. Recent touches get more weight because they are closer to conversion. Practically, time decay flatters whatever channel runs the closing nurture, which is almost always email, which is almost always already credited. It double-counts your closer.

Skip it unless you have a documented reason that contradicts the above.

Building a custom model when the built-ins do not fit

If your deal cycle has a defined stage gate you trust (say, demo booked is your real conversion event, not closed-won), you need stage-weighted attribution that HubSpot does not ship out of the box. Build it with a workflow.

exports.main = async (event, callback) => {
  const dealId = event.object.objectId;

  const deal = await hsClient.crm.deals.basicApi.getById(dealId, [
    "amount",
    "hs_deal_stage_probability",
    "dealstage",
  ]);

  const contactIds = await getAssociatedContactIds(dealId);
  const interactions = [];
  for (const cid of contactIds) {
    const events = await getInteractionTimeline(cid);
    interactions.push(...events);
  }
  interactions.sort((a, b) => a.timestamp - b.timestamp);

  // W-shaped weights: first 30%, lead conversion 30%, opportunity creation 30%, others split 10%
  const weights = computeWShapedWeights(interactions);

  const amount = Number(deal.properties.amount || 0);
  const attribution = {};

  for (let i = 0; i < interactions.length; i++) {
    const source = interactions[i].source || "direct";
    attribution[source] = (attribution[source] || 0) + amount * weights[i];
  }

  await persistAttribution(dealId, attribution);
  callback({ outputFields: { attributed: "true" } });
};

Persist into a custom object so the report query is fast. Do not recompute on every dashboard load.

HubSpot attribution depends on the hubspotutk cookie. Cookie lifespan, third-party blocking in Safari, and increasing first-party consent friction all shrink the window in which a touch is captured.

In 2026, expect cookie attribution to capture 50-70% of touches reliably, not 100%. The other 30-50% goes “direct” because the touch was real but not tracked. Direct is now the largest channel in many portals. That does not mean direct is winning. It means tracking is losing.

Mitigations:

  • First-party tracking via server-side events
  • UTM hygiene with documented standards
  • Self-reported attribution on forms (“how did you hear about us”) with structured options, treated as a tiebreaker not gospel

The self-reported question is the cheapest control. The structured options matter. Free text becomes garbage.

Pipeline attribution vs revenue attribution

Pipeline attribution credits sources for opportunities created. Revenue attribution credits sources for closed-won. They are different and should be reported separately.

A channel can be great at pipeline and terrible at revenue. Paid social often is. You see it only when you split the views. Pipeline-only dashboards justify spend that revenue-only dashboards kill.

Reconciling to the GL

Pick one source of truth for the revenue number. It is the GL, not HubSpot. HubSpot’s revenue may include taxes, exclude refunds, or differ on close date conventions.

Build a monthly reconciliation:

  • GL revenue by close month
  • HubSpot closed-won amount by close month
  • Variance with explanation by category (timing, refund, tax, currency)

If you cannot reconcile within 2%, your attribution numbers do not matter. Fix reconciliation first.

See multi-touch attribution models for the model deep dive and the attribution reports overview for HubSpot’s built-in flavors.

Bottom line

  • Pick by question answered, not by what makes your channel look best.
  • W-shaped for marketing balance, first touch for finance defensibility, run both.
  • Time decay rarely tells you anything first touch and last touch do not.
  • 30-50% direct in your attribution is a tracking problem, not a channel; mitigate with first-party events and self-reported tiebreakers.
  • Reconcile to the GL monthly within 2%; the model is meaningless if the totals do not match.
[object Object]
Share