Case study · GA4 · Admin API · Data quality
A GA4 property that had
never recorded a conversion.
The business made decisions from GA4 every week. Nobody had opened its settings since the old WordPress site was replaced. I did, before trusting a single number in it.
- 0
- real conversions recorded before the audit
- 11
- key events now, one per real action
- 88%
- of “Direct” traffic carrying a bot signature
Summary
Problem
Two data streams, about thirty plugin leftovers, and one key event, “purchase”, for a business that sells nothing online. Real conversions recorded, ever: zero.
Solution
A clean property with one key event per service, channels that describe where people really come from, and bot traffic measured instead of guessed.
A tool first
Clicking through the GA4 admin for every check wasn't going to scale, so I built a small write-capable GA4 Admin connector (an MCP server on a Cloudflare Worker, authenticated with a service account that only has access to this one property). Every change below was made and read back through it.
Cleaning up, carefully
- A second data stream from the old WordPress plugin. Before deleting it I checked its traffic: zero sessions in 30 days, while the real one was busy.
- 29 custom dimensions from the same plugin archived (GA4 can't delete them). Two left alone, because they didn't clearly come from the plugin.
- One key event per service (rooms, terrace, offices, coworking, business registration, general), plus the actions nobody tracked: WhatsApp, phone calls, directions, and the two highest-intent buttons on the site, “Book a tour” and the plan sign-ups, which handed visitors to the booking system with no trace at all.
A fix that silently never applied
Visitors from WhatsApp, Instagram and the newsletter were all landing in “Direct”, because GA4's default channels have no box for them. I created a custom channel group. Eleven days later, a health check showed it had never been applied: a new group isn't primary until you say so, and the API doesn't. I added that call to the connector and set it.
A month later the same group caused the opposite problem: it had only my custom rules, so everything else, organic, paid, direct, fell into “Unassigned”. I rebuilt it with the custom rules first and all of GA4's default channels after them, plus a rule for front-desk QR sign-ups, which turned out to be most of “Unassigned”.
Bots, measured twice
“Direct” was dominated by sessions from countries the business doesn't serve, with almost no engagement and a few seconds each: 88.6% of the channel. Cloudflare's free Bot Fight Mode was switched on. I re-ran the same breakdown eleven days later: 87.8%. It hadn't worked. These bots run JavaScript, which the free tier can't catch. I wrote that down instead of calling it fixed, and planned a phased, geo-targeted challenge rule instead of a paid upgrade.
What finally removed them was a side effect of real consent mode going live: with analytics off until a visitor agrees, bot sessions in “Direct” fell by more than 95%.
Total traffic halved the same week. That isn't a loss, it's the first honest number. I logged it so nobody compares before and after as if they measured the same thing.
“An analytics tool nobody has audited is a set of opinions with a dashboard.”