Google Analytics (GA4)
Pull traffic, conversion, and campaign-attribution reports from a Google Analytics 4 property via the Analytics Data API v1.
- Base URL:
https://analyticsdata.googleapis.com/v1beta - Auth:
Authorization: Bearer <OAuth2 access token>(scopehttps://www.googleapis.com/auth/analytics.readonly) - Property:
properties/{propertyId} - Standard library only, response bodies capped at 5 MB.
Operations
| operation | HTTP | Description |
|---|---|---|
run-report |
POST .../properties/{id}:runReport |
Custom report of GA4 event data over a date range. |
batch-run-reports |
POST .../properties/{id}:batchRunReports |
Multiple reports in a single call. |
run-realtime |
POST .../properties/{id}:runRealtimeReport |
Realtime event data (last ~30 min, no date range). |
get-metadata |
GET .../properties/{id}/metadata |
All dimensions and metrics available for the property. |
apiKey setup
The GA4 Data API does not accept a static API key. You must supply a
short-lived OAuth2 access token in the apiKey input. It is sent verbatim
as Authorization: Bearer <apiKey>. The token must carry the scope
https://www.googleapis.com/auth/analytics.readonly (or .../analytics).
Two common ways to mint one:
- Service account (recommended for automation) — create a service account
in the Google Cloud Console, enable the Google Analytics Data API, grant the
service-account email Viewer access to your GA4 property
(Admin → Property Access Management), then exchange its JWT for an access
token at
https://oauth2.googleapis.com/token. Feed the resultingaccess_tokenintoapiKey. - gcloud (quick test):
gcloud auth print-access-tokenwhile logged in as a user with property access.
Access tokens expire (~1 hour), so refresh before each run for scheduled jobs.
Find your propertyId in GA4: Admin → Property Settings → Property ID
(a numeric value like 123456789).
Examples
Last 7 days of sessions and active users by source/campaign:
{
"apiKey": "ya29.a0Af...<access-token>",
"operation": "run-report",
"propertyId": "123456789",
"metrics": "activeUsers,sessions,conversions",
"dimensions": "sessionSource,sessionCampaignName",
"startDate": "7daysAgo",
"endDate": "today",
"limit": "100"
}
Realtime active users by country:
{
"apiKey": "ya29.a0Af...<access-token>",
"operation": "run-realtime",
"propertyId": "123456789",
"metrics": "activeUsers",
"dimensions": "country"
}
Discover available dimensions and metrics:
{
"apiKey": "ya29.a0Af...<access-token>",
"operation": "get-metadata",
"propertyId": "123456789"
}
Two reports in one call:
{
"apiKey": "ya29.a0Af...<access-token>",
"operation": "batch-run-reports",
"propertyId": "123456789",
"requests": "[{\"metrics\":[{\"name\":\"sessions\"}],\"dateRanges\":[{\"startDate\":\"7daysAgo\",\"endDate\":\"today\"}]},{\"metrics\":[{\"name\":\"totalUsers\"}],\"dateRanges\":[{\"startDate\":\"28daysAgo\",\"endDate\":\"today\"}]}]"
}
Output
Every operation publishes:
result— the GA4 Data API JSON response body, as a JSON string.status— the HTTP status code ("200"on success).
On error the tool prints {"error": "..."} and exits non-zero, marking the
step FAILED.
Publishes
The keys a later task may reference as {{taskName.key}}. Referencing anything not listed here resolves to nothing at run time.
errorresultstatus
Input Properties
Every property this tool accepts, from its own tool.iml.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey |
string | yes | — | GA4 OAuth2 access token (sent as 'Authorization: Bearer |
operation |
string | yes | — | One of: run-report, batch-run-reports, run-realtime, get-metadata |
propertyId |
string | no | — | GA4 property id, e.g. '123456789' or 'properties/123456789'. Required for every operation. |
metrics |
string | no | — | run-report/run-realtime: comma-separated metric names, e.g. 'activeUsers,sessions,conversions'. |
dimensions |
string | no | — | run-report/run-realtime: comma-separated dimension names, e.g. 'date,sessionSource,sessionCampaignName'. |
startDate |
string | no | — | run-report: start date 'YYYY-MM-DD' or relative like '7daysAgo'. Defaults to '7daysAgo'. |
endDate |
string | no | — | run-report: end date 'YYYY-MM-DD' or 'today'/'yesterday'. Defaults to 'today'. |
limit |
string | no | — | run-report/run-realtime: optional max number of rows to return. |
requests |
string | no | — | batch-run-reports: JSON array of RunReportRequest objects, e.g. [{"metrics":[{"name":"sessions"}],"dateRanges":[{"startDate":"7daysAgo","endDate":"today"}]}]. |