Connecting to GA4

Telescope uses a Google service account — the credential type designed for server-to-server access. No browser consent flow, no refresh token to expire, and no Google account for your editors.

1. Enable the Data API

In the Google Cloud console, create or pick a project, then enable the Google Analytics Data API. This is the API Telescope calls; the older Reporting API is not used.

2. Create a service account and key

Still in the Cloud console, create a service account. It needs no project-level IAM roles — the access that matters is granted inside Analytics in the next step. Then create a JSON key for it and download the file.

3. Grant it access to your property

In Google Analytics, go to Admin → Property access management and add the service account’s email address — it looks like [email protected] — as a Viewer.

Viewer is enough. Telescope only ever reads.

4. Fill in the settings

In Craft, go to Settings → Plugins → Telescope and set:

  • Service account credentials — paste the JSON itself, or give the path to the key file.
  • GA4 property ID — the numeric ID from Admin → Property details. This is not the G-XXXXXXX measurement ID; Telescope will tell you so if you paste one by mistake.

Hit Test connection.

Keeping the key out of project config

Project config is usually committed, and a private key does not belong in a repository. Both credential fields parse environment variables, so put the real values in .env:

# .env
GOOGLE_ANALYTICS_CREDENTIALS="/path/to/service-account.json"
GOOGLE_ANALYTICS_PROPERTY_ID="123456789"

and enter $GOOGLE_ANALYTICS_CREDENTIALS and $GOOGLE_ANALYTICS_PROPERTY_ID in the settings. Project config then only ever records the variable names.

The credentials setting accepts the JSON inline as well, so GOOGLE_ANALYTICS_CREDENTIALS can hold the whole key if you would rather not put a file on disk.

Verifying it works

php craft telescope/analytics/check

This checks the credentials parse, the token exchange succeeds, and the property answers — the three things that can independently go wrong.

Using OAuth instead

If you already have an OAuth client and refresh token for the Analytics API, switch Authentication method to OAuth refresh token and supply the client ID, client secret and refresh token.

A service account is the better default — a refresh token can be revoked, expires if unused, and is tied to a person. The OAuth path exists so an existing set of credentials does not have to be thrown away.