Create Google Ads Demand Gen campaign (adsap_google_create_demand_gen_campaign)
Platform: Google Ads · Read or write: Write · Plan: Early Access · Consumes a task: Yes · Preview supported: Yes
What it does
Creates a full Demand Gen campaign in one request: budget, campaign, an ad group with channel controls, ad group level location and language targeting, and one ad. The ad is either an image ad or a YouTube video ad. The campaign is always created paused. Ask for a preview first.
When to use it
- Use it for a new campaign on YouTube, Discover, Gmail, Maps and the Google Display Network. The campaign carries one image ad or one YouTube video ad.
- For an image ad, upload the images first with
adsap_google_upload_assetand pass the asset IDs. A video ad takes YouTube video IDs and 1 to 5 long headlines. - Pick surfaces with
ad_group.channels: either astrategyor aselectedset, never both. With neither, the ad group usesALL_CHANNELS. - Locations and languages are applied on the ad group, not on the campaign. With no
language_ids, the tool targets English (1000). - It supports a preview call. With
dry_runset totrue, Google validates the plan, nothing is created, and no task is used.
Worked example
You ask
“Preview a Demand Gen campaign in account 1234567890 for the summer collection. 20 a day, France, YouTube feed and Discover only, with the three images I uploaded.”
The assistant calls adsap_google_create_demand_gen_campaign
{
"ad_account_id": "1234567890",
"campaign": { "name": "Summer collection, Demand Gen", "daily_budget": 20 },
"geo": {
"location_ids": ["2250"]
},
"ad_group": {
"channels": {
"selected": { "youtube_in_feed": true, "discover": true }
}
},
"ad": {
"ad_type": "multi_asset",
"final_url": "https://www.example.com/summer",
"business_name": "Example Store",
"headlines": ["Summer Collection Is Here"],
"descriptions": ["New styles for warm days. Free returns for 30 days."],
"logo_asset_ids": ["30000000001"],
"landscape_image_asset_ids": ["30000000002"],
"square_image_asset_ids": ["30000000003"]
},
"dry_run": true
}Adsap returns
The field names are the ones Adsap returns. The values are examples.
{
"ok": true,
"dry_run": true,
"platform": "google",
"action": "create_demandgen_campaign",
"plan": {
"campaign": {
"name": "Summer collection, Demand Gen",
"status_at_create": "PAUSED",
"daily_budget": 20,
"bidding_strategy": "maximize_clicks",
"target_cpa": null,
"target_roas": null
},
"geo": {
"location_ids": ["2250"],
"negative_location_ids": []
},
"language_ids": ["1000"],
"ad_group": {
"name": "Summer collection, Demand Gen - ad group",
"channels": "youtube_in_feed+discover",
"optimized_targeting": true
},
"ad": {
"ad_type": "multi_asset",
"final_url": "https://www.example.com/summer",
"business_name": "Example Store",
"headlines": 1,
"long_headlines": 0,
"descriptions": 1,
"logos": 1,
"landscape_images": 1,
"square_images": 1,
"portrait_images": 0,
"tall_portrait_images": 0,
"youtube_videos": 0,
"call_to_action": null
},
"operations_count": 6,
"conversion_actions_found": 0
},
"bidding_strategy": "maximize_clicks",
"google_validation": "passed",
"warnings": [
"This account has NO enabled conversion actions - defaulting to Maximize Clicks. Switch to a conversion-based strategy once conversion tracking is set up."
]
}How to read it
plan is what Adsap would send to Google. status_at_create is PAUSED, so nothing spends yet. ad_group.channels lists the surfaces that were set to true. language_ids shows the English default, because the call sent no languages. The ad counts confirm which assets made it into the ad.
bidding_strategy shows what auto resolved to. Here conversion_actions_found is 0, so the tool picked maximize_clicks, and warnings explains it. google_validation is passed when Google accepts the plan. Otherwise it holds Google’s error message. To create the campaign, the assistant repeats the call without dry_run and gets a campaign_id and an ad_group_id back.
Parameters
Descriptions are shortened from the tool schema. Your assistant sees the full text.
| Name | Type | Required | Description |
|---|---|---|---|
ad_account_id | string | Yes | Bare 10-digit Google Ads customer ID (from adsap_google_list_ad_accounts). No dashes, no act_ prefix. |
campaign | object | Yes | |
campaign.name | string | Yes | |
campaign.daily_budget | number | Yes | Daily budget in the ACCOUNT CURRENCY as a plain number: minimum 5 (Google’s Demand Gen floor, local-currency equivalent of 5 USD). NOT micros, NOT cents. |
campaign.bidding_strategy | one of auto, maximize_clicks, maximize_conversions, target_roas | No | The documented Demand Gen set. ‘auto’ (default) picks maximize_conversions when enabled conversion actions exist, else maximize_clicks. |
campaign.target_cpa | number | No | Optional target cost-per-action in the account currency. Requires bidding_strategy maximize_conversions. |
campaign.target_roas | number | No | Target return on ad spend as a multiplier (3.5 = 350%). REQUIRED with bidding_strategy target_roas; Google rejects accounts without enough conversion history. |
geo | object | Yes | |
geo.location_ids | array of string | Yes | Geo target constant ids to TARGET (from adsap_google_search_geo_targets). Demand Gen applies these at the AD GROUP level. |
geo.negative_location_ids | array of string | No | Geo target constant ids to EXCLUDE. |
language_ids | array of string | No | Language constant ids (default [‘1000’] = English). |
ad_group | object | No | |
ad_group.name | string | No | Ad group name (defaults to ‘<campaign name> - ad group’). |
ad_group.channels | object | No | |
ad_group.optimized_targeting | boolean | No | Google AI expands beyond your (optional) audience signals. Leave true unless the user asks otherwise. |
ad | object | Yes | |
ad.ad_type | one of multi_asset, video_responsive | Yes | ’multi_asset’ = image ad; ‘video_responsive’ = YouTube video ad. |
ad.name | string | No | Ad name (defaults to ‘<campaign name> - ad’; Google REQUIRES a name on video ads). |
ad.final_url | string | Yes | |
ad.business_name | string | Yes | Your business name as shown in ads (<=25 characters). |
ad.headlines | array of string | Yes | 1-5 unique headlines. Max 30 chars each for multi_asset, 40 for video_responsive. |
ad.long_headlines | array of string | No | Long headlines (<=90 chars). REQUIRED (1-5) for video_responsive; not used by multi_asset. |
ad.descriptions | array of string | Yes | 1-5 unique descriptions, each <=90 characters. |
ad.logo_asset_ids | array of string | Yes | 1-5 LOGO-eligible image asset ids from adsap_google_upload_asset (1:1, min 128x128). |
ad.landscape_image_asset_ids | array | No | multi_asset: MARKETING_IMAGE asset ids (1.91:1, min 600x314). At least one landscape OR square image required. |
ad.square_image_asset_ids | array | No | multi_asset: SQUARE_MARKETING_IMAGE asset ids (1:1, min 300x300). |
ad.portrait_image_asset_ids | array | No | multi_asset optional: PORTRAIT (4:5, min 480x600) asset ids. |
ad.tall_portrait_image_asset_ids | array | No | multi_asset optional: TALL_PORTRAIT (9:16, min 600x1067) asset ids: the vertical-feed slot Demand Gen adds over PMax. |
ad.youtube_video_ids | array of string | No | video_responsive: 1-5 YouTube video ids (REQUIRED for that type; created/reused as named assets). Not allowed on multi_asset. |
ad.call_to_action | one of LEARN_MORE, GET_QUOTE, APPLY_NOW, SIGN_UP, CONTACT_US, SUBSCRIBE, DOWNLOAD, BOOK_NOW and 9 more | No | Optional CTA; Google automates it when unset. |
dry_run | boolean | No | Preview only: the request is validated and the resolved payload returned, nothing is created or changed. |
Example prompts
- “Preview a Demand Gen campaign at 20 dollars a day targeting the UK, YouTube and Discover only, with these images.”
- “Create a Demand Gen video campaign using my YouTube video and these five headlines.”
- “Create the Demand Gen campaign we just previewed.”
Notes
The daily budget floor is 5 in the account currency. Target ROAS needs conversion history or Google rejects it. Set display to true in the channel selection to reach the Google Display Network.
Related tools
adsap_google_create_app_campaign: Create a complete Google App campaign in ONE atomic request: budget, campaign (ALWAYS created PAUSED: activate later with…adsap_google_create_display_campaign: Create a classic standalone Google Display campaign in ONE atomic request: budget, campaign (ALWAYS created PAUSED: activate later with…adsap_google_create_pmax_campaign: Create a complete Google Ads Performance Max campaign in ONE atomic request: budget, campaign (ALWAYS created PAUSED: activate later with…adsap_google_create_search_campaign: Create a complete Google Ads Search campaign in ONE atomic request: budget, campaign (ALWAYS created PAUSED: activate later with…adsap_google_create_shopping_campaign: Create a complete standard Google Shopping campaign in ONE atomic request: budget, campaign (ALWAYS created PAUSED: activate later with…adsap_google_list_campaigns: List Google Ads campaigns in a Google Ads account (cache-first; auto-refreshes from Google when the cache is missing or older than 1 hour).
Guide
Read Demand Gen campaigns for the workflow around this tool, and the Tool reference for every tool.
The Google Ads MCP server page shows how to connect Google Ads to Claude, ChatGPT or Perplexity.