Investigation · Ad attribution leak

Why ~1 in 5 ad clients
looks like they came for free

About a fifth of new clients each month have no Google click on record, yet clearly came through the paid funnel. This is a full teardown of where the tracking loses them, whether Google's own data can plug the gap, and how to monitor it going forward.

The finding

The "organic" number is not organic

In June, 216 people became new clients. Only 170 had a Google ad click recorded. The other 46 look organic — but when you check how they actually arrived, most of them came straight through the paid placement funnel.

216
new clients, June 2026
170
had a Google ad click on record
41
no click — but took a LUFT call
5
genuinely no signal at all
170 · attributed
23
18
5
Attributed — Google click captured (170) Filed as "organic" but took a LUFT call (23) Never tracked at all, but took a LUFT call (18) No click, no call — genuine unknown (5)
The headline: the true organic floor is about 5 people a month, not 45. The other ~41 are paid clients the tracking failed to credit — so the Paid Search report understates how well the ads actually work by roughly 20%.

It happens every month

Share of each month's new clients who took a LUFT call but had no ad click recorded. The genuine "no click, no call" group sat at 3–7 people every single month — a stable, believable organic floor.

42%
Feb
26%
Mar
15%
Apr
15%
May
19%
Jun
20%
Jul

Feb is inflated — click history was still being backfilled that month. The settled rate is 15–20% of new clients mis-filed as non-paid.

Front A · The tracker

Are we doing something technically wrong?

◆ Partly — the capture is good, the memory is short

The attribution-tracker plugin reads the Google click id server-side, from the URL, on every page load — before any JavaScript, cookie banner or ad blocker can interfere. That part is genuinely well built: a consent pop-up does not block it. The click id is written to a first-party cookie and a server-side session row.

The loss happens later — at the moment a click has to be tied to a person. Three structural weaknesses:

Ad click
gclid read from URL, server-side ✓
Stored
in a cookie — but only 30 days, one browser
Weeks pass
therapy is a slow decision; cookie expires or Safari caps it to 7 days
Books & buys
different device / cookie gone → no click id at submit
Result
conversion is discarded or filed as organic
How a paid client gets lostVulnerable?ImpactWhy
Consent banner / ad blocker blocks captureNoNoneclick id is read server-side from the URL before any JS runs — the plugin's real strength
Cookie only lasts 30 daysYesHighGoogle's own window is 90 days; anyone booking 31–90 days after clicking is already lost. Therapy is a long-consideration purchase.
Safari caps the cookie to 7 daysYesHighthe JS rewrites the cookie on every page, which Safari (ITP) truncates to 7 days — a big share of mobile traffic
Clicked on mobile, booked on desktopYesHighattribution is per-browser cookie only; there is no cross-device or logged-in-account stitching
Booked under a different email than capturedPartialMediumthe email fallback needs an exact match to a prior click-carrying record
gclid stripped by a redirect before WordPress loadsPartialMediumcapture only sees the URL on the page WordPress actually boots
The core defect: if there's no live click id at the moment someone submits a form or books, the plugin throws the conversion away entirely — it doesn't even record that a conversion happened. So the tool is blind to its own miss rate, and the lost clients silently fall into the "organic" bucket. The plugin already stores click-time data (in a sessions table) that could rescue many of these, but it never links it back to the person who converts.

Net: we are not mis-capturing gclids at the door — we're forgetting them before the slow therapy decision completes, and discarding the evidence when we do.

Front B · Google Ads API

Can Google's own data fill the gap?

✓ Yes — as a yardstick now, and a recovery tool with one change

The plugin already pulls Google's own conversion numbers every night via the Google Ads API. Google counts conversions using its own cross-device identity graph (signed-in Google users), which is more complete than our cookie and consent-independent. That makes it valuable in two distinct ways.

1. As an independent yardstick — available today

Google's reported "Therapist Match Form Completed" conversions vs. what our own tracking captured, by month. Two independent counts in the same ballpark — which is exactly what lets us measure our own miss rate instead of guessing it.

MonthGoogle-reported conversionsOur captured Google clicksAd spend
Apr 2026837959£10,946
May 20266901,066£9,146
Jun 20261,1691,285£10,879
Jul 2026485608£4,933

Note these count form completions, not purchases — Google can't see who eventually bought unless we tell it. Which is the second use:

2. As a recovery tool — Enhanced Conversions for Leads

This is the real prize. We upload each purchaser's hashed email and phone number back to Google at the point of sale. Google matches that hash to the original ad click on their side — using their identity graph, which still works even when our cookie is long gone. It directly recovers exactly the clients we're currently losing: the cross-device and slow-decision bookers. The export list this needs already exists in the warehouse (ads_offline_conversions); what's missing is the upload being switched on and fed by purchase, not just click.

Honest limit: the Google Ads API gives aggregate counts — how many conversions, by campaign — with no per-person row. It's perfect as the denominator to size and monitor the leak, but it can't attribute an individual client on its own. Enhanced Conversions is the piece that pushes per-person attribution back into Google's hands where the match still works.
Front C · The monitor

A leak monitor in the Data Hub

✓ Buildable now — every input already lands in the warehouse

A new report that takes every new client each month and sorts them into four honest buckets, so the leak is a number we watch — not a surprise we rediscover. Every client falls into exactly one:

BucketDefinitionWhat it meansJun
Attributedhas a Google click eventconfidently paid — working as intended170
Probable lost paidno click, but took a LUFT callthe leak — almost certainly paid, credit missing41
Never trackedno click, no tracker row at alltracking never fired — a separate coverage gap(18 of the 41)
Genuine unknownno click, no call, no tracker rowthe true organic / direct floor5

The headline metric is the leak rate — "probable lost paid" as a share of all new clients — trended monthly, with Google's reported-conversion count beside it as the independent cross-check. When the leak rate moves, we'll know immediately, and we'll be able to prove a capture fix worked by watching it fall.

Why it's safe to trust: it reuses the exact reconciled tables behind the existing reports — new-client cohorts, LUFT calls, the click events and the Google Ads conversion feed. No new data collection; just a lens that has never been pointed at the gap before.
What to do

Recommendations, cheapest first

Three quick wins recover a lot of the leak for little effort; two bigger builds close most of the rest and make it permanent.

1

Stop discarding un-clicked conversions

Record the conversion even when no click id is present, flagged as unattributed. This alone makes the leak measurable instead of invisible — the precondition for everything else.

Quick win
2

Extend the cookie to 90 days & stop Safari truncating it

Match Google's own conversion window, and stop the JavaScript rewriting the cookie on every page (which Safari caps to 7 days). Recovers the slow-decision and mobile bookers directly.

Quick win
3

Build the leak monitor (Front C)

The Data Hub report above — turns this one-off investigation into a number watched every month, and the way we prove any fix worked.

Quick win
4

Turn on Enhanced Conversions for Leads (Front B)

Upload hashed email + phone at purchase so Google re-attributes the clients our cookie lost, using their cross-device graph. The export already exists in the warehouse.

Bigger build
5

Bridge click-time data to the person

Use the click-time session rows (and logged-in accounts) to reconcile a click captured in one browser with a booking made in another. Closes the cross-device gap at source.

Bigger build
Bottom line: nothing here is broken in what we've built on the Data Hub — CAC, the driver tree and the cohort numbers are all correct. What's wrong is the paid-vs-organic split underneath the ads, and it's understating the ads by ~20%. Items 1–3 are small and recover most of the visibility this week; 4–5 make the recovery permanent.