Shopping Campaigns

A Shopping campaign is a campaign type that helps promote your products by giving users detailed product information before they even click your ad. Ads in Shopping campaigns show users a photo of your product, plus a title, price, store name, and more.

This guide describes how to set up and manage Shopping campaigns in the AdWords API.

Linking your Merchant Center and AdWords accounts

Before you can create a Shopping campaign, you need to first link your AdWords account to your Google Merchant Center account. This involves two steps:

  1. Send an invitation from your Merchant Center account to your AdWords account.
  2. Accept the invitation in your AdWords account.

Send an invitation from your Merchant Center account

You can use the Merchant Center user interface to send this invitation, or use the Content API for Shopping to update the adwordsLinks of your Account.

Managing invitations in your AdWords account

You can use getServiceLinks and mutateServiceLinks of CustomerService to retrieve, accept, and reject links between your AdWords account and other services, including Merchant Center.

To retrieve all links to your account, simply call getServiceLinks with a predicate on serviceType = MERCHANT_CENTER as follows:

Java

// Get the CustomerService.
CustomerServiceInterface customerService =
    adWordsServices.get(session, CustomerServiceInterface.class);

// Create a selector that filters by service type.
Selector selector =
    new SelectorBuilder()
        .fields("ServiceType")
        .equals("ServiceType", ServiceType.MERCHANT_CENTER.getValue())
        .build();

// Get the service links.
ServiceLink[] serviceLinks = customerService.getServiceLinks(selector);

// Display the results.
if (serviceLinks != null) {
  for (ServiceLink serviceLink : serviceLinks) {
    System.out.printf(
        "Found service link with service link ID %d, type %s, name '%s', and status %s.%n",
        serviceLink.getServiceLinkId(),
        serviceLink.getServiceType(),
        serviceLink.getName(),
        serviceLink.getLinkStatus());
  }
} else {
  System.out.println("No service links found.");
}

CSharp

// Get the CustomerService.
CustomerService customerService =
    (CustomerService) user.GetService(AdWordsService.v201710.CustomerService);

// Create a selector that filters by service type.
Selector selector = new Selector() {
  fields = new string[] { ServiceLink.Fields.ServiceType },
  predicates = new Predicate[] {
    Predicate.Equals(ServiceLink.Fields.ServiceType, ServiceType.MERCHANT_CENTER.ToString())
  }
};

// Get the service links.
ServiceLink[] serviceLinks = customerService.getServiceLinks(selector);

// Display the results.
if (serviceLinks != null) {
  foreach (ServiceLink serviceLink in serviceLinks) {
    Console.WriteLine("Found service link with service link ID {0}, type {1}, name " +
        "'{2}', and status {3}.", serviceLink.serviceLinkId, serviceLink.serviceType,
        serviceLink.name, serviceLink.linkStatus);
  }
} else {
  Console.WriteLine("No service links found.");
}

Python

def main(client):
  # Initialize appropriate service.
  customer_service = client.GetService('CustomerService',
                                       version='v201710')

  selector = {
      'fields': ['ServiceType'],
      'predicates': [
          {
              'field': 'ServiceType',
              'operator': 'EQUALS',
              'values': ['MERCHANT_CENTER']
          }
      ]
  }

  service_links = customer_service.getServiceLinks(selector)

  # Display results.
  if service_links:
    for service_link in service_links:
      print ('Service link with service link ID \'%s\', type \'%s\', '
             'name \'%s\', and status \'%s\' was found.' %
             (service_link['serviceLinkId'],
              service_link['serviceType'],
              service_link['name'],
              service_link['linkStatus']))
  else:
    print 'No service links were found.'


if __name__ == '__main__':
  # Initialize client object.
  adwords_client = adwords.AdWordsClient.LoadFromStorage()
  main(adwords_client)

PHP

$customerService =
    $adWordsServices->get($session, CustomerService::class);

// Create a selector to select all service links.
$selector = new Selector();
$selector->setFields(['ServiceType']);
$selector->setPredicates([
    new Predicate('ServiceType', PredicateOperator::EQUALS,
        [ServiceType::MERCHANT_CENTER])
]);

// Get the service links on the server.
$serviceLinks = $customerService->getServiceLinks($selector);

// Print out some information about service links.
if ($serviceLinks !== null) {
  foreach ($serviceLinks as $serviceLink) {
    printf(
        "Found service link with service link ID %d, type %s, name '%s',"
            . " and status %s.\n",
        $serviceLink->getServiceLinkId(),
        $serviceLink->getServiceType(),
        $serviceLink->getName(),
        $serviceLink->getLinkStatus()
    );
  }
} else {
  print "No service links found.\n";
}

Perl

my $client = shift;

# Create a selector that filters by service type.
my $paging = Google::Ads::AdWords::v201710::Paging->new({
  startIndex    => 0,
  numberResults => PAGE_SIZE
});
my $selector = Google::Ads::AdWords::v201710::Selector->new({
    fields     => ["ServiceType"],
    predicates => [
      Google::Ads::AdWords::v201710::Predicate->new({
          field    => "ServiceType",
          operator => "EQUALS",
          values   => ["MERCHANT_CENTER"]})
    ],
    paging => $paging
  });

# Get the service links.
my $service_links =
  $client->CustomerService->getServiceLinks({selector => $selector});

# Display the results.
if ($service_links) {
  foreach my $service_link ($service_links) {
    printf(
      "Found service link with service link ID %d," .
        " type %s, name '%s', and status %s.\n",
      $service_link->get_serviceLinkId(), $service_link->get_serviceType(),
      $service_link->get_name(),          $service_link->get_linkStatus());

  }
} else {
  printf("No service links found.\n");
}

Ruby

# Get the CustomerService.
customer_srv = adwords.service(:CustomerService, API_VERSION)

# Create a selector that filters by service type.
selector = {
  :fields => ['ServiceType'],
  :predicates => [{
    :field => 'ServiceType',
    :operator => 'EQUALS',
    :values => ['MERCHANT_CENTER']
  }]
}

# Get the service links.
service_links = customer_srv.get_service_links(selector)

# Display the results.
if service_links.kind_of?(Array)
  service_links.each do |service_link|
    puts ("Found service link with service link ID %d, type %s, name '%s'," +
        " and status %s.") % [
          service_link[:service_link_id],
          service_link[:service_type],
          service_link[:name],
          service_link[:link_status]
        ]
  end
else
  puts "No service links found."
end

To accept an invitation, call mutateServiceLinks and pass a SET operation that changes the linkStatus from PENDING to ACTIVE. Make sure you set the serviceType and the serviceLinkId on the operand.

Java

// Get the CustomerService.
CustomerServiceInterface customerService =
    adWordsServices.get(session, CustomerServiceInterface.class);

// Create the operation to set the status to ACTIVE.
ServiceLinkOperation op = new ServiceLinkOperation();
op.setOperator(Operator.SET);
ServiceLink serviceLink = new ServiceLink();
serviceLink.setServiceLinkId(serviceLinkId);
serviceLink.setServiceType(ServiceType.MERCHANT_CENTER);
serviceLink.setLinkStatus(ServiceLinkLinkStatus.ACTIVE);
op.setOperand(serviceLink);

// Update the service link.
ServiceLink[] mutatedServiceLinks =
    customerService.mutateServiceLinks(new ServiceLinkOperation[] {op});

// Display the results.
for (ServiceLink mutatedServiceLink : mutatedServiceLinks) {
  System.out.printf(
      "Service link with service link ID %d, type '%s' updated to status: %s.%n",
      mutatedServiceLink.getServiceLinkId(),
      mutatedServiceLink.getServiceType(),
      mutatedServiceLink.getLinkStatus());
}

CSharp

using (CustomerService customerService = (CustomerService) user.GetService(
    AdWordsService.v201710.CustomerService)) {

  // Create the operation to set the status to ACTIVE.
  ServiceLinkOperation op = new ServiceLinkOperation();
  op.@operator = Operator.SET;
  ServiceLink serviceLink = new ServiceLink();
  serviceLink.serviceLinkId = serviceLinkId;
  serviceLink.serviceType = ServiceType.MERCHANT_CENTER;
  serviceLink.linkStatus = ServiceLinkLinkStatus.ACTIVE;
  op.operand = serviceLink;

  try {
    // Update the service link.
    ServiceLink[] mutatedServiceLinks =
        customerService.mutateServiceLinks(new ServiceLinkOperation[] { op });

    // Display the results.
    foreach (ServiceLink mutatedServiceLink in mutatedServiceLinks) {
      Console.WriteLine("Service link with service link ID {0}, type '{1}' updated to " +
          "status: {2}.", mutatedServiceLink.serviceLinkId, mutatedServiceLink.serviceType,
          mutatedServiceLink.linkStatus);
    }

Python

def main(client, service_link_id):
  # Initialize appropriate service.
  customer_service = client.GetService(
      'CustomerService', version='v201710')

  # Create the operation to set the status to ACTIVE.
  operations = [{
      'operator': 'SET',
      'operand': {
          'serviceLinkId': service_link_id,
          'serviceType': 'MERCHANT_CENTER',
          'linkStatus': 'ACTIVE',
      }
  }]

  # Update the service link.
  mutated_service_links = customer_service.mutateServiceLinks(operations)

  # Display results.
  for mutated_service_link in mutated_service_links:
    print ('Service link with service link ID "%s", type "%s" was updated '
           'to status: "%s".' % (mutated_service_link['serviceLinkId'],
                                 mutated_service_link['serviceType'],
                                 mutated_service_link['linkStatus']))

PHP

$customerService = $adWordsServices->get($session, CustomerService::class);

// Create service link.
$serviceLink = new ServiceLink();
$serviceLink->setServiceLinkId($serviceLinkId);
$serviceLink->setServiceType(ServiceType::MERCHANT_CENTER);
$serviceLink->setLinkStatus(ServiceLinkLinkStatus::ACTIVE);

// Create a service link operation and add it to the list.
$operations = [];
$operation = new ServiceLinkOperation();
$operation->setOperator(Operator::SET);
$operation->setOperand($serviceLink);
$operations[] = $operation;

// Accept service links on the server and print out some information about
// accepted service links.
$serviceLinks = $customerService->mutateServiceLinks($operations);
foreach ($serviceLinks as $serviceLink) {
  printf(
      "Service link with service link ID %d and type '%s' updated to status"
          . ": %s.\n",
      $serviceLink->getServiceLinkId(),
      $serviceLink->getServiceType(),
      $serviceLink->getLinkStatus()
  );
}

Perl

my $client          = shift;
my $service_link_id = shift;

my $service_link = Google::Ads::AdWords::v201710::ServiceLink->new({
  serviceLinkId => $service_link_id,
  serviceType   => "MERCHANT_CENTER",
  linkStatus    => "ACTIVE"
});

# Create the operation to set the status to ACTIVE.
my $op = Google::Ads::AdWords::v201710::ServiceLinkOperation->new({
  operator => "SET",
  operand  => $service_link
});

# Update the service link.
my $mutated_service_links =
  $client->CustomerService->mutateServiceLinks({operations => [$op]});

# Display the results.
foreach my $mutated_service_link ($mutated_service_links) {
  printf(
    "Service link with service link ID %d, " .
      "type '%s' updated to status: %s.\n",
    $mutated_service_link->get_serviceLinkId(),
    $mutated_service_link->get_serviceType(),
    $mutated_service_link->get_linkStatus());

}

Ruby

# Get the CustomerService.
customer_srv = adwords.service(:CustomerService, API_VERSION)

# Create the operation to set the status to ACTIVE.
operation = {
  :operator => 'SET',
  :operand => {
    :service_link_id => service_link_id,
    :service_type => 'MERCHANT_CENTER',
    :link_status => 'ACTIVE'
  }
}

# Update the service link.
mutated_service_links = customer_srv.mutate_service_links([operation])

# Display the results.
mutated_service_links.each do |mutated_service_link|
  puts ("Service link with service link ID %d, type '%s' updated to status:" +
      "%s.") % [
        mutated_service_link[:service_link_id],
        mutated_service_link[:service_type],
        mutated_service_link[:link_status]
      ]
end

To reject an invitation, call mutateServiceLinks and pass a REMOVE operation with an operand that has serviceType and serviceLinkId set.

Java

// Get the CustomerService.
CustomerServiceInterface customerService =
    adWordsServices.get(session, CustomerServiceInterface.class);

// Create the operation to remove the service link.
ServiceLinkOperation op = new ServiceLinkOperation();
op.setOperator(Operator.REMOVE);
ServiceLink serviceLink = new ServiceLink();
serviceLink.setServiceLinkId(serviceLinkId);
serviceLink.setServiceType(ServiceType.MERCHANT_CENTER);
op.setOperand(serviceLink);

// Remove the service link.
ServiceLink[] mutatedServiceLinks =
    customerService.mutateServiceLinks(new ServiceLinkOperation[] {op});

// Display the results.
for (ServiceLink mutatedServiceLink : mutatedServiceLinks) {
  System.out.printf(
      "Service link with service link ID %d and type '%s' was removed.%n",
      mutatedServiceLink.getServiceLinkId(), mutatedServiceLink.getServiceType());
}

CSharp

// Get the CustomerService.
CustomerService customerService =
    (CustomerService) user.GetService(AdWordsService.v201710.CustomerService);

// Create the operation to remove the service link.
ServiceLinkOperation op = new ServiceLinkOperation();
op.@operator = Operator.REMOVE;
ServiceLink serviceLink = new ServiceLink();
serviceLink.serviceLinkId = serviceLinkId;
serviceLink.serviceType = ServiceType.MERCHANT_CENTER;
op.operand = serviceLink;

// Remove the service link.
ServiceLink[] mutatedServiceLinks = customerService.mutateServiceLinks(
    new ServiceLinkOperation[] { op });

// Display the results.
foreach (ServiceLink mutatedServiceLink in mutatedServiceLinks) {
  Console.WriteLine("Service link with service link ID {0} and type '{1}' was removed.",
      mutatedServiceLink.serviceLinkId, mutatedServiceLink.serviceType);
}

Python

def main(client, service_link_id):
  # Initialize appropriate service.
  customer_service = client.GetService(
      'CustomerService', version='v201710')

  # Create the operation to set the status to ACTIVE.
  operations = [{
      'operator': 'REMOVE',
      'operand': {
          'serviceLinkId': service_link_id,
          'serviceType': 'MERCHANT_CENTER',
      }
  }]

  # Remove the service link.
  mutated_service_links = customer_service.mutateServiceLinks(operations)

  # Display results.
  for mutated_service_link in mutated_service_links:
    print ('Service link with service link ID \'%s\' and type \'%s\' was '
           'removed.' % (mutated_service_link['serviceLinkId'],
                         mutated_service_link['serviceType']))

PHP

$customerService = $adWordsServices->get($session, CustomerService::class);

// Create service link.
$serviceLink = new ServiceLink();
$serviceLink->setServiceLinkId($serviceLinkId);
$serviceLink->setServiceType(ServiceType::MERCHANT_CENTER);

// Create a service link operation and add it to the list.
$operations = [];
$operation = new ServiceLinkOperation();
$operation->setOperator(Operator::REMOVE);
$operation->setOperand($serviceLink);
$operations[] = $operation;

// Reject service links on the server and print out some information about
// rejected service links.
$serviceLinks = $customerService->mutateServiceLinks($operations);
foreach ($serviceLinks as $serviceLink) {
  printf(
      "Service link with service link ID %d and type '%s' was removed.\n",
      $serviceLink->getServiceLinkId(),
      $serviceLink->getServiceType()
  );
}

Perl

my $client          = shift;
my $service_link_id = shift;

my $service_link = Google::Ads::AdWords::v201710::ServiceLink->new({
  serviceLinkId => $service_link_id,
  serviceType   => "MERCHANT_CENTER"
});

# Create the operation to remove the service link.
my $op = Google::Ads::AdWords::v201710::ServiceLinkOperation->new({
  operator => "REMOVE",
  operand  => $service_link
});

# Remove the service link.
my $mutated_service_links =
  $client->CustomerService->mutateServiceLinks({operations => [$op]});

# Display the results.
foreach my $mutated_service_link ($mutated_service_links) {
  printf(
    "Service link with service link ID %d and type '%s' was removed.\n",
    $mutated_service_link->get_serviceLinkId(),
    $mutated_service_link->get_serviceType());

}

Ruby

# Get the CustomerService.
customer_srv = adwords.service(:CustomerService, API_VERSION)

# Create the operation to remove the service link.
operation = {
  :operator => 'REMOVE',
  :operand => {
    :service_link_id => service_link_id,
    :service_type => 'MERCHANT_CENTER'
  }
}

# Update the service link.
mutated_service_links = customer_srv.mutate_service_links([operation])

# Display the results.
mutated_service_links.each do |mutated_service_link|
  puts "Service link with service link ID %d, type '%s' was removed." % [
    mutated_service_link[:service_link_id],
    mutated_service_link[:service_type]
  ]
end

Creating a Shopping campaign

When creating a Shopping campaign, you set the budgets, bids, and settings. The simplest type of Shopping campaign has one bid for all products.

There are two steps unique to setting up a Shopping campaign:

  1. Setting the campaign's advertisingChannelType to SHOPPING.

  2. Creating a ShoppingSetting and add it to the campaign.

Both steps are shown in the code below.

Java

// Create campaign.
Campaign campaign = new Campaign();
campaign.setName("Shopping campaign #" + System.currentTimeMillis());
// The advertisingChannelType is what makes this a Shopping campaign
campaign.setAdvertisingChannelType(AdvertisingChannelType.SHOPPING);

// 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);

// Set shared budget (required).
Budget budget = new Budget();
budget.setBudgetId(budgetId);
campaign.setBudget(budget);

// Set bidding strategy (required).
BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();
biddingStrategyConfiguration.setBiddingStrategyType(BiddingStrategyType.MANUAL_CPC);
campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

// All Shopping campaigns need a ShoppingSetting.
ShoppingSetting shoppingSetting = new ShoppingSetting();
shoppingSetting.setSalesCountry("US");
shoppingSetting.setCampaignPriority(0);
shoppingSetting.setMerchantId(merchantId);

// Set to 'true' to enable Local Inventory Ads in your campaign.
shoppingSetting.setEnableLocal(true);

campaign.setSettings(new Setting[] {shoppingSetting});

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

// Make the mutate request.
CampaignReturnValue campaignAddResult =
    campaignService.mutate(new CampaignOperation[] {campaignOperation});

// Display result.
campaign = campaignAddResult.getValue(0);

System.out.printf("Campaign with name '%s' and ID %d was added.%n", campaign.getName(),
    campaign.getId());

As shown in the sample above, a ShoppingSetting has the following properties:

merchantId (required)
The Merchant Center Account ID that your products belong to.
salesCountry (required)
Only products with a matching target country in Merchant Center will be selected. Note that this does not affect ads targeting.
campaignPriority (optional, default: 0)
Either 0, 1, or 2. This determines which campaign should take priority when more than one campaign uses the same Merchant Center data feed. The campaign with the higher priority will be selected. If two campaigns have the same priority, then each ad will be covered by the one that sets the highest bid for the product.
enableLocal (optional, default: false)
If set to true, this flag enables local inventory ads in your Shopping campaigns.
purchasePlatform (optional, default: MERCHANT)
Indicates the platform on which a shopping product can be purchased. Available starting with v201705, and only if your Merchant Center account is enabled for Purchases on Google.

Creating a Shopping ad group and ads

In order to serve ads for your Shopping campaign, you must create an AdGroup with at least one ad in the ad group.

Shopping campaigns support two types of ad groups:

  • SHOPPING_PRODUCT_ADS: This is the default ad group type for shopping campaigns, serving standard product ads.
  • SHOPPING_SHOWCASE_ADS: This ad group type is limited to serving Showcase ads in shopping results. To create one, you need to:
    1. Set the adGroupType field of your ad group to SHOPPING_SHOWCASE_ADS.
    2. Set the biddingStrategyType of your ad group's biddingStrategyConfiguration to MANUAL_CPC or ENHANCED_CPC.

Once you create the required type of ad group, complete the basic setup of your campaign by adding a ProductAd or a ShowcaseAd to your ad group.

Next, you need to decide which products to include and how much to bid for them.

Partitioning

The full power of Shopping campaigns comes from dividing your product inventory along multiple dimensions and working with product groups individually. Consider the diagram below, where the products have been broadly divided as Electronics (which is further divided by brand), Toys and "Everything else" (which is further divided by Used status)

You create this structure as a tree. Each level of the tree represents a partition.

Each node in the tree is either a subdivision or a unit. A subdivision introduces a new level in the tree, while units are leaves of the tree. Each subdivision must always be completely partitioned, so it must contain a unit type representing Other. In the example, the root, Category: Electronics and Category: (Other) nodes are subdivisions.

Nodes are objects of the ProductPartition class, a subclass of the Criterion class. ProductPartitions are linked to the AdGroup with either BiddableAdGroupCriterion or NegativeAdGroupCriterion.

The combination of ProductPartition type and AdGroupCriterion type produces the following effects:

ProductPartition Type AdGroupCriterion Type Effect
UNIT BiddableAdGroupCriterion A bid for items matching this leaf of the tree.
UNIT NegativeAdGroupCriterion This combination indicates that you do not wish to bid for this particular leaf in this ad group, but that other ad groups and (lower priority) campaigns may do so.

Other combinations result in an error.

A ProductPartition also has a caseValue which can be any of several subclasses of the ProductDimension type. A ProductDimension represents the values associated with your products, such as brand, category, or condition. A full description of the available ProductDimension types is available in the reference documentation.

Each immediate child of a subdivision must have a caseValue of the same ProductDimension subtype. Only the root node doesn't have a caseValue.

ProductPartition root = new ProductPartition();
root.setPartitionType(ProductPartitionType.SUBDIVISION);
root.setId(-1);

ProductPartition node1 = new ProductPartition();
node1.setPartitionType(ProductPartitionType.UNIT);
node1.setCaseValue(new ProductBrand(null, "Brand A"));
node1.setParentCriterionId(root.getId());

Remember that each subdivision must contain an "empty" caseValue of the correct type, representing "all other values".

ProductPartition node2 = new ProductPartition();
node2.setPartitionType(ProductPartitionType.UNIT);
node2.setCaseValue(new ProductBrand());
node2.setParentCriterionId(root.getId());

Temporary IDs

Criteria are not assigned IDs until the mutate request that creates them is processed by the server. However, a ProductPartition is invalid until it is complete, so whenever you create a subdivision you must also create at least one of its children in the same operation.

To allow you to set the parentCriterionId for the child nodes, you can use temporary criterion IDs. These are locally unique (rather than globally unique) identifiers that apply only within the context of a single mutate request. Any negative integer can be used as a temporary ID. In the sample code above, the ID of the root ProductPartition is set to -1.

When the request is processed, each Criterion is assigned a positive global ID as usual.

Product dimensions

The following ProductDimension types are available for Shopping campaigns:

ProductBiddingCategory, ProductCustomAttribute, and ProductType are further split into subtypes. When subdividing by one of these types, each caseValue for that subdivision must also be of the same subtype.

ProductBiddingCategory and ProductType are hierarchical, with the subtypes representing depth within the hierarchy. The category Media is a BIDDING_CATEGORY_L1 while Books is a BIDDING_CATEGORY_L2 and has Media as its parent. You cannot subdivide by a caseValue unless the parent has already been subdivided further up the tree.

For example, you cannot have the Books category as a node directly under the root, nor can Books be directly under Electronics, since Electronics is not the parent of Books.

ProductCustomAttribute is not hierarchical. Instead, the subtypes CUSTOM_ATTRIBUTE_0 through CUSTOM_ATTRIBUTE_4 map to the values custom attribute 0 to custom attribute 4 in Merchant Center.

You can specify local, online, or both channels through the product dimensions ProductChannel and ProductChannelExclusivity.

Bidding categories

The values for the ProductBiddingCategory type are fixed IDs. You can retrieve the full set of bidding categories from the ConstantDataService method getProductBiddingCategoryData. We highly recommended that you cache the results of this call as the data set is large and changes infrequently.

Modifying existing ProductPartition trees

The tree must always remain complete, so any mutate operation that would make a tree invalid must be part of the same request as an operation that fixes it again. To be valid, all child nodes of a subdivision must have a caseValue of the same type, and every subdivision must contain an "other" node.

If you wish to further subdivide a leaf node you must remove the existing unit and replace it with a subdivision with the same caseValue. You can then add your refinements as children of the new node.

Removing a subdivision causes all of its children to be recursively removed too.

Filter by product dimensions

You can add a ProductScope criterion to filter the products in a campaign. You can create at most one ProductScope per campaign. A ProductScope is a container for one or more ProductDimensions that represent a simple filter on one aspect of a product. For example, if you add a ProductBrand subtype of ProductDimension and set its value to Nexus, the campaign will apply only to products that have "Nexus" set as the brand in Merchant Center.

ProductScope productScope = new ProductScope();
productScope.setDimensions(new ProductDimension[] {new ProductBrand(null, "Nexus")});

You can add up to seven ProductDimensions to a ProductScope. Products must match all of the given ProductDimensions to be included in the campaign.

Bidding restrictions

The bidding restrictions on a shopping ad group varies based on whether its type is SHOPPING_PRODUCT_ADS or SHOPPING_SHOWCASE_ADS. The following table summarizes the differences.

  SHOPPING_PRODUCT_ADS SHOPPING_SHOWCASE_ADS
Bidding Strategy Only the following types are supported:
  • MANUAL_CPC
  • ENHANCED_CPC
  • TARGET_ROAS
  • TARGET_SPEND
Only the following types are supported:
  • MANUAL_CPC
  • ENHANCED_CPC
Bidding strategy at ad group level Optional Required
Bids at product partition node level Required Not allowed

Reporting

Shopping campaigns introduce two new reports, a Product Partition report and a Shopping Performance report.

See the Reporting guide for more information.

Enviar comentarios sobre…

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