This guide explains how to create a basic report for your Analytics data using the Google Analytics Data API v1. Reports from the Data API v1 are similar to the reports you can generate in the Reports section of the Google Analytics UI.
This guide covers core reporting, the general reporting feature of the Data API. The Data API v1 also has specialized Realtime reporting and Funnel reporting.
runReport
is the recommended method
for queries, and is used in all examples throughout this guide. See advanced
features for an overview of other core reporting methods. Try the
Query Explorer to test your
queries.
Reports overview
Reports are tables of event data for a Google Analytics 4 property. Each report table has the dimensions and metrics requested in your query, with data in individual rows.
Use filters to return only rows matching a certain condition, and pagination to navigate through results.
Here's a sample report table that shows one dimension (Country
) and one metric
(activeUsers
):
Country | Active Users |
---|---|
Japan | 2541 |
France | 12 |
Specify a data source
Every runReport
request requires you to specify a Google Analytics 4 property
ID. The Analytics property you specify is used as the dataset for
that query. Here's an example:
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
The response from this request includes only data from the Analytics property
you specify as the GA4_PROPERTY_ID
.
If you use the Data API client libraries, specify the data
source in the property
parameter, in the form of
properties/GA4_PROPERTY_ID
. See the
quick start guide for examples of using the
client libraries.
See Send Measurement Protocol events to Google Analytics if you want to include Measurement Protocol events in your reports.
Generate a report
To generate a report, construct a
RunReportRequest
object.
We recommend starting with the following parameters:
- A valid entry in the
dateRanges
field. - At least one valid entry in the
dimensions
field. - At least one valid entry in the
metrics
field.
Here's a sample request with the recommended fields:
HTTP
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
"dateRanges": [{ "startDate": "2023-09-01"", "endDate": "2023-09-15" }],
"dimensions": [{ "name": "country" }],
"metrics": [{ "name": "activeUsers" }]
}
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Metric, MetricType, RunReportRequest, ) def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report(property_id) def run_report(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report of active users grouped by country.""" client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", dimensions=[Dimension(name="country")], metrics=[Metric(name="activeUsers")], date_ranges=[DateRange(start_date="2020-09-01", end_date="2020-09-15")], ) response = client.run_report(request) print_run_report_response(response) def print_run_report_response(response): """Prints results of a runReport call.""" print(f"{response.row_count} rows received") for dimensionHeader in response.dimension_headers: print(f"Dimension header name: {dimensionHeader.name}") for metricHeader in response.metric_headers: metric_type = MetricType(metricHeader.type_).name print(f"Metric header name: {metricHeader.name} ({metric_type})") print("Report result:") for rowIdx, row in enumerate(response.rows): print(f"\nRow {rowIdx}") for i, dimension_value in enumerate(row.dimension_values): dimension_name = response.dimension_headers[i].name print(f"{dimension_name}: {dimension_value.value}") for i, metric_value in enumerate(row.metric_values): metric_name = response.metric_headers[i].name print(f"{metric_name}: {metric_value.value}")
Query for metrics
Metrics
are the quantitative measurements of your
event data. You must specify at least one metric in your runReport
requests.
See API Metrics for a full list of metrics you can query.
Here's a sample request that shows three metrics, grouped by the dimension
date
:
HTTP
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
"dateRanges": [{ "startDate": "7daysAgo", "endDate": "yesterday" }],
"dimensions": [{ "name": "date" }],
"metrics": [
{
"name": "activeUsers"
},
{
"name": "newUsers"
},
{
"name": "totalRevenue"
}
],
}
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Metric, RunReportRequest, ) from run_report import print_run_report_response def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report_with_multiple_metrics(property_id) def run_report_with_multiple_metrics(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report of active users, new users and total revenue grouped by date dimension.""" client = BetaAnalyticsDataClient() # Runs a report of active users grouped by three dimensions. request = RunReportRequest( property=f"properties/{property_id}", dimensions=[Dimension(name="date")], metrics=[ Metric(name="activeUsers"), Metric(name="newUsers"), Metric(name="totalRevenue"), ], date_ranges=[DateRange(start_date="7daysAgo", end_date="today")], ) response = client.run_report(request) print_run_report_response(response)
Here's a sample response that shows 1135 Active Users, 512 New Users, and
73.0841 Total Revenue in your Analytics property's currency on the date
20231025
(October 25, 2023).
"rows": [
...
{
"dimensionValues": [
{
"value": "20231025"
}
],
"metricValues": [
{
"value": "1135"
},
{
"value": "512"
},
{
"value": "73.0841"
}
]
},
...
],
Read the response
The report response contains a header and
rows of data. The header consists of
DimensionHeaders
and
MetricHeaders
, which list the columns in the
report. Each row consists of
DimensionValues
and
MetricValues
. The order of the
columns is consistent in the request, header, and rows.
Here's a sample response for the previous sample request:
{
"dimensionHeaders": [
{
"name": "country"
}
],
"metricHeaders": [
{
"name": "activeUsers",
"type": "TYPE_INTEGER"
}
],
"rows": [
{
"dimensionValues": [
{
"value": "Japan"
}
],
"metricValues": [
{
"value": "2541"
}
]
},
{
"dimensionValues": [
{
"value": "France"
}
],
"metricValues": [
{
"value": "12"
}
]
}
],
"metadata": {},
"rowCount": 2
}
Group and filter data
Dimensions are qualitative attributes you can use
to group and filter your data. For example, the city
dimension indicates the
city, like Paris
or New York
, where each event originated. Dimensions are
optional for runReport
requests, and you can use up to nine dimensions per
request.
See the API dimensions for a full list of the dimensions you can use to group and filter your data.
Group
Here's a sample request that groups active users into three dimensions:
HTTP
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
"dateRanges": [{ "startDate": "7daysAgo", "endDate": "yesterday" }],
"dimensions": [
{
"name": "country"
},
{
"name": "region"
},
{
"name": "city"
}
],
"metrics": [{ "name": "activeUsers" }]
}
```
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Metric, RunReportRequest, ) from run_report import print_run_report_response def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report_with_multiple_dimensions(property_id) def run_report_with_multiple_dimensions(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report of active users grouped by three dimensions.""" client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", dimensions=[ Dimension(name="country"), Dimension(name="region"), Dimension(name="city"), ], metrics=[Metric(name="activeUsers")], date_ranges=[DateRange(start_date="7daysAgo", end_date="today")], ) response = client.run_report(request) print_run_report_response(response)
Here's a sample report row for the previous request. This row shows that there were 47 active users during the specified date range with events from Cape Town, South Africa.
"rows": [
...
{
"dimensionValues": [
{
"value": "South Africa"
},
{
"value": "Western Cape"
},
{
"value": "Cape Town"
}
],
"metricValues": [
{
"value": "47"
}
]
},
...
],
Filter
You generate reports with data for only specific dimension values. To filter
dimensions, specify a FilterExpression
in the
dimensionFilter
field.
Here's an example that returns a time series report of eventCount
, when
eventName
is first_open
for each date
:
HTTP
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
"dateRanges": [{ "startDate": "7daysAgo", "endDate": "yesterday" }],
"dimensions": [{ "name": "date" }],
"metrics": [{ "name": "eventCount" }],
"dimensionFilter": {
"filter": {
"fieldName": "eventName",
"stringFilter": {
"value": "first_open"
}
}
},
}
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Filter, FilterExpression, Metric, RunReportRequest, ) from run_report import print_run_report_response def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report_with_dimension_filter(property_id) def run_report_with_dimension_filter(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report using a dimension filter. The call returns a time series report of `eventCount` when `eventName` is `first_open` for each date. This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange for more information. """ client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", dimensions=[Dimension(name="date")], metrics=[Metric(name="eventCount")], date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")], dimension_filter=FilterExpression( filter=Filter( field_name="eventName", string_filter=Filter.StringFilter(value="first_open"), ) ), ) response = client.run_report(request) print_run_report_response(response)
Here's another FilterExpression
example,
where andGroup
includes only data that meets all criteria in the expressions
list. This dimensionFilter
selects for when both browser
is Chrome
and
countryId
is US
:
HTTP
...
"dimensionFilter": {
"andGroup": {
"expressions": [
{
"filter": {
"fieldName": "browser",
"stringFilter": {
"value": "Chrome"
}
}
},
{
"filter": {
"fieldName": "countryId",
"stringFilter": {
"value": "US"
}
}
}
]
}
},
...
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Filter, FilterExpression, FilterExpressionList, Metric, RunReportRequest, ) from run_report import print_run_report_response def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report_with_multiple_dimension_filters(property_id) def run_report_with_multiple_dimension_filters(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report using multiple dimension filters joined as `and_group` expression. The filter selects for when both `browser` is `Chrome` and `countryId` is `US`. This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange for more information. """ client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", dimensions=[Dimension(name="browser")], metrics=[Metric(name="activeUsers")], date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")], dimension_filter=FilterExpression( and_group=FilterExpressionList( expressions=[ FilterExpression( filter=Filter( field_name="browser", string_filter=Filter.StringFilter(value="Chrome"), ) ), FilterExpression( filter=Filter( field_name="countryId", string_filter=Filter.StringFilter(value="US"), ) ), ] ) ), ) response = client.run_report(request) print_run_report_response(response)
An orGroup
includes data that meets any of the criteria in the expressions
list.
A notExpression
excludes data that matches its inner expression. Here's a
dimensionFilter
that returns data for only when the pageTitle
isn't My
Homepage
. The report shows event data for every pageTitle
other than My
Homepage
:
HTTP
...
"dimensionFilter": {
"notExpression": {
"filter": {
"fieldName": "pageTitle",
"stringFilter": {
"value": "My Homepage"
}
}
}
},
...
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Filter, FilterExpression, Metric, RunReportRequest, ) from run_report import print_run_report_response def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report_with_dimension_exclude_filter(property_id) def run_report_with_dimension_exclude_filter(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report using a filter with `not_expression`. The dimension filter selects for when `pageTitle` is not `My Homepage`. This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange for more information. """ client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", dimensions=[Dimension(name="pageTitle")], metrics=[Metric(name="sessions")], date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")], dimension_filter=FilterExpression( not_expression=FilterExpression( filter=Filter( field_name="pageTitle", string_filter=Filter.StringFilter(value="My Homepage"), ) ) ), ) response = client.run_report(request) print_run_report_response(response)
An inListFilter
matches data for any of the values in the list. Here's a
dimensionFilter
that returns event data where eventName
is any of
purchase
, in_app_purchase
, and app_store_subscription_renew
:
HTTP
...
"dimensionFilter": {
"filter": {
"fieldName": "eventName",
"inListFilter": {
"values": ["purchase",
"in_app_purchase",
"app_store_subscription_renew"]
}
}
},
...
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Filter, FilterExpression, Metric, RunReportRequest, ) from run_report import print_run_report_response def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report_with_dimension_in_list_filter(property_id) def run_report_with_dimension_in_list_filter(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report using a dimension filter with `in_list_filter` expression. The filter selects for when `eventName` is set to one of three event names specified in the query. This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange for more information. """ client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", dimensions=[Dimension(name="eventName")], metrics=[Metric(name="sessions")], date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")], dimension_filter=FilterExpression( filter=Filter( field_name="eventName", in_list_filter=Filter.InListFilter( values=[ "purchase", "in_app_purchase", "app_store_subscription_renew", ] ), ) ), ) response = client.run_report(request) print_run_report_response(response)
Navigate long reports
By default, the report contains only the first 10,000 rows of event data. To
view up to 1000,000 rows in the report, you can include "limit": 100000
in the
RunReportRequest
.
For reports with more than 100,000 rows, you have to send a series of requests and page through the results. For example, here's a request for the first 100,000 rows:
HTTP
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
...
"limit": 100000,
"offset": 0
}
Python
request = RunReportRequest( property=f"properties/{property_id}", date_ranges=[DateRange(start_date="365daysAgo", end_date="yesterday")], dimensions=[ Dimension(name="firstUserSource"), Dimension(name="firstUserMedium"), Dimension(name="firstUserCampaignName"), ], metrics=[ Metric(name="sessions"), Metric(name="conversions"), Metric(name="totalRevenue"), ], limit=100000, offset=0, ) response = client.run_report(request)
The rowCount
parameter in the response indicates the total number of rows,
independent of the limit
and offset
values in the request. For example, if
the response shows "rowCount": 272345
, you need three requests of 100,000 rows
each to retrieve all the data.
Here's a sample request for the next 100,000 rows. All other parameters, such as
dateRange
, dimensions
, and metrics
should be the same as the first
request.
HTTP
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
...
"limit": 100000,
"offset": 100000
}
Python
request = RunReportRequest( property=f"properties/{property_id}", date_ranges=[DateRange(start_date="365daysAgo", end_date="yesterday")], dimensions=[ Dimension(name="firstUserSource"), Dimension(name="firstUserMedium"), Dimension(name="firstUserCampaignName"), ], metrics=[ Metric(name="sessions"), Metric(name="conversions"), Metric(name="totalRevenue"), ], limit=100000, offset=100000, ) response = client.run_report(request)
You can use offset
values, for example 200000
or 300000
, to retrieve
subsequent results. All other parameters such as dateRange
, dimensions
, and
metrics
should be the same as the first request.
Use multiple date ranges
One report request can retrieve data for multiple
dateRanges
. For example, this report compares
the first two weeks for August in 2022 and 2023:
HTTP
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
"dateRanges": [
{
"startDate": "2022-08-01",
"endDate": "2022-08-14"
},
{
"startDate": "2023-08-01",
"endDate": "2023-08-14"
}
],
"dimensions": [{ "name": "platform" }],
"metrics": [{ "name": "activeUsers" }]
}
Python
from google.analytics.data_v1beta import BetaAnalyticsDataClient from google.analytics.data_v1beta.types import ( DateRange, Dimension, Metric, RunReportRequest, ) from run_report import print_run_report_response def run_sample(): """Runs the sample.""" # TODO(developer): Replace this variable with your Google Analytics 4 # property ID before running the sample. property_id = "YOUR-GA4-PROPERTY-ID" run_report_with_date_ranges(property_id) def run_report_with_date_ranges(property_id="YOUR-GA4-PROPERTY-ID"): """Runs a report using two date ranges.""" client = BetaAnalyticsDataClient() request = RunReportRequest( property=f"properties/{property_id}", date_ranges=[ DateRange(start_date="2019-08-01", end_date="2019-08-14"), DateRange(start_date="2020-08-01", end_date="2020-08-14"), ], dimensions=[Dimension(name="platform")], metrics=[Metric(name="activeUsers")], ) response = client.run_report(request) print_run_report_response(response)
When you include multiple dateRanges
in a request, a dateRange
column is
automatically added to the response. When the dateRange
column is
date_range_0
, that row's data is for the first date range. When the
dateRange
column is date_range_1
, that row's data is for the second date
range.
Here's a sample response for two date ranges:
{
"dimensionHeaders": [
{
"name": "platform"
},
{
"name": "dateRange"
}
],
"metricHeaders": [
{
"name": "activeUsers",
"type": "TYPE_INTEGER"
}
],
"rows": [
{
"dimensionValues": [
{
"value": "iOS"
},
{
"value": "date_range_0"
}
],
"metricValues": [
{
"value": "774"
}
]
},
{
"dimensionValues": [
{
"value": "Android"
},
{
"value": "date_range_1"
}
],
"metricValues": [
{
"value": "335"
}
]
},
...
],
}
Next steps
See advanced features and realtime reporting for an overview of more advanced reporting features of the Data API v1.