---
title: "List Google Analytics (GA4) dimensions and metrics"
method: GET
path: "/v1/analytics/googleanalytics/metadata"
tags: ["Analytics"]
---

# List Google Analytics (GA4) dimensions and metrics

`GET /v1/analytics/googleanalytics/metadata`

## Request

- Base URL: `https://zernio.com/api`
- URL: `https://zernio.com/api/v1/analytics/googleanalytics/metadata`
- Auth: HTTP bearer

Every dimension and metric the connected GA4 property accepts in a report, including its
custom definitions. Cached for one hour.

## Query parameters

- `accountId` string, required

## Response `200`

Available dimensions and metrics

- object
  - `accountId` string
  - `propertyId` string
  - `dimensions` object[]
    - `apiName` string
    - `uiName` string
    - `description` string
    - `category` string
    - `customDefinition` boolean
  - `metrics` object[]
    - `apiName` string
    - `uiName` string
    - `description` string
    - `type` string
    - `category` string
    - `customDefinition` boolean

## Other responses

- `400`: Invalid request
- `401`: Missing or invalid API key. `code` is `missing_credentials` when no Authorization header was sent and `invalid_credentials` when the key is unknown, revoked or expired.
- `403`: The Google account that connected the property lost access to it, or revoked Zernio. Reconnect Google Analytics.
- `404`: Resource not found
- `429`: The connected account's upstream platform quota is exhausted. Behavior per platform: - **Reddit:** rate-limits per connected Reddit user (1000 requests per 10-minute window), shared by every operation on that account. Retry after the window resets; repeated calls while exhausted do not succeed and keep the budget spent. - **Google Ads:** writes and reports run on one developer token shared by every Google Ads account on Zernio. It holds Standard access (no daily operations cap), so this only happens when Google throttles the token or your ad account. - **Google Ads envelope:** `code: rate_limited`, `platform: google`, `details.quotaScope: DEVELOPER` (`ACCOUNT` when it is your own ad account's quota), `details.resetsAt` (ISO instant when Google accepts requests again) and `Retry-After` counting down to it. Retrying earlier cannot succeed. - **YouTube Analytics:** reads (channel-insights, demographics, daily-views, video-retention) use the "Queries per day" quota of the Google Cloud project the account is connected through, shared with other Zernio customers, so a 429 is not your own volume. Resets at midnight Pacific Time. - **YouTube Analytics envelope:** `code: rate_limited`, `platform: google`, `details.quotaExhausted: true`, `details.quotaScope: DEVELOPER`, `details.resetsAt` and `Retry-After` counting down to it. Retrying earlier cannot succeed. - **Meta ads:** every Meta throttle (codes 4, 17, 32, 613 and business-use-case codes 80000-80014) returns 429 `rate_limited`, even when Meta answers HTTP 400. `Retry-After` comes from Meta's `x-business-use-case-usage` estimate when sent, else Meta's 60-second minimum (30 seconds for the one-write-per-30-seconds limit on one object). - **Pinterest ads:** limits per user and app, per category (ads_read, ads_write, ads_analytics). `Retry-After` comes from Pinterest's `x-ratelimit-reset` when sent, otherwise 60 seconds. - **TikTok ads:** limits per app and per endpoint (per second, minute and day), answering overage with code 40100 or code 40002 `OVER_QPS_LIMIT`. Both return 429 `rate_limited` with `platform: tiktok` and `Retry-After: 10`. Space out bulk reads (e.g. one ad at a time per advertiser) instead of retrying at once. **TikTok Smart+ review read** (`GET /v1/ads/{adId}/tiktok-smart-plus-review`) has its own stricter TikTok quota. After an overage, Zernio answers 429 for that advertiser and connection without calling TikTok for about 60 seconds, then 120, up to 240 while TikTok keeps refusing, each with up to 10% random jitter. A successful call holds nothing back; the next overage pauses about 60 seconds again. `Retry-After` is the time left. The advertiser-wide read (`GET /v1/ads/tiktok-smart-plus-reviews`) answers 200 with `retryAfterSeconds` and `refreshState` instead. Keep one request in flight per advertiser there.

## Changes

- **2026-10-26** `cef81aa186cc`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/analytics/googleanalytics/metadata/get.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) - [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) - [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/c319eb5d95b6?raw)
