# 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). ## Kde získat údaje (návod pro klienta) **ID property** (`property_id` v URL): GA4 → **Administrace → Nastavení property** → *ID property* (např. `123456789`). **A) Service account – doporučeno (`X-GA-Credentials`)** 1. [Google Cloud Console](https://console.cloud.google.com/) → projekt. 2. **APIs & Services → Library** → povolit **Google Analytics Data API** a **Google Analytics Admin API**. 3. **IAM & Admin → Service Accounts → Create service account**. 4. U účtu **Keys → Add key → JSON** → stáhne se klíč. 5. `client_email` z JSON přidat v GA4 **Administrace → Správa přístupu k property** jako **Viewer**. 6. JSON zakódovat do base64 (viz výše) → hlavička `X-GA-Credentials`. **B) Hotový OAuth2 token – rychlý test (`X-GA-Access-Token`)** 1. [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/). 2. Scope `https://www.googleapis.com/auth/analytics.readonly` → **Authorize APIs** (Google účet s přístupem k property). 3. **Exchange authorization code for tokens** → *Access token* → hlavička `X-GA-Access-Token` (platí ~1 h). ## 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: ```json { "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: ```json { "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 ```bash 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"}]}' ```