Select Google Ads Account
Verify and bind one provider-returned Google Ads customer account.
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Google-Ads-specific bind body — adds the 10-digit customer-id check.
The check lives HERE, not on the base IntegrationAccountSelect, because
that base is also the body for Meta Facebook-Page select (workspace + brand),
whose page ids are NOT 10-digit — a base-level validator would 422 valid Meta
binds. Persisting a malformed id would later break the Google Ads API URL /
login-customer-id header.
Response
Successful Response
Integration status — includes has_oauth_credentials so UI knows when the user has saved their own Google Cloud OAuth app credentials.
SECURITY — extra_data is deliberately NOT a field here. This model is
the response_model for the workspace/brand integration-status routes
(GET /brands/{id}/integrations/status,
GET /workspaces/{id}/integrations/status) and for the nested
WorkspaceDetailResponse.integration_credentials list. FastAPI's
response_model + Pydantic from_attributes is a strict allow-list:
only the fields declared below are read off the ORM row and serialized, so
IntegrationCredential.extra_data is dropped before it reaches the
client. That matters because OAuth providers (e.g. Meta) stash secrets in
extra_data — workspace/team Meta publishing flows store encrypted Page
tokens for selection, and brand Meta Ads stores the encrypted Marketing API
user token. Adding an extra_data field to this model would leak those
tokens to the browser — the exact class of bug fixed for the TEAM status
endpoint in PR #2079. If a future edit UI needs config from extra_data,
expose a NEW field carrying only the non-secret keys (as
meta_ad_account does below) — never the raw dict. Pinned by
tests/contracts/shapes/test_integration_status_response_no_extra_data.py.
Selected Meta Marketing API account, safe to expose to the browser.