What we learn building against the GA4 Data API — why the numbers disagree,
where Analytics hides things, and how to get a straight answer without
building a report first.
GA4 has no built-in AI channel, so assistant referrals land in Referral. To separate them, build a Free Form exploration with Session source as the dimension and apply a regex filter matching chatgpt|openai|perplexity|gemini|claude|anthropic|copilot. That returns AI assistant sessions as their own group.
Bounce rate exists in GA4 but is hidden from standard reports. Add it under Reports, Engagement, Pages and screens, then click the pencil icon and add Bounce rate to the Metrics card. It is the exact inverse of engagement rate, so a 65% engagement rate always means a 35% bounce rate.
Search Console counts clicks inside Google Search; GA4 counts sessions after your tracking script loads. A gap of 20-30% is normal, and Consent Mode v2 has pushed some sites past 50%. Use Search Console for what happens in the SERP and GA4 for what happens on the site.
GA4's standard reports show session source as a hostname only, so referrals collapse to reddit.com or news.ycombinator.com with no path. The full referring URL lives in the pageReferrer dimension, which you can add in a Free Form exploration to see exactly which page linked to you.
GA4 standard reports carry 24 to 48 hours of processing latency while the Realtime report covers only the last 30 minutes. Seeing traffic in Realtime but nothing in standard reports is normal, not a tracking failure. Analyse data at least two days old for stable numbers.
In March 2024 Google renamed GA4 conversions to key events, reserving conversion for Google Ads. You mark important actions as key events in GA4 and import them into Ads, where they become conversions. The two counters use different dates and different attribution models, so they will not match.
The five worth checking daily are users, engagement rate, conversions, top landing pages and traffic source mix. Together they answer how many people came, whether they engaged, whether they acted, what they arrived on, and where they came from. Everything else in GA4 is diagnostic detail you only need once one of these five moves.
GA4's default reporting model is data-driven attribution, which uses machine learning to distribute conversion credit across every touchpoint in a path rather than giving all of it to the last click. Change it under Admin, Data display, Attribution settings. The change is retroactive for reports; it does not alter the underlying event data.
The hardest part of moving from Universal Analytics to GA4 is not the interface, it is that the data model changed: GA4 records events rather than pageviews and sessions, so metrics with the same name often mean different things. Expect your numbers to differ, and rebuild reports around events rather than translating old ones.
A dimension with more than 500 unique values in a day is high cardinality in GA4. High-cardinality dimensions push reports toward the daily row limit, and everything beyond it is collapsed into a single (other) row. The data still exists; the report just cannot display that many distinct values.
Consent Mode v2 blocks GA4 hits when a visitor declines analytics cookies, so sessions drop while real traffic does not. Basic mode sends nothing until consent is granted. Advanced mode sends cookieless pings that let Google model the gap, which Basic cannot do.
Thresholding is a privacy control, not sampling. GA4 withholds rows when too few users sit behind them, typically under 50, and it is usually triggered by Google Signals being active alongside demographic or cross-device data. Widening the date range or turning off Google Signals removes it.
If a payment provider appears in your referral report, checkout redirects are starting new GA4 sessions and crediting purchases to the payment domain instead of the original marketing channel. Fix it by adding those domains under Admin, Data streams, Configure tag settings, List unwanted referrals.
GA4 uses four separate labels for untraceable traffic. (not set) means the field was never populated, (direct)/(none) means no source signal arrived, Unassigned means the source did not match any channel rule, and (other) means the row was collapsed by cardinality limits. Only Unassigned is fixed in the reporting layer.
GTM Preview needs a handshake between your browser, tagassistant.google.com and your site, carried by a gtm_debug URL parameter and third-party cookies. It usually fails because cookies are blocked, a consent banner or CSP blocks the script, or your server strips unknown query parameters.
GA4 links domains by appending a _gl linker parameter to outbound links. If a redirect, an SPA router or a URL rewrite strips it, the second domain mints a new client ID, the session splits, and the conversion is credited to direct instead of the original channel.
Duplicate GA4 events usually mean the same event fires twice from two sources: a hardcoded gtag alongside GTM, Enhanced Measurement overlapping a custom tag, or a purchase page refiring on refresh. Open DebugView, trigger the event once, and count how many times it lands.
Before launching we audited our own marketing site and found every quantitative claim on it was fabricated: 10k+ analysts, 15,000+ newsletter subscribers, three invented author bylines, and a version number that did not match the shipped extension. All of it is now removed. This is the full list and the checks that catch it.
When a GA4 Data API report requests two date ranges, GA4 appends a synthetic dateRange dimension and returns one row per dimension value per range. Rows are not ordered current-then-previous — any metric sort interleaves them. Read the dateRange dimension value on each row instead of trusting row position.