GA4 custom report
ga4_reportAny GA4 report: your own dimensions, metrics, filters and order.
A read-only wrapper over the Data API's runReport, the GA4 counterpart of search_analytics_query. Use it when the fixed ga4_* tools do not have the slice you need: landing page x source/medium x country, one country or device only, custom dimensions, item-level ecommerce. Field names are GA4 API names (sessionSourceMedium, landingPagePlusQueryString, itemName, itemRevenue, customEvent:plan); call ga4_metadata to find the property's own, custom definitions included. Google rejects an unknown name or a pair it cannot combine, and the error says which.
Do not add rows up for users: GA4 deduplicates users across rows, so
the row sum overcounts. totals is Google's own total for the whole
report, filters applied, and is the figure to quote.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"property_id": "<property_id>",
"metrics": "<metrics>"
},
"name": "ga4_report"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | lookback window (1-365), default 28 | |
| limit | No | rows to return (1-10000), default 100 | |
| offset | No | rows to skip, for the next page | |
| metrics | Yes | 1 to 10 metric API names, e.g. ["sessions", "keyEvents", "totalRevenue"] | |
| end_date | No | optional YYYY-MM-DD. Alone, the window is `days` days ending on this date | |
| order_by | No | a metric or dimension in the report. Default: the first metric | |
| dimensions | No | 0 to 9 dimension API names, e.g. ["landingPage", "sessionSourceMedium", "country"]. Omit for totals only | |
| order_desc | No | descending (default) or ascending | |
| start_date | No | optional YYYY-MM-DD. With it the window is start_date to end_date (or today), and days is ignored | |
| property_id | Yes | GA4 property id (numeric or "properties/XYZ") | |
| metric_filter | No | the same shape, on metrics, applied after aggregation, e.g. {"filter": {"fieldName": "sessions", "numericFilter": {"operation": "GREATER_THAN", "value": {"int64Value": "10"}}}} | |
| include_totals | No | return Google's total row as `totals` (default True) | |
| dimension_filter | No | a GA4 FilterExpression in the Data API's JSON shape, on dimensions. One filter: {"filter": {"fieldName": "country", "stringFilter": {"value": "United States"}}} Values match what GA4 reports (it says "Türkiye", not "Turkey"), so break down by the field first when unsure. stringFilter takes matchType EXACT (default), BEGINS_WITH, ENDS_WITH, CONTAINS, FULL_REGEXP or PARTIAL_REGEXP and caseSensitive; inListFilter takes {"values": [...]}. Combine with andGroup / orGroup ({"expressions": [...]}) or notExpression. A list of filters means all must match |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||