Skip to main content
Google Ads API overview
Release notes
Authentication and authorization
Google Ads management
Create assets with generative AI (closed beta)
Create and manage campaigns
Report and monitor performance
Audience and creator insights
Develop applications
Test and troubleshoot your application
Productionize your application
Send feedback
Create a Demand Gen Campaign Stay organized with collections
Save and categorize content based on your preferences.
outlined_flag
Demand Gen campaign assets must meet high quality standards to be served on visual and entertainment-focused surfaces like Discover and YouTube.
Creating a Demand Gen campaign involves several steps: budgeting, campaign setup with bidding strategies, ad group creation, audience definition, and asset and ad creation.
It is recommended to create all required entities for a Demand Gen campaign in a single API request using the GoogleAdsService.Mutate method for efficiency and to prevent orphaned entities.
Demand Gen campaigns require a non-shared budget and support setting a campaign total budget using the total_amount_micros field and setting the period to CUSTOM.
Demand Gen campaigns have an AdvertisingChannelType of DEMAND_GEN and support various bidding strategies, with ad group-level location and language criteria and channel controls available.
Check that minimum requirements
are met. Demand Gen campaign assets must meet high standards of quality,
as they will be served on visual, entertainment-focused surfaces such as
Discover and YouTube.
To create a Demand Gen campaign:
Create a budget.
Create a Demand Gen campaign with appropriate bidding strategies.
Create an ad group without a type.
Create audiences.
Create assets and Demand Gen ads.
We recommend creating all the required entities in a single API request, using
the GoogleAdsService.Mutate
method:
Java
// The below methods create and return MutateOperations that we later provide to
// the GoogleAdsService.Mutate method in order to create the entities in a single
// request. Since the entities for a Demand Gen campaign are closely tied to one-another
// it's considered a best practice to create them in a single Mutate request; the
// entities will either all complete successfully or fail entirely, leaving no
// orphaned entities. See:
// https://developers.google.com/google-ads/api/docs/mutating/overview
List<MutateOperation>
operations
=
new
ArrayList
<> ();
// A utility to create temporary IDs for the resources.
AtomicLong
tempId
=
new
AtomicLong
(
-
1
);
// Creates a new campaign budget operation and adds it to the list of operations.
String
budgetResourceName
=
ResourceNames
.
campaignBudget
(
customerId
,
tempId
.
getAndDecrement
());
operations
.
add
(
MutateOperation
.
newBuilder
()
.
setCampaignBudgetOperation
(
createCampaignBudgetOperation
(
budgetResourceName
))
.
build
());
// Creates a new campaign operation and adds it to the list of operations.
String
campaignResourceName
=
ResourceNames
.
campaign
(
customerId
,
tempId
.
getAndDecrement
());
operations
.
add
(
MutateOperation
.
newBuilder
()
.
setCampaignOperation
(
createDemandGenCampaignOperation
(
campaignResourceName
,
budgetResourceName
))
.
build
());
// Creates a new ad group operation and adds it to the list of operations.
String
adGroupResourceName
=
ResourceNames
.
adGroup
(
customerId
,
tempId
.
getAndDecrement
());
operations
.
add
(
MutateOperation
.
newBuilder
()
.
setAdGroupOperation
(
createDemandGenAdGroupOperation
(
adGroupResourceName
,
campaignResourceName
))
.
build
());
// Creates the asset operations for the ad.
Map<String
,
String
>
assetResourceNames
=
new
HashMap
<> ();
operations
.
addAll
(
createAssetOperations
(
customerId
,
youTubeVideoId
,
tempId
,
assetResourceNames
));
// Creates a new ad group ad operation and adds it to the list of operations.
operations
.
add
(
MutateOperation
.
newBuilder
()
.
setAdGroupAdOperation
(
createDemandGenAdGroupAdOperation
(
adGroupResourceName
,
assetResourceNames
))
.
build
());
// Creates the service client.
try
(
GoogleAdsServiceClient
googleAdsServiceClient
=
googleAdsClient
.
getLatestVersion
().
createGoogleAdsServiceClient
())
{
// Sends the mutate request.
MutateGoogleAdsResponse
response
=
googleAdsServiceClient
.
mutate
(
String
.
valueOf
(
customerId
),
operations
);
// Prints the results.
System
.
out
.
printf
(
"Created campaign with resource name: %s%n"
,
response
.
getMutateOperationResponses
(
1
)
.
getCampaignResult
()
.
getResourceName
());
System
.
out
.
printf
(
"Created ad group with resource name: %s%n"
,
response
.
getMutateOperationResponses
(
2
)
.
getAdGroupResult
()
.
getResourceName
());
for
(
Map
.
Entry<String
,
String
>
entry
:
assetResourceNames
.
entrySet
())
{
System
.
out
.
printf
(
"Created asset with temporary resource name '%s' and final resource name '%s'.%n"
,
entry
.
getValue
(),
response
.
getMutateOperationResponses
(
operations
.
indexOf
(
getOperationForAsset
(
operations
,
entry
.
getValue
())))
.
getAssetResult
()
.
getResourceName
());
}
System
.
out
.
printf
(
"Created ad group ad with resource name: %s%n"
,
response
.
getMutateOperationResponses
(
operations
.
size
()
-
1
)
.
getAdGroupAdResult
()
.
getResourceName
());
}
C#
// The below methods create and return MutateOperations that we later provide to
// the GoogleAdsService.Mutate method in order to create the entities in a single
// request. Since the entities for a Demand Gen campaign are closely tied to one-another
// it's considered a best practice to create them in a single Mutate request; the
// entities will either all complete successfully or fail entirely, leaving no
// orphaned entities. See:
// https://developers.google.com/google-ads/api/docs/mutating/overview
MutateOperation
campaignBudgetOperation
=
CreateCampaignBudgetOperation
(
budgetResourceName
);
MutateOperation
campaignOperation
=
CreateDemandGenCampaignOperation
(
campaignResourceName
,
budgetResourceName
);
MutateOperation
adGroupOperation
=
CreateAdGroupOperation
(
adGroupResourceName
,
campaignResourceName
);
// Send the operations in a single mutate request.
MutateGoogleAdsRequest
mutateGoogleAdsRequest
=
new
MutateGoogleAdsRequest
{
CustomerId
=
customerId
.
ToString
()
};
// It's important to create these entities in this order because they depend on
// each other, for example the ad group depends on the
// campaign, and the ad group ad depends on the ad group.
mutateGoogleAdsRequest
.
MutateOperations
.
Add
(
campaignBudgetOperation
);
mutateGoogleAdsRequest
.
MutateOperations
.
Add
(
campaignOperation
);
mutateGoogleAdsRequest
.
MutateOperations
.
Add
(
adGroupOperation
);
mutateGoogleAdsRequest
.
MutateOperations
.
AddRange
(
CreateAssetOperations
(
videoAssetResourceName
,
videoId
,
logoResourceName
,
client
.
Config
)
);
mutateGoogleAdsRequest
.
MutateOperations
.
Add
(
CreateDemandGenAdOperation
(
adGroupResourceName
,
videoAssetResourceName
,
logoResourceName
)
);
MutateGoogleAdsResponse
response
=
googleAdsServiceClient
.
Mutate
(
mutateGoogleAdsRequest
);
PHP
This example is not yet available in PHP; you can take a look at the other languages.
Python
# The below methods create and return MutateOperations that we later provide
# to the GoogleAdsService.Mutate method in order to create the entities in a
# single request. Since the entities for a Demand Gen campaign are closely
# tied to one-another it's considered a best practice to create them in a
# single Mutate request; the entities will either all complete successfully
# or fail entirely, leaving no orphaned entities. See:
# https://developers.google.com/google-ads/api/docs/mutating/overview
mutate_operations
:
List
[
MutateOperation
]
=
[
# It's important to create these entities in this order because they
# depend on each other, for example the ad group depends on the
# campaign, and the ad group ad depends on the ad group.
create_campaign_budget_operation
(
client
,
budget_resource_name
),
create_demand_gen_campaign_operation
(
client
,
campaign_resource_name
,
budget_resource_name
),
create_ad_group_operation
(
client
,
ad_group_resource_name
,
campaign_resource_name
),
*
create_asset_operations
(
# Use iterable unpacking
client
,
video_asset_resource_name
,
video_id
,
logo_asset_resource_name
,
),
create_demand_gen_ad_operation
(
client
,
ad_group_resource_name
,
video_asset_resource_name
,
logo_asset_resource_name
,
),
]
# Send the operations in a single mutate request.
googleads_service
.
mutate
(
customer_id
=
customer_id
,
mutate_operations
=
mutate_operations
)
Ruby
operations
=
[]
operations
<<
client
.
operation
.
mutate
do
|
m
|
m
.
campaign_budget_operation
=
create_campaign_budget_operation
(
client
,
budget_resource_name
)
end
operations
<<
client
.
operation
.
mutate
do
|
m
|
m
.
campaign_operation
=
create_demand_gen_campaign_operation
(
client
,
campaign_resource_name
,
budget_resource_name
)
end
operations
<<
client
.
operation
.
mutate
do
|
m
|
m
.
ad_group_operation
=
create_ad_group_operation
(
client
,
ad_group_resource_name
,
campaign_resource_name
)
end
operations
+=
create_asset_operations
(
client
,
video_asset_resource_name
,
video_id
,
logo_asset_resource_name
)
.
map
do
|
asset_op
|
client
.
operation
.
mutate
do
|
m
|
m
.
asset_operation
=
asset_op
end
end
operations
<<
client
.
operation
.
mutate
do
|
m
|
m
.
ad_group_ad_operation
=
create_demand_gen_ad_operation
(
client
,
ad_group_resource_name
,
video_asset_resource_name
,
logo_asset_resource_name
)
end
response
=
client
.
service
.
google_ads
.
mutate
(
customer_id
:
customer_id
,
mutate_operations
:
operations
,
)
Perl
This example is not yet available in Perl; you can take a look at the other languages.
Create budget
Create a budget
. Note that a
Demand Gen campaign can't use a shared budget. We recommend that you have a
sufficient daily budget to account for at least 15 times your expected target
CPA bid. Learn more
.
Java
private
static
String
addCampaignBudget
(
GoogleAdsClient
googleAdsClient
,
long
customerId
)
{
CampaignBudget
budget
=
CampaignBudget
.
newBuilder
()
.
setName
(
"Interplanetary Cruise Budget #"
+
getPrintableDateTime
())
.
setDeliveryMethod
(
BudgetDeliveryMethod
.
STANDARD
)
.
setAmountMicros
(
500_000
)
.
build
();
CampaignBudgetOperation
op
=
CampaignBudgetOperation
.
newBuilder
().
setCreate
(
budget
).
build
();
try
(
CampaignBudgetServiceClient
campaignBudgetServiceClient
=
googleAdsClient
.
getLatestVersion
().
createCampaignBudgetServiceClient
())
{
MutateCampaignBudgetsResponse
response
=
campaignBudgetServiceClient
.
mutateCampaignBudgets
(
Long
.
toString
(
customerId
),
ImmutableList
.
of
(
op
));
String
budgetResourceName
=
response
.
getResults
(
0
).
getResourceName
();
System
.
out
.
printf
(
"Added budget: %s%n"
,
budgetResourceName
);
return
budgetResourceName
;
}
}
C#
private
static
string
CreateBudget
(
GoogleAdsClient
client
,
long
customerId
)
{
// Get the BudgetService.
CampaignBudgetServiceClient
budgetService
=
client
.
GetService
(
Services
.
V22
.
CampaignBudgetService
);
// Create the campaign budget.
CampaignBudget
budget
=
new
CampaignBudget
()
{
Name
=
"Interplanetary Cruise Budget #"
+
ExampleUtilities
.
GetRandomString
(),
DeliveryMethod
=
BudgetDeliveryMethod
.
Standard
,
AmountMicros
=
500000
};
// Create the operation.
CampaignBudgetOperation
budgetOperation
=
new
CampaignBudgetOperation
()
{
Create
=
budget
};
// Create the campaign budget.
MutateCampaignBudgetsResponse
response
=
budgetService
.
MutateCampaignBudgets
(
customerId
.
ToString
(),
new
CampaignBudgetOperation
[]
{
budgetOperation
});
return
response
.
Results
[
0
].
ResourceName
;
}
PHP
private static function addCampaignBudget(GoogleAdsClient $googleAdsClient, int $customerId)
{
// Creates a campaign budget.
$budget = new CampaignBudget([
'name' => 'Interplanetary Cruise Budget #' . Helper::getPrintableDatetime(),
'delivery_method' => BudgetDeliveryMethod::STANDARD,
'amount_micros' => 500000
]);
// Creates a campaign budget operation.
$campaignBudgetOperation = new CampaignBudgetOperation();
$campaignBudgetOperation->setCreate($budget);
// Issues a mutate request.
$campaignBudgetServiceClient = $googleAdsClient->getCampaignBudgetServiceClient();
$response = $campaignBudgetServiceClient->mutateCampaignBudgets(
MutateCampaignBudgetsRequest::build($customerId, [$campaignBudgetOperation])
);
/** @var CampaignBudget $addedBudget */
$addedBudget = $response->getResults()[0];
printf("Added budget named '%s'%s", $addedBudget->getResourceName(), PHP_EOL);
return $addedBudget->getResourceName();
}
Python
# Create a budget, which can be shared by multiple campaigns.
campaign_budget_operation
:
CampaignBudgetOperation
=
client
.
get_type
(
"CampaignBudgetOperation"
)
campaign_budget
:
CampaignBudget
=
campaign_budget_operation
.
create
campaign_budget
.
name
=
f
"Interplanetary Budget
{
uuid
.
uuid4
()
}
"
campaign_budget
.
delivery_method
=
(
client
.
enums
.
BudgetDeliveryMethodEnum
.
STANDARD
)
campaign_budget
.
amount_micros
=
500000
# Add budget.
campaign_budget_response
:
MutateCampaignBudgetsResponse
try
:
budget_operations
:
List
[
CampaignBudgetOperation
]
=
[
campaign_budget_operation
]
campaign_budget_response
=
(
campaign_budget_service
.
mutate_campaign_budgets
(
customer_id
=
customer_id
,
operations
=
budget_operations
,
)
)
except
GoogleAdsException
as
ex
:
handle_googleads_exception
(
ex
)
Ruby
# Create a budget, which can be shared by multiple campaigns.
campaign_budget
=
client
.
resource
.
campaign_budget
do
|
cb
|
cb
.
name
=
"Interplanetary Budget
#{
(
Time
.
new
.
to_f
*
1000
)
.
to_i
}
"
cb
.
delivery_method
=
:STANDARD
cb
.
amount_micros
=
500000
end
operation
=
client
.
operation
.
create_resource
.
campaign_budget
(
campaign_budget
)
# Add budget.
return_budget
=
client
.
service
.
campaign_budget
.
mutate_campaign_budgets
(
customer_id
:
customer_id
,
operations
:
[
operation
]
,
)
Perl
# Create a campaign budget, which can be shared by multiple campaigns.
my
$campaign_budget
=
Google::Ads::GoogleAds::V22::Resources::
CampaignBudget
-
> new
({
name
=
>
"Interplanetary budget #"
.
uniqid
(),
deliveryMethod
=
>
STANDARD
,
amountMicros
=
>
500000
});
# Create a campaign budget operation.
my
$campaign_budget_operation
=
Google::Ads::GoogleAds::V22::Services::CampaignBudgetService::
CampaignBudgetOperation
-
> new
({
create
=
>
$campaign_budget
});
# Add the campaign budget.
my
$campaign_budgets_response
=
$api_client
-
> CampaignBudgetService
()
-
> mutate
({
customerId
=
>
$customer_id
,
operations
=
>
[
$campaign_budget_operation
]});
Set the campaign total budget
Demand Gen campaigns support setting a campaign total budget
.
To use a CampaignBudget
as a campaign total budget, set the total_amount_micros
field
instead of the amount_micros
field and set the period
field to CUSTOM
.
Create campaign and bidding strategy
After the budget is created, you can create a campaign.
Demand Gen campaigns have an AdvertisingChannelType
of DEMAND_GEN
. No AdvertisingChannelSubType
should be set.
Set up conversion goals
for your campaign.
Supported bidding strategies
are maximize clicks, target CPA, maximize conversions, and target ROAS.
Java
// Creates the campaign.
Campaign
campaign
=
Campaign
.
newBuilder
()
.
setResourceName
(
campaignResourceName
)
.
setName
(
"Demand Gen campaign "
+
System
.
currentTimeMillis
())
// Demand Gen campaigns are supported in the DEMAND_GEN channel.
.
setAdvertisingChannelType
(
AdvertisingChannelType
.
DEMAND_GEN
)
// Sets the campaign status to PAUSED. The campaign is enabled later.
.
setStatus
(
CampaignStatus
.
PAUSED
)
.
setCampaignBudget
(
budgetResourceName
)
// Declares whether this campaign serves political ads targeting the EU.
.
setContainsEuPoliticalAdvertising
(
DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING
)
// Sets the bidding strategy.
.
setTargetCpa
(
TargetCpa
.
newBuilder
().
setTargetCpaMicros
(
10_000_000L
).
build
())
.
build
();
// Creates the operation.
return
CampaignOperation
.
newBuilder
().
setCreate
(
campaign
).
build
();
C#
private
MutateOperation
CreateDemandGenCampaignOperation
(
string
campaignResourceName
,
string
budgetResourceName
)
{
return
new
MutateOperation
{
CampaignOperation
=
new
CampaignOperation
{
Create
=
new
Campaign
{
Name
=
$"Demand Gen #{ExampleUtilities.GetRandomString()}"
,
// Set the campaign status as PAUSED.
Status
=
CampaignStatus
.
Paused
,
// AdvertisingChannelType must be DEMAND_GEN.
AdvertisingChannelType
=
AdvertisingChannelType
.
DemandGen
,
// Assign the resource name with a temporary ID.
ResourceName
=
campaignResourceName
,
// Set the budget using the given budget resource name.
CampaignBudget
=
budgetResourceName
,
// Use the Target CPA bidding strategy.
TargetCpa
=
new
TargetCpa
()
{
TargetCpaMicros
=
1
_000_000
,
},
ContainsEuPoliticalAdvertising
=
EuPoliticalAdvertisingStatus
.
DoesNotContainEuPoliticalAdvertising
}
}
};
}
PHP
This example is not yet available in PHP; you can take a look at the other languages.
Python
def
create_demand_gen_campaign_operation
(
client
:
GoogleAdsClient
,
campaign_resource_name
:
str
,
budget_resource_name
:
str
,
)
-
> MutateOperation
:
"""Creates a MutateOperation that creates a new Campaign.
A temporary ID will be assigned to this campaign so that it can be
referenced by other objects being created in the same Mutate request.
Args:
client: An initialized GoogleAdsClient instance.
campaign_resource_name: The temporary resource name of the campaign.
budget_resource_name: The resource name of the budget to assign.
Returns:
A MutateOperation for creating a Campaign.
"""
mutate_operation
:
MutateOperation
=
client
.
get_type
(
"MutateOperation"
)
campaign_operation
:
CampaignOperation
=
mutate_operation
.
campaign_operation
campaign
:
Campaign
=
campaign_operation
.
create
campaign
.
name
=
f
"Demand Gen #
{
uuid4
()
}
"
# Set the campaign status as PAUSED. The campaign is the only entity in the
# mutate request that should have its status set.
campaign
.
status
=
client
.
enums
.
CampaignStatusEnum
.
PAUSED
# AdvertisingChannelType must be DEMAND_GEN.
campaign
.
advertising_channel_type
=
(
client
.
enums
.
AdvertisingChannelTypeEnum
.
DEMAND_GEN
)
# Assign the resource name with a temporary ID.
campaign
.
resource_name
=
campaign_resource_name
# Set the budget using the given budget resource name.
campaign
.
campaign_budget
=
budget_resource_name
# Use the Target CPA bidding strategy.
campaign
.
bidding_strategy_type
=
(
client
.
enums
.
BiddingStrategyTypeEnum
.
TARGET_CPA
)
campaign
.
target_cpa
.
target_cpa_micros
=
1_000_000
return
mutate_operation
.
py
Ruby
def
create_demand_gen_campaign_operation
(
client
,
campaign_resource_name
,
budget_resource_name
)
client
.
operation
.
create_resource
.
campaign
do
|
c
|
c
.
name
=
"Demand Gen #
#{
Time
.
now
.
to_f
}
"
# Recommendation: Set the campaign to PAUSED when creating it to
# prevent the ads from immediately serving. Set to ENABLED once you've
# added targeting and the ads are ready to serve.
c
.
status
=
:PAUSED
# AdvertisingChannelType must be DEMAND_GEN.
c
.
advertising_channel_type
=
:DEMAND_GEN
# Assign the resource name with a temporary ID.
c
.
resource_name
=
campaign_resource_name
# Set the budget using the given budget resource name.
c
.
campaign_budget
=
budget_resource_name
# Use the Target CPA bidding strategy.
c
.
bidding_strategy_type
=
:TARGET_CPA
c
.
target_cpa
=
client
.
resource
.
target_cpa
do
|
tc
|
tc
.
target_cpa_micros
=
1_000_000
end
# Declare whether or not this campaign serves political ads targeting the EU.
# Valid values are CONTAINS_EU_POLITICAL_ADVERTISING and
# DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING.
c
.
contains_eu_political_advertising
=
:DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING
# Optional fields
c
.
start_date
=
DateTime
.
parse
((
Date
.
today
+
1
)
.
to_s
)
.
strftime
(
'%Y%m%d'
)
c
.
end_date
=
DateTime
.
parse
(
Date
.
today
.
next_year
.
to_s
)
.
strftime
(
'%Y%m%d'
)
end
end
.
rb
Perl
This example is not yet available in Perl; you can take a look at the other languages.
Create ad group
Create an ad group without a type and attach it to the Demand Gen campaign.
With Demand Gen, you can choose to set the location and language group criteria
at the ad group level.
When creating an ad group, you can also configure channel controls
to decide where your ads will be shown.
Java
// Creates the ad group.
AdGroup
adGroup
=
AdGroup
.
newBuilder
()
.
setResourceName
(
adGroupResourceName
)
.
setName
(
"Demand Gen ad group "
+
System
.
currentTimeMillis
())
.
setCampaign
(
campaignResourceName
)
.
setStatus
(
AdGroupStatus
.
ENABLED
)
// Selects the specific channels for the ad group.
// For further information on Demand Gen channel controls, see
// https://developers.google.com/google-ads/api/docs/demand-gen/channel-controls
.
setDemandGenAdGroupSettings
(
DemandGenAdGroupSettings
.
newBuilder
()
.
setChannelControls
(
DemandGenChannelControls
.
newBuilder
()
.
setSelectedChannels
(
DemandGenSelectedChannels
.
newBuilder
()
.
setGmail
(
false
)
.
setDiscover
(
false
)
.
setDisplay
(
false
)
.
setYoutubeInFeed
(
true
)
.
setYoutubeInStream
(
true
)
.
setYoutubeShorts
(
true
)
.
build
())
.
build
())
.
build
())
.
build
();
// Creates the operation.
return
AdGroupOperation
.
newBuilder
().
setCreate
(
adGroup
).
build
();
C#
private
MutateOperation
CreateAdGroupOperation
(
string
adGroupResourceName
,
string
campaignResourceName
)
{
return
new
MutateOperation
{
AdGroupOperation
=
new
AdGroupOperation
{
// Creates an ad group.
Create
=
new
AdGroup
{
ResourceName
=
adGroupResourceName
,
Name
=
$"Earth to Mars Cruises #{ExampleUtilities.GetRandomString()}"
,
Status
=
AdGroupStatus
.
Enabled
,
Campaign
=
campaignResourceName
,
// Select the specific channels for the ad group.
// For further information on Demand Gen channel controls, see
// https://developers.google.com/google-ads/api/docs/demand-gen/channel-controls
DemandGenAdGroupSettings
=
new
DemandGenAdGroupSettings
{
ChannelControls
=
new
DemandGenChannelControls
{
SelectedChannels
=
new
DemandGenSelectedChannels
{
Gmail
=
false
,
Discover
=
false
,
Display
=
false
,
YoutubeInFeed
=
true
,
YoutubeInStream
=
true
,
YoutubeShorts
=
true
,
}
}
}
}
}
};
}
PHP
This example is not yet available in PHP; you can take a look at the other languages.
Python
def
create_ad_group_operation
(
client
:
GoogleAdsClient
,
ad_group_resource_name
:
str
,
campaign_resource_name
:
str
,
)
-
> MutateOperation
:
"""Creates a MutateOperation that creates a new AdGroup.
Args:
client: An initialized GoogleAdsClient instance.
ad_group_resource_name: The temporary resource name of the ad group.
campaign_resource_name: The temporary resource name of the campaign the
ad group will belong to.
Returns:
A MutateOperation for creating an AdGroup.
"""
mutate_operation
:
MutateOperation
=
client
.
get_type
(
"MutateOperation"
)
ad_group_operation
:
AdGroupOperation
=
mutate_operation
.
ad_group_operation
# Creates an ad group.
ad_group
:
AdGroup
=
ad_group_operation
.
create
ad_group
.
resource_name
=
ad_group_resource_name
ad_group
.
name
=
f
"Earth to Mars Cruises #
{
uuid4
()
}
"
ad_group
.
status
=
client
.
enums
.
AdGroupStatusEnum
.
ENABLED
ad_group
.
campaign
=
campaign_resource_name
# Select the specific channels for the ad group. For further information on
# Demand Gen channel controls, see:
# https://developers.google.com/google-ads/api/docs/demand-gen/channel-controls
selected_channel_controls
=
(
ad_group
.
demand_gen_ad_group_settings
.
channel_controls
.
selected_channels
)
selected_channel_controls
.
gmail
=
False
selected_channel_controls
.
discover
=
False
selected_channel_controls
.
display
=
False
selected_channel_controls
.
youtube_in_feed
=
True
selected_channel_controls
.
youtube_in_stream
=
True
selected_channel_controls
.
youtube_shorts
=
True
return
mutate_operation
.
py
Ruby
def
create_ad_group_operation
(
client
,
ad_group_resource_name
,
campaign_resource_name
)
# Creates an ad group.
client
.
operation
.
create_resource
.
ad_group
do
|
ag
|
ag
.
resource_name
=
ad_group_resource_name
ag
.
name
=
"Earth to Mars Cruises #
#{
Time
.
now
.
to_f
}
"
ag
.
status
=
:ENABLED
ag
.
campaign
=
campaign_resource_name
# Select the specific channels for the ad group.
# For further information on Demand Gen channel controls, see
# https://developers.google.com/google-ads/api/docs/demand-gen/channel-controls
ag
.
demand_gen_ad_group_settings
=
client
.
resource
.
demand_gen_ad_group_settings
do
|
dgas
|
dgas
.
channel_controls
=
client
.
resource
.
demand_gen_channel_controls
do
|
dcc
|
dcc
.
selected_channels
=
client
.
resource
.
demand_gen_selected_channels
do
|
dsc
|
dsc
.
gmail
=
false
dsc
.
discover
=
false
dsc
.
display
=
false
dsc
.
youtube_in_feed
=
true
dsc
.
youtube_in_stream
=
true
dsc
.
youtube_shorts
=
true
end
end
end
end
end
.
rb
Perl
This example is not yet available in Perl; you can take a look at the other languages.
Create assets and ads
There are three types of ads available for Demand Gen campaigns:
First, create assets
for these ad types. Check out
the Demand Gen campaign asset specs and best practices guide
for the list of assets that are available for each Demand Gen ad type.
The guide has guidance on what assets are required and how many assets are
recommended.
We also recommend evaluating asset performances to fine-tune
creatives: the reporting
section covers how to retrieve performance
metrics for Demand Gen campaigns.
DemandGenCarouselAdInfo
has an additional specialized asset called AdDemandGenCarouselCardAsset
.
After the assets and ads have been created, add the ads to the ad group.
Java
DemandGenVideoResponsiveAdInfo
.
Builder
videoResponsiveAdbuilder
=
DemandGenVideoResponsiveAdInfo
.
newBuilder
()
.
setBusinessName
(
AdTextAsset
.
newBuilder
()
.
setText
(
"Interplanetary Cruises"
)
.
build
()
)
.
addVideos
(
AdVideoAsset
.
newBuilder
()
.
setAsset
(
assetResourceNames
.
get
(
"Video"
))
.
build
()
)
.
addAllLongHeadlines
(
Arrays
.
asList
(
"Long headline 1"
).
stream
()
.
map
(
s
-
>
AdTextAsset
.
newBuilder
().
setText
(
s
).
build
())
.
collect
(
Collectors
.
toList
())
)
.
addAllHeadlines
(
Arrays
.
asList
(
"Headline 1"
,
"Headline 2"
,
"Headline 3"
).
stream
()
.
map
(
s
-
>
AdTextAsset
.
newBuilder
().
setText
(
s
).
build
())
.
collect
(
Collectors
.
toList
()))
.
addAllDescriptions
(
Arrays
.
asList
(
"Description 1"
,
"Description 2"
).
stream
()
.
map
(
s
-
>
AdTextAsset
.
newBuilder
().
setText
(
s
).
build
())
.
collect
(
Collectors
.
toList
()))
.
addLogoImages
(
AdImageAsset
.
newBuilder
().
setAsset
(
assetResourceNames
.
get
(
"LogoImage"
)));
AdGroupAd
adGroupAd
=
AdGroupAd
.
newBuilder
()
.
setAdGroup
(
adGroupResourceName
)
.
setAd
(
Ad
.
newBuilder
()
.
setName
(
"Demand gen video responsive ad"
)
.
addFinalUrls
(
"https://www.example.com"
)
.
setDemandGenVideoResponsiveAd
(
videoResponsiveAdbuilder
.
build
())
.
build
())
.
build
();
return
AdGroupAdOperation
.
newBuilder
().
setCreate
(
adGroupAd
).
build
();
C#
private
MutateOperation
CreateDemandGenAdOperation
(
string
adGroupResourceName
,
string
videoAssetResourceName
,
string
logoResourceName
)
{
Ad
ad
=
new
Ad
{
Name
=
"Demand gen video responsive ad"
,
FinalUrls
=
{
"http://example.com"
},
DemandGenVideoResponsiveAd
=
new
DemandGenVideoResponsiveAdInfo
{
BusinessName
=
new
AdTextAsset
{
Text
=
"Interplanetary Cruises"
},
}
};
ad
.
DemandGenVideoResponsiveAd
.
Videos
.
Add
(
new
AdVideoAsset
{
Asset
=
videoAssetResourceName
});
ad
.
DemandGenVideoResponsiveAd
.
LogoImages
.
Add
(
new
AdImageAsset
{
Asset
=
logoResourceName
});
ad
.
DemandGenVideoResponsiveAd
.
Headlines
.
Add
(
new
AdTextAsset
{
Text
=
"Interplanetary cruises"
});
ad
.
DemandGenVideoResponsiveAd
.
LongHeadlines
.
Add
(
new
AdTextAsset
{
Text
=
"Travel the World"
});
ad
.
DemandGenVideoResponsiveAd
.
Descriptions
.
Add
(
new
AdTextAsset
{
Text
=
"Book now for an extra discount"
});
return
new
MutateOperation
{
AdGroupAdOperation
=
new
AdGroupAdOperation
{
Create
=
new
AdGroupAd
{
AdGroup
=
adGroupResourceName
,
Ad
=
ad
}
}
};
}
PHP
This example is not yet available in PHP; you can take a look at the other languages.
Python
def
create_demand_gen_ad_operation
(
client
:
GoogleAdsClient
,
ad_group_resource_name
:
str
,
video_asset_resource_name
:
str
,
logo_asset_resource_name
:
str
,
)
-
> MutateOperation
:
"""Creates a MutateOperation that creates a new Demand Gen Ad.
Args:
client: An initialized GoogleAdsClient instance.
ad_group_resource_name: The ad group the ad will belong to.
video_asset_resource_name: The video asset resource name.
logo_asset_resource_name: The logo asset resource name.
Returns:
A MutateOperation for creating an AdGroupAd.
"""
mutate_operation
:
MutateOperation
=
client
.
get_type
(
"MutateOperation"
)
ad_group_ad_operation
:
AdGroupAdOperation
=
(
mutate_operation
.
ad_group_ad_operation
)
ad_group_ad
:
AdGroupAd
=
ad_group_ad_operation
.
create
ad_group_ad
.
ad_group
=
ad_group_resource_name
ad_group_ad
.
status
=
client
.
enums
.
AdGroupAdStatusEnum
.
ENABLED
ad
:
Ad
=
ad_group_ad
.
ad
ad
.
name
=
"Demand gen multi asset ad"
ad
.
final_urls
.
append
(
DEFAULT_FINAL_URL
)
demand_gen_ad
:
DemandGenVideoResponsiveAdInfo
=
(
ad
.
demand_gen_video_responsive_ad
)
# Ensure business_name is an AssetLink and assign text to its text_asset.text
demand_gen_ad
.
business_name
.
text
=
"Interplanetary Cruises"
# If it needs to be an AssetLink to a text asset,
# that would require creating another asset.
# Create AssetLink for video
video_asset_link
:
AdVideoAsset
=
client
.
get_type
(
"AdVideoAsset"
)
video_asset_link
.
asset
=
video_asset_resource_name
demand_gen_ad
.
videos
.
append
(
video_asset_link
)
# Create AssetLink for logo
logo_image_asset_link
:
AdImageAsset
=
client
.
get_type
(
"AdImageAsset"
)
logo_image_asset_link
.
asset
=
logo_asset_resource_name
demand_gen_ad
.
logo_images
.
append
(
logo_image_asset_link
)
# Create AssetLink for headline
headline_asset_link
:
AdTextAsset
=
client
.
get_type
(
"AdTextAsset"
)
headline_asset_link
.
text
=
"Interplanetary cruises"
demand_gen_ad
.
headlines
.
append
(
headline_asset_link
)
# Create AssetLink for long headline
long_headline_asset_link
:
AdTextAsset
=
client
.
get_type
(
"AdTextAsset"
)
long_headline_asset_link
.
text
=
"Travel the World"
demand_gen_ad
.
long_headlines
.
append
(
long_headline_asset_link
)
# Create AssetLink for description
description_asset_link
:
AdTextAsset
=
client
.
get_type
(
"AdTextAsset"
)
description_asset_link
.
text
=
"Book now for an extra discount"
demand_gen_ad
.
descriptions
.
append
(
description_asset_link
)
return
mutate_operation
.
py
Ruby
def
create_demand_gen_ad_operation
(
client
,
ad_group_resource_name
,
video_asset_resource_name
,
logo_asset_resource_name
)
client
.
operation
.
create_resource
.
ad_group_ad
do
|
aga
|
aga
.
ad_group
=
ad_group_resource_name
aga
.
status
=
:ENABLED
aga
.
ad
=
client
.
resource
.
ad
do
|
ad
|
ad
.
name
=
"Demand gen video responsive ad"
ad
.
final_urls
<<
DEFAULT_FINAL_URL
ad
.
demand_gen_video_responsive_ad
=
client
.
resource
.
demand_gen_video_responsive_ad_info
do
|
dgv
|
dgv
.
business_name
=
client
.
resource
.
ad_text_asset
do
|
ata
|
ata
.
text
=
"Interplanetary Cruises"
end
dgv
.
videos
<<
client
.
resource
.
ad_video_asset
do
|
ava
|
ava
.
asset
=
video_asset_resource_name
end
dgv
.
logo_images
<<
client
.
resource
.
ad_image_asset
do
|
aia
|
aia
.
asset
=
logo_asset_resource_name
end
dgv
.
headlines
<<
client
.
resource
.
ad_text_asset
do
|
ata
|
ata
.
text
=
"Interplanetary cruises"
end
dgv
.
long_headlines
<<
client
.
resource
.
ad_text_asset
do
|
ata
|
ata
.
text
=
"Travel the World"
end
dgv
.
descriptions
<<
client
.
resource
.
ad_text_asset
do
|
ata
|
ata
.
text
=
"Book now for an extra discount"
end
end
end
end
end
.
rb
Perl
This example is not yet available in Perl; you can take a look at the other languages.
Send feedback
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License
, and code samples are licensed under the Apache 2.0 License
. For details, see the Google Developers Site Policies
. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-03 UTC.
Need to tell us more?
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-12-03 UTC."],[],[]]