Follow The Spend
Attribution

How attribution is computed

The math, step by step. Useful for analysts who want to reproduce numbers or reconcile against other tools.

This page is for the technically-minded reader who wants to understand exactly what FTS does to turn raw events into attributed revenue. If you just want to use Pulse and trust the numbers, How attribution works is the lighter read.

The pipeline

For every conversion (Shopify order linked to a visitor journey), attribution runs through these steps:

  1. Identify the visitor. Match the order's customer ID to the visitor cookie. If matched: proceed. If unmatched: order is recorded but flagged with no attributable journey.
  2. Pull the journey. Get every session for this visitor, ordered by session start time, ascending.
  3. Apply the lookback filter. Drop any session older than 30 days before the conversion timestamp.
  4. Apply the model. Distribute conversion revenue across the remaining sessions according to the active model.
  5. Aggregate by channel. For each session that received credit, increment the corresponding channel's revenue total by its credit amount.

That's the full pipeline. Five deterministic steps. The same inputs always produce the same outputs.

Step 1 — Identify the visitor

Two paths from order to visitor:

Path A: Pixel-driven (the common case). When the visitor reaches the thank-you page, our pixel fires a conversion event with both the order ID (read from the page) and the visitor cookie. The two are linked.

Path B: Webhook-only (the express-checkout case). Buy It Now / Shop Pay buyers never see the thank-you page. The order webhook arrives with a customer ID, and we look up whether that customer has any prior identification on a visitor cookie. If yes, we link to that visitor. If no, the order is unattributed (shows as direct).

See Why Buy It Now / Shop Pay shows as direct for the full v1.0 limitation.

Step 2 — Pull the journey

The journey is all sessions belonging to this visitor, sorted by session start time ascending. This includes:

  • Sessions that converted in the past
  • Sessions that bounced
  • Sessions before identification (anonymous), if they were on the same cookie
  • Sessions across multiple days

It does not include:

  • Sessions on a different cookie (e.g. different browser, different device — unless merged via customer login)
  • Sessions before our pixel was installed on your store

Step 3 — Apply the lookback filter

We compare each session's start time to the conversion timestamp:

keep_session = (conversion_time - session_start_time) <= 30 days

Sessions older than 30 days are dropped from the journey for attribution purposes. They remain visible in the Visitor Journey UI (so you can see the full history) but are not credited.

This is a per-conversion lookback, not a per-visitor one. If a visitor has two conversions, each conversion's attribution is computed against its own 30-day window.

Step 4 — Apply the model

Three deterministic rules.

First-touch

credit[first_session] = order_revenue
credit[other_sessions] = 0

The earliest session in the lookback-filtered journey gets 100% of the credit. All other sessions get zero.

Last-touch

credit[last_session] = order_revenue
credit[other_sessions] = 0

The latest session before the conversion gets 100%. The "last" session is usually the converting session itself.

Linear

credit[each_session] = order_revenue / N

Where N is the number of sessions in the lookback-filtered journey. Equal split, no weighting.

Step 5 — Aggregate by channel

For each session that received credit, add its credit to the running total for that session's channel:

channel_revenue[meta_paid_social] += credit[session_1]
channel_revenue[email]             += credit[session_2]
channel_revenue[direct]            += credit[session_3]
...

Repeat across every conversion in the active date range. The resulting per-channel totals are what populate the channel performance table in Pulse.

Worked example

A visitor with this journey converts at $120:

Day 1, 14:32 — Meta paid social  (4 min, no order)
Day 3, 09:15 — Klaviyo email      (1 min, no order)
Day 5, 21:08 — Direct → ORDER ($120)

All three sessions are within the 30-day lookback (relative to day 5). The journey passes through unfiltered.

ModelMeta paid socialEmailDirect
First-touch$120$0$0
Last-touch$0$0$120
Linear$40$40$40

These numbers are exactly what Pulse will show under each model toggle for this conversion's contribution.

What changes when models switch

Nothing in the data. The journey, the sessions, the order, the channel classifications — all stay the same. Only the credit allocation changes. This is why Pulse can switch models with zero recalculation lag.

It also means you can sanity-check by adding up attributed revenue across all channels. Under all three models, the total should equal total conversion revenue (within rounding).

Edge cases

A few worth knowing:

  • Single-session journey. All three models give 100% credit to the single session. First/last/linear produce identical results.
  • Two sessions on the same channel. Linear splits evenly between the two; first/last credits one of them. Channel-level total is the same.
  • Refunded order. When a refund webhook arrives, we reduce the original order's revenue by the refund amount. Attribution is recomputed using the (smaller) revenue figure. If fully refunded, attribution credit goes to zero across all sessions.
  • Cancelled order. Excluded from attribution entirely (never enters the pipeline).

Where to go next

On this page