Overview

The Google Analytics Admin API v1 lets you to generate data access reports using the runAccessReport method. The report provides records of each time a user reads Google Analytics reporting data. Access records are retained for up to 2 years. Data Access reports are only available to users with Administrator role.

Creating a Data Access Report

Data Access reporting is provided by the runAccessReport method.

Shared Features with Core Reports

Data Access report requests have the same semantics with Core report requests, for many shared features. For example Pagination, Dimension Filters, Date Ranges specification behave the same in Data Access Reports as Core Reports.

Familiarize yourself with the overview of the Core Reporting functionality of the Data API v1, as the remainder of this document will focus on the features specific to the Data Access report requests.

Selecting a Reporting Entity

Similar to the Core reporting functionality of the Data API v1, runAccessReport method of the Google Analytics Admin API v1 requires the Google Analytics 4 property identifier to be specified inside a URL request path in the form of properties/GA4_PROPERTY_ID, such as:

  POST  https://analyticsadmin.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runAccessReport

The resulting data access report will be generated based on the Google Analytics data access records for the specified Google Analytics 4 property.

If you are using one of the Admin API client libraries, there is no need to manipulate the request URL path manually. Most API clients provide a property parameter that expects a string in the form of properties/GA4_PROPERTY_ID. See the code snippet at the end of this guide for an example of using the client libraries.

Dimensions and Metrics

Dimensions describe and group access data for your property. For example, the dimension userEmail indicates the email of the user that accessed reporting data. Dimension values in report responses are strings.

Metrics represent the quantitative measurements of a report. The accessCount metric returns the total number of data access records.

See the Data Access Schema for a full list of dimension and metric names available in data access report requests.

Data Access Report Request

To request data access reports, construct a RunAccessReportRequest object. We recommend starting with these request parameters:

  • At least one valid entry in the date ranges field.
  • At least one valid entry in the dimensions field.
  • If not using the epochTimeMicros dimension, at least one valid entry in the metrics field to receive quantitative data for each combination of dimension values in a report.

Here is a sample request with the recommended fields. This query will generate a list of user emails, the most recent time they accessed the specified property during the range of last 7 days, and the corresponding access count.

HTTP

POST https://analyticsadmin.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runAccessReport
{
  "dateRanges": [
    {
      "startDate": "7daysAgo",
      "endDate": "today"
    }
  ],
  "dimensions": [
    {
      "dimensionName": "mostRecentAccessEpochTimeMicros"
    },
    {
      "dimensionName": "userEmail"
    }
  ],
  "metrics": [
    {
      "metricName": "accessCount"
    }
  ]
}

Report Response

Conceptually similar to the Core reporting functionality of the Data API v1, the Data Access Report Response of the access report request is primarily a header and rows. The header consists of AccessDimensionHeaders and AccessMetricHeaders which list the columns in the Report.

Each access report row consists of AccessDimensionValues and AccessMetricValues for the columns in the report. The ordering of columns is consistent in the request, the header, and every row.

Here is a sample response for the preceding sample request:

{
  "dimensionHeaders": [
    {
      "dimensionName": "mostRecentAccessEpochTimeMicros"
    },
    {
      "dimensionName": "userEmail"
    }
  ],
  "metricHeaders": [
    {
      "metricName": "accessCount"
    }
  ],
  "rows": [
    {
      "dimensionValues": [
        {
          "value": "1667591408427733"
        },
        {
          "value": "Bola@example.net"
        }
      ],
      "metricValues": [
        {
          "value": "1238"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "1667710959827161"
        },
        {
          "value": "Alex@example.net"
        }
      ],
      "metricValues": [
        {
          "value": "475"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "1667868650762743"
        },
        {
          "value": "Mahan@example.net"
        }
      ],
      "metricValues": [
        {
          "value": "96"
        }
      ]
    }
  ],
  "rowCount": 3
}

Filtering on Access Records

Use the dimensionFilter field of the RunAccessReportRequest object to restrict report response to specific dimension values which match the filter.

The following example generates a report based on individual data access records, filtering on access records of a single user with email Alex@example.net. The report contains the time of each access record, user's email and IP address.

HTTP

POST https://analyticsadmin.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runAccessReport
{
  "dateRanges": [
    {
      "startDate": "7daysAgo",
      "endDate": "today"
    }
  ],
  "dimensions": [
    {
      "dimensionName": "epochTimeMicros"
    },
    {
      "dimensionName": "userEmail"
    },
    {
      "dimensionName": "userIP"
    }
  ],
  "dimensionFilter": {
    "accessFilter": {
      "fieldName": "userEmail",
      "stringFilter": {
        "matchType": "EXACT",
        "value": "Alex@example.net"
      }
    }
  }
}

Similarly, the metricFilter field of the RunAccessReportRequest object can be used to restrict report response to specific metric values which match the filter.

The following example generates a report containing emails and access counts of all users, who accessed the specified property more than 100 times.

HTTP

{
  "dateRanges": [
    {
      "startDate": "7daysAgo",
      "endDate": "today"
    }
  ],
  "dimensions": [
    {
      "dimensionName": "userEmail"
    }
  ],
  "metricFilter": {
    "accessFilter": {
      "numericFilter": {
        "operation": "GREATER_THAN",
        "value": {
          "int64Value": 100
        }
      },
      "fieldName": "accessCount"
    }
  },
  "metrics": [
    {
      "metricName": "accessCount"
    }
  ]
}

Example reports

Here are some sampler reports you can try.

Most Recent Access Per User Report

The following sample access report that can be created using runAccessReport:

Most Recent Access Epoch Time Micros User Email Access Count
1525220215025371 Bola@example.net 5
1525220215028361 Alex@example.net 36
1525220215027671 Charlie@example.net 1153
1525220215027341 Mahan@example.net 1

This report can be generated by querying dimensions mostRecentAccessEpochTimeMicros, userEmail and the accessCount metric. The report contains one row per each user: mostRecentAccessEpochTimeMicros dimension aggregates data access records for each user accessing the property and returns the last access time (in Unix microseconds since the epoch) for each row.

User Access Breakdown Report

Another example of a useful report is a breakdown of user accesses by Access Mechanism (e.g. Google Analytics User Interface, API, etc).

Most Recent Access Epoch Time Micros User Email Access Mechanism Access Count
1525220215028367 Alex@example.net Firebase 31
1525220215555778 Alex@example.net Google Analytics User Interface 1
1525220215022378 Bola@example.net Google Analytics User Interface 65
1525220215026389 Bola@example.net Google Analytics API 894
1525220215025631 Charlie@example.net Google Analytics API 67
1525220215068325 Mahan@example.net Google Ads 3

This report can be generated by querying dimensions mostRecentAccessEpochTimeMicros, userEmail, accessMechanism, and the accessCount metric.

The report contains one row per each user/access mechanism combination. The mostRecentAccessEpochTimeMicros dimension contains the last time a user accessed the property using the specified Access Mechanism.

Property Access Overview Report

It is possible to generate a report for a property without breaking down on individual users. For example, the following report states how often a property is accessed using different Access Mechanisms:

Accessed Property Id Accessed Property Name Access Mechanism Access Count
12345678 DemoApp Firebase 31
12345678 DemoApp Google Analytics User Interface 624
12345678 DemoApp Google Ads 83
12345678 DemoApp Google Analytics API 1744

This report can be generated by querying dimensions accessedPropertyId, accessedPropertyName, accessMechanism, and the accessCount metric.

The report contains one row per each property Id/access mechanism combination.

Individual Data Accesses Report

To generate a report where each row is based on an individual data access record, omit the mostRecentAccessEpochTimeMicros dimension from a query and use the epochTimeMicros dimension instead. It is not necessary to query the accessCount metric, since every row of the report contains information about a single data access occurrence.

The following report contains detailed information about each time a user accessed the specified property.

Epoch Time Micros User Email Accessed Property Id Accessed Property Name User IP Access Mechanism Cost Data Returned Revenue Data Returned
1525220215025371 Bola@example.net 12345678 DemoApp 1.2.3.1 Google Analytics User Interface true true
1525220645645645 Mahan@example.net 12345678 DemoApp 1.2.3.5 Google Analytics User Interface false false
1525220211312322 Bola@example.net 12345678 DemoApp 11.22.33.11 Google Ads true false
1525220210234221 Alex@example.net 12345678 DemoApp 11.22.33.22 Firebase false false
1525220215028368 Alex@example.net 12345678 DemoApp 1.2.3.2 Google Ads false false
1525220214234231 Mahan@example.net 12345678 DemoApp 11.22.33.55 Google Ads true true
1525220423423452 Charlie@example.net 12345678 DemoApp 1.2.3.3 Google Analytics API true false
1525220132312333 Mahan@example.net 12345678 DemoApp 1.2.3.5 Google Ads true true

This report can be generated by querying dimensions epochTimeMicros, userEmail, accessedPropertyId, accessedPropertyName, userIP, accessMechanism, costDataReturned, revenueDataReturned.

Client libraries

See the Quick start guide for an explanation on how to install and configure client libraries.

Here's an example using the Python client library that runs a data access query and prints the response.

Python

from datetime import datetime

from google.analytics.admin import AnalyticsAdminServiceClient
from google.analytics.admin_v1alpha.types import (
    AccessDateRange,
    AccessDimension,
    AccessMetric,
    RunAccessReportRequest,
)


def run_sample():
    """Runs the sample."""
    # TODO(developer): Replace this variable with your Google Analytics 4
    #  property ID (e.g. "123456") before running the sample.
    property_id = "YOUR-GA4-PROPERTY-ID"
    run_access_report(property_id)


def run_access_report(property_id: str, transport: str = None):
    """
    Runs an access report for a Google Analytics property. The report will
    aggregate over dimensions `userEmail`, `accessedPropertyId`,
    `reportType`, `revenueDataReturned`, `costDataReturned`,
    `userIP`, and return the access count, as well as the most recent access
    time for each combination.
    See https://developers.google.com/analytics/devguides/config/admin/v1/access-api-schema
    for the description of each field used in a data access report query.
    Args:
        property_id(str): The Google Analytics Property ID.
        transport(str): The transport to use. For example, "grpc"
            or "rest". If set to None, a transport is chosen automatically.
    """
    client = AnalyticsAdminServiceClient(transport=transport)
    request = RunAccessReportRequest(
        entity=f"properties/{property_id}",
        dimensions=[
            AccessDimension(dimension_name="userEmail"),
            AccessDimension(dimension_name="accessedPropertyId"),
            AccessDimension(dimension_name="reportType"),
            AccessDimension(dimension_name="revenueDataReturned"),
            AccessDimension(dimension_name="costDataReturned"),
            AccessDimension(dimension_name="userIP"),
            AccessDimension(dimension_name="mostRecentAccessEpochTimeMicros"),
        ],
        metrics=[AccessMetric(metric_name="accessCount")],
        date_ranges=[AccessDateRange(start_date="yesterday", end_date="today")],
    )

    access_report = client.run_access_report(request)

    print("Result:")
    print_access_report(access_report)


def print_access_report(response):
    """Prints the access report."""
    print(f"{response.row_count} rows received")
    for dimensionHeader in response.dimension_headers:
        print(f"Dimension header name: {dimensionHeader.dimension_name}")
    for metricHeader in response.metric_headers:
        print(f"Metric header name: {metricHeader.metric_name})")

    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].dimension_name
            if dimension_name.endswith("Micros"):
                # Convert microseconds since Unix Epoch to datetime object.
                dimension_value_formatted = datetime.utcfromtimestamp(
                    int(dimension_value.value) / 1000000
                )
            else:
                dimension_value_formatted = dimension_value.value
            print(f"{dimension_name}: {dimension_value_formatted}")

        for i, metric_value in enumerate(row.metric_values):
            metric_name = response.metric_headers[i].metric_name
            print(f"{metric_name}: {metric_value.value}")