Skip to content

AN-441822 Add Google Ads API enum values to paid media schemas#2112

Merged
waykar-prashant merged 7 commits intoadobe:masterfrom
ejsuncy:AN-441822/paid-media-google-ads-enum-support
Mar 30, 2026
Merged

AN-441822 Add Google Ads API enum values to paid media schemas#2112
waykar-prashant merged 7 commits intoadobe:masterfrom
ejsuncy:AN-441822/paid-media-google-ads-enum-support

Conversation

@ejsuncy
Copy link
Copy Markdown
Contributor

@ejsuncy ejsuncy commented Mar 19, 2026

Summary

  • Extends paid media field group enums to support Google Ads API v23 data ingestion
  • Adds new enum values across 8 schema files: campaignType, adGroupType, bidStrategyType, adType, assetType, servingStatus, experienceType, audienceType
  • Adds campaign-level bidStrategy enum (matching adgroup-level bidStrategyType)
  • Adds GOOGLE_MERCHANT_CENTER to productSource enum
  • Clarifies campaignType vs automatedCampaignType mapping; removes PERFORMANCE_MAX from automatedCampaignType (already in campaignType)
  • Reverts platform, position, and adPosition dimensional breakdown fields back to free-form text (the ingest process will maintain mappings on their side for flexibility)
  • Adds responsive_search, responsive_display, and dynamic_assembly experience type enums to support Google Ads experience ID derivation (where experienceID = ad.id for standard campaigns, experienceID = exp_ + asset_group.id for PMax)
  • All additions are platform-agnostic and additive-only (no breaking changes)

Closes #2113

Details

For comprehensive documentation of the Google Ads API → XDM enum mapping (including match type analysis, per-value rationale, and open questions), see the internal Jira ticket: AN-441822

Experience Type Enums Added

Enum Value Description Google Ads Mapping
responsive_search Responsive Search Ad (RSA) — multiple headlines/descriptions dynamically combined by Google ad.type == RESPONSIVE_SEARCH_AD
responsive_display Responsive Display Ad (RDA) — multiple headlines/descriptions/images dynamically combined ad.type == RESPONSIVE_DISPLAY_AD
dynamic_assembly Dynamic assembly (e.g., PMax) — platform dynamically assembles ads from an asset pool campaign.type == PERFORMANCE_MAX

Google Ads Experience ID Derivation Logic

IF ad.type IN (RSA, RDA, VIDEO_AD, IMAGE_AD, ...):
  experienceID = ad.id                    # no prefix (native ID)
ELSE IF campaign.type == PERFORMANCE_MAX:
  experienceID = "exp_" + asset_group.id  # "exp_" prefix (synthetic)
ELSE:
  experienceID = "exp_" + ad.id           # "exp_" prefix (fallback)

This mirrors the Meta convention where the first conditions use native platform IDs (no prefix) and synthetic/fallback IDs use the exp_ prefix.

Files Changed

File Fields Modified
core-paid-media-campaign-details.schema.json campaignType (+8 values, clarified description), bidStrategy (added enum matching adgroup-level), automatedCampaignType (removed PERFORMANCE_MAX, clarified description), subType (clarified description), productSource (+1 GOOGLE_MERCHANT_CENTER)
core-paid-media-adgroup-details.schema.json adGroupType (+3), bidStrategyType (+10)
core-paid-media-ad-details.schema.json adType (+6)
core-paid-media-asset-details.schema.json assetType (+7)
core-paid-media-metadata.schema.json servingStatus (+3)
core-paid-media-experience-details.schema.json experienceType (+4: audio, responsive_search, responsive_display, dynamic_assembly)
core-paid-media-dimensional-breakdowns.schema.json platform, position, adPosition kept as free-form text
paid-media-targeting.schema.json audienceType (+3: logical, rule_based, crm_based)

Validation

  • npm test — 2366 passing
  • npm run lint — clean (no formatting changes)

🤖 Generated with Claude Code

Extend paid media field group enums to support Google Ads API v23 data
ingestion while keeping schemas platform-agnostic. Additions include:

- campaignType: performance_max, demand_gen, multi_channel, local,
  local_services, hotel, travel, smart
- adGroupType: hotel, travel, audio
- bidStrategyType: maximize_conversion_value, manual_cpm, manual_cpv,
  target_cpm, target_cpv, target_cpc, percent_cpc, commission,
  manual_cpa, fixed_cpm
- adType: audio, call, smart, local, hotel, travel
- assetType: dynamic, call, app_link, booking, location,
  hotel_property, message
- servingStatus: LIMITED, LEARNING, NOT_ELIGIBLE
- experienceType: audio
- dimensionalBreakdowns.platform: new cross-platform enum
- dimensionalBreakdowns.position/adPosition: new cross-platform enum

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ejsuncy ejsuncy marked this pull request as ready for review March 19, 2026 20:04
@ejsuncy ejsuncy marked this pull request as draft March 19, 2026 23:06
Remove enum constraints from dimensional breakdown fields that were
originally free-form strings. The ingest process will maintain mappings
on their side for flexibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ejsuncy ejsuncy marked this pull request as ready for review March 23, 2026 17:52
"sponsored_tv": "Sponsored TV (Amazon)",
"traffic": "Traffic Campaign",
"performance_max": "Performance Max Campaign (Google)",
"demand_gen": "Demand Gen Campaign (Google)",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to understand the difference between this field and automatedCampaignType?
Do we expect automatedCampaignType to be mapped with Campaign Type or Campaign Sub Type in case of Google Ads?

https://github.com/googleads/google-ads-python/blob/main/google/ads/googleads/v23/enums/types/advertising_channel_type.py
https://github.com/googleads/google-ads-python/blob/main/google/ads/googleads/v23/enums/types/advertising_channel_sub_type.py

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here what is the definition of AutomationCampaignType? Is it any campaign type using automated bid strategies like TCPA/TROAS etc?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good questions. I've clarified the mapping in the latest commit:

  • campaignType maps to Google Ads advertising_channel_type — it's the primary campaign channel identity (SEARCH, DISPLAY, PERFORMANCE_MAX, etc.)
  • automatedCampaignType is a cross-platform automation product classification, not a 1:1 mapping of any single Google field. For Google Ads, automated sub-types from advertising_channel_sub_type (e.g., SMART_CAMPAIGN → SMART_PLUS, APP_CAMPAIGN → AUTO_CAMPAIGN) map here.
  • subType (free-form string) maps to advertising_channel_sub_type for non-automated variants (e.g., VIDEO_NON_SKIPPABLE, VIDEO_SEQUENCE).
  • isAutomatedCampaign = true for inherently automated campaign types (performance_max, smart, demand_gen) and platform automation features (TikTok Smart+, Meta Advantage+).

I also removed PERFORMANCE_MAX from automatedCampaignType since it's already captured by campaignType — having it in both was creating ambiguity.

@csanthosh13
Copy link
Copy Markdown

"xdm:productSource": {
"type": "string",
"title": "Product Source",
"description": "Source of products for the campaign",
"enum": [
"CATALOG",
"STORE",
"TIKTOK_SHOP",
"AMAZON",
"SHOPIFY",
"MANUAL",
"OTHER"
],
Can we consider Google Merchant Center as a source. In case of Google Ads, for Shopping campaigns, the product inventory comes from Google Merchant Center

@csanthosh13
Copy link
Copy Markdown

paidMedia.campaignDetails.targeting.interestTargeting.customAudiences.audienceType

custom, lookalike, retargeting, similar

https://github.com/googleads/google-ads-python/blob/main/google/ads/googleads/v23/enums/types/user_list_type.py

UNSPECIFIED = 0
UNKNOWN = 1
REMARKETING = 2
LOGICAL = 3
EXTERNAL_REMARKETING = 4
RULE_BASED = 5
SIMILAR = 6
CRM_BASED = 7
LOOKALIKE = 9
Will update this in wiki. Seems missed

Dan Bunker and others added 2 commits March 24, 2026 12:36
Add the same bid strategy enum list from adgroup-level bidStrategyType
to campaign-level bidStrategy field, since bid strategy is predominantly
a campaign-level setting in search networks like Google Ads. Update
example file to use a valid enum value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…add enums

- Clarify campaignType vs automatedCampaignType relationship: campaignType
  maps to Google Ads advertising_channel_type, automatedCampaignType is a
  cross-platform automation classification (not a 1:1 platform field mapping)
- Remove PERFORMANCE_MAX from automatedCampaignType (already in campaignType)
- Update subType description to clarify it maps to advertising_channel_sub_type
  for non-automated variants
- Add GOOGLE_MERCHANT_CENTER to productSource enum for Shopping campaigns
- Add Google Ads user_list_type values to audienceType enum: logical,
  rule_based, crm_based (REMARKETING/EXTERNAL_REMARKETING already covered
  by retargeting)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ejsuncy
Copy link
Copy Markdown
Contributor Author

ejsuncy commented Mar 24, 2026

"xdm:productSource": { "type": "string", "title": "Product Source", "description": "Source of products for the campaign", "enum": [ "CATALOG", "STORE", "TIKTOK_SHOP", "AMAZON", "SHOPIFY", "MANUAL", "OTHER" ], Can we consider Google Merchant Center as a source. In case of Google Ads, for Shopping campaigns, the product inventory comes from Google Merchant Center

added GOOGLE_MERCHANT_CENTER to the productSource enum

@ejsuncy
Copy link
Copy Markdown
Contributor Author

ejsuncy commented Mar 24, 2026

paidMedia.campaignDetails.targeting.interestTargeting.customAudiences.audienceType

custom, lookalike, retargeting, similar

https://github.com/googleads/google-ads-python/blob/main/google/ads/googleads/v23/enums/types/user_list_type.py

UNSPECIFIED = 0 UNKNOWN = 1 REMARKETING = 2 LOGICAL = 3 EXTERNAL_REMARKETING = 4 RULE_BASED = 5 SIMILAR = 6 CRM_BASED = 7 LOOKALIKE = 9 Will update this in wiki. Seems missed

Added logical, rule_based, and crm_based to the audienceType enum. The existing retargeting value already covers REMARKETING and EXTERNAL_REMARKETING, and similar/lookalike were already present.

@ejsuncy ejsuncy requested a review from csanthosh13 March 24, 2026 19:11
Copy link
Copy Markdown

@csanthosh13 csanthosh13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Dan Bunker and others added 2 commits March 30, 2026 10:37
Add responsive_search, responsive_display, and dynamic_assembly to
experienceType enum to support Google Ads experience ID derivation
where experienceID = ad.id for standard campaigns and
experienceID = exp_ + asset_group.id for PMax.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@waykar-prashant waykar-prashant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@waykar-prashant waykar-prashant merged commit 14605fd into adobe:master Mar 30, 2026
3 checks passed
ejsuncy pushed a commit to ejsuncy/xdm that referenced this pull request Mar 30, 2026
Change lowest_cost_without_cap to lowest_cost in Meta campaign
example to match the bidStrategy enum added in PR adobe#2112.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ejsuncy ejsuncy deleted the AN-441822/paid-media-google-ads-enum-support branch March 30, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Google Ads API v23 enum values to paid media field group schemas

3 participants