Features
Attribution at every stage of the funnel
Ad platforms report the conversion they touched last. Attruly measures every channel, campaign, ad group, keyword, landing page, country, device and OS version against every milestone you define — signed up, activated, added a card, subscribed.
Funnel-stage attribution
Every milestone, measured against every segment
Put your goals in order once and every channel, campaign, device model and OS version is measured against all of them at the same time. The ranking changes as you move down the stages, and that change is the whole report.
| Channel | Signed up | Activated | Added payment | Subscribed | Revenue |
|---|---|---|---|---|---|
| Paid Social | 418 | 9623.0% | 122.9% | 30.7% | $1,497 |
| Paid Search | 301 | 17257.1% | 8829.2% | 4113.6% | $20.5K |
| Organic Search | 224 | 15870.5% | 9743.3% | 6227.7% | $30.9K |
| 148 | 12181.8% | 8456.8% | 5839.2% | $28.9K | |
| AI Assistants | 63 | 4469.8% | 2742.9% | 1625.4% | $7,980 |
| Direct | 190 | 11862.1% | 6132.1% | 3417.9% | $17K |
Paid Social brings 418 signups here, more than any other channel. Ninety-six activate, twelve add a payment method, three subscribe. Email brings 148 signups and ends with 58 subscriptions.
Ranked on signups, Paid Social leads the account by almost three to one. Ranked on subscriptions it finishes last, and the platform optimising it has no way to say so.
Progression funnel
Every stage in order, with the people lost at each step and the share of the previous stage that carried through.
Stage matrix
One row per segment, one column per stage. Each cell carries a count and that segment’s own entry-to-stage rate, tinted against the cohort’s rate at the same stage — good at a signup step and good at a checkout step are orders of magnitude apart.
Highest and lowest yield
The segments beating or missing the cohort’s own rate at the stages that pay, ranked by how much traffic the gap covers. Missing the average by twelve points on nine hundred people outranks missing it by forty on eleven.
Best performer at each stage
The top segment for every milestone with its share of everyone who reached it, and the runner-up behind it.
Tracking health
Unexpanded {campaign} placeholders, one value spelled two ways, a utm_source with no utm_medium, and the share of entrants carrying no campaign data at all — counted in people affected.
How the cohort is counted
The rules, written where you can check them
A funnel report is worth acting on only if you know what it counted. These are the rules Attruly applies, and the screen repeats them next to the numbers they produced.
Entry is the first time, ever
A person enters the funnel the first time they ever convert on step one, and they belong to the period that entry falls in. Converting on step one again next month does not move them.
Later stages are counted as of today
A cohort from this week has had less time to reach the bottom than one from three months ago, so a recent window always reads less converted. The report says that under the chart rather than letting anyone mistake a young cohort for a bad one.
Stages are ordered, not nested
Someone can reach stage four without ever matching stage three. That shows up as a gain on the stage, with the count named, because a drop-off of minus eighteen rendered as a drop-off is a lie.
Under 10 people it says nothing
A segment with fewer than 10 entrants is never called good or bad. A rate built on four signups is not a finding, and one lucky conversion in a segment of two should not arrive at the top of the page as the best thing in the account.
The window is yours
Leave a funnel open when the journey legitimately runs for months, or give it a fixed window when the question is whether somebody finished checkout — a purchase six weeks later is a different visit and a different intent.
First touch or last
The entry can be credited to the touch that started the person or the one that closed them, and the whole report recomputes either way.
Dimensions
Sixteen ways to cut the same funnel
Switch the breakdown and the same cohort is regrouped against the same milestones. Start at channel to see the shape, then go down to the ad group, the keyword, the device model or the OS version — the level an ad platform lets you act on.
Android 10 signs up 187 people this month, more than any other OS version in the account. Four of them reach the payment step. None subscribe.
That is an exclusion you can paste into Google Ads this afternoon. Grouped by channel, those 187 people disappear into a row that looks healthy. Counted only at the last step, they never appear at all.
Acquisition
- Channel
- Source
- Medium
- Source / Medium
- Campaign
- Ad group / Content
- Keyword / Term
- Referrer
Content
- Landing page
Audience
- Country
- Region
- City
Technology
- Device type
- Device model
- Operating system
- Browser
Media spend attaches to channel, source, medium and campaign. Nobody can upload a cost per browser version, so on the other dimensions the cost metrics stay blank instead of showing you a zero you might believe.
Identity
One person, however many devices
A funnel counts people, not sessions. Stage four is only comparable to stage one if the product knows that the anonymous browser from March and the signed contract from May are the same person.
An alias graph, not a cookie
Every identifier we have ever seen for a person — browser ids and your own user ids — points at one profile. Resolving a visitor is a single indexed lookup.
Merging, done carefully
When two profiles turn out to be one person, they merge: the identified profile survives, the earlier first-touch is kept, and every conversion is re-credited.
Cross-device by default
Someone who researched on their phone and bought on a laptop is one customer with one path — as long as they identified on both.
Attribution models
Six models, and the funnel entry takes one too
Every report is computed under a model you pick, and switching it recomputes the page. It is the fastest way to see how much of your reporting is a modelling choice rather than a fact.
| Model | Type | What it is for |
|---|---|---|
| First touch | Single touch | Answers "what creates demand". Favours awareness channels and will make your brand campaigns look better than your retargeting. Use it when you are deciding where to spend to reach new people. |
| Last touch | Single touch | The default in most ad platforms, which is why they all claim the same conversion. Favours closing channels — branded search, retargeting, email. Simple, and consistently overstates the bottom of the funnel. |
| Last non-direct | Single touch | Last touch, but it skips past "direct" — someone typing your URL or arriving with a stripped referrer is not a marketing channel. This is what GA4 does by default and it is usually the fairest single-touch view. |
| Linear | Multi touch | Treats every touch as equally responsible. Honest about the fact that a journey has many steps, deliberately naive about which mattered. A good sanity check against the single-touch models. |
| Position based | Multi touch | The U-shaped model. Rewards the channel that found the person and the channel that closed them, while still acknowledging the middle. The pragmatic default for most teams running both awareness and performance. |
| Time decay | Multi touch | Credit halves for every half-life period further from the conversion. Right for short consideration cycles, where a touch from six weeks ago genuinely mattered less than one from yesterday. |
A funnel entry takes first or last touch, so you can ask whether the campaign that started these people was the same one that closed them.
AI analysis
An analyst that has to show its working
Sixteen dimensions across five stages is more cells than anyone reads on a Monday. Point the analysis at a window and it returns the segments carrying people to the money, the ones consuming budget and stopping early, ordered recommendations, and the caveats that would make the read unreliable. Every number in the output is copied from the evidence pack rather than estimated.
- Reads six traffic breakdowns — channel, source / medium, campaign, landing page, device type and operating system — against the window before it.
- Reads your primary funnel as well: the same segments scored at every stage, so it can tell you where a campaign stops rather than only that it converts badly.
- Will not build a traffic recommendation on a segment under thirty visits, or a funnel recommendation on one with fewer than ten people in it. It can raise either as something to watch, and has to say that is what it is doing.
- Refuses to run at all on a window with fewer than fifty visits, and tells you to widen the range instead of inventing a conclusion.
- Never recommends spending more or less on Direct, because nobody can buy Direct. A high direct share is raised as a tracking-coverage caveat instead.
- Says nothing about ROAS or CPA when the project has no cost data. It knows conversion rates and revenue, not what anything cost, and it names that as the gap.
- Returns fewer items and low confidence when the evidence does not support more. An empty list is an acceptable answer.
- Knows that funnel stages are not strictly nested, so it does not report a later stage overtaking an earlier one as an error.
- Reads aggregates only. No email address, name, IP address or individual profile reaches a model provider.
Reporting
Group by anything, measure anything
Any dimension against any of twenty-one metrics, filtered, sorted, compared with the previous period and exported to CSV. The overview is the same data read at a glance.
Visitors
17.4K
+18.4%vs previous period
Conversions
814
+24.1%vs previous period
Attributed revenue
$121.3K
+31.7%vs previous period
Blended ROAS
4.0x
−4.2%vs previous period
Visits over time
Revenue by channel
- Organic Search212 conversions · 4.3% rate$31.8K
- Paid Search184 conversions · 3.0% rate$27.6K
- Email148 conversions · 6.7% rate$22.2K
- Direct96 conversions · 4.0% rate$14.4K
- AI Assistants51 conversions · 5.4% rate$9,180
- 3 more rows not shown
Traffic mix
- Paid Search27%
- Organic Search22%
- Paid Social18%
- Direct11%
- Email10%
- Referral5%
- AI Assistants4%
- Organic Social4%
Metrics
- Visitors
- New visitors
- Visits
- Pageviews
- Bounces
- Time on site
- Conversions
- Revenue
- Spendneeds spend
- Impressionsneeds spend
- Ad clicksneeds spend
- Bounce rate
- Avg. visit
- Pages / visit
- Conv. rate
- Rev. / visitor
- Avg. value
- CPAneeds spend
- ROASneeds spend
- CPCneeds spend
- CTRneeds spend
Tracking
Two SDKs, one dataset
The browser SDK captures the top of the funnel: the click, the campaign, the landing page. The server SDK captures the stages that pay — the webhook, the CRM stage change, the refund — which a browser never sees. Both write to the same person.
- Under 4KBGzipped, no dependencies, loaded with defer so it never blocks a paint.
- First-partyServed from your Attruly domain, so ad blockers and ITP treat it as yours.
- Automatic capturePageviews, SPA route changes, UTM parameters, click ids and referrers.
- Offline safeEvents queue when the network is gone and flush on reconnect, deduplicated by message id.
<script defer
src="https://www.attruly.com/a.js"
data-key="pk_live_YOUR_KEY"></script>attruly.identify('user_8412', {
email: 'sam@acme.com',
plan: 'growth',
})
attruly.track('Demo Booked', {
source: 'pricing_page',
seats: 12,
})import { Attruly } from '@attruly/node'
const attruly = new Attruly({ apiKey: process.env.ATTRULY_SECRET_KEY })
// A Stripe webhook the browser never sees — still attributed to the
// campaign that brought this person in, months earlier.
await attruly.track({
userId: invoice.customer,
event: 'Subscription Paid',
revenue: invoice.amount_paid / 100,
currency: invoice.currency.toUpperCase(),
})Classification
Your utm_source is a mess. That is fine.
Google / Paid, google / cpc and an untagged gclid all mean the same thing. Attruly folds them into one row so a campaign enters the funnel once, with the spelling your traffic actually used.
Paid Search
PaidSearch ads — Google Ads, Microsoft Ads. Matched on a cpc/ppc/paid medium or a gclid.
Paid Social
PaidPaid placements on social platforms, including clicks carrying an fbclid or ttclid.
Display
PaidBanner, programmatic and retargeting placements.
Video
PaidVideo placements — YouTube campaigns and in-stream advertising.
Organic Search
Unpaid search traffic, matched on an organic medium or a search-engine referrer.
Organic Social
Unpaid posts, profile links and shares on social platforms.
AI Assistants
Referrals from ChatGPT, Claude, Gemini, Perplexity and peers.
Newsletters, lifecycle and drip campaigns, plus links opened from webmail.
Affiliate & Partner
PaidAffiliate links, partner co-marketing and referral programmes.
SMS & Messaging
SMS, WhatsApp, push notifications and in-app messaging.
Referral
Links from third-party sites that are not search, social or AI.
Internal
Traffic tagged from the project’s own properties — not an acquisition source.
Other Campaign
Tagged traffic whose medium does not map to a known channel.
Direct
No campaign tag and no referrer. Typed URLs, bookmarks, and traffic that lost its referrer in transit.
The rest of it
What running this every week needs
The tracking, the identity graph, the models and the reporting are one system, because attribution breaks at the seams between tools.
One project per site
Every site gets its own keys, goals, funnels, timezone and currency, and they never share data. That separation is what makes this workable for an agency.
Raw events, kept
Not a sampled aggregate. Every event stays queryable and exportable for as long as your plan retains it, so a number you disagree with can be traced back to its rows.
Real-time
An event lands and the dashboard reflects it. Nothing waits four hours to tell you whether a launch worked.
Person-level paths
Open a profile and read the whole path in order — every touch, every session, every event, with the credit each one received.
Spend, CPA and ROAS
Import your media spend and every channel, source, medium and campaign row carries its own cost per acquisition and return, next to the conversions it earned.
First-party by design
Your domain, your data, your database. Self-host the whole thing on your own infrastructure if that is what compliance needs.
See it against your own funnel
Install the snippet, put your milestones in order, and compare what Attruly says to what your ad platforms claim.