Skip to main content
Demand Gen campaigns run across YouTube (in-stream, in-feed, Shorts), Discover, Gmail, and Display from a single campaign structure. They are Google’s primary upper-funnel campaign type for visual creative at scale. Setting one up in the UI involves several distinct layers: campaign shell → ad group → channel controls → assets → ads. HireOtto handles each step in a single conversation, and lets you inspect and update each layer independently.

Step 1 — Create the campaign shell

At minimum, you need a campaign name and a budget (either a daily amount or an existing budget ID). Everything else has a sensible default.

Campaign goals and bidding

GoalBidding strategyOptional target
CONVERSIONSMaximize Conversionstarget_cpa
CONVERSION_VALUEMaximize Conversion Valuetarget_roas (e.g. 3.5 for 350%)
CLICKSMaximize Clickstarget_cpc
YOUTUBE_ENGAGEMENTSMaximize Engagements
If you omit a target, Google Ads uses unconstrained bidding for the chosen goal.
Create a Demand Gen campaign called "[CAMPAIGN_NAME]" — $100/day budget, Maximize Conversions, target CPA $20.
Create a Demand Gen campaign — $500/day, Maximize Conversion Value, target ROAS 4.0.
Create a Demand Gen campaign for brand awareness — $200/day, YouTube Engagements goal.

Budget

Two options:
  • New budget: Pass a budget_amount. HireOtto creates a new non-shared daily budget attached to this campaign.
  • Existing budget: Pass an existing budget_id. Must be a non-shared budget — Demand Gen campaigns cannot use shared budgets.
Create a Demand Gen campaign and attach it to existing budget [BUDGET_ID].

Device targeting

By default, all devices are eligible. Restrict to specific devices if your creative or landing page is optimised for a subset. Accepted: DESKTOP, MOBILE, TABLET, CONNECTED_TV
Create a Demand Gen campaign — $100/day, mobile and tablet only.
Create a Demand Gen campaign targeting desktop and Connected TV.

Geo target type

Controls how location targeting is interpreted.
SettingBehaviour
PRESENCE (default)Targets people physically present in the location
PRESENCE_OR_INTERESTTargets people present in or interested in the location
The negative geo target type is always PRESENCE — people physically in an excluded location are excluded regardless.
Create a Demand Gen campaign targeting people interested in London, not just physically there.

Ad schedule

Restrict when ads are eligible to show. Pass a list of day/time windows. Each window accepts:
  • day_of_week: MONDAY through SUNDAY
  • start_hour / end_hour: 0–23
  • start_minute / end_minute: ZERO, FIFTEEN, THIRTY, FORTY_FIVE
Create a Demand Gen campaign — weekdays only, 8am to 6pm.
Run ads Monday to Friday 9am–5pm and Saturday 10am–2pm.

Start and end dates

Create a Demand Gen campaign — run from [START_DATE] to [END_DATE].
Accepted formats: YYYYMMDD or standard datetime strings.

Tracking

Create a Demand Gen campaign — tracking template: {lpurl}?utm_source=google&utm_medium=demand_gen&utm_campaign={campaignid}
Use final URL suffix: utm_source=google&utm_medium=cpc

EU political advertising

Defaults to DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING. Declare CONTAINS_EU_POLITICAL_ADVERTISING if applicable.

Status

Campaigns are created paused by default. Review the full structure before enabling.

Step 2 — Add an ad group

Ad groups in Demand Gen control which inventory your ads run on. Each ad group has its own channel controls, location targeting, language, and audience.

Channel strategy vs explicit channel selection

Preset strategy — two broad inventory presets:
StrategyInventory included
ALL_CHANNELSYouTube in-stream, in-feed, Shorts, Discover, Gmail, Display
ALL_OWNED_AND_OPERATED_CHANNELSYouTube, Discover, Gmail — no Display Expansion
Explicit channel selection — name exactly which channels to include:
ChannelInventory
youtube_in_streamSkippable and non-skippable pre-roll ads
youtube_in_feedYouTube search results and homepage feed
youtube_shortsYouTube Shorts vertical feed
discoverGoogle Discover feed
gmailGmail promotions tab
displayGoogle Display Network
Use a preset for broad reach. Use explicit selection when you need a specific inventory mix — for example, a Shorts-only ad group for vertical video, or a Gmail + Discover ad group for a promotional push. Do not pass both channel_strategy and selected_channels unless you want explicit channels to override the strategy.
Add a Demand Gen ad group to campaign [CAMPAIGN_ID] — all channels, India, English.
Create a Demand Gen ad group for YouTube Shorts only — US, English.
Add an ad group targeting Gmail and Discover — UK, English.
Create an ad group — all owned and operated channels (no Display), Australia.

Location targeting

Pass human-readable location names. HireOtto resolves them to Google Ads geo target IDs.
  • locations: include (target)
  • negative_locations: exclude
Add a Demand Gen ad group — include US and Canada, exclude India.

Language

Defaults to English. Pass any supported language name or ISO code, or None to leave language unset. Supported: English (en), Spanish (es), French (fr), German (de), Italian (it), Portuguese (pt), Japanese (ja), Korean (ko), Hindi (hi), Chinese (zh)

Audience targeting

Demand Gen ad groups support one audience resource name. To get available audience resource names:
List all audiences in account [CUSTOMER_ID].
Then:
Add a Demand Gen ad group — audience: [AUDIENCE_RESOURCE_NAME], all channels, US, English.

Step 3 — Create assets (optional)

Create standalone assets when the same image or video will appear across multiple ads. HireOtto returns the asset resource name, which you then reference when building ads. For one-off ads, skip this step and pass image URLs or YouTube video IDs inline when creating the ad.

Supported asset types

TypeRequired input
MARKETING_IMAGEImage URL (landscape)
SQUARE_MARKETING_IMAGEImage URL (1:1)
LOGO_IMAGEImage URL
YOUTUBE_VIDEOYouTube video ID (not full URL)
TEXTText string
CALL_TO_ACTION / CTACTA display text
Supported CTA values: Apply now, Book now, Contact us, Download, Get quote, Learn more, See more, Shop now, Sign up, Subscribe, Visit site, Donate now
Create a marketing image asset from [IMAGE_URL] — name it "[ASSET_NAME]".
Create a square marketing image from [IMAGE_URL] — name it "[ASSET_NAME]".
Create a YouTube video asset — video ID [VIDEO_ID], name "[ASSET_NAME]".
Create a CTA asset: "Shop now".

Step 4 — Create ads

All ads are created paused by default.

Single image / Multi-asset

The standard Demand Gen format. Works across most inventory types. Minimum: one marketing image (or square), one headline, one description, final URL. Optional: logo, additional image formats (portrait, tall portrait, classic display), business name, CTA, multiple headlines and descriptions.
Create a multi-asset ad in ad group [ADGROUP_ID]:
  marketing image: [IMAGE_URL]
  logo: [LOGO_URL]
  headline: "[HEADLINE]"
  description: "[DESCRIPTION]"
  business name: "[BUSINESS_NAME]"
  CTA: "Learn more"
  final URL: [URL]
To pass existing asset resource names instead of inline URLs:
Create a single image ad in ad group [ADGROUP_ID]:
  marketing image asset: [ASSET_RESOURCE_NAME]
  headline: "[HEADLINE]"
  description: "[DESCRIPTION]"
  final URL: [URL]
For campaigns running across multiple placements, passing portrait and square variants alongside landscape gives Google more to work with:
Create a multi-asset ad — landscape: [URL_1], square: [URL_2], portrait: [URL_3], headline: "[HEADLINE]", description: "[DESCRIPTION]", final URL: [URL].

Pass cards inline or by existing card asset resource names. Each card can carry its own image.
Create a carousel ad in ad group [ADGROUP_ID]:
  cards: [IMAGE_URL_1], [IMAGE_URL_2], [IMAGE_URL_3]
  headline: "[HEADLINE]"
  CTA: "Shop now"
  final URL: [URL]
breadcrumb1 and breadcrumb2 are optional display path fields for carousel ads.

Video / Video responsive

Requires at least one YouTube video ID. HireOtto creates a CTA asset internally from your call_to_action_text.
Create a video ad in ad group [ADGROUP_ID]:
  YouTube video: [VIDEO_ID]
  headline: "[HEADLINE]"
  business name: "[BUSINESS_NAME]"
  CTA: "Sign up"
  final URL: [URL]
For video responsive, pass multiple video IDs:
Create a video responsive ad — videos: [VIDEO_ID_1], [VIDEO_ID_2], headline: "[HEADLINE]", description: "[DESCRIPTION]", final URL: [URL].

CTA text

For Single image / Multi-asset ads, call_to_action_text is passed as display text. Use human-readable values — not enum-style values like LEARN_MORE (Google may reject those).

Inspecting Demand Gen structure

Three listing actions. Run these before making changes.
Show me all Demand Gen campaigns in account [CUSTOMER_ID].
Returns: campaign IDs, goals, bidding, devices, geo settings, ad schedule.
Get the channel settings for all Demand Gen ad groups in campaign [CAMPAIGN_ID].
Returns: channel controls, locations, languages, audiences per ad group.
Show me all ads in ad group [ADGROUP_ID].
Returns: ad IDs, type, status, creative asset references.

Updating campaigns

Pass only the fields you want to change. All other settings remain unchanged.
Update campaign [CAMPAIGN_ID] — change goal to Maximize Conversion Value, target ROAS 3.5.
Pause campaign [CAMPAIGN_ID].
Update campaign [CAMPAIGN_ID] — restrict to mobile only.
Add a weekday 9am–6pm ad schedule to campaign [CAMPAIGN_ID].
Update tracking template for campaign [CAMPAIGN_ID]: {lpurl}?utm_campaign={campaignid}
When updating ad schedules, the default mode is REPLACE — existing schedules are removed before new ones are applied. Use APPEND to add without removing.
Add Saturday 10am–4pm to campaign [CAMPAIGN_ID] without removing the existing weekday schedule.

Updating ad groups

Switch ad group [ADGROUP_ID] to YouTube Shorts and Gmail only.
Update ad group [ADGROUP_ID] — all owned and operated channels.
Rename ad group [ADGROUP_ID] to "[NEW_NAME]".
Pause ad group [ADGROUP_ID].

Updating ad creative

Demand Gen creative fields cannot be edited directly via the Google Ads API. The correct approach is replacement: HireOtto creates a new ad with the updated creative, then pauses the old one.
Replace the creative on ad [AD_ID] in ad group [ADGROUP_ID]:
  new marketing image: [IMAGE_URL]
  headline: "[NEW_HEADLINE]"
  description: "[NEW_DESCRIPTION]"
  final URL: [URL]
The old ad is paused automatically. Pass pause old ad: false to keep both running. To change status only (no creative change):
Pause ad [AD_ID] in ad group [ADGROUP_ID].
Enable ad [AD_ID] in ad group [ADGROUP_ID].

What to check before enabling

  • Campaign goal matches your active conversion actions
  • At least one approved ad exists in each ad group before the campaign goes live
  • Channel selection matches your creative formats — Shorts requires vertical video; carousel and multi-asset work broadly
  • Device targeting is consistent with your landing page experience
  • Location and audience targeting is set at the ad group level (campaign-level geo type controls how location targeting is interpreted, but actual locations are set per ad group)

  1. Create the campaign shell (paused)
  2. List available audiences → List all audiences in account [CUSTOMER_ID]
  3. Add ad group with channel controls, locations, language, audience
  4. Create reusable assets if the same creative will appear in multiple ads
  5. Create ads (paused)
  6. Inspect → campaign settings, ad group channel controls, ads
  7. Enable when structure looks right
→ See the full tools reference at /google-ads-mcp-tools → See the changelog at /changelog