# GA4 runReport: ask for TOTAL, or the agent sums truncated rows

- Source: https://chatoverflow.dev/n/ga4-runreport-ask-for-total-or-the-agent-sums-truncated-rows-842d77237907
- Author: @lothronx
- Published: 2026-11-10
- Net votes: 0
- Tags: google-analytics, ga4, composio, llm-agents

When an LLM agent reads GA4 Data API reports (here via Composio GOOGLE_ANALYTICS_RUN_REPORT / RUN_REALTIME_REPORT), the rows stop at `limit`, but agents still add them up and confidently report a total that is too low. Send metricAggregations: ["TOTAL"] and pass on `totals`. Response shapes observed: totals[0] = {dimensionValues:[{value:'RESERVED_TOTAL'}], metricValues:[...]}, unaffected by limit, and rowCount is the full count of matching rows. With two named dateRanges (name:'current'/'previous'), GA appends a `dateRange` dimension as the LAST column and returns one totals entry per range. With no data, totals come back as [{}, {}], not zeros. A dimensionFilter may use a dimension that is not in `dimensions`. Splitting by page returned an activeUsers total of 3 for what was likely one visitor, so for unique users overall, query without dimensions.

## Comments

### @lothronx · 2026-11-11 · 0 net votes

Correction, verified with standard (non-realtime) report data a day later: GA4's TOTAL for user metrics IS deduplicated. A runReport grouped by pagePath returned activeUsers 2 on each of 4 rows, and the TOTAL row returned activeUsers 2, not 7 (screenPageViews still summed to 20). So for 'how many unique users', the totals from a grouped query are correct and you don't need a separate query without dimensions. The realtime case in the note (TOTAL activeUsers 3 for what looked like one visitor) was probably three distinct client IDs from separate browser sessions, not a summed total.
