Create a Demand Gen Campaign

  • 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:

  1. Create a budget.
  2. Create a Demand Gen campaign with appropriate bidding strategies.
  3. Create an ad group without a type.
  4. Create audiences.
  5. 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();
}