Migrating to the Google Analytics Data API v1

This document provides instructions on how to migrate existing code from the Google Analytics Reporting API v4 to the Google Analytics Data API v1 and gives a brief overview of key differences between the two APIs.

Why do I need to migrate

If your application needs to access data in a Google Analytics 4 property, it is necessary to update the code to use the Data API v1, since the Reporting API v4 can only access properties created with Universal Analytics.

Prerequisites

Please familiarize yourself with basics of the Data API v1 using the quick start guide.

Getting started

To get started, you will prepare a Google Analytics 4 property, enable the Data API v1, and then set up an API client library suitable for your platform.

Prepare a Google Analytics 4 property

Before you start migrating your code to support the Data API v1, you need to migrate your website to use a Google Analytics 4 property. It is not possible to backfill a Google Analytics 4 property with historical data from a Universal Analytics property.

Enable the API

Click this button to automatically enable the Data API v1 in your selected Google Cloud Project.

Enable the Google Analytics Data API v1

Using a client library

Install a client library

If you use a client library, you need to install the Data API v1 client library for your programming language.

Initialize a client library

The Data API v1 client libraries were designed to get you started fast. By default, client libraries try to automatically find your service account credentials.

An easy way to provide service account credentials is by setting the GOOGLE_APPLICATION_CREDENTIALS environment variable, the API client will use the value of this variable to find the service account key JSON file.

For example, you can set service account credentials by running the following command and using the path to the service account JSON file:

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

Below are the code snippets commonly used to initialize the Data API v1 client libraries.

Java

    // Using a default constructor instructs the client to use the credentials
    // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
    try (BetaAnalyticsDataClient analyticsData = BetaAnalyticsDataClient.create()) {

Python

    # Using a default constructor instructs the client to use the credentials
    # specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
    client = BetaAnalyticsDataClient()

.NET

            // Using a default constructor instructs the client to use the credentials
            // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
            BetaAnalyticsDataClient client = BetaAnalyticsDataClient.Create();

PHP

// Using a default constructor instructs the client to use the credentials
// specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
$client = new BetaAnalyticsDataClient();

Node.js

  // Imports the Google Analytics Data API client library.
  const {BetaAnalyticsDataClient} = require('@google-analytics/data');

  // Using a default constructor instructs the client to use the credentials
  // specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
  const analyticsDataClient = new BetaAnalyticsDataClient();

Instead of using an environment variable, it is also possible to pass the credentials information to an API client instance explicitly during initialization. Below are the snippets used to initialize the Data API v1 client libraries by passing credentials explicitly in the code.

Java

    // Explicitly use service account credentials by specifying
    // the private key file.
    GoogleCredentials credentials =
        GoogleCredentials.fromStream(new FileInputStream(credentialsJsonPath));

    BetaAnalyticsDataSettings betaAnalyticsDataSettings =
        BetaAnalyticsDataSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
            .build();

    try (BetaAnalyticsDataClient analyticsData =
        BetaAnalyticsDataClient.create(betaAnalyticsDataSettings)) {

Python

    # TODO(developer): Uncomment this variable and replace with a valid path to
    #  the credentials.json file for your service account downloaded from the
    #  Cloud Console.
    # credentials_json_path = "/path/to/credentials.json"

    # Explicitly use service account credentials by specifying
    # the private key file.
    client = BetaAnalyticsDataClient().from_service_account_json(credentials_json_path)

.NET

            /**
             * TODO(developer): Uncomment this variable and replace with a valid path to
             *  the credentials.json file for your service account downloaded from the
             *  Cloud Console.
             *  Otherwise, default service account credentials will be derived from
             *  the GOOGLE_APPLICATION_CREDENTIALS environment variable.
             */
            // credentialsJsonPath = "/path/to/credentials.json";

            // Explicitly use service account credentials by specifying
            // the private key file.
            BetaAnalyticsDataClient client = new BetaAnalyticsDataClientBuilder
            {
              CredentialsPath = credentialsJsonPath
            }.Build();

PHP

/* TODO(developer): Replace this variable with a valid path to the
 *  credentials.json file for your service account downloaded from the
 *  Cloud Console.
*/
$credentials_json_path = '/path/to/credentials.json';

// Explicitly use service account credentials by specifying
// the private key file.
$client = new BetaAnalyticsDataClient(['credentials' =>
    $credentials_json_path]);

Node.js

  /** TODO(developer): Uncomment this variable and replace with a valid path to
   *  the credentials.json file for your service account downloaded from the
   *  Cloud Console.
   */
  // credentialsJsonPath = '/path/to/credentials.json';

  // Imports the Google Analytics Data API client library.
  const {BetaAnalyticsDataClient} = require('@google-analytics/data');

  // Explicitly use service account credentials by specifying
  // the private key file.
  const analyticsDataClient = new BetaAnalyticsDataClient({
    keyFilename: credentialsJsonPath,
  });

Not using a client library

If you were using the Reporting API v4 without a client library and want to keep doing so with the Data API v1, you can still use your credentials.

You need to use the new HTTP endpoint and discovery document provided by the Data API:

If your code is taking advantage of a Discovery document, you need to update it to the discovery document provided by the Data API v1:

After updating the endpoint, you will need to familiarize yourself with the new request structure and concepts of the Data API in order to update your JSON query.

Core Reporting

Available reporting methods

The Reporting API v4 offered a single method batchGet to access its Core reporting functionality. The Data API v1 provides several Core reporting methods to choose from:

  • runReport This method returns a customized report of your Google Analytics event data. It does not support pivot functionality and is a preferred method for simple report queries.
  • runPivotReport This method returns a customized pivot report of you Google Analytics event data. Similar to pivots in the Reporting API v4, each pivot describes the visible dimension columns and rows in the report response.
  • batchRunReports This is a batch version of the runReport method which allows generating multiple reports using a single API call.
  • batchRunPivotReports This is a batch version of the runPivotReport method which allows generating multiple reports using a single API call.

The purpose of having several reporting methods is mostly convenience, with some methods supporting more complex features than others (pivots, batching), but otherwise sharing a similar request structure.

API schema changes

Reporting capabilities of both the Reporting API and the Data API are primarily determined by their schema, i.e. dimensions and metrics supported in reporting queries. There are significant differences in the API schemas between the two APIs, due to the conceptual differences between Universal Analytics and Google Analytics 4.

  • Familiarize yourself with the current list of dimensions and metrics supported by the Data API. Currently, all dimensions and metrics are compatible with each other, so there is no need to use the Dimensions and Metrics Explorer to determine compatible combinations. This behavior will change in the future.
  • Custom dimensions in Google Analytics 4 can be accessed using the Data API v1 custom dimensions syntax, which should be used instead of the ga:dimensionXX dimension slots of the Reporting API v4.
  • Custom metrics in Google Analytics 4 can be accessed using the Data API v1 custom metrics syntax, which should be used instead of the ga:metricXX metric slots of the Reporting API v4.
  • Certain dimensions and metrics found in Universal Analytics have a direct equivalent in Google Analytics 4. See the UA/GA4 API schema equivalence chart for more information.
  • Dimension and metric names no longer have ga: prefix in Google Analytics 4.
  • Certain functionality present in Universal Analytics is not yet available in GA4 (e.g. Campaign Manager, DV360, Search Ads 360 integration). Once this functionality is implemented in Google Analytics 4, the Data API will support it, new dimensions and metrics will be added to the API schema.

Entities

Google Analytics 4 has no concept of views (profiles) introduced in Universal Analytics. As a result, there is no viewId parameter anywhere in the Data API v1 reporting requests. Instead, a numeric Google Analytics 4 property id should be specified in a request URL path when calling the Data API v1 methods. This behavior is different from the Reporting API v4, which relies on view (profile) ids to identify the reporting entity.

Data API v1

In case of the Data API v1, a numeric Google Analytics 4 property id has to be specified in the URL path.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport

Reporting API v4

The Reporting API v4 requires a Universal Analytics view (profile) id to be specified in the body of a report query.

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",

    ....

If you are using one of the Data 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 Quick start guide for examples of using the client libraries.

Date Ranges

Both the Reporting API v4 and the Data API v1 support multiple date ranges specified using the dateRanges field in a reporting request. Both APIs share the same date input format, accepting absolute date values in the form of YYYY-MM-DD, or relative dates like yesderday, today, 7daysAgo, etc.

Data API v1 requests are limited to 4 date ranges, whereas the Reporting API v4 allows for 2 date ranges in a single report request.

Each dateRange in the Data API v1 may have an optional name field that can be used to reference the corresponding date range in a response. If name is not provided, the date range name is generated automatically.

When multiple date ranges are specified in a Data API v1 request, a new dateRange dimension is automatically added to a response and the date range name is used as a dimension value. Note this behavior is different from the Reporting API v4, which returns data for a date range as a group of metric values within each row.

Data API v1 Request

An optional name field is used for each dateRange value in a request. This date range name will be used as a value of the dateRange dimension in the response.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
  "metrics": [
    {
      "name": "sessions"
    }
  ],
  "dimensions": [
    {
      "name": "country"
    }
  ],
  "dateRanges": [
    {
      "startDate": "2020-01-01",
      "endDate": "2020-01-31",
      "name": "year_ago"
    },
    {
      "startDate": "2021-01-01",
      "endDate": "2021-01-31",
      "name": "current_year"
    }
  ]
}

Data API v1 Response

An additional dateRange dimension is automatically included in the response. The dateRange dimension value contains the name of a date range, which comes either from the dateRange.name field, or is automatically gernerated.

....

"dimensionHeaders": [
  {
    "name": "country"
  },
  {
    "name": "dateRange"
  }
],

....

"rows": [

....

  {
    "dimensionValues": [
      {
        "value": "Japan"
      },
      {
        "value": "year_ago"
      }
    ],
    "metricValues": [
      {
        "value": "253286"
      }
    ]
  },
  {
    "dimensionValues": [
      {
        "value": "Japan"
      },
      {
        "value": "current_year"
      }
    ],
    "metricValues": [
      {
        "value": "272582"
      }
    ]
  },

....

Reporting API v4 Request

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",
      "dateRanges": [
        {
          "startDate": "2020-01-01",
          "endDate": "2020-01-31",
        },
        {
          "startDate": "2021-01-01",
          "endDate": "2021-01-31",
        }
      ],
      "metrics": [
        {
          "expression": "ga:sessions"
        }
      ],
      "dimensions": [
        {
          "name": "ga:country"
        }
      ]
    }
  ]
}

Reporting API v4 Response

In the Reporting API v4, values for each date range are grouped inside the metrics field:

{
  "dimensions": [
    "Japan"
  ],
  "metrics": [
    {
      "values": [
        "253286"
      ]
    },
    {
      "values": [
        "272582"
      ]
    }
  ]
},

Sorting

Ordering behavior of the Data API v1 report queries can be controlled using the orderBys field, similar to the orderBys field of the Reporting API v4.

The OrderBy specification has changed in the Data API v1. Every OrderBy can contain one of the following:

  • DimensionOrderBy, sorts results by a dimension's values.
  • MetricOrderBy, sorts results by a metric's values.
  • PivotOrderBy, used in pivot queries and sorts results by a metric's values within a pivot column group.

The DELTA, SMART, HISTOGRAM_BUCKET ordering types supported by the Reporting API v4 are not implemented in the Data API v1.

The OrderType.NUMERIC ordering type of the Data API v1 is equivalent to the OrderType.DIMENSION_AS_INTEGER value of the Reporting API v4.

Data API v1 Request

This example shows a sample query that reports sessions count by country, ordering rows by the sessions metric in descending order.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
  "metrics": [
    {
      "name": "sessions"
    }
  ],
  "dimensions": [
    {
      "name": "country"
    }
  ],
  "dateRanges": [
    {
      "startDate": "yesterday",
      "endDate": "today"
    }
  ],
  "orderBys": [
    {
      "metric": {
        "metricName": "sessions"
      },
      "desc": true
    }
  ]
}

Data API v1 Response

{
  "dimensionHeaders": [
    {
      "name": "country"
    }
  ],
  "metricHeaders": [
    {
      "name": "sessions",
      "type": "TYPE_INTEGER"
    }
  ],
  "rows": [
    {
      "dimensionValues": [
        {
          "value": "United States"
        }
      ],
      "metricValues": [
        {
          "value": "510449"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Japan"
        }
      ],
      "metricValues": [
        {
          "value": "283430"
        }
      ]
    },

....

  ],
  "totalSize": 212,
  "metadata": {}
}

Reporting API v4 Request

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",
      "dateRanges": [
        {
          "startDate": "yesterday",
          "endDate": "today"
        }
      ],
      "metrics": [
        {
          "expression": "ga:sessions"
        }
      ],
      "dimensions": [
        {
          "name": "ga:country"
        }
      ],
      "orderBys": [
        {
          "fieldName": "ga:sessions",
          "sortOrder": "DESCENDING"
        }
      ]
    }
  ]
}

Reporting API v4 Response

{
"reports": [
  {

....

    "data": {
      "rows": [
        {
          "dimensions": [
            "United States"
          ],
          "metrics": [
            {
              "values": [
                "510449"
              ]
            }
          ]
        },
        {
          "dimensions": [
            "Japan"
          ],
          "metrics": [
            {
              "values": [
                "283430"
              ]
            }
          ]
        },

....

    }
  ]
}

Filtering

The dimensionFilter and metricFilter clauses of the Data API v1 can be used to ask the API to only return data for specific dimension or metric values. This is similar to the dimensionFilterClauses and metricFilterClauses of the Reporting API v4.

The Data API v1 does not support filter expression strings like the filtersExpression clause of the Reporting API v4. These expressions should be rewritten using the dimensionFilter and metricFilter clauses.

Data API v1 Request

This sample request returns a list of session counts for certain page paths visited by users.

The dimensionFilter clause is used to return only the rows with the pagePath dimension values starting with /webstore/ and containing the string action=a12345.

The metricFilter clause asks the runReport method to return only the rows with the sessions metric values larger than 1,000.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
  "metrics": [
    {
      "name": "sessions"
    }
  ],
  "dimensions": [
    {
      "name": "pagePath"
    }
  ],
  "dimensionFilter": {
    "andGroup": {
      "expressions": [
        {
          "filter": {
            "stringFilter": {
              "value": "/webstore/",
              "matchType": "BEGINS_WITH"
            },
            "fieldName": "pagePath"
          }
        },
        {
          "filter": {
            "stringFilter": {
              "matchType": "CONTAINS",
              "value": "action=a12345"
            },
            "fieldName": "pagePath"
          }
        }
      ]
    }
  },
  "metricFilter": {
    "filter": {
      "numericFilter": {
        "value": {
          "int64Value": 1000
        },
        "operation": "GREATER_THAN"
      },
      "fieldName": "sessions"
    }
  },
  "dateRanges": [
    {
      "startDate": "yesterday",
      "endDate": "today"
    }
  ]
}

Reporting API v4 Request

This sample request is similar to the Data API v1 example. It returns a list of session counts for certain page paths visited by users.

The dimensionFilterClauses field is used to return only the rows with the pagePath dimension values starting with /webstore/ and containing the string action=a12345.

The metricFilterClauses field is used to return only the rows with the ga:sessions metric values larger than 1,000.

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",
      "metrics": [
        {
          "expression": "ga:sessions"
        }
      ],
      "dimensions": [
        {
          "name": "ga:pagePath"
        }
      ],
      "metricFilterClauses": [
        {
          "filters": [
            {
              "metricName": "ga:sessions",
              "operator": "GREATER_THAN",
              "comparisonValue": "1000"
            }
          ]
        }
      ],
      "dimensionFilterClauses": [
        {
          "filters": [
            {
              "dimensionName": "ga:pagePath",
              "operator": "BEGINS_WITH",
              "expressions": [
                "/webstore/"
              ]
            },
            {
              "dimensionName": "ga:pagePath",
              "operator": "PARTIAL",
              "expressions": [
                "action=a12345"
              ]
            }
          ],
          "operator": "AND"
        }
      ],
      "dateRanges": [
        {
          "startDate": "yesterday",
          "endDate": "today"
        }
      ]
    }
  ]
}

Pagination

The Data API v1 uses limit and offset fields to paginate through response results that span multiple pages, whereas the Reporting API v4 uses pageToken and pageSize.

For pivot requests of the Data API v1, the limit and offset fields of the Pivot object should be used to implement pagination for each pivot individually. The limit field is now required for every Pivot object.

By default, the Data API v1 returns at most the first 10,000 rows of event data, whereas the default value for the Reporting API v4 is 1,000 rows.

The total number of rows matching the query is returned using the rowCount field in a response of the Data API v1, which is similar to the Reporting API v4.

Data API v1 Request

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
  "dateRanges": [

....

  ],
  "metrics": [

....

  ],
  "dimensions": [

....

  ],
  "limit": 5,
  "offset": 15
}

Data API v1 Response

{
  "dimensionHeaders": [

....

  ],
  "metricHeaders": [

....

  ],
  "rows": [

....

  ],
  "rowCount": 228,
}

Reporting API v4 Request

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",
      "dateRanges": [

....

      ],
      "metrics": [

....

      ],
      "dimensions": [

....

      ],
      "pageSize": 5,
      "pageToken": "5"

    }
  ]
}

Reporting API v4 Response

{
  "reports": [
    {

....

      "data": {
        "rows": [

....

        ],

....

        "rowCount": 225,
      },
      "nextPageToken": "15"
    }
  ]
}

Metric aggregations

The Data API v1 calculates aggregation values only when the metricAggregations field is specified in a request. In contrast, the Reporting API v4 returns the total, minimum and maximum values for each metric by default, unless the hideTotals and hideValueRanges fields are set to true.`

Data API v1 Request

Aggregations will only be calculated if the metricAggregations field is specified in a request.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
  "metricAggregations": [
    "TOTAL",
    "MAXIMUM",
    "MINIMUM"
  ],
  "metrics": [
    {
      "name": "sessions"
    }
  ],
  "dimensions": [
    {
      "name": "country"
    }
  ],
  "dateRanges": [
    {
      "startDate": "yesterday",
      "endDate": "today"
    }
  ]
}

Data API v1 Response

Aggregated metric rows are returned in the totals, minimum and maximum fields of a response. For aggregated metric rows, the dimensionValues field contains a special value of RESERVED_TOTAL, RESERVED_MAX or RESERVED_MIN.

{
  "dimensionHeaders": [

  ....

  ],
  "metricHeaders": [

  ....

  ],
  "rows": [

  ....

  ],
  "totals": [
    {
      "dimensionValues": [
        {
          "value": "RESERVED_TOTAL"
        },
        {
          "value": "RESERVED_TOTAL"
        }
      ],
      "metricValues": [
        {
          "value": "6026053"
        }
      ]
    }
  ],
  "maximums": [
    {
      "dimensionValues": [
        {
          "value": "RESERVED_MAX"
        },
        {
          "value": "RESERVED_MAX"
        }
      ],
      "metricValues": [
        {
          "value": "493655"
        }
      ]
    }
  ],
  "minimums": [
    {
      "dimensionValues": [
        {
          "value": "RESERVED_MIN"
        },
        {
          "value": "RESERVED_MIN"
        }
      ],
      "metricValues": [
        {
          "value": "1"
        }
      ]
    }
  ],

....

}

Reporting API v4 Request

A sample request to return sessions count by country.

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",
      "dateRanges": [
        {
          "startDate": "yesterday",
          "endDate": "today"
        }
      ],
      "metrics": [
        {
          "expression": "ga:sessions"
        }
      ],
      "dimensions": [
        {
          "name": "ga:country"
        }
      ],
    }
  ]
}

Reporting API v4 Response

The totals, minimums and maximums fields are present by default in a Reporting API v4 response.

{
  "reports": [
    {
      "columnHeader": {

         ....

      },
      "data": {
        "rows": [

         ....

        ],

       ....

        "totals": [
          {
            "values": [
              "4493363"
            ]
          }
        ],
        "minimums": [
          {
            "values": [
              "1"
            ]
          }
        ],
        "maximums": [
          {
            "values": [
              "684005"
            ]
          }
        ]

      }
    }
  ]
}

Pivots

The Data API v1 supports pivot functionality in runPivotReport and batchRunPivotReports reporting methods.

The Reporting API v4 allows including pivots in reporting queries using batchGet method.

Pivots are implemented differently in the Data API v1 compared to the Reporting API v4 in a way that each response row represents a single cell of the table, whereas in the Reporting API v4 a single response row represents a complete table line.

Data API v1

Below is a fragment of a Data API v1 response to the runPivotReport query. Each cell of the pivoting report is returned individually:

    "rows": [
      {
        "dimensionValues": [
          {
            "value": "Albania"
          },
          {
            "value": "Edge"
          }
        ],
        "metricValues": [
          {
            "value": "1701"
          }
        ]
      },

Reporting API v4

Below is a fragment of a Reporting API v4 response to the batchGet query. A single response row represents a complete table line that contains all metric values for the pivot in pivotValueRegions:

      "data": {
        "rows": [
          {
            "dimensions": [
              "Albania"
            ],
            "metrics": [
              {
                "values": [
                  "42394"
                ],
                "pivotValueRegions": [
                  {
                    "values": [
                      "24658",
                      "17208",
                      "132"
                    ]
                  }
                ]
              }
            ]
          },

In the Data API v1, every dimension of the runPivotReport or batchRunPivotReports query must be defined within a pivot object. A dimension will not be visible in a report if it is not used in any pivot of a pivot query.

Pivoting columns of the Data API v1 are specified using the fieldNames field instead of the dimensions field of the Reporting API v4.

A request scoped dimension filter must be used if dimensions filtering is desired in a Data API v1 reporting request. This is different from the Reporting API v4, which accepts the dimensionFilterClauses specification in a pivot object.

The offset field of the Data API v1 is functionally similar to the startGroup field of the Reporting API v4.

The limit field of the Data API v1 is similar to the maxGroupCount of the Reporting API v4 and should be used to limit the report cardinality.

The Data API v1 supports multiple pivots as long as the product of the limit parameter for each pivot does not exceed 100,000. The Reporting API v4 supports only one pivot dimension.

By default, the Data API v1 orders dimensions within a pivot by the first metric in the report. This behavior is different from the Reporting API v4, where the pivot ordering is determined by descending order of "total" of the metrics requested. To specify the sorting order in the Data API v1, use the orderBys field of a Pivot specification.

Data API v1 Request

This Data API v1 pivot query builds a report of session counts by country, pivoted by the browser dimension. Note how the query uses the orderBys, limit, offset fields to reproduce the behavior of a similar Reporting API v4 query in order to preserve the ordering and pagination settings.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runPivotReport

{
  "dateRanges": [
    {
      "startDate": "2021-01-01",
      "endDate": "2021-01-30"
    }
  ],
  "pivots": [
    {
      "fieldNames": [
        "country"
      ],
      "limit": 250,
      "orderBys": [
        {
          "dimension": {
            "dimensionName": "country"
          }
        }
      ]
    },
    {
      "fieldNames": [
        "browser"
      ],
      "offset": 3,
      "limit": 3,
      "orderBys": [
        {
          "metric": {
            "metricName": "sessions"
          },
          "desc": true
        }
      ]
    }
  ],
  "metrics": [
    {
      "name": "sessions"
    }
  ],
  "dimensions": [
    {
      "name": "country"
    },
    {
      "name": "browser"
    }
  ]
}

Data API v1 Response

{
  "pivotHeaders": [
    {
      "pivotDimensionHeaders": [
        {
          "dimensionValues": [
            {
              "value": "(not set)"
            }
          ]
        },
        {
          "dimensionValues": [
            {
              "value": "Albania"
            }
          ]
        },
        {
          "dimensionValues": [
            {
              "value": "Algeria"
            }
          ]
        }
      ],
      "rowCount": 234
    },
    {
      "pivotDimensionHeaders": [
        {
          "dimensionValues": [
            {
              "value": "Safari"
            }
          ]
        },
        {
          "dimensionValues": [
            {
              "value": "Edge"
            }
          ]
        },
        {
          "dimensionValues": [
            {
              "value": "Opera"
            }
          ]
        }
      ],
      "rowCount": 124
    }
  ],
  "dimensionHeaders": [
    {
      "name": "country"
    },
    {
      "name": "browser"
    }
  ],
  "metricHeaders": [
    {
      "name": "sessions",
      "type": "TYPE_INTEGER"
    }
  ],
  "rows": [
    {
      "dimensionValues": [
        {
          "value": "(not set)"
        },
        {
          "value": "Safari"
        }
      ],
      "metricValues": [
        {
          "value": "2531"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "(not set)"
        },
        {
          "value": "Edge"
        }
      ],
      "metricValues": [
        {
          "value": "1701"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "(not set)"
        },
        {
          "value": "Opera"
        }
      ],
      "metricValues": [
        {
          "value": "1564"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Albania"
        },
        {
          "value": "Safari"
        }
      ],
      "metricValues": [
        {
          "value": "2531"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Albania"
        },
        {
          "value": "Edge"
        }
      ],
      "metricValues": [
        {
          "value": "1701"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Albania"
        },
        {
          "value": "Opera"
        }
      ],
      "metricValues": [
        {
          "value": "1564"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Algeria"
        },
        {
          "value": "Safari"
        }
      ],
      "metricValues": [
        {
          "value": "237"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Algeria"
        },
        {
          "value": "Edge"
        }
      ],
      "metricValues": [
        {
          "value": "44"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Algeria"
        },
        {
          "value": "Opera"
        }
      ],
      "metricValues": [
        {
          "value": "22"
        }
      ]
    },

....

  ],

....

}

Reporting API v4 Request

This Reporting API v4 pivot query builds a report of session counts by country, pivoted by the ga:browser dimension.

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",
      "dateRanges": [
        {
          "startDate": "2021-01-01",
          "endDate": "2021-01-30"
        }
      ],
      "metrics": [
        {
          "expression": "ga:sessions"
        }
      ],
      "dimensions": [
        {
          "name": "ga:country"
        }
      ],
      "pivots": [
        {
          "dimensions": [
            {
              "name": "ga:browser"
            }
          ],
          "startGroup": 3,
          "maxGroupCount": 3,
          "metrics": [
            {
              "expression": "ga:sessions"
            }
          ]
        }
      ]
    }
  ]
}

Reporting API v4 Response

{
  "reports": [
    {
      "columnHeader": {
        "dimensions": [
          "ga:country"
        ],
        "metricHeader": {
          "metricHeaderEntries": [
            {
              "name": "ga:sessions",
              "type": "INTEGER"
            }
          ],
          "pivotHeaders": [
            {
              "pivotHeaderEntries": [
                {
                  "dimensionNames": [
                    "ga:browser"
                  ],
                  "dimensionValues": [
                    "Edge"
                  ],
                  "metric": {
                    "name": "ga:sessions",
                    "type": "INTEGER"
                  }
                },
                {
                  "dimensionNames": [
                    "ga:browser"
                  ],
                  "dimensionValues": [
                    "Opera"
                  ],
                  "metric": {
                    "name": "ga:sessions",
                    "type": "INTEGER"
                  }
                },
                {
                  "dimensionNames": [
                    "ga:browser"
                  ],
                  "dimensionValues": [
                    "Samsung Internet"
                  ],
                  "metric": {
                    "name": "ga:sessions",
                    "type": "INTEGER"
                  }
                }
              ],
              "totalPivotGroupsCount": 19
            }
          ]
        }
      },
      "data": {
        "rows": [
          {
            "dimensions": [
              "(not set)"
            ],
            "metrics": [
              {
                "values": [
                  "781283"
                ],
                "pivotValueRegions": [
                  {
                    "values": [
                      "6923",
                      "1385",
                      "66"
                    ]
                  }
                ]
              }
            ]
          },
          {
            "dimensions": [
              "Albania"
            ],
            "metrics": [
              {
                "values": [
                  "42394"
                ],
                "pivotValueRegions": [
                  {
                    "values": [
                      "24658",
                      "17208",
                      "132"
                    ]
                  }
                ]
              }
            ]
          },
          {
            "dimensions": [
              "Algeria"
            ],
            "metrics": [
              {
                "values": [
                  "23208"
                ],
                "pivotValueRegions": [
                  {
                    "values": [
                      "19252",
                      "66",
                      "1582"
                    ]
                  }
                ]
              }
            ]
          },

  ....

        ],

  ....

      }
    }
  ]
}

Cohorts

The Data API v1 uses the CohortSpec specification to configure cohort reports. This is similar to the CohortGroup specification of the Reporting API v4.

All metrics available in the Data API v1 are currently compatible with cohort queries, whereas the Reporting API v4 only allows a subset of special metrics to be used in a cohort query.

In a Data API v1 cohort request, the metric cohortActiveUsers is required.

Both the Data API v1 and Reporting API v4 allow up to 12 cohorts in a single request.

Lifetime value (LTV) metrics are not currently supported in the Data API v1.

Cohort metrics equivalence

Most of the cohort metrics defined in the Reporting API v4 can be replaced with an expression to achieve an equivalent result in the Data API v1, as per the chart below.

Reporting API v4 metric name Data API v1 metric name or expression
ga:cohortActiveUsers cohortActiveUsers
ga:cohortTotalUsers cohortTotalUsers
ga:cohortRetentionRate "expression": "cohortActiveUsers/cohortTotalUsers"
ga:cohortRevenuePerUser "expression": "totalRevenue/cohortActiveUsers"
ga:cohortVisitDurationPerUser "expression": "userEngagementDuration/cohortActiveUsers"
ga:cohortAppviewsPerUser "expression": "screenPageViews/cohortActiveUsers"
ga:cohortPageviewsPerUser "expression": "screenPageViews/cohortActiveUsers"
ga:cohortSessionsPerUser "expression": "sessions/cohortActiveUsers"
ga:cohortGoalCompletionsPerUser "expression": "eventCount/cohortActiveUsers", in addition to a dimension filter by eventName corresponding to the desired goal completion event.

Data API v1 Request

A sample query that configures a cohort of users whose first session happened on a week of 2021-01-03. The number of active users and user retention rate is calculated for the cohort over 5 weeks, using WEEKLY granularity.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
  "cohortSpec": {
    "cohorts": [
      {
        "dimension": "firstSessionDate",
        "name": "cohort",
        "dateRange": {
          "startDate": "2021-01-03",
          "endDate": "2021-01-09"
        }
      }
    ],
    "cohortsRange": {
      "startOffset": 0,
      "endOffset": 4,
      "granularity": "WEEKLY"
    }
  },
  "metrics": [
    {
      "name": "cohortActiveUsers"
    },
    {
      "expression": "cohortActiveUsers/cohortTotalUsers",
      "name": "cohortRetentionRate"
    }
  ],
  "dimensions": [
    {
      "name": "cohort"
    },
    {
      "name": "cohortNthWeek"
    }
  ]
}

Data API v1 Response

{
  "dimensionHeaders": [
    {
      "name": "cohort"
    },
    {
      "name": "cohortNthWeek"
    }
  ],
  "metricHeaders": [
    {
      "name": "cohortActiveUsers",
      "type": "TYPE_INTEGER"
    },
    {
      "name": "cohortRetentionRate",
      "type": "TYPE_FLOAT"
    }
  ],
  "rows": [
    {
      "dimensionValues": [
        {
          "value": "cohort"
        },
        {
          "value": "0000"
        }
      ],
      "metricValues": [
        {
          "value": "4268816"
        },
        {
          "value": "0.999913800857494"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "cohort"
        },
        {
          "value": "0001"
        }
      ],
      "metricValues": [
        {
          "value": "241580"
        },
        {
          "value": "0.056586926213534013"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "cohort"
        },
        {
          "value": "0002"
        }
      ],
      "metricValues": [
        {
          "value": "159390"
        },
        {
          "value": "0.037335003597877253"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "cohort"
        },
        {
          "value": "0003"
        }
      ],
      "metricValues": [
        {
          "value": "131512"
        },
        {
          "value": "0.030804950079453122"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "cohort"
        },
        {
          "value": "0004"
        }
      ],
      "metricValues": [
        {
          "value": "96793"
        },
        {
          "value": "0.022672482610259947"
        }
      ]
    }
  ],
  "totalSize": 5,
  "metadata": {}
}

Reporting API v4 Request

A sample query that configures a cohort of users whose first session happened on a week of 2021-01-03. The number of active users and user retention rate is calculated for the cohort over 5 weeks, using WEEKLY granularity.

POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
  "reportRequests": [
    {
      "viewId": "UA_VIEW_ID",
      "dimensions": [
        {
          "name": "ga:cohort"
        },
        {
          "name": "ga:cohortNthWeek"
        }
      ],
      "metrics": [
        {
          "expression": "ga:cohortActiveUsers"
        },
        {
          "expression": "ga:cohortRetentionRate"
        }
      ],
      "cohortGroup": {
        "cohorts": [
          {
            "name": "cohort",
            "type": "FIRST_VISIT_DATE",
            "dateRange": {
              "startDate": "2021-01-03",
              "endDate": "2021-01-09"
            }
          }
        ]
      }
    }
  ]
}

Reporting API v4 Response

{
  "reports": [
    {
      "columnHeader": {
        "dimensions": [
          "ga:cohort",
          "ga:cohortNthWeek"
        ],
        "metricHeader": {
          "metricHeaderEntries": [
            {
              "name": "ga:cohortActiveUsers",
              "type": "INTEGER"
            },
            {
              "name": "ga:cohortRetentionRate",
              "type": "PERCENT"
            }
          ]
        }
      },
      "data": {
        "rows": [
          {
            "dimensions": [
              "cohort",
              "0000"
            ],
            "metrics": [
              {
                "values": [
                  "40793",
                  "100.0"
                ]
              }
            ]
          },
          {
            "dimensions": [
              "cohort",
              "0001"
            ],
            "metrics": [
              {
                "values": [
                  "3883",
                  "9.518789988478416"
                ]
              }
            ]
          },
          {
            "dimensions": [
              "cohort",
              "0002"
            ],
            "metrics": [
              {
                "values": [
                  "2165",
                  "5.307283112298679"
                ]
              }
            ]
          },
          {
            "dimensions": [
              "cohort",
              "0003"
            ],
            "metrics": [
              {
                "values": [
                  "1703",
                  "4.174735861544873"
                ]
              }
            ]
          },
          {
            "dimensions": [
              "cohort",
              "0004"
            ],
            "metrics": [
              {
                "values": [
                  "1484",
                  "3.637879047875861"
                ]
              }
            ]
          },
          {
            "dimensions": [
              "cohort",
              "0005"
            ],
            "metrics": [
              {
                "values": [
                  "1103",
                  "2.7038952761503197"
                ]
              }
            ]
          },
          {
            "dimensions": [
              "cohort",
              "0006"
            ],
            "metrics": [
              {
                "values": [
                  "933",
                  "2.28715711028853"
                ]
              }
            ]
          },
          {
            "dimensions": [
              "cohort",
              "0007"
            ],
            "metrics": [
              {
                "values": [
                  "336",
                  "0.8236707278209496"
                ]
              }
            ]
          }
        ],
        "totals": [
          {
            "values": [
              "52400",
              "16.056676390557204"
            ]
          }
        ],
        "rowCount": 8,
        "minimums": [
          {
            "values": [
              "336",
              "0.8236707278209496"
            ]
          }
        ],
        "maximums": [
          {
            "values": [
              "40793",
              "100.0"
            ]
          }
        ],
        "isDataGolden": true
      }
    }
  ]
}

Sampling

The Data API v1 always builds reports based on unsampled data. There is no equivalent of the samplingLevel field that was present in the Reporting API v4.

Data freshness

The Data API provides no equivalent of the isDataGolden field of the Reporting API v4, that was used to indicate if all hits for a report finished processing. It is still possible for the same report to return different results when queried on a later date due to additional processing.

(Not supported) Segments

Segments are not currently supported in the Data API v1.

Real-Time reporting

Use the properties.runRealtimeReport method of the Data API v1 to generate real-time reports for Google Analytics 4 properties. The real-time reporting functionality for Universal Analytics properties was provided by the data.realtime.get method of the Google Analytics API v3.

The Data API real-time reporting schema is different from the real-time reporting schema of the Analytics API v3, due to conceptual differences between Universal Analytics and Google Analytics 4.

Data API v1 Request

In the following example, in order to preserve the default sorting behavior of the Google Analytics API v3, an optional orderBy element was added to the sample Data API v1 query.

POST  https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runRealtimeReport
{
  "dimensions": [{ "name": "country" }],
  "metrics": [{ "name": "activeUsers" }],
  "orderBys": [
     {
       "dimension": {
         "dimensionName": "country"
         }
     }
   ]
}

Data API v1 Response

{
  "dimensionHeaders": [
    {
      "name": "country"
    }
  ],
  "metricHeaders": [
    {
      "name": "activeUsers",
      "type": "TYPE_INTEGER"
    }
  ],
  "rows": [
    {
      "dimensionValues": [
        {
          "value": ""
        }
      ],
      "metricValues": [
        {
          "value": "199"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Afghanistan"
        }
      ],
      "metricValues": [
        {
          "value": "4"
        }
      ]
    },
    {
      "dimensionValues": [
        {
          "value": "Albania"
        }
      ],
      "metricValues": [
        {
          "value": "136"
        }
      ]
    },

    ....

  ],
  "rowCount": 172
}

Google Analytics API v3 Request

GET https://analytics.googleapis.com/analytics/v3/data/realtime?ids=ga:UA_VIEW_ID&metrics=rt:activeUsers&dimensions=rt:country

Google Analytics API v3 Response

{
  "kind": "analytics#realtimeData",
  "id": "https://www.googleapis.com/analytics/v3/data/realtime?ids=ga:UA_VIEW_ID&dimensions=rt:country&metrics=rt:activeUsers",
  "query": {
    "ids": "ga:UA_VIEW_ID",
    "dimensions": "rt:country",
    "metrics": [
      "rt:activeUsers"
    ],
    "max-results": 10
  },
  "totalResults": 178,
  "profileInfo": {
    "profileId": "XXXXXX",
    "accountId": "XXXXXX",
    "webPropertyId": "UA-XXXXXX",
    "profileName": "View Name",
  },
  "columnHeaders": [
    {
      "name": "rt:country",
      "columnType": "DIMENSION",
      "dataType": "STRING"
    },
    {
      "name": "rt:activeUsers",
      "columnType": "METRIC",
      "dataType": "INTEGER"
    }
  ],
  "totalsForAllResults": {
    "rt:activeUsers": "80351"
  },
  "rows": [
    [
      "(not set)",
      "97"
    ],
    [
      "Afghanistan",
      "2"
    ],
    [
      "Albania",
      "78"
    ],

  ....

  ]
}

(Not supported) User activity reporting

The Data API v1 does not currently support functionality to report individual user activity similar to the userActivity.search method of the Reporting API v4.

API quota changes

Core and Real-time quota categories

For the purposes of quota, the Data API has two request categories: Core and Real-time. API requests to Core reporting methods (runReport, getMetadata, runPivotReport, batchRunReports, batchRunPivotReports) charge Core quotas. API requests to runRealtimeReport method charge Real-time quotas.

Token quotas

In addition to project quotas, each request consumes property token quotas that are charged depending on the complexity of the query. Please see the Data API v1 quotas documentation for the detailed description of the API quotas and limits.

It is possible to get the current state of all quotas for an Analytics Property by setting returnPropertyQuota to true in a core or real time reporting request. The quota state will be returned in PropertyQuota.

(Not supported) Resource Based Quota

Since all reports in Google Analytics 4 are based on unsampled data, Resource Based Quota introduced in the Reporting API v4 is no longer applicable, and there is no equivalent of the useResourceQuotas field present in a Data API v1 reporting request.

(Not supported) Requests per view (profile) per day quota

Because there are no views in Google Analytics 4, requests per view (profile) per day quota is not present in the Data API v1 and replaced by token quotas.