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
| Goal | Bidding strategy | Optional target |
|---|---|---|
CONVERSIONS | Maximize Conversions | target_cpa |
CONVERSION_VALUE | Maximize Conversion Value | target_roas (e.g. 3.5 for 350%) |
CLICKS | Maximize Clicks | target_cpc |
YOUTUBE_ENGAGEMENTS | Maximize Engagements | — |
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.
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
Geo target type
Controls how location targeting is interpreted.| Setting | Behaviour |
|---|---|
PRESENCE (default) | Targets people physically present in the location |
PRESENCE_OR_INTEREST | Targets people present in or interested in the location |
PRESENCE — people physically in an excluded location are excluded regardless.
Ad schedule
Restrict when ads are eligible to show. Pass a list of day/time windows. Each window accepts:day_of_week: MONDAY through SUNDAYstart_hour/end_hour: 0–23start_minute/end_minute: ZERO, FIFTEEN, THIRTY, FORTY_FIVE
Start and end dates
YYYYMMDD or standard datetime strings.
Tracking
EU political advertising
Defaults toDOES_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:| Strategy | Inventory included |
|---|---|
ALL_CHANNELS | YouTube in-stream, in-feed, Shorts, Discover, Gmail, Display |
ALL_OWNED_AND_OPERATED_CHANNELS | YouTube, Discover, Gmail — no Display Expansion |
| Channel | Inventory |
|---|---|
youtube_in_stream | Skippable and non-skippable pre-roll ads |
youtube_in_feed | YouTube search results and homepage feed |
youtube_shorts | YouTube Shorts vertical feed |
discover | Google Discover feed |
gmail | Gmail promotions tab |
display | Google Display Network |
channel_strategy and selected_channels unless you want explicit channels to override the strategy.
Location targeting
Pass human-readable location names. HireOtto resolves them to Google Ads geo target IDs.locations: include (target)negative_locations: exclude
Language
Defaults to English. Pass any supported language name or ISO code, orNone 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: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
| Type | Required input |
|---|---|
MARKETING_IMAGE | Image URL (landscape) |
SQUARE_MARKETING_IMAGE | Image URL (1:1) |
LOGO_IMAGE | Image URL |
YOUTUBE_VIDEO | YouTube video ID (not full URL) |
TEXT | Text string |
CALL_TO_ACTION / CTA | CTA display text |
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.Carousel image
Pass cards inline or by existing card asset resource names. Each card can carry its own image.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 yourcall_to_action_text.
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.Updating campaigns
Pass only the fields you want to change. All other settings remain unchanged.REPLACE — existing schedules are removed before new ones are applied. Use APPEND to add without removing.
Updating ad groups
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.pause old ad: false to keep both running.
To change status only (no creative change):
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)
Recommended workflow
- Create the campaign shell (paused)
- List available audiences →
List all audiences in account [CUSTOMER_ID] - Add ad group with channel controls, locations, language, audience
- Create reusable assets if the same creative will appear in multiple ads
- Create ads (paused)
- Inspect → campaign settings, ad group channel controls, ads
- Enable when structure looks right