Skip to main content
Version: Next

GoogleAds

Google Ads source connector

Support Those Engines

Spark
Flink
SeaTunnel Zeta

Key Features

Description

Reads data from Google Ads resources (campaign, ad_group, keyword_view, ...) using the Google Ads REST API (googleAds:search) with GAQL queries. Supports single-resource, full-GAQL-query, and multi-table (tables_configs) batch ingestion. Results are streamed page by page via nextPageToken, so only one page is held in memory at a time.

Authentication uses the OAuth 2.0 refresh-token grant plus a Google Ads developer token. The access token is refreshed automatically when it expires.

The output schema is derived automatically: the connector queries the googleAdsFields:search metadata service for the data type of every selected field and builds the schema in the SELECT field order, so column i always corresponds to selected field i.

Supported DataSource Info

DatasourceSupported Versions
Google AdsREST API v21 (default, configurable via api_version)

Prerequisites

  1. A Google Ads developer token (from the API Center of a manager/MCC account).
  2. An OAuth2 client ID / client secret (Google Cloud Console, OAuth consent configured for the https://www.googleapis.com/auth/adwords scope).
  3. A refresh token authorized for that scope (e.g. via the OAuth 2.0 Playground or the Google Ads API oauth helper scripts).
  4. The customer ID of the account to query (digits only, no dashes). If it is a client account under an MCC, also set login_customer_id to the MCC customer ID.

Source Options

NameTypeRequiredDefaultDescription
developer_tokenStringYes-Google Ads API developer token.
client_idStringYes-OAuth2 client ID.
client_secretStringYes-OAuth2 client secret.
refresh_tokenStringYes-OAuth2 refresh token for the adwords scope.
customer_idStringYes-Customer ID to query, digits only, e.g. 1234567890.
login_customer_idStringNo-Manager (MCC) customer ID, digits only. Required when customer_id is managed by an MCC.
api_versionStringNov21Google Ads REST API version.
resourceStringNo*-Resource for single-table mode, e.g. campaign. Requires fields. Exclusive with query and tables_configs.
fieldsListNo-Ordered list of GAQL field paths, e.g. [campaign.id, metrics.clicks]. The output schema follows this order.
filterStringNo-GAQL WHERE clause appended to the auto-built SELECT <fields> FROM <resource> query.
queryStringNo*-Full GAQL query. Exclusive with resource/fields/filter and tables_configs.
tables_configsListNo*-Multi-table configuration list. Each entry requires table_path. Exclusive with resource and query.
request_timeout_msIntegerNo60000HTTP request timeout in milliseconds for a single call.
max_retriesIntegerNo3Maximum retries for transient HTTP failures (429/5xx/network errors) of a single request.
retry_backoff_msLongNo1000Base backoff in milliseconds between retries; doubled per attempt.
page_sizeIntegerNo-Page size for search requests. When unset the server default is used. Note: recent API versions ignore or reject an explicit page size.

* Exactly one of resource, query or tables_configs must be provided.

GAQL has no SELECT *, so the field list is always explicit — either via fields or inside query. Invalid field names are rejected before any data is read, with the offending name in the error message. Invalid GAQL (HTTP 400) is never retried and the API error message is surfaced as-is.

tables_configs entry options

NameTypeRequiredDescription
table_pathStringYesFormat: database.resource, e.g. google_ads.campaign.
fieldsListNo*Ordered GAQL field paths for this table.
queryStringNo*Full GAQL query for this table. Its FROM resource must match table_path.
filterStringNoGAQL WHERE clause (only with fields).
customer_idStringNoPer-table customer ID override; falls back to the global customer_id.

* Exactly one of fields or query per entry.

Data Type Mapping

Google Ads Data TypeSeaTunnel Data TypeNotes
INT64, UINT64BIGINTThe REST API serializes int64 as a JSON string; parsed to long.
INT32INT
DOUBLE, FLOATDOUBLE
BOOLEANBOOLEAN
DATESTRINGDeliberate: date-like fields have non-uniform formats (2026-09-01, 2026-09, 2026-36).
STRING, ENUM, RESOURCE_NAMESTRINGEnums are symbolic strings, e.g. ENABLED.
MESSAGESTRINGNested messages are emitted as JSON text.
Other / unknownSTRINGForward-compatible fallback.

Fields absent from a result row (the API omits empty fields entirely) are emitted as null.

Example

Single resource

source {
GoogleAds {
developer_token = "your_developer_token"
client_id = "your_client_id"
client_secret = "your_client_secret"
refresh_token = "your_refresh_token"
customer_id = "1234567890"

resource = "campaign"
fields = ["campaign.id", "campaign.name", "campaign.status", "metrics.clicks", "metrics.impressions"]
filter = "segments.date DURING LAST_30_DAYS"
}
}

Full GAQL query

source {
GoogleAds {
developer_token = "your_developer_token"
client_id = "your_client_id"
client_secret = "your_client_secret"
refresh_token = "your_refresh_token"
customer_id = "1234567890"

query = "SELECT ad_group.id, ad_group.name, metrics.clicks FROM ad_group WHERE metrics.clicks > 0"
}
}

Multiple tables (with per-table customer ID)

source {
GoogleAds {
developer_token = "your_developer_token"
client_id = "your_client_id"
client_secret = "your_client_secret"
refresh_token = "your_refresh_token"
customer_id = "1234567890"
login_customer_id = "9876543210"

tables_configs = [
{
table_path = "google_ads.campaign"
fields = ["campaign.id", "campaign.name", "metrics.cost_micros"]
filter = "segments.date DURING LAST_7_DAYS"
},
{
table_path = "google_ads.ad_group"
query = "SELECT ad_group.id, ad_group.name FROM ad_group"
customer_id = "2345678901"
}
]
}
}

Limitations

  • Batch only; no incremental/CDC reads (use filter with date segments for windowed extraction).
  • No parallel reading; each job reads with a single split.
  • No exactly-once semantics; re-running a job re-reads the data.
  • Nested MESSAGE fields are emitted as JSON strings, not nested rows.

Changelog

next version

  • Add Google Ads source connector with GAQL, automatic schema derivation and multi-table support