Dynamic Search Ads

Dynamic Search Ads (DSAs) allow you to target entire web sites—or portions of them—without having to create keywords and ad copy for all the possible matches. Instead, whenever a relevant user search occurs, the system dynamically generates an ad with a headline based on the query, and with text based on your most relevant landing page. The ad enters the auction and competes normally. So you get better results from broader exposure for more of your in-stock inventory, without making any changes to your existing keyword campaigns.

In addition to allowing you to broadly target an entire website or domain, DSAs can also serve as a nice "catch-all" or back-up option for your existing campaigns and keywords. You can set up keywords, ad groups, and ad copy as you do today, and then add a Dynamic Search Ad to catch as many queries as possible that don't match your existing campaign setup.

This guide describes how to create and use Dynamic Search Ads with the AdWords API.

Creating DSAs

To set up Dynamic Search Ads with the API, follow these steps:

  1. Set up your campaign and specify its domain.
  2. Create an ad group for features related to Dynamic Search Ads.
  3. Create one or more Dynamic Search Ads.
  4. Specify one or more criteria for showing the DSAs in the campaign.

Set up your campaign

To tell AdWords that you're going to be using DSAs with your campaign, you first need to create a campaign with advertisingChannelType as SEARCH. Also, specify a domain on which the Dynamic Search Ads will operate. This is done by setting a DynamicSearchAdsSetting object on the settings property of the Campaign object.

The following example creates a DSA campaign.

C#

private static Campaign CreateCampaign(AdWordsUser user, Budget budget) {
  using (CampaignService campaignService =
      (CampaignService) user.GetService(AdWordsService.v201710.CampaignService)) {
    // Create a Dynamic Search Ads campaign.
    Campaign campaign = new Campaign();
    campaign.name = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString();
    campaign.advertisingChannelType = AdvertisingChannelType.SEARCH;

    // 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.
    campaign.status = CampaignStatus.PAUSED;

    BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
    biddingConfig.biddingStrategyType = BiddingStrategyType.MANUAL_CPC;
    campaign.biddingStrategyConfiguration = biddingConfig;

    campaign.budget = new Budget();
    campaign.budget.budgetId = budget.budgetId;

    // Required: Set the campaign's Dynamic Search Ads settings.
    DynamicSearchAdsSetting dynamicSearchAdsSetting = new DynamicSearchAdsSetting();
    // Required: Set the domain name and language.
    dynamicSearchAdsSetting.domainName = "example.com";
    dynamicSearchAdsSetting.languageCode = "en";

    // Set the campaign settings.
    campaign.settings = new Setting[] { dynamicSearchAdsSetting };

    // Optional: Set the start date.
    campaign.startDate = DateTime.Now.AddDays(1).ToString("yyyyMMdd");

    // Optional: Set the end date.
    campaign.endDate = DateTime.Now.AddYears(1).ToString("yyyyMMdd");

    // Create the operation.
    CampaignOperation operation = new CampaignOperation();
    operation.@operator = Operator.ADD;
    operation.operand = campaign;

    try {
      // Add the campaign.
      CampaignReturnValue retVal = campaignService.mutate(
          new CampaignOperation[] { operation });

      // Display the results.
      Campaign newCampaign = retVal.value[0];
      Console.WriteLine("Campaign with id = '{0}' and name = '{1}' was added.",
        newCampaign.id, newCampaign.name);
      return newCampaign;
    } catch (Exception e) {
      throw new System.ApplicationException("Failed to add campaigns.", e);
    }
  }
}

Java

private static Campaign createCampaign(
    AdWordsServicesInterface adWordsServices, AdWordsSession session, Budget budget)
    throws RemoteException, ApiException {
  // Get the CampaignService.
  CampaignServiceInterface campaignService =
      adWordsServices.get(session, CampaignServiceInterface.class);

  // Create campaign.
  Campaign campaign = new Campaign();
  campaign.setName("Interplanetary Cruise #" + System.currentTimeMillis());
  campaign.setAdvertisingChannelType(AdvertisingChannelType.SEARCH);

  // 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.
  campaign.setStatus(CampaignStatus.PAUSED);

  BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();
  biddingStrategyConfiguration.setBiddingStrategyType(BiddingStrategyType.MANUAL_CPC);
  campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

  // Only the budgetId should be sent, all other fields will be ignored by CampaignService.
  Budget campaignBudget = new Budget();
  campaignBudget.setBudgetId(budget.getBudgetId());
  campaign.setBudget(campaignBudget);

  // Required: Set the campaign's Dynamic Search Ads settings.
  DynamicSearchAdsSetting dynamicSearchAdsSetting = new DynamicSearchAdsSetting();
  // Required: Set the domain name and language.
  dynamicSearchAdsSetting.setDomainName("example.com");
  dynamicSearchAdsSetting.setLanguageCode("en");

  // Set the campaign settings.
  campaign.setSettings(new Setting[] {dynamicSearchAdsSetting});

  // Optional: Set the start date.
  campaign.setStartDate(new DateTime().plusDays(1).toString("yyyyMMdd"));
  // Optional: Set the end date.
  campaign.setEndDate(new DateTime().plusYears(1).toString("yyyyMMdd"));

  // Create the operation.
  CampaignOperation operation = new CampaignOperation();
  operation.setOperand(campaign);
  operation.setOperator(Operator.ADD);

  // Add the campaign.
  Campaign newCampaign = campaignService.mutate(new CampaignOperation[] {operation}).getValue(0);

  // Display the results.
  System.out.printf(
      "Campaign with name '%s' and ID %d was added.%n",
      newCampaign.getName(), newCampaign.getId());

  return newCampaign;
}

Python

campaign_service = client.GetService('CampaignService')

operations = [{
    'operator': 'ADD',
    'operand': {
        'name': 'Interplanetary Cruise #%d' % uuid.uuid4(),
        # 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.
        'status': 'PAUSED',
        'advertisingChannelType': 'SEARCH',
        'biddingStrategyConfiguration': {
            'biddingStrategyType': 'MANUAL_CPC',
        },
        'budget': budget,
        # Required: Set the campaign's Dynamic Search Ad settings.
        'settings': [{
            'xsi_type': 'DynamicSearchAdsSetting',
            # Required: Set the domain name and language.
            'domainName': 'example.com',
            'languageCode': 'en'
        }],
        # Optional: Set the start date.
        'startDate': (datetime.datetime.now() +
                      datetime.timedelta(1)).strftime('%Y%m%d'),
        # Optional: Set the end date.
        'endDate': (datetime.datetime.now() +
                    datetime.timedelta(365)).strftime('%Y%m%d'),
    }
}]

campaign = campaign_service.mutate(operations)['value'][0]
campaign_id = campaign['id']

print 'Campaign with ID "%d" and name "%s" was added.' % (
    campaign_id, campaign['name'])

PHP

private static function createCampaign(AdWordsServices $adWordsServices,
    AdWordsSession $session, Budget $budget) {
  $campaignService = $adWordsServices->get($session, CampaignService::class);

  // Create campaign with some properties set.
  $campaign = new Campaign();
  $campaign->setName('Interplanetary Cruise #' . uniqid());
  $campaign->setAdvertisingChannelType(AdvertisingChannelType::SEARCH);

  // 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.
  $campaign->setStatus(CampaignStatus::PAUSED);

  $biddingStrategyConfiguration = new BiddingStrategyConfiguration();
  $biddingStrategyConfiguration->setBiddingStrategyType(
      BiddingStrategyType::MANUAL_CPC);
  $campaign->setBiddingStrategyConfiguration($biddingStrategyConfiguration);

  // Only the budgetId should be sent, all other fields will be ignored by
  // CampaignService.
  $campaignBudget = new Budget();
  $campaignBudget->setBudgetId($budget->getBudgetId());
  $campaign->setBudget($campaignBudget);

  // Required: Set the campaign's Dynamic Search Ads settings.
  $dynamicSearchAdsSetting = new DynamicSearchAdsSetting();
  // Required: Set the domain name and language.
  $dynamicSearchAdsSetting->setDomainName('example.com');
  $dynamicSearchAdsSetting->setLanguageCode('en');

  // Set the campaign settings.
  $campaign->setSettings([$dynamicSearchAdsSetting]);

  // Optional: Set the start date.
  $campaign->setStartDate(date('Ymd', strtotime('+1 day')));
  // Optional: Set the end date.
  $campaign->setEndDate(date('Ymd', strtotime('+1 year')));

  // Create a campaign operation.
  $operation = new CampaignOperation();
  $operation->setOperand($campaign);
  $operation->setOperator(Operator::ADD);

  // Create the campaign on the server and print out some information.
  $result = $campaignService->mutate([$operation]);
  $campaign = $result->getValue()[0];
  printf("Campaign with name '%s' and ID %d was added.\n",
      $campaign->getName(), $campaign->getId());

  return $campaign;
}

Perl

# Creates the campaign.
sub _create_campaign {
  my ($client, $budget) = @_;

  # Required: Set the campaign's Dynamic Search Ads settings.
  my $dynamic_search_ads_setting =
    Google::Ads::AdWords::v201710::DynamicSearchAdsSetting->new({
      # Required: Set the domain name and language.
      domainName   => "example.com",
      languageCode => "en"
    });

  # Calculating a start date of today and an end date 1 year from now.
  my (undef, undef, undef, $mday, $mon, $year) = localtime(time + 60 * 60 * 24);
  my $start_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday);
  (undef, undef, undef, $mday, $mon, $year) =
    localtime(time + 60 * 60 * 24 * 365);
  my $end_date = sprintf("%d%02d%02d", ($year + 1900), ($mon + 1), $mday);

  my $campaign = Google::Ads::AdWords::v201710::Campaign->new({
      name => sprintf("Interplanetary Cruise #%s", uniqid()),
      biddingStrategyConfiguration =>
        Google::Ads::AdWords::v201710::BiddingStrategyConfiguration->new({
          biddingStrategyType => "MANUAL_CPC"
        }
        ),
      # Only the budgetId should be sent, all other fields will be ignored by
      # CampaignService.
      budget => Google::Ads::AdWords::v201710::Budget->new(
        {budgetId => $budget->get_budgetId()}
      ),
      advertisingChannelType => "SEARCH",
      settings               => [$dynamic_search_ads_setting],
      # Additional properties (non-required).
      startDate => $start_date,
      endDate   => $end_date,
      # Recommendation: Set the campaign to PAUSED when creating it to stop
      # the ads from immediately serving. Set to ENABLED once you've added
      # targeting and the ads are ready to serve.
      status => "PAUSED"
    });

  # Create operation.
  my $campaign_operation =
    Google::Ads::AdWords::v201710::CampaignOperation->new({
      operator => "ADD",
      operand  => $campaign
    });

  # Add campaigns.
  my $result =
    $client->CampaignService()->mutate({operations => [$campaign_operation]});

  # Display campaigns.
  my $new_campaign = $result->get_value()->[0];
  printf "Campaign with name '%s' and ID %d was added.\n",
    $new_campaign->get_name(),
    $new_campaign->get_id();
  return $new_campaign;
}

Ruby

def create_campaign(adwords, budget)
  campaign_srv = adwords.service(:CampaignService, API_VERSION)

  campaign = {
    :name => "Interplanetary Cruise #%d" % (Time.now.to_f * 1000).to_i,
    :advertising_channel_type => 'SEARCH',
    # 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.
    :status => 'PAUSED',
    :bidding_strategy_configuration => {
      :bidding_strategy_type => 'MANUAL_CPC'
    },
    # Only the budgetId should be sent; all other fields will be ignored by
    # CampaignService.
    :budget => {
      :budget_id => budget[:budget_id]
    },
    :settings => [
      :xsi_type => 'DynamicSearchAdsSetting',
      :domain_name => 'example.com',
      :language_code => 'en'
    ],
    # Optional: Set the start and end dates.
    :start_date => DateTime.parse((Date.today + 1).to_s).strftime('%Y%m%d'),
    :end_date => DateTime.parse(Date.today.next_year.to_s).strftime('%Y%m%d')
  }

  operation = {
    :operand => campaign,
    :operator => 'ADD'
  }

  new_campaign = campaign_srv.mutate([operation])[:value].first
  puts "Campaign with name '%s' and ID %d was added." %
      [new_campaign[:name], new_campaign[:id]]

  return new_campaign
end

Create your ad group

To use DSA features, you need to create an ad group with adGroupType as AdGroupType.SEARCH_DYNAMIC_ADS. This ad group type enforces the following restrictions:

  • This ad group type can be added only to search campaigns.
  • There should be a valid DynamicSearchAdsSetting at the campaign level for the ad group to be added. An AdGroupServiceError.CANNOT_ADD_ADGROUP_OF_TYPE_DSA_TO_CAMPAIGN_WITHOUT_DSA_SETTING error will be thrown if this setting is missing.
  • No positive keywords are allowed in this ad group type. Audience, dynamic ad targets and negative keywords are allowed.
  • As with all ad groups, the adGroupType cannot be changed after construction.
  • Only ad formats related to Dynamic Search Ads are allowed in this ad group.

The code example below shows how to create a SEARCH_DYNAMIC_ADS ad group.

C#

private static AdGroup CreateAdGroup(AdWordsUser user, long campaignId) {
  using (AdGroupService adGroupService =
      (AdGroupService) user.GetService(AdWordsService.v201710.AdGroupService)) {
    // Create the ad group.
    AdGroup adGroup = new AdGroup();

    // Required: Set the ad group's type to Dynamic Search Ads.
    adGroup.adGroupType = AdGroupType.SEARCH_DYNAMIC_ADS;

    adGroup.name = string.Format("Earth to Mars Cruises #{0}",
      ExampleUtilities.GetRandomString());
    adGroup.campaignId = campaignId;
    adGroup.status = AdGroupStatus.PAUSED;

    // Recommended: Set a tracking URL template for your ad group if you want to use URL
    // tracking software.
    adGroup.trackingUrlTemplate = "http://tracker.example.com/traveltracker/{escapedlpurl}";

    // Set the ad group bids.
    BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();

    CpcBid cpcBid = new CpcBid();
    cpcBid.bid = new Money();
    cpcBid.bid.microAmount = 3000000;

    biddingConfig.bids = new Bids[] { cpcBid };

    adGroup.biddingStrategyConfiguration = biddingConfig;

    // Create the operation.
    AdGroupOperation operation = new AdGroupOperation();
    operation.@operator = Operator.ADD;
    operation.operand = adGroup;

    try {
      // Create the ad group.
      AdGroupReturnValue retVal = adGroupService.mutate(new AdGroupOperation[] { operation });

      // Display the results.
      AdGroup newAdGroup = retVal.value[0];
      Console.WriteLine("Ad group with id = '{0}' and name = '{1}' was created.",
        newAdGroup.id, newAdGroup.name);
      return newAdGroup;
    } catch (Exception e) {
      throw new System.ApplicationException("Failed to create ad group.", e);
    }
  }
}

Java

private static AdGroup createAdGroup(
    AdWordsServicesInterface adWordsServices, AdWordsSession session, Campaign campaign)
    throws ApiException, RemoteException {
  // Get the AdGroupService.
  AdGroupServiceInterface adGroupService =
      adWordsServices.get(session, AdGroupServiceInterface.class);

  // Create the ad group.
  AdGroup adGroup = new AdGroup();

  // Required: Set the ad group's type to Dynamic Search Ads.
  adGroup.setAdGroupType(AdGroupType.SEARCH_DYNAMIC_ADS);

  adGroup.setName("Earth to Mars Cruises #" + System.currentTimeMillis());
  adGroup.setCampaignId(campaign.getId());
  adGroup.setStatus(AdGroupStatus.PAUSED);

  // Recommended: Set a tracking URL template for your ad group if you want to use URL
  // tracking software.
  adGroup.setTrackingUrlTemplate("http://tracker.example.com/traveltracker/{escapedlpurl}");
  
  // Set the ad group bids.
  BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();

  CpcBid cpcBid = new CpcBid();
  cpcBid.setBid(new Money());
  cpcBid.getBid().setMicroAmount(3000000L);

  biddingConfig.setBids(new Bids[] {cpcBid});

  adGroup.setBiddingStrategyConfiguration(biddingConfig);

  // Create the operation.
  AdGroupOperation operation = new AdGroupOperation();
  operation.setOperand(adGroup);
  operation.setOperator(Operator.ADD);

  AdGroup newAdGroup = adGroupService.mutate(new AdGroupOperation[] {operation}).getValue(0);
  System.out.printf(
      "Ad group with name '%s' and ID %d was added.%n", newAdGroup.getName(), newAdGroup.getId());
  return newAdGroup;
}

Python

ad_group_service = client.GetService('AdGroupService')

operations = [{
    'operator': 'ADD',
    'operand': {
        'campaignId': campaign_id,
        'adGroupType': 'SEARCH_DYNAMIC_ADS',
        'name': 'Earth to Mars Cruises #%d' % uuid.uuid4(),
        'status': 'PAUSED',
        'biddingStrategyConfiguration': {
            'bids': [{
                'xsi_type': 'CpcBid',
                'bid': {
                    'microAmount': '3000000'
                },
            }]
        }
    }
}]

ad_group = ad_group_service.mutate(operations)['value'][0]
ad_group_id = ad_group['id']

print 'Ad group with ID "%d" and name "%s" was created.' % (
    ad_group_id, ad_group['name'])

PHP

private static function createAdGroup(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    Campaign $campaign
) {
  $adGroupService = $adWordsServices->get($session, AdGroupService::class);

  // Create the ad group.
  $adGroup = new AdGroup();

  // Required: Set the ad group's type to Dynamic Search Ads.
  $adGroup->setAdGroupType(AdGroupType::SEARCH_DYNAMIC_ADS);

  $adGroup->setName('Interplanetary Cruise #' . uniqid());
  $adGroup->setCampaignId($campaign->getId());
  $adGroup->setStatus(AdGroupStatus::PAUSED);

  // Recommended: Set a tracking URL template for your ad group if you want to
  // use URL tracking software.
  $adGroup->setTrackingUrlTemplate(
      'http://tracker.example.com/traveltracker/{escapedlpurl}');

  // Set the ad group bids.
  $biddingStrategyConfiguration = new BiddingStrategyConfiguration();

  $cpcBid = new CpcBid();
  $money = new Money();
  $money->setMicroAmount(3000000);
  $cpcBid->setBid($money);
  $biddingStrategyConfiguration->setBids([$cpcBid]);

  $adGroup->setBiddingStrategyConfiguration($biddingStrategyConfiguration);

  // Create an ad group operation.
  $operation = new AdGroupOperation();
  $operation->setOperand($adGroup);
  $operation->setOperator(Operator::ADD);

  // Create the ad group on the server and print out some information.
  $result = $adGroupService->mutate([$operation]);
  $adGroup = $result->getValue()[0];
  printf("Ad group with name '%s' and ID %d was added.\n",
      $adGroup->getName(), $adGroup->getId());

  return $adGroup;
}

Perl

# Creates the ad group.
sub _create_ad_group {
  my ($client, $campaign) = @_;

  my $ad_group = Google::Ads::AdWords::v201710::AdGroup->new({
      name       => sprintf("Earth to Mars Cruises #%s", uniqid()),
      campaignId => $campaign->get_id(),
      # Required: Set the ad group's type to Dynamic Search Ads.
      adGroupType => "SEARCH_DYNAMIC_ADS",
      status      => "PAUSED",
      # Recommended: Set a tracking URL template for your ad group if you want
      # to use URL tracking software.
      trackingUrlTemplate =>
        "http://tracker.example.com/traveltracker/{escapedlpurl}",
      biddingStrategyConfiguration =>
        Google::Ads::AdWords::v201710::BiddingStrategyConfiguration->new({
          bids => [
            Google::Ads::AdWords::v201710::CpcBid->new({
                bid => Google::Ads::AdWords::v201710::Money->new(
                  {microAmount => 3000000}
                ),
              }
            ),
          ]})});

  # Create operation.
  my $ad_group_operation =
    Google::Ads::AdWords::v201710::AdGroupOperation->new({
      operator => "ADD",
      operand  => $ad_group
    });

  my $result =
    $client->AdGroupService()->mutate({operations => [$ad_group_operation]});
  my $new_ad_group = $result->get_value()->[0];
  printf "Ad group with name '%s' and ID %d was added.\n",
    $new_ad_group->get_name(), $new_ad_group->get_id();
  return $new_ad_group;
}

Ruby

def create_ad_group(adwords, campaign)
  ad_group_srv = adwords.service(:AdGroupService, API_VERSION)

  ad_group = {
    # Required: Set the ad group's tpe to Dynamic Search Ads.
    :ad_group_type => 'SEARCH_DYNAMIC_ADS',
    :name => "Earth to Mars Cruises #%d" % (Time.now.to_f * 1000).to_i,
    :campaign_id => campaign[:id],
    :status => 'PAUSED',
    # Recommended: Set a tracking URL template for your ad group if you want to
    # use URL tracking software.
    :tracking_url_template =>
        'http://tracker.example.com/traveltracker/{escapedlpurl}',
    :bidding_strategy_configuration => {
      :bids => [{
        :xsi_type => 'CpcBid',
        :bid => {
          :micro_amount => 3_000_000
        }
      }]
    }
  }

  operation = {
    :operand => ad_group,
    :operator => 'ADD'
  }

  new_ad_group = ad_group_srv.mutate([operation])[:value].first
  puts "Ad group with name '%s' and ID %d was added." %
      [new_ad_group[:name], new_ad_group[:id]]

  return new_ad_group
end

Create the DSA

The next step is to create an ExpandedDynamicSearchAd object. This ad will have its headline, display URL, and final URL auto-generated at serving time according to domain name specific information provided by DynamicSearchAdsSetting at the campaign level. You need to provide the ad's description.

C#

private static ExpandedDynamicSearchAd CreateExpandedDSA(AdWordsUser user, long adGroupId) {
  using (AdGroupAdService adGroupAdService =
      (AdGroupAdService) user.GetService(AdWordsService.v201710.AdGroupAdService)) {
    // Create an Expanded Dynamic Search Ad. This ad will have its headline, display URL and
    // final URL auto-generated at serving time according to domain name specific information
    // provided by DynamicSearchAdsSetting at the campaign level.
    ExpandedDynamicSearchAd expandedDSA = new ExpandedDynamicSearchAd();
    // Set the ad description.
    expandedDSA.description = "Buy your tickets now!";

    // Create the ad group ad.
    AdGroupAd adGroupAd = new AdGroupAd();
    adGroupAd.adGroupId = adGroupId;
    adGroupAd.ad = expandedDSA;

    // Optional: Set the status.
    adGroupAd.status = AdGroupAdStatus.PAUSED;

    // Create the operation.
    AdGroupAdOperation operation = new AdGroupAdOperation();
    operation.@operator = Operator.ADD;
    operation.operand = adGroupAd;

    try {
      // Create the ad.
      AdGroupAdReturnValue retval = adGroupAdService.mutate(
          new AdGroupAdOperation[] { operation });

      // Display the results.
      AdGroupAd newAdGroupAd = retval.value[0];
      ExpandedDynamicSearchAd newAd = newAdGroupAd.ad as ExpandedDynamicSearchAd;
      Console.WriteLine("Expanded Dynamic Search Ad with ID '{0}' and description '{1}' " +
          "was added.", newAd.id, newAd.description);
      return newAd;
    } catch (Exception e) {
      throw new System.ApplicationException("Failed to create Expanded Dynamic Search Ad.", e);
    }
  }
}

Java

private static void createExpandedDSA(
    AdWordsServicesInterface adWordsServices, AdWordsSession session, AdGroup adGroup)
    throws ApiException, RemoteException {
  // Get the AdGroupAdService.
  AdGroupAdServiceInterface adGroupAdService =
      adWordsServices.get(session, AdGroupAdServiceInterface.class);

  // Create the expanded Dynamic Search Ad. This ad will have its headline and final URL
  // auto-generated at serving time according to domain name specific information provided
  // by DynamicSearchAdsSetting at the campaign level.
  ExpandedDynamicSearchAd expandedDSA = new ExpandedDynamicSearchAd();
  // Set the ad description.
  expandedDSA.setDescription("Buy your tickets now!");

  // Create the ad group ad.
  AdGroupAd adGroupAd = new AdGroupAd();
  adGroupAd.setAdGroupId(adGroup.getId());
  adGroupAd.setAd(expandedDSA);

  // Optional: Set the status.
  adGroupAd.setStatus(AdGroupAdStatus.PAUSED);

  // Create the operation.
  AdGroupAdOperation operation = new AdGroupAdOperation();
  operation.setOperator(Operator.ADD);
  operation.setOperand(adGroupAd);

  // Create the ad.
  AdGroupAd newAdGroupAd =
      adGroupAdService.mutate(new AdGroupAdOperation[] {operation}).getValue(0);
  ExpandedDynamicSearchAd newExpandedDSA = (ExpandedDynamicSearchAd) newAdGroupAd.getAd();
  System.out.printf(
      "Expanded Dynamic Search Ad with ID %d and description '%s' was added.%n",
      newExpandedDSA.getId(), newExpandedDSA.getDescription());
}

Python

# Get the AdGroupAdService.
ad_group_ad_service = client.GetService('AdGroupAdService')

# Create the operation
operations = [{
    'operator': 'ADD',
    'operand': {
        'xsi_type': 'AdGroupAd',
        'adGroupId': ad_group_id,
        # Create the expanded dynamic search ad. This ad will have its
        # headline and final URL auto-generated at serving time according to
        # domain name specific information provided by DynamicSearchAdsSetting
        # at the campaign level.
        'ad': {
            'xsi_type': 'ExpandedDynamicSearchAd',
            # Set the ad description.
            'description': 'Buy your tickets now!'
        },
        # Optional: Set the status.
        'status': 'PAUSED',
    }
}]

# Create the ad.
ad = ad_group_ad_service.mutate(operations)['value'][0]['ad']

# Display the results.
print ('Expanded dynamic search ad with ID "%d" and description "%s" was '
       'added' % (ad['id'], ad['description']))

PHP

private static function createExpandedDSA(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    AdGroup $adGroup
) {
  $adGroupAdService
      = $adWordsServices->get($session, AdGroupAdService::class);

  // Create the expanded Dynamic Search Ad. This ad will have its headline
  // and final URL auto-generated at serving time according to domain name
  // specific information provided by DynamicSearchAdsSetting at the
  // campaign level.
  $expandedDSA = new ExpandedDynamicSearchAd();
  // Set the ad description.
  $expandedDSA->setDescription('Buy your tickets now!');

  // Create the ad group ad.
  $adGroupAd = new AdGroupAd();
  $adGroupAd->setAdGroupId($adGroup->getId());
  $adGroupAd->setAd($expandedDSA);

  // Optional: Set the status.
  $adGroupAd->setStatus(AdGroupAdStatus::PAUSED);

  // Create the operation.
  $operation = new AdGroupAdOperation();
  $operation->setOperator(Operator::ADD);
  $operation->setOperand($adGroupAd);

  // Create the ad on the server and print some information.
  $result = $adGroupAdService->mutate([$operation]);
  $newAdGroupAd = $result->getValue()[0];
  $expandedDSA = $newAdGroupAd->getAd();
  printf(
      "Expanded Dynamic Search Ad with ID %d and description '%s' was"
          . " added.\n",
      $expandedDSA->getId(),
      $expandedDSA->getDescription()
  );
}

Perl

# Creates the expanded Dynamic Search Ad.
sub _create_expanded_DSA {
  my ($client, $ad_group) = @_;
  # Create the expanded Dynamic Search Ad. This ad will have its headline and
  # final URL auto-generated at serving time according to domain name specific
  # information provided by DynamicSearchAdsSetting at the campaign level.
  my $expanded_DSA =
    Google::Ads::AdWords::v201710::ExpandedDynamicSearchAd->new({
      # Set the ad description.
      description => "Buy your tickets now!",
    });

  # Create the ad group ad.
  my $ad_group_ad = Google::Ads::AdWords::v201710::AdGroupAd->new({
    adGroupId => $ad_group->get_id(),
    ad        => $expanded_DSA,
    # Optional: Set the status.
    status => "PAUSED"
  });

  # Create operation.
  my $operation = Google::Ads::AdWords::v201710::AdGroupAdOperation->new({
    operator => "ADD",
    operand  => $ad_group_ad
  });

  my $result =
    $client->AdGroupAdService()->mutate({operations => [$operation]});
  my $new_ad_group_ad = $result->get_value()->[0];
  my $new_expanded_dsa = $new_ad_group_ad->get_ad();
  printf
    "Expanded Dynamic Search Ad with ID %d and description '%s' was added.\n",
    $new_expanded_dsa->get_id(), $new_expanded_dsa->get_description();
}

Ruby

def create_expanded_dsa(adwords, ad_group)
  ad_group_ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  # Create the expanded Dynamic Search Ad. This ad will have its headline and
  # final URL auto-generated at serving time according to domain name specific
  # information provided by DynamicSearchAdsSetting at the campaign level.
  expanded_dsa = {
    :xsi_type => 'ExpandedDynamicSearchAd',
    :description => 'Buy your tickets now!'
  }

  ad_group_ad = {
    :ad_group_id => ad_group[:id],
    :ad => expanded_dsa,
    # Optional: Set the status.
    :status => 'PAUSED'
  }

  operation = {
    :operand => ad_group_ad,
    :operator => 'ADD'
  }

  new_ad_group_ad = ad_group_ad_srv.mutate([operation])[:value].first
  new_expanded_dsa = new_ad_group_ad[:ad]
  puts "Expanded Dynamic Search Ad with ID %d and description '%s' was added." %
      [new_expanded_dsa[:id], new_expanded_dsa[:description]]
end

In Dynamic Search Ads, the finalUrls field is computed by the AdWords system when it creates the DSA. As a result, you can't set this field when creating DSAs. To use URL tracking software, you can specify which additional tracking parameters or redirects are needed using the trackingUrlTemplate field. When specifying this field, you must include one of the following parameters to allow the AdWords system to put in the resulting matched final URL:

Parameter Explanation
{unescapedlpurl}

Unescaped landing page URL—if you want to add something to the end, for example:

{unescapedlpurl}?dsa=true

{escapedlpurl}

Escaped (URL encoded) landing page URL—if you want to redirect to a tracker, for example:

http://tracking.com/lp={escapedurl}

{lpurlpath}

Only the path and query params from the computed URL, for example:

http://tracking.com.com/track/{lpurlpath}

{lpurl}

Encodes ? and = of landing page URL, ends with search query. If found at the very beginning of the trackingUrlTemplate field, it will actually be replaced by the {unescapedurl} value, e.g.:

http://tracking.com/redir.php?tracking=xyz&url={lpurl}

For example:

dsa.setTrackingUrlTemplate("http://example.org/traveltracker/{escapedlpurl}");

Specify criteria for the DSA

Finally, you'll want to set up some criteria to trigger serving of the Dynamic Search Ads. This is done via the Webpage criterion object.

To the Webpage criterion, you'll add a WebpageParameter object, which contains between one and three WebpageConditions. These objects let you specify exactly what to filter or search on within the domain specified previously in the campaign settings.

There are four items you can filter on within a domain:

WebPageConditionOperand Description
URL A string matching a partial URL of a page.
CATEGORY A string with a category to match against precisely.
PAGE_TITLE A string matching a partial page title.
PAGE_CONTENT A string matching some content within any given indexed page.
CUSTOM_LABEL A string matching a webpage custom label targeting condition. See Targeting page feed URLs using custom labels.

As an example, let's create a webpage condition that searches for anything in the /children branch of our Mars vacation site, but only those pages with "Special Offer" in the title.

Discovering your site's categories

You can use DataService to fetch a list of categories that Google thinks apply to your site. You can filter on domains or campaigns. As an example, this code fetches the list of categories for our site, within a specific campaign:

DataServiceInterface dataService =
  adWordsServices.get(session, DataServiceInterface.class);

// Create selector.
SelectorBuilder builder = new SelectorBuilder();
Selector selector = builder
    .fields("DomainName", "Category", "IsoLanguage")
    .equals("DomainName", "example.org")
    .equals("CampaignId", campaignId)
    .limit(PAGE_SIZE)
    .build();

DomainCategoryPage page = dataService.getDomainCategory(selector);

Excluding parts of your site

It's also possible to use the AdGroupCriterionService to set up negative Webpage criteria. You could use this, for example, to exclude pages with a particular title that you want to manage via another campaign or adgroup.

Other criteria

Dynamic Search Ad campaigns and ad groups are not restricted to only Webpage criteria; you can continue to use other criterion types to further refine and improve the quality of your ads. You should be judicious in your use of additional criteria, however, as adding too many can diminish the effectiveness of your auto-targeting via DSAs.

DSA page feeds

By default, Dynamic Search Ads are set up to target entire web sites—or portions of them without focusing on specific page URLs. If you need better control over the URLs, you can use DSA page feeds to specify precisely which URLs to use with your Dynamic Search Ads. When you provide a page feed of your products and their landing pages, it helps AdWords determine when to show your ads and where to direct people on your website.

To set up a DSA page feed:

  1. Create a feed and populate it with page URLs.
  2. Set up the campaign to use the DSA page feed.
  3. Recommended: Add custom labels to the URLs in your page feed to categorize and organize the targets for your Dynamic Search Ads.

Create a page feed

The first step in using DSA page feeds is to create a feed with criterionType = 61. The procedure is similar to that listed in our feed services guide, except for the following differences.

  1. You only need to create the feed, populate the items, and map the feed to the page feed placeholder fields.
  2. DSA page feeds use the criterionType field instead of the placeholderType field.

Refer to our code examples section for a working example.

Set up the campaign for page feeds

You can set up a DSA campaign to use page feeds by setting the pagefeed property for its DynamicSearchAdSetting.

Start by retrieving the DynamicSearchAdSetting for your Dynamic Search Ad campaign.

C#

using (CampaignService campaignService = (CampaignService) user.GetService(
    AdWordsService.v201710.CampaignService)) {

  Selector selector = new Selector() {
    fields = new string[] { Campaign.Fields.Id, Campaign.Fields.Settings },
    predicates = new Predicate[]{
    Predicate.Equals(Campaign.Fields.Id, campaignId)
  },
    paging = Paging.Default
  };

  CampaignPage page = campaignService.get(selector);

  if (page == null || page.entries == null || page.entries.Length == 0) {
    throw new System.ApplicationException(string.Format(
        "Failed to retrieve campaign with ID = {0}.", campaignId));
  }
  Campaign campaign = page.entries[0];

  if (campaign.settings == null) {
    throw new System.ApplicationException("This is not a DSA campaign.");
  }

  DynamicSearchAdsSetting dsaSetting = null;
  Setting[] campaignSettings = campaign.settings;

  for (int i = 0; i < campaign.settings.Length; i++) {
    Setting setting = campaignSettings[i];
    if (setting is DynamicSearchAdsSetting) {
      dsaSetting = (DynamicSearchAdsSetting) setting;
      break;
    }
  }

  if (dsaSetting == null) {
    throw new System.ApplicationException("This is not a DSA campaign.");
  }

Java

// Get the CampaignService.
CampaignServiceInterface campaignService =
    adWordsServices.get(session, CampaignServiceInterface.class);

Selector selector =
    new SelectorBuilder()
        .fields(CampaignField.Id, CampaignField.Settings)
        .equalsId(campaignId)
        .build();

CampaignPage campaignPage = campaignService.get(selector);
if (campaignPage.getEntries() == null || campaignPage.getTotalNumEntries() == 0) {
  throw new IllegalArgumentException("No campaign found with ID: " + campaignId);
}
Campaign campaign = campaignPage.getEntries(0);

if (campaign.getSettings() == null) {
  throw new IllegalArgumentException(
      "Campaign with ID " + campaignId + " is not a DSA campaign.");
}

DynamicSearchAdsSetting dsaSetting = null;
for (Setting setting : campaign.getSettings()) {
  if (setting instanceof DynamicSearchAdsSetting) {
    dsaSetting = (DynamicSearchAdsSetting) setting;
    break;
  }
}

if (dsaSetting == null) {
  throw new IllegalArgumentException(
      "Campaign with ID " + campaignId + " is not a DSA campaign.");
}

Python

# Get the CampaignService.
campaign_service = client.GetService('CampaignService', version='v201710')

selector = {
    'fields': ['Id', 'Settings'],
    'predicates': [{
        'field': 'Id',
        'operator': 'EQUALS',
        'values': [campaign_id]
    }]
}

response = campaign_service.get(selector)

if response['totalNumEntries']:
  campaign = response['entries'][0]
else:
  raise ValueError('No campaign with ID "%d" exists.' % campaign_id)

if not campaign['settings']:
  raise ValueError('This is not a DSA campaign.')

dsa_setting = None

campaign_settings = campaign['settings']

for setting in campaign_settings:
  if setting['Setting.Type'] == 'DynamicSearchAdsSetting':
    dsa_setting = setting
    break

if dsa_setting is None:
  raise ValueError('This is not a DSA campaign.')
    

PHP

$campaignService = $adWordsServices->get($session, CampaignService::class);

// Create selector.
$selector = new Selector();
$selector->setFields(['Id', 'Settings']);
$selector->setPredicates(
    [new Predicate('CampaignId', PredicateOperator::IN, [$campaignId])]);

$result = $campaignService->get($selector);
if (empty($result->getEntries()) || $result->getTotalNumEntries() === 0) {
  throw new InvalidArgumentException(
      'No campaign found with ID: ' . $campaignId);
}
$campaign = $result->getEntries()[0];

if ($campaign->getSettings() === null) {
  throw new InvalidArgumentException(
      'Campaign with ID ' . $campaignId . ' is not a DSA campaign.');
}

$dsaSetting = null;
foreach ($campaign->getSettings() as $setting) {
  if ($setting instanceof DynamicSearchAdsSetting) {
    $dsaSetting = $setting;
    break;
  }
}

if ($dsaSetting === null) {
  throw new InvalidArgumentException(
      'Campaign with ID ' . $campaignId . ' is not a DSA campaign.');
}
    

Perl

my $paging = Google::Ads::AdWords::v201710::Paging->new({
  startIndex    => 0,
  numberResults => PAGE_SIZE
});
my $selector = Google::Ads::AdWords::v201710::Selector->new({
    fields     => ["Id", "Settings"],
    predicates => [
      Google::Ads::AdWords::v201710::Predicate->new({
          field    => "CampaignId",
          operator => "EQUALS",
          values   => [$campaign_id]})
    ],
    paging => $paging
  });

my $dsa_setting = undef;
Google::Ads::AdWords::Utilities::PageProcessor->new({
    client   => $client,
    service  => $client->CampaignService(),
    selector => $selector
  }
  )->process_entries(
  sub {
    my ($campaign) = @_;
    if ($campaign->get_settings()) {
      foreach my $setting (@{$campaign->get_settings()}) {
        if (
          $setting->isa(
            "Google::Ads::AdWords::v201710::DynamicSearchAdsSetting"))
        {
          $dsa_setting = $setting;
          last;
        }
      }
    }
  });

if (!$dsa_setting) {
  die sprintf("Campaign with ID %s is not a DSA campaign.", $campaign_id);
}
    

Ruby

campaign_srv = adwords.service(:CampaignService, API_VERSION)

selector = {
  :fields => ['Id', 'Settings'],
  :predicates => [
    {:field => 'CampaignId', :operator => 'IN', :values => [campaign_id]}
  ]
}

campaign_page = campaign_srv.get(selector)
if campaign_page.nil? or campaign_page[:entries].nil? or
    campaign_page[:total_num_entries] == 0
  raise 'No campaign found with ID: %d' % campaign_id
end

campaign = campaign_page[:entries].first

if campaign[:settings].nil?
  raise 'Campaign with ID %d is not a DSA campaign.' % campaign_id
end

dsa_setting = nil
campaign[:settings].each do |setting|
  if setting[:setting_type] == 'DynamicSearchAdsSetting'
    dsa_setting = setting
    break
  end
end

if dsa_setting.nil?
  raise 'Campaign with ID %d is not a DSA campaign.' % campaign_id
end
    

Next, set the page feeds by specifying the feedIds in the pageFeed property of your campaign's DynamicSearchAdsSetting. You can optionally use the useSuppliedUrlsOnly field to specify whether or not to use only the specified URLs for your Dynamic Search Ads.

C#

  // Use a page feed to specify precisely which URLs to use with your
  // Dynamic Search Ads.
  dsaSetting.pageFeed = new PageFeed() {
    feedIds = new long[] {
      feedId
    },
  };

  // Optional: Specify whether only the supplied URLs should be used with your
  // Dynamic Search Ads.
  dsaSetting.useSuppliedUrlsOnly = true;

  Campaign campaignToUpdate = new Campaign();
  campaignToUpdate.id = campaignId;
  campaignToUpdate.settings = campaignSettings;

  CampaignOperation operation = new CampaignOperation();
  operation.operand = campaignToUpdate;
  operation.@operator = Operator.SET;

  try {
    CampaignReturnValue retval = campaignService.mutate(
        new CampaignOperation[] { operation });
    Campaign updatedCampaign = retval.value[0];
    Console.WriteLine("DSA page feed for campaign ID '{0}' was updated with feed ID '{1}'.",
        updatedCampaign.id, feedId);
  } catch (Exception e) {
    throw new System.ApplicationException("Failed to set page feed for campaign.", e);
  }
}

Java

// Use a page feed to specify precisely which URLs to use with your
// Dynamic Search Ads.
PageFeed pageFeed = new PageFeed();
pageFeed.setFeedIds(new long[] {feedDetails.feedId});
dsaSetting.setPageFeed(pageFeed);

// Optional: Specify whether only the supplied URLs should be used with your
// Dynamic Search Ads.
dsaSetting.setUseSuppliedUrlsOnly(true);

Campaign updatedCampaign = new Campaign();
updatedCampaign.setId(campaignId);
updatedCampaign.setSettings(campaign.getSettings());

CampaignOperation operation = new CampaignOperation();
operation.setOperand(updatedCampaign);
operation.setOperator(Operator.SET);

updatedCampaign = campaignService.mutate(new CampaignOperation[] {operation}).getValue(0);
System.out.printf(
    "DSA page feed for campaign ID %d was updated with feed ID %d.%n",
    updatedCampaign.getId(), feedDetails.feedId);

Python

dsa_setting['pageFeed'] = {
    'feedIds': [feed_id]
}

# Optional: Specify whether only the supplied URLs should be used with your
# Dynamic Search Ads.
dsa_setting['useSuppliedUrlsOnly'] = True

operation = {
    'operand': {
        'id': campaign_id,
        'settings': campaign_settings
    },
    'operator': 'SET'
}

campaign_service.mutate([operation])
print 'DSA page feed for campaign ID "%d" was updated with feed ID "%d".' % (
    campaign_id, feed_id)

PHP

// Use a page feed to specify precisely which URLs to use with your
// Dynamic Search Ads.
$pageFeed = new PageFeed();
$pageFeed->setFeedIds([$feedDetails->feedId]);
$dsaSetting->setPageFeed($pageFeed);

// Optional: Specify whether only the supplied URLs should be used with your
// Dynamic Search Ads.
$dsaSetting->setUseSuppliedUrlsOnly(true);

$updatedCampaign = new Campaign();
$updatedCampaign->setId($campaignId);
$updatedCampaign->setSettings($campaign->getSettings());

$operation = new CampaignOperation();
$operation->setOperand($updatedCampaign);
$operation->setOperator(Operator::SET);

// Update the campaign on the server and print out some information.
$result = $campaignService->mutate([$operation]);
$updatedCampaign = $result->getValue()[0];
printf("DSA page feed for campaign ID %d was updated with feed ID %d.\n",
    $updatedCampaign->getId(), $feedDetails->feedId);

Perl

# Use a page feed to specify precisely which URLs to use with your
# Dynamic Search Ads.
my $page_feed = Google::Ads::AdWords::v201710::PageFeed->new({
    feedIds => [$feed_details->{"feedId"}]});
$dsa_setting->set_pageFeed($page_feed);

# Optional: Specify whether only the supplied URLs should be used with your
# Dynamic Search Ads.
$dsa_setting->set_useSuppliedUrlsOnly(1);

my $updated_campaign = Google::Ads::AdWords::v201710::Campaign->new({
    id       => $campaign_id,
    settings => [$dsa_setting]});

my $operation = Google::Ads::AdWords::v201710::CampaignOperation->new({
  operand  => $updated_campaign,
  operator => "SET"
});

$client->CampaignService()->mutate({operations => [$operation]});
printf(
  "DSA page feed for campaign ID %d was updated with feed ID %d.\n",
  $updated_campaign->get_id(),
  $feed_details->{"feedId"});

Ruby

# Use a page feed to specify precisely which URLs to use with your Dynamic
# Search Ads.
page_feed = {
  :feed_ids => [feed_details[:feed_id]]
}
dsa_setting[:page_feed] = page_feed

# Optional: Specify whether only the supplied URLs should be used with your
# Dynamic Search Ads.
dsa_setting[:use_supplied_urls_only] = true

updated_campaign = {
  :id => campaign_id,
  :settings => campaign[:settings]
}

operation = {
  :operand => updated_campaign,
  :operator => 'SET'
}

updated_campaign = campaign_srv.mutate([operation])[:value].first
puts "DSA page feed for campaign ID %d was updated with feed ID %d." % [
  updated_campaign[:id], feed_details[:feed_id]
]

These settings map to the AdWords UI as follows.

useSuppliedUrlsOnly pageFeed.feedIds AdWords UI Setting
false N/A Use Google’s index of my website.
false One or more feed IDs are specified. Use URLs from both Google’s index of my website and my page feed.
true One or more feed IDs are specified. Use URLs from my page feed only.
true empty or null. Not supported. API throws SettingError.DYNAMIC_SEARCH_ADS_SETTING_AT_LEAST_ONE_FEED_ID_MUST_BE_PRESENT error.

Targeting page feed URLs using custom labels

You can optionally use custom labels to target and bid on URLs in the page feed. This can be done by creating a Webpage criterion that filters using operand as CUSTOM_LABEL.

C#

private static BiddableAdGroupCriterion AddDsaTargeting(AdWordsUser user, long adGroupId,
    string labelName) {
  using (AdGroupCriterionService adGroupCriterionService =
      (AdGroupCriterionService) user.GetService(
          AdWordsService.v201710.AdGroupCriterionService)) {

    // Create a webpage criterion.
    Webpage webpage = new Webpage();

    WebpageParameter parameter = new WebpageParameter();
    parameter.criterionName = "Test criterion";
    webpage.parameter = parameter;

    // Add a condition for label=specified_label_name.
    WebpageCondition condition = new WebpageCondition();
    condition.operand = WebpageConditionOperand.CUSTOM_LABEL;
    condition.argument = labelName;
    parameter.conditions = new WebpageCondition[] { condition };

    BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
    criterion.adGroupId = adGroupId;
    criterion.criterion = webpage;

    // Set a custom bid for this criterion.
    BiddingStrategyConfiguration biddingStrategyConfiguration =
        new BiddingStrategyConfiguration();

    biddingStrategyConfiguration.bids = new Bids[] {
    new CpcBid() {
      bid = new Money() {
        microAmount = 1500000
      }
    }
  };

    criterion.biddingStrategyConfiguration = biddingStrategyConfiguration;

    AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
    operation.operand = criterion;
    operation.@operator = Operator.ADD;

    try {
      AdGroupCriterionReturnValue retval = adGroupCriterionService.mutate(
          new AdGroupCriterionOperation[] { operation });
      BiddableAdGroupCriterion newCriterion = (BiddableAdGroupCriterion) retval.value[0];

      Console.WriteLine("Web page criterion with ID = {0} and status = {1} was created.",
        newCriterion.criterion.id, newCriterion.userStatus);
      return newCriterion;
    } catch (Exception e) {
      throw new System.ApplicationException("Failed to create webpage criterion for " +
          "custom page feed label.", e);
    }
  }
}
    

Java

private static void addDsaTargeting(
    AdWordsServicesInterface adWordsServices,
    AdWordsSession session,
    Long adGroupId,
    String dsaPageUrlLabel)
    throws ApiException, RemoteException {
  // Get the AdGroupCriterionService.
  AdGroupCriterionServiceInterface adGroupCriterionService =
      adWordsServices.get(session, AdGroupCriterionServiceInterface.class);

  // Create a webpage criterion.
  Webpage webpage = new Webpage();

  WebpageParameter parameter = new WebpageParameter();
  parameter.setCriterionName("Test criterion");
  webpage.setParameter(parameter);

  // Add a condition for label=specified_label_name.
  WebpageCondition condition = new WebpageCondition();
  condition.setOperand(WebpageConditionOperand.CUSTOM_LABEL);
  condition.setArgument(dsaPageUrlLabel);
  parameter.setConditions(new WebpageCondition[] {condition});

  BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
  criterion.setAdGroupId(adGroupId);
  criterion.setCriterion(webpage);

  // Set a custom bid for this criterion.
  BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();

  CpcBid cpcBid = new CpcBid();
  Money money = new Money();
  money.setMicroAmount(1_500_000L);
  cpcBid.setBid(money);
  biddingStrategyConfiguration.setBids(new Bids[] {cpcBid});

  criterion.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

  AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
  operation.setOperand(criterion);
  operation.setOperator(Operator.ADD);

  BiddableAdGroupCriterion newCriterion =
      (BiddableAdGroupCriterion)
          adGroupCriterionService.mutate(new AdGroupCriterionOperation[] {operation}).getValue(0);
  System.out.printf(
      "Web page criterion with ID %d and status '%s' was created.%n",
      newCriterion.getCriterion().getId(), newCriterion.getUserStatus());
}
    

Python

# Get the AdGroupCriterionService.
ad_group_criterion_service = client.GetService('AdGroupCriterionService',
                                               version='v201710')

# Create the operation.
operation = {
    'operand': {
        'xsi_type': 'BiddableAdGroupCriterion',
        'adGroupId': ad_group_id,
        # Create a webpage criterion.
        'criterion': {
            'xsi_type': 'Webpage',
            'parameter': {
                'criterionName': 'Test criterion',
                # Add a condition for label=specified_label_name.
                'conditions': [{
                    'operand': 'CUSTOM_LABEL',
                    'argument': label_name
                }],
            }
        },
        # Set a custom bid for this criterion
        'biddingStrategyConfiguration': {
            'bids': [{
                'xsi_type': 'CpcBid',
                'bid': {
                    'microAmount': 1500000
                }
            }]
        }
    },
    'operator': 'ADD'
}

criterion = ad_group_criterion_service.mutate([operation])['value'][0]
print 'Web page criterion with ID "%d" and status "%s" was created.' % (
    criterion['criterion']['id'], criterion['userStatus'])
return criterion
    

PHP

private static function addDsaTargeting(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    $adGroupId,
    $dsaPageUrlLabel
) {
  $adGroupCriterionService =
      $adWordsServices->get($session, AdGroupCriterionService::class);

  // Create a webpage criterion.
  $webpage = new Webpage();

  $parameter = new WebpageParameter();
  $parameter->setCriterionName('Test criterion');
  $webpage->setParameter($parameter);

  // Add a condition for label=specified_label_name.
  $condition = new WebpageCondition();
  $condition->setOperand(WebpageConditionOperand::CUSTOM_LABEL);
  $condition->setArgument($dsaPageUrlLabel);
  $parameter->setConditions([$condition]);

  $criterion = new BiddableAdGroupCriterion();
  $criterion->setAdGroupId($adGroupId);
  $criterion->setCriterion($webpage);

  // Set a custom bid for this criterion.
  $biddingStrategyConfiguration = new BiddingStrategyConfiguration();

  $cpcBid = new CpcBid();
  $money = new Money();
  $money->setMicroAmount(1500000);
  $cpcBid->setBid($money);
  $biddingStrategyConfiguration->setBids([$cpcBid]);

  $criterion->setBiddingStrategyConfiguration($biddingStrategyConfiguration);

  $operation = new AdGroupCriterionOperation();
  $operation->setOperand($criterion);
  $operation->setOperator(Operator::ADD);

  // Create ad group criterion on the server and print out some information.
  $result = $adGroupCriterionService->mutate([$operation]);
  $criterion = $result->getValue()[0];
  printf("Web page criterion with ID %d and status '%s' was created.\n",
      $criterion->getCriterion()->getId(), $criterion->getUserStatus());
}
    

Perl

sub _add_dsa_targeting {
  my ($client, $ad_group_id, $dsa_page_url_label) = @_;

  # Create a webpage criterion.
  # Add a condition for label=specified_label_name.
  my $condition = Google::Ads::AdWords::v201710::WebpageCondition->new({
    operand  => "CUSTOM_LABEL",
    argument => $dsa_page_url_label
  });

  # Create a webpage criterion for special offers.
  my $parameter = Google::Ads::AdWords::v201710::WebpageParameter->new({
      criterionName => "Test criterion",
      conditions    => [$condition]});

  my $webpage = Google::Ads::AdWords::v201710::Webpage->new({
    parameter => $parameter
  });

  # Create biddable ad group criterion.
  my $biddable_ad_group_criterion =
    Google::Ads::AdWords::v201710::BiddableAdGroupCriterion->new({
      adGroupId => $ad_group_id,
      criterion => $webpage,
      # Set a custom bid for this criterion.
      biddingStrategyConfiguration =>
        Google::Ads::AdWords::v201710::BiddingStrategyConfiguration->new({
          bids => [
            Google::Ads::AdWords::v201710::CpcBid->new({
                bid => Google::Ads::AdWords::v201710::Money->new(
                  {microAmount => 1500000}
                ),
              }
            ),
          ]})});

  # Create operation.
  my $operation =
    Google::Ads::AdWords::v201710::AdGroupCriterionOperation->new({
      operator => "ADD",
      operand  => $biddable_ad_group_criterion
    });

  # Create the criterion.
  my $result =
    $client->AdGroupCriterionService()->mutate({operations => [$operation]});
  my $new_ad_group_criterion = $result->get_value()->[0];
  printf "Web page criterion with ID %d and status '%s' was created.\n",
    $new_ad_group_criterion->get_criterion()->get_id(),
    $new_ad_group_criterion->get_userStatus();
}
    

Ruby

def add_dsa_targeting(adwords, ad_group_id, dsa_page_url_label)
  ad_group_criterion_srv =
      adwords.service(:AdGroupCriterionService, API_VERSION)

  webpage = {
    :xsi_type => 'Webpage',
    :parameter => {
      :criterion_name => 'Test criterion',
      :conditions => [{
        :operand => 'CUSTOM_LABEL',
        :argument => dsa_page_url_label
      }]
    }
  }

  bidding_strategy_configuration = {
    :bids => [{
      :xsi_type => 'CpcBid',
      :bid => {
        :micro_amount => 1_500_000
      }
    }]
  }

  criterion = {
    :xsi_type => 'BiddableAdGroupCriterion',
    :ad_group_id => ad_group_id,
    :criterion => webpage,
    :bidding_strategy_configuration => bidding_strategy_configuration
  }

  operation = {
    :operand => criterion,
    :operator => 'ADD'
  }

  new_criterion = ad_group_criterion_srv.mutate([operation])[:value].first
  puts "Web page criterion with ID %d and status '%s' was created." %
      [new_criterion[:criterion][:id], new_criterion[:user_status]]
end
    

Reporting

You can download three different reports for Dynamic Search Ads.

Criteria Performance report

The Parameter or Dynamic ad target field in this report includes the name of the WebpageParameter associated with this object, for those cases where the criterion object was of type WebpageCriterion. Note that this is an "attribute" type field, which means it contains fixed data—in this case the WebpageParameter associated with the performance data.

Keywordless Category report

The Keywordless Category Performance report includes keywordless ads for Dynamic Search Ads statistics aggregated by category. This report does not return zero impression rows. The Category0, Category1, and Category2 fields contain the category and sub-category information related to the results.

Top level categories First level sub-categories Second level sub-categories Clicks Impressions Day Cost
Tourism & Travel Extraterrestrial Mars 1 71 6/20/2014 0.05
Tourism & Travel Adventure Travel 0 279 6/21/2014 0

Keywordless Query report

The Keywordless Query Performance report includes keywordless ads for Dynamic Search Ads statistics based on search terms. This report does not return zero impression rows. The Query field contains any matching queries that generated results.

Search term Clicks Impressions Day Cost URL
mars luxury 0 20 6/20/2014 0 http://example.org/LuxuryMarsCruises
mars luxury 0 14 6/21/2014 0 http://example.org/LuxuryMarsCruises
low cost mars 0 24 6/20/2014 0 http://example.org/MarsOnABudget
low cost mars 0 18 6/21/2014 0 http://example.org/MarsOnABudget
mars landmarks 0 130 6/21/2014 0 http://example.org/MajorTouristSpots
mars funny face 0 44 6/21/2014 0 http://example.org/MajorTouristSpots
space travel safety 1 3 6/20/2014 0.05 http://example.org/ButIsItSafe
mars departure points 0 11 6/21/2014 0 http://example.org/HowToGetToMars
mars beaches 0 24 6/20/2014 0 http://example.org/MarsBeachVacations
mars beaches 0 39 6/21/2014 0 http://example.org/MarsBeachVacations
mars canyoning 0 23 6/21/2014 0 http://example.org/DayTripsAndActivities
Total 1 350 -- 0.05 --

Code examples

Complete code examples for working with Dynamic Search Ads are available in each client library:

Enviar comentarios sobre…

¿Necesitas ayuda? Visita nuestra página de asistencia.