Google Analytics logo

Google Analytics

Overview

The Ingest Google Analytics connector reads from GA4 across two Google API surfaces — the Admin API (configuration metadata: properties, custom dimensions, data streams, etc.) and the Data API (reports and metadata). Both surfaces share one OAuth2 scope, analytics.readonly, and one access token.

Two authentication flows are supported; you can switch between them with a dbt var:

  • OAuth2 user-consent (oauth2_ac, default) — same shape as a typical "Sign in with Google" flow. Best when one specific Google user owns the access (e.g. a marketing-ops account). 4 secrets stored: client_id, client_secret, access_token, refresh_token.
  • JWT service account (jwt_bearer) — a Google service account signs a JWT and exchanges it for an access token. No browser consent. Best when access should not be tied to any one user. 2 secrets stored: client_email, private_key. The service account email must be added as a Viewer on each GA4 property you want to read.

Setup guide

Path A — User-consent OAuth (oauth2_ac)

  1. In Google Cloud Console, create or pick a project, then go to APIs & Services → Library and enable Google Analytics Admin API and Google Analytics Data API.
  2. Open APIs & Services → Credentials and click Create Credentials → OAuth client ID. Application type: Web application. Add the Ingest callback URL provided by your Ingest contact as an Authorized redirect URI.
  3. Copy the Client ID and Client Secret.
  4. Run the one-shot consent flow your Ingest contact provides — this opens the Google consent screen, captures the code, and exchanges it for an access_token and refresh_token. Both values land in the secret payload.
  5. Paste all four values (client_id, client_secret, access_token, refresh_token) into the Ingest UI under Connectors → Google Analytics.

Path B — Service account (jwt_bearer)

  1. In Google Cloud Console → IAM & Admin → Service Accounts, create a service account (no project-level roles needed).
  2. On the service account's Keys tab, Add Key → Create new key → JSON. Download the file once.
  3. From the JSON: copy client_email (looks like ingest-ga@<project>.iam.gserviceaccount.com) and private_key (the multi-line -----BEGIN PRIVATE KEY----- block, including the literal \n line separators).
  4. In each GA4 property you want Ingest to read, open Admin → Property Access Management and add the service account email as a Viewer.
  5. Paste client_email and private_key into the Ingest UI under Connectors → Google Analytics, and tell your Ingest contact to set var('google_analytics_auth_type', 'jwt_bearer') for your project.

Mind the limits

The Admin API allows 600 requests per minute per user (≈10 req/sec) and the Data API uses a token-bucket quota per user per project. Ingest dispatches at 3 req/sec by default and uses AIMD backoff on 429 responses to tune up to whatever the actual ceiling is for your workload.

Errors with status 400 (malformed report request), 401 (bad/expired token), 403 (service account not added as Viewer on the property, or scope missing), or 404 (wrong property id) are treated as fatal — fix the cause before retrying.

Pick endpoints

The discovery topology is rooted at account_summaries, which returns nested property summaries flattened into one row per (account, property). Most customers want:

  • Configuration metadata (Admin API)account_summaries, data_streams, custom_dimensions, custom_metrics, key_events, data_retention_settings. The "what's set up in GA4" surface.
  • Reporting metadata (Data API)metadata, audience_exports. Lists the dimensions/metrics available to query and any pre-built audience exports.
  • Reports (Data API, currently parked)run_report, run_pivot_report, run_realtime_report, batch_run_reports, check_compatibility. These all use POST with a JSON body; the Ingest runtime currently only supports query-string GET requests, so these endpoints are excluded from the catalog. They will graduate when the runtime gains JSON-body support.

Supported streams

11 endpoints are available out of the box. Each endpoint syncs into its own Iceberg table in Snowflake.

EndpointDescriptionReference
account_summaries
account_summaries
audience_exports
audience_exports
custom_dimensions
custom_dimensions
custom_metrics
custom_metrics
data_retention_settings
data_retention_settings
data_streams
data_streams
firebase_links
firebase_links
google_ads_links
google_ads_links
key_events
key_events
measurement_protocol_secrets
measurement_protocol_secrets
metadata
metadata

Authentication

Auth type
OAuth 2.0

Performance & limits

Rate limit
Admin API allows 600 req/min/user (10 req/sec); Data API uses a token-bucket quota per user per project. Ingest dispatches at 3 req/sec by default and lets AIMD tune up.
Automatic backoff
Ingest throttles requests to the published rate limit and retries with exponential backoff on transient errors. You don't need to handle 429s, retries, or pagination yourself.

Resources