Files
analytics/documentation/google-analytics.md
T
JiriUhlir 6934f22253 first
2026-06-18 11:58:23 +02:00

3.1 KiB

Google Analytics (GA4)

Proxy over the GA4 Data API (analyticsdata.googleapis.com/v1beta) and Admin API (analyticsadmin.googleapis.com/v1beta).

Credentials

Token has precedence over the service account:

Header Meaning
X-GA-Access-Token Ready OAuth2 access token, used directly as Authorization: Bearer.
X-GA-Credentials Base64 of a Google service-account JSON key. The proxy mints a short-lived token (scope https://www.googleapis.com/auth/analytics.readonly) via google-auth and caches it in memory until ~60 s before expiry.
X-GA-Quota-Project Optional GCP project id → upstream x-goog-user-project.

At least one of X-GA-Access-Token / X-GA-Credentials is required (otherwise 401 missing_credentials).

The service account (or token) must have access to the GA4 property — add its client_email as a viewer in GA Admin → Property Access Management.

Encoding the key: base64 -w0 service-account.json (Linux) or [Convert]::ToBase64String([IO.File]::ReadAllBytes("service-account.json")) (PowerShell).

Data API endpoints

property_id may be the bare number (123456789) or properties/123456789.

Method Path Upstream
POST /ga/data/properties/{id}/runReport :runReport
POST /ga/data/properties/{id}/runPivotReport :runPivotReport
POST /ga/data/properties/{id}/batchRunReports :batchRunReports
POST /ga/data/properties/{id}/batchRunPivotReports :batchRunPivotReports
POST /ga/data/properties/{id}/runRealtimeReport :runRealtimeReport
POST /ga/data/properties/{id}/checkCompatibility :checkCompatibility
GET /ga/data/properties/{id}/metadata /metadata

The POST body is the GA4 request object, forwarded unchanged. Example runReport body:

{
  "dateRanges": [{ "startDate": "7daysAgo", "endDate": "today" }],
  "dimensions": [{ "name": "country" }],
  "metrics": [{ "name": "activeUsers" }]
}

Admin API endpoints (read)

Method Path Notes
GET /ga/admin/accounts pageSize, pageToken
GET /ga/admin/accountSummaries accounts + their properties
GET /ga/admin/properties?accountId=123 builds filter=parent:accounts/123
GET /ga/admin/properties/{id} single property
GET /ga/admin/properties/{id}/dataStreams data streams

Errors

UpstreamError is returned as JSON with the upstream status and body:

{
  "error": "upstream_error",
  "status": 403,
  "detail": "User does not have sufficient permissions for this property.",
  "upstream_status": 403,
  "upstream_body": { "error": { "code": 403, "status": "PERMISSION_DENIED" } }
}

Timeouts → 504, unreachable/transport → 502, token minting failure → 401.

curl example

curl -X POST "https://services.csbot.cz/apps/analytics/ga/data/properties/123456789/runReport" \
  -H "X-GA-Access-Token: ya29...." \
  -H "Content-Type: application/json" \
  -d '{"dateRanges":[{"startDate":"7daysAgo","endDate":"today"}],"metrics":[{"name":"activeUsers"}]}'