Whoa that’s quite a change

If you’ve been using the old Google Analytics API to fetch your site data into your app/custom dashboard and taken a look at the new API for Google Analytics 4 (GA4) then you’ve probably had a bit of a shock as it’s very different.

No longer can you just pass some easily assembled JSON into the API calls and get your results, we’re in to a full blown and complex (relatively speaking) SDK from Google.

If you’ve found the official documentation lacking and you’ve not yet found the official Google samples like we didn’t until we’d tested the API and written this for a client (yes, this is the kind of extra mile we go to), then read on as we’re going to have a whirlwind tour of getting your data quickly.

Installing the library

As you’d expect from a modern PHP SDK it uses composer to manage dependencies, so that’s what we’ll be using to install it:

composer require google/analytics-data

If you want to take advantage of streaming APIs then you’ll need to make sure your PHP install has grpc and protobuf extensions installed.

You’ll also need to make sure you’re using BetaAnalyticsDataGrpcClient and not BetaAnalyticsDataClient to send your queries.

Enabling access to the API

You’re going to need to do two things to get access to the API:

  1. Enable it for your Google Analytics Property
  2. Create and download an authentication token

Fortunately Google has a nice button for doing this in their API Quickstart document where you need to follow Step 1 and Step 2.

If you want to get even deeper in to it then Google has more information on authenticating with their Cloud SDK (this is a subset of it).

Getting your property ID

Don’t get all GA-XXXXXXX happy just yet, that won’t be your GA4 property ID as needed by the API.  What you need is a fully numeric property ID and the easiest place to copy that from is by logging in to Google Analytics and choosing “Admin” (the little gearwheel icon) at the bottom of the left hand menu and then clicking “Property Settings” and you’ll see your ID at the top right:

The image shows the Google Analytics dashboard, with the settings screen open. A pink arrow points to where the property ID is location.

Running a report

To run your first report there’s a lot to understand, and if you’re just looking at the GitHub repo for the library then you’re probably going to be left scratching your head, so we’re going to do our best to have a look at what you’ll need to know to get your first data back.

We’ve shown code fragments for each item, and at the end we’ll build it into a query you can run.

Date Ranges

Unless you want to query all of your data then you’re going to need to specify a date range to look at.  As well as an actual date, you can also use today as a value, to represent todays date (as if it wasn’t obvious).

Copy to Clipboard

Dimensions

Dimensions are the details about your users e.g. their location, the page they visited, their browser, etc. etc.  The dimensions here are the data we want Google to return to us about our visitors.

Copy to Clipboard

Details of the various data dimensions and available metrics can be found in the Google API docs (API Dimensions & Metrics)

Metrics

Metrics are the bits we’re really interested in, how many active users, bounce rates, sessions, conversions, page views etc.

Copy to Clipboard

As with the dimensions example above, you can specify multiple metrics by defining a new Metric() as an array item.

Ordering

You’re probably going to want your results in some sort of order rather than having your app sort the data itself.

Copy to Clipboard

Filtering

This is where we can start to get really specific, we can filter data down based on dimensionsand metrics. The dimensions used to filtering don’t have to be the same as those being returned in the query.

Simple filters

The quickest way to get up and running is with a simple filter that matches against a single dimension or metric.

Copy to Clipboard
String matching

You’ll have noticed that we specified a match_type for the filter, it’s always a good idea to set your own for code clarity reasons, especially as Google don’t say what the default of MATCH_TYPE_UNSPECIFIED actually is (although it appears to be EXACT).

The different types of matches are shown below:

Copy to Clipboard
Numeric matching

As well as matching by string, you can also perform numeric matches, but these are going to be most useful for a MetricFilter rather than a DimensionFilter:

Copy to Clipboard

As with the StringMatch there are multiple possible match criteria for NumericMatch:

Copy to Clipboard
Filtering based on a list

If we have multiple values that we want to match exactly against a single dimension then InListFilter is what we need:

Copy to Clipboard

Building more complex filters

This is where we can get really powerful and start building complex expressions, much as we would if we were querying in SQL.  Unfortunately it isn’t quite as elegant to look at, but non-the-less the AND, OR, NOT can all be combined so you can get exactly the data you want.

The main thing to note is the FilterExpressionList that filters need to be inside of when using the and_group or or_group.

AND: This AND this
Copy to Clipboard
OR: This OR this
Copy to Clipboard
NOT: NOT this
Copy to Clipboard

Putting it all together and generating a report

You’ve decided which dimensions you need, and what metrics will be useful, so now it’s time to get the data from Google.

Copy to Clipboard

As you’d expect given the rest of the SDK and API, the response isn’t a simple associative array, it’s a complex structure which is returned as RunReportResponse which has several methods:

  • getDimensionHeaders() – Get details of the dimensions returned
  • getMetricHeaders() – Get details of the metrics returned
  • getRows() – Get the rows of data returned
  • getTotals() – Get the aggregate totals returned
  • getMaximums() – Get the aggregate maximums returned
  • getMinimums() – Get the aggregate minimums returned
  • and a few others

You’ll notice the aggregates in there, we haven’t covered that yet, we might do that in a part two at some point.

To actually get your data you’ll want to call getRows() and iterate over it.  To access the dimensions and metrics you’ll need to use:

  • $row->getDimensionValues()
  • $row->getMetricValues()

Both of which return arrays of data, to get the actual value from an entry you’ll need to call getValue()

Closing thoughts

It’s somewhat unfortunate that Google have made the new API much more complicated, but in doing so it does bring it inline with the other Google Cloud APIs.  Hopefully this will be enough to get you up and running with querying data from the GA4 API before Google closes down GA3 and you lose access to your stats.

If you spot any errors or have any comments then please feel free to get in touch with us on social media, by email or any of the usual channels.

Ah ha… samples.

After we’d written all of this, we eventually stumbled upon the code samples for the PHP API, which were a singular link that was easily missed (our customer missed it as well) in the Google docs.

You can find the official Google PHP samples in their GitHub repo: https://github.com/GoogleCloudPlatform/php-docs-samples/tree/main/analyticsdata/src