Mobile App Campaigns

This guide describes how to create, configure, and monitor performance of the following mobile app campaign types:

Universal App Campaigns

A Universal app campaign (UAC) is a campaign that allows you to easily promote your Android or iOS apps across Google's top properties including Search, Play, YouTube, and the Google Display Network. This guide shows how to create one, set targeting, and run reports.

Constructing a campaign

1. Create a budget

To create a universal app campaign, start by creating a budget. Universal app campaigns don't support shared budgets, so you need to set the budget's isExplicitlyShared property to false.

Java

// Get the BudgetService.
BudgetServiceInterface budgetService =
    adWordsServices.get(session, BudgetServiceInterface.class);

// Create the campaign budget.
Budget budget = new Budget();
budget.setName("Interplanetary Cruise App Budget #" + System.currentTimeMillis());
Money budgetAmount = new Money();
budgetAmount.setMicroAmount(50000000L);
budget.setAmount(budgetAmount);
budget.setDeliveryMethod(BudgetBudgetDeliveryMethod.STANDARD);

// Universal app campaigns don't support shared budgets.
budget.setIsExplicitlyShared(false);
BudgetOperation budgetOperation = new BudgetOperation();
budgetOperation.setOperand(budget);
budgetOperation.setOperator(Operator.ADD);

// Add the budget
Budget addedBudget = budgetService.mutate(new BudgetOperation[] {budgetOperation}).getValue(0);
    

C#

// Get the BudgetService.
BudgetService budgetService =
  (BudgetService) user.GetService(AdWordsService.v201702.BudgetService);

// Create the campaign budget.
Budget budget = new Budget();
budget.name = "Interplanetary Cruise App Budget #" + ExampleUtilities.GetRandomString();
budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD;
budget.amount = new Money();
budget.amount.microAmount = 5000000;

// Universal app campaigns don't support shared budgets.
budget.isExplicitlyShared = false;

BudgetOperation budgetOperation = new BudgetOperation();
budgetOperation.@operator = Operator.ADD;
budgetOperation.operand = budget;

BudgetReturnValue budgetRetval = budgetService.mutate(
  new BudgetOperation[] { budgetOperation });
    

Python

budget_service = client.GetService('BudgetService', version='v201609')

# Create a budget.
budget = {
    'name': 'Interplanetary Cruise App Budget #%s' % uuid.uuid4(),
    'amount': {
        'microAmount': '50000000'
    },
    'deliveryMethod': 'STANDARD',
    'isExplicitlyShared': False
}

budget_operations = [{
    'operator': 'ADD',
    'operand': budget
}]

# Create the budget and return its ID.
budget_id = budget_service.mutate(budget_operations)['value'][0]['budgetId']
    

PHP

$budgetService = $adWordsServices->get($session, BudgetService::class);

// Create the shared budget (required).
$budget = new Budget();
$budget->setName('Interplanetary Cruise Budget #' . uniqid());
$money = new Money();
$money->setMicroAmount(50000000);
$budget->setAmount($money);
$budget->setDeliveryMethod(BudgetBudgetDeliveryMethod::STANDARD);

// Universal App campaigns don't support shared budgets.
$budget->setIsExplicitlyShared(false);
$operations = [];

// Create a budget operation.
$operation = new BudgetOperation();
$operation->setOperand($budget);
$operation->setOperator(Operator::ADD);
$operations[] = $operation;

// Create the budget on the server.
$result = $budgetService->mutate($operations);
$budget = $result->getValue()[0];

printf("Budget with name '%s' and ID %d was created.\n",
    $budget->getName(), $budget->getBudgetId());
    

Perl

# Create the campaign budget.
my $budget = Google::Ads::AdWords::v201702::Budget->new({
  # Required attributes.
  name => "Interplanetary Cruise App Budget #" . uniqid(),
  amount =>
    Google::Ads::AdWords::v201702::Money->new({microAmount => 5000000}),
  deliveryMethod => "STANDARD",
  # Universal app campaigns don't support shared budgets.
  isExplicitlyShared => 0
});

my $budget_operation = Google::Ads::AdWords::v201702::BudgetOperation->new({
  operator => "ADD",
  operand  => $budget
});

# Add budget.
my $addedBudget =
  $client->BudgetService()->mutate({operations => ($budget_operation)})
  ->get_value();
printf
  "Budget with name '%s' and ID %d was created.\n",
  $addedBudget->get_name(), $addedBudget->get_budgetId()->get_value();
    

Ruby

# Create a budget.
budget = {
  :name => 'Interplanetary budget #%d' % (Time.new.to_f * 1000).to_i,
  :amount => {:micro_amount => 50000000},
  :delivery_method => 'STANDARD',
  # Universal app campaigns don't support shared budgets.
  :is_explicitly_shared => false
}
budget_operation = {:operator => 'ADD', :operand => budget}

# Add the budget.
return_budget = budget_srv.mutate([budget_operation])
budget_id = return_budget[:value].first[:budget_id]
    

See our Campaign Budgets guide for more details.

2. Create the campaign

Next, create your campaign. You need to keep the following restrictions in mind when creating a universal app campaign:

  1. The campaign's advertisingChannelType must be set to MULTI_CHANNEL and advertisingChannelSubType to UNIVERSAL_APP_CAMPAIGN.
  2. Only the TARGET_CPA bidding strategy type is supported.
  3. Many of the settings in normal campaigns like networkSetting, frequencyCap and trackingUrlTemplate cannot be set for universal app campaigns. See the reference docs for a full list of settings that cannot be set.

Java

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

// Create the campaign.
Campaign campaign = new Campaign();
campaign.setName("Interplanetary Cruise App #" + System.currentTimeMillis());

// 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 the advertising channel and subchannel types for universal app campaigns.
campaign.setAdvertisingChannelType(AdvertisingChannelType.MULTI_CHANNEL);
campaign.setAdvertisingChannelSubType(AdvertisingChannelSubType.UNIVERSAL_APP_CAMPAIGN);

// Set the campaign's bidding strategy. universal app campaigns
// only support TARGET_CPA bidding strategy.
BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
biddingConfig.setBiddingStrategyType(BiddingStrategyType.TARGET_CPA);

// Set the target CPA to $1 / app install.
TargetCpaBiddingScheme biddingScheme = new TargetCpaBiddingScheme();
biddingScheme.setTargetCpa(new Money());
biddingScheme.getTargetCpa().setMicroAmount(1000000L);

biddingConfig.setBiddingScheme(biddingScheme);
campaign.setBiddingStrategyConfiguration(biddingConfig);

// Set the campaign's budget.
campaign.setBudget(new Budget());
campaign.getBudget().setBudgetId(createBudget(adWordsServices, session));

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

C#

// Get the CampaignService.
CampaignService campaignService =
  (CampaignService) user.GetService(AdWordsService.v201702.CampaignService);

// Create the campaign.
Campaign campaign = new Campaign();
campaign.name = "Interplanetary Cruise App #" + ExampleUtilities.GetRandomString();

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

// Set the advertising channel and subchannel types for universal app campaigns.
campaign.advertisingChannelType = AdvertisingChannelType.MULTI_CHANNEL;
campaign.advertisingChannelSubType = AdvertisingChannelSubType.UNIVERSAL_APP_CAMPAIGN;

// Set the campaign's bidding strategy. Universal app campaigns
// only support TARGET_CPA bidding strategy.
BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
biddingConfig.biddingStrategyType = BiddingStrategyType.TARGET_CPA;

// Set the target CPA to $1 / app install.
TargetCpaBiddingScheme biddingScheme = new TargetCpaBiddingScheme();
biddingScheme.targetCpa = new Money();
biddingScheme.targetCpa.microAmount = 1000000;

biddingConfig.biddingScheme = biddingScheme;
campaign.biddingStrategyConfiguration = biddingConfig;

// Set the campaign's budget.
campaign.budget = new Budget();
campaign.budget.budgetId = CreateBudget(user).budgetId;

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

Python

# Initialize appropriate services.
campaign_service = client.GetService('CampaignService', version='v201609')

budget_id = CreateBudget(client)

# Create the Universal App campaign.
universal_app_campaign = {
    'name': 'Interplanetary Cruise App #%s' % uuid.uuid4(),
    # 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',
    'advertisingChannelType': 'MULTI_CHANNEL',
    'advertisingChannelSubType': 'UNIVERSAL_APP_CAMPAIGN',
    # Set the campaign's bidding strategy. Universal app campaigns only
    # support TARGET_CPA bidding strategy.
    'biddingStrategyConfiguration': {
         # Set the target CPA to $1 / app install.
        'biddingScheme': {
            'xsi_type': 'TargetCpaBiddingScheme',
            'targetCpa': {
                'microAmount': '1000000'
            }
        },
        'biddingStrategyType': 'TARGET_CPA'
    },
    # Note that only the budgetId is required
    'budget': {
        'budgetId': budget_id
    },
    # Optional fields
    'startDate': (datetime.datetime.now() +
                  datetime.timedelta(1)).strftime('%Y%m%d'),
    'endDate': (datetime.datetime.now() +
                datetime.timedelta(365)).strftime('%Y%m%d'),
}
    

PHP

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

// Create campaign with some properties set.
$campaign = new Campaign();
$campaign->setName('Interplanetary Cruise #' . uniqid());
// 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.
$campaign->setStatus(CampaignStatus::PAUSED);

// Set the advertising channel and subchannel types for Universal app
// campaigns.
$campaign->setAdvertisingChannelType(AdvertisingChannelType::MULTI_CHANNEL);
$campaign->setAdvertisingChannelSubType(
    AdvertisingChannelSubType::UNIVERSAL_APP_CAMPAIGN);

// Set the campaign's bidding strategy. Universal App campaigns
// only support TARGET_CPA bidding strategy.
$biddingStrategyConfiguration = new BiddingStrategyConfiguration();
$biddingStrategyConfiguration->setBiddingStrategyType(
    BiddingStrategyType::TARGET_CPA);

// Set the target CPA to $1 / app install.
$biddingScheme = new TargetCpaBiddingScheme();
$money = new Money();
$money->setMicroAmount(1000000);
$biddingScheme->setTargetCpa($money);

$biddingStrategyConfiguration->setBiddingScheme($biddingScheme);
$campaign->setBiddingStrategyConfiguration($biddingStrategyConfiguration);

// Set shared budget (required).
$campaign->setBudget(new Budget());
$campaign->getBudget()->setBudgetId(
    self::createBudget($adWordsServices, $session));

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

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

Perl

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 $budgetId = create_budget($client);

my $campaign = Google::Ads::AdWords::v201702::Campaign->new({
    name => "Interplanetary Cruise App #" . uniqid(),
    # Bidding strategy (required).
    # Set the campaign's bidding strategy. Universal app campaigns
    # only support TARGET_CPA bidding strategy.
    biddingStrategyConfiguration =>
      Google::Ads::AdWords::v201702::BiddingStrategyConfiguration->new({
        biddingStrategyType => "TARGET_CPA",
        # Set the target CPA to $1 / app install.
        biddingScheme =>
          Google::Ads::AdWords::v201702::TargetCpaBiddingScheme->new({
            targetCpa => Google::Ads::AdWords::v201702::Money->new(
              {microAmount => 1000000})})}
      ),
    # Budget (required) - note only the budgetId is required.
    budget =>
      Google::Ads::AdWords::v201702::Budget->new({budgetId => $budgetId}),
    # Advertising channel type (required).
    # Set the advertising channel and subchannel types for universal
    # app campaigns.
    advertisingChannelType    => "MULTI_CHANNEL",
    advertisingChannelSubType => "UNIVERSAL_APP_CAMPAIGN",
    settings                  => [$universalAppSetting, $geoSetting],
    # 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"
  });
    

Ruby

campaign_srv = adwords.service(:CampaignService, API_VERSION)
budget_srv = adwords.service(:BudgetService, API_VERSION)

# Create a budget.
budget = {
  :name => 'Interplanetary budget #%d' % (Time.new.to_f * 1000).to_i,
  :amount => {:micro_amount => 50000000},
  :delivery_method => 'STANDARD',
  # Universal app campaigns don't support shared budgets.
  :is_explicitly_shared => false
}
budget_operation = {:operator => 'ADD', :operand => budget}

# Add the budget.
return_budget = budget_srv.mutate([budget_operation])
budget_id = return_budget[:value].first[:budget_id]

# Create campaigns.
universal_app_campaign = {
  :name => "Interplanetary Cruise #%d" % (Time.new.to_f * 1000).to_i,
  # Recommendation: Set the campaign to PAUSED when creating it to stop the
  # ads from immediately serving. Set it to ENABLED once you've added
  # targeting and the ads are ready to serve.
  :status => 'PAUSED',
  # Set the advertising channel and subchannel types for universal app
  # campaigns.
  :advertising_channel_type => 'MULTI_CHANNEL',
  :advertising_channel_sub_type => 'UNIVERSAL_APP_CAMPAIGN',
  # Set the campaign's bidding strategy. Universal app campaigns only support
  # the TARGET_CPA bidding strategy.
  :bidding_strategy_configuration => {
    :bidding_scheme => {
      :xsi_type => 'TargetCpaBiddingScheme',
      :target_cpa => {
        :micro_amount => 1000000
      }
    }
  },
  # Budget (required) - note only the budget ID is required.
  :budget => {:budget_id => budget_id},
  # Optional fields:
  :start_date =>
      DateTime.parse((Date.today + 1).to_s).strftime('%Y%m%d'),
  :end_date =>
      DateTime.parse((Date.today + 365).to_s).strftime('%Y%m%d')
}
    

3. Customize your ads

Unlike other campaign types, universal app campaigns don't allow users to create ads. Instead, ads are generated across several formats and networks based on your app's store listing, additional text ideas, and assets you specify in the campaign's settings. The following snippet shows how to set your campaign's assets.

Java

// Set the campaign's assets and ad text ideas. These values will be used to
// generate ads.
UniversalAppCampaignSetting universalAppSetting = new UniversalAppCampaignSetting();
universalAppSetting.setAppId("com.labpixies.colordrips");
universalAppSetting.setDescription1("A cool puzzle game");
universalAppSetting.setDescription2("Remove connected blocks");
universalAppSetting.setDescription3("3 difficulty levels");
universalAppSetting.setDescription4("4 colorful fun skins");

// Optional: You can set up to 10 image assets for your campaign.
// See UploadImage.java for an example on how to upload images.
//
// universalAppSetting.setImageMediaIds(new long[] { INSERT_IMAGE_MEDIA_ID_HERE });
    

C#

// Set the campaign's assets and ad text ideas. These values will be used to
// generate ads.
UniversalAppCampaignSetting universalAppSetting = new UniversalAppCampaignSetting();
universalAppSetting.appId = "com.labpixies.colordrips";
universalAppSetting.description1 = "A cool puzzle game";
universalAppSetting.description2 = "Remove connected blocks";
universalAppSetting.description3 = "3 difficulty levels";
universalAppSetting.description4 = "4 colorful fun skins";

// Optional: You can set up to 10 image assets for your campaign.
// See UploadImage.cs for an example on how to upload images.
//
// universalAppSetting.imageMediaIds = new long[] { INSERT_IMAGE_MEDIA_ID_HERE };
    

Python

universal_app_campaign['settings'] = [
    # Set the campaign's assets and ad text ideas. These values will
    # be used to generate ads.
    {
        'xsi_type': 'UniversalAppCampaignSetting',
        'appId': 'com.interplanetarycruise.booking',
        'description1': 'Best Space Cruise Line',
        'description2': 'Visit all the planets',
        'description3': 'Trips 7 days a week',
        'description4': 'Buy your tickets now!',
        # Optional: You can set up to 10 image assets for your campaign.
        # See upload_image.py for an example on how to upload images.
        #
        # 'imageMediaIds': [INSERT_IMAGE_MEDIA_ID(s)_HERE]
    }
]
    

PHP

// Set the campaign's assets and ad text ideas. These values will be used to
// generate ads.
$universalAppSetting = new UniversalAppCampaignSetting();
$universalAppSetting->setAppId('com.labpixies.colordrips');
$universalAppSetting->setDescription1('A cool puzzle game');
$universalAppSetting->setDescription2('Remove connected blocks');
$universalAppSetting->setDescription3('3 difficulty levels');
$universalAppSetting->setDescription4('4 colorful fun skins');

// Optional: You can set up to 10 image assets for your campaign.
// See UploadImage.php for an example on how to upload images.
//
// $universalAppSetting->imageMediaIds = array(INSERT_IMAGE_MEDIA_ID_HERE);
    

Perl

# Set the campaign's assets and ad text ideas. These values will be used to
# generate ads.
my $universalAppSetting =
  Google::Ads::AdWords::v201702::UniversalAppCampaignSetting->new({
    appId        => "com.labpixies.colordrips",
    description1 => "A cool puzzle game",
    description2 => "Remove connected blocks",
    description3 => "3 difficulty levels",
    description4 => "4 colorful fun skins"
  });

# Optional: You can set up to 10 image assets for your campaign.
# See upload_image.pl for an example on how to upload images.
# universalAppSetting->set_imageMediaIds([INSERT_IMAGE_MEDIA_ID_HERE]);
    

Ruby

universal_app_setting = {
  # Set the campaign's assets and ad text ideas. These values will be used to
  # generate ads.
  :xsi_type => 'UniversalAppCampaignSetting',
  :app_id => 'com.labpixies.colordrips',
  :description1 => 'A cool puzzle game',
  :description2 => 'Remove connected blocks',
  :description3 => '3 difficulty levels',
  :description4 => '4 colorful fun skins'
  # Optional: You can set up to 10 image assets for your campaign. See
  # upload_image.rb for an example on how to upload images.
  #
  # :image_media_ids => [INSERT_IMGAGE_MEDIA_ID(s)_HERE]
}
    

4. Optimize your campaign

You can optimize your campaign using two settings:

  • universalAppBiddingStrategyGoalType allows you to specify a goal type when optimizing the campaign's bidding strategy.

  • When you select your bidding strategy goal type as OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME, you can also optimize for a set of in-app conversion types using the campaign's selectiveOptimization field . You can use the ConversionTrackerService to retrieve the list of all the conversion trackers.

Java

// Optimize this campaign for getting new users for your app.
universalAppSetting.setUniversalAppBiddingStrategyGoalType(
    UniversalAppBiddingStrategyGoalType.OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME);

// If you select the OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME goal type, then also specify
// your in-app conversion types so AdWords can focus your campaign on people who are
// most likely to complete the corresponding in-app actions.
// Conversion type IDs can be retrieved using ConversionTrackerService.get.
//
// campaign.selectiveOptimization = new SelectiveOptimization();
// campaign.selectiveOptimization.conversionTypeIds =
//    new long[] { INSERT_CONVERSION_TYPE_ID_1_HERE, INSERT_CONVERSION_TYPE_ID_2_HERE };

// Optional: Set the campaign settings for Advanced location options.
GeoTargetTypeSetting geoSetting = new GeoTargetTypeSetting();
geoSetting.setPositiveGeoTargetType(
    GeoTargetTypeSettingPositiveGeoTargetType.LOCATION_OF_PRESENCE);
geoSetting.setNegativeGeoTargetType(GeoTargetTypeSettingNegativeGeoTargetType.DONT_CARE);

campaign.setSettings(new Setting[] {universalAppSetting, geoSetting});
    

C#

// Optimize this campaign for getting new users for your app.
universalAppSetting.universalAppBiddingStrategyGoalType =
    UniversalAppBiddingStrategyGoalType.OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME;

// Optional: If you select the OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME goal
// type, then also specify your in-app conversion types so AdWords can
// focus your campaign on people who are most likely to complete the
// corresponding in-app actions.
// Conversion type IDs can be retrieved using ConversionTrackerService.get.
//
// campaign.selectiveOptimization = new SelectiveOptimization();
// campaign.selectiveOptimization.conversionTypeIds =
//    new long[] { INSERT_CONVERSION_TYPE_ID_1_HERE, INSERT_CONVERSION_TYPE_ID_2_HERE };

// Optional: Set the campaign settings for Advanced location options.
GeoTargetTypeSetting geoSetting = new GeoTargetTypeSetting();
geoSetting.positiveGeoTargetType =
    GeoTargetTypeSettingPositiveGeoTargetType.LOCATION_OF_PRESENCE;
geoSetting.negativeGeoTargetType =
    GeoTargetTypeSettingNegativeGeoTargetType.DONT_CARE;

campaign.settings = new Setting[] { universalAppSetting, geoSetting };
    

Python

# Optimize this campaign for getting new users for your app.
universal_app_campaign_setting = universal_app_campaign['settings'][0]
universal_app_campaign_setting['universalAppBiddingStrategyGoalType'] = (
    'OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME')

# Optional: If you select the OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME goal type,
# then also specify your in-app conversion types so AdWords can focus your
# campaign on people who are most likely to complete the corresponding in-app
# actions.
#
# Conversions type IDs can be retrieved using ConversionTrackerService.get.
# universal_app_campaign['selectiveOptimization'] = {
#     'conversionTypeIds': [INSERT_CONVERSION_TYPE_ID(s)_HERE]
# }

# Optional: Set the campaign settings for Advanced location options.
universal_app_campaign['settings'].append({
    'xsi_type': 'GeoTargetTypeSetting',
    'positiveGeoTargetType': 'DONT_CARE',
    'negativeGeoTargetType': 'DONT_CARE'
})
    

PHP

// Optimize this campaign for getting new users for your app.
$universalAppSetting->setUniversalAppBiddingStrategyGoalType(
    UniversalAppBiddingStrategyGoalType
        ::OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME);

// If you select bidding strategy goal type as
// OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME, then you may specify a set of
// conversion types for in-app actions to optimize the campaign towards.
// Conversion type IDs can be retrieved using ConversionTrackerService.get.
//
// $campaign->selectiveOptimization = new SelectiveOptimization();
// $campaign->selectiveOptimization->conversionTypeIds = array(
//     INSERT_CONVERSION_TYPE_ID_1_HERE,
//     INSERT_CONVERSION_TYPE_ID_2_HERE
// );

// Optional: Set the campaign settings for Advanced location options.
$geoTargetTypeSetting = new GeoTargetTypeSetting();
$geoTargetTypeSetting->setNegativeGeoTargetType(
    GeoTargetTypeSettingNegativeGeoTargetType::LOCATION_OF_PRESENCE);
$campaign->setSettings([$universalAppSetting, $geoTargetTypeSetting]);
    

Perl

# Optimize this campaign for getting new users for your app.
$universalAppSetting->set_universalAppBiddingStrategyGoalType(
  "OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME");

# If you select the OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME goal type, then also
# specify your in-app conversion types so AdWords can focus your campaign on
# people who are most likely to complete the corresponding in-app actions.
# Conversion type IDs can be retrieved using ConversionTrackerService.get.

# my $selectiveOptimization =
# Google::Ads::AdWords::v201702::SelectiveOptimization->new({
#  conversionTypeIds =>
#    [INSERT_CONVERSION_TYPE_ID_1_HERE, INSERT_CONVERSION_TYPE_ID_2_HERE]
# });
# $campaign->set_selectiveOptimization($selectiveOptimization);

# Optional: Set the campaign settings for advanced location options.
my $geoSetting = Google::Ads::AdWords::v201702::GeoTargetTypeSetting->new({
  positiveGeoTargetType => "LOCATION_OF_PRESENCE",
  negativeGeoTargetType => "DONT_CARE"
});
    

Ruby

# Optimize this campaign for getting new users for your app.
universal_app_setting[:universal_app_bidding_strategy_goal_type] =
    'OPTIMIZE_FOR_INSTALL_CONVERSION_VOLUME'

# Optional: If you select OPTIMIZE_FOR_IN_APP_CONVERSION_VOLUME goal type,
# then also specify your in-app conversion types so AdWords can focus your
# campaign on people who are most likely to complete the corresponding in-app
# actions.
# Conversion type IDs can be retrieved using ConversionTrackerService.get.
#
# universal_app_campaign[:selective_optimization] = {
#   :conversion_type_ids => [INSERT_CONVERSION_TYPE_ID(s)_HERE]
# }

# Optional: Set the campaign settings for Advanced location options.
geo_setting = {
  :xsi_type => 'GeoTargetTypeSetting',
  :positive_geo_target_type => 'DONT_CARE',
  :negative_geo_target_type => 'DONT_CARE'
}

universal_app_campaign[:settings] = [
  universal_app_setting,
  geo_setting
]
    

Finally, create your campaign using the CampaignService.mutate method:

Java

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

CampaignOperation[] operations = new CampaignOperation[] {operation};

// Add the campaign.
CampaignReturnValue result = campaignService.mutate(operations);

// Display the results.
for (Campaign newCampaign : result.getValue()) {
  System.out.printf(
      "Universal app campaign with name '%s' and ID %d was added.%n",
      newCampaign.getName(), newCampaign.getId());

  // Optional: Set the campaign's location and language targeting. No other targeting
  // criteria can be used for universal app campaigns.
  setCampaignTargetingCriteria(newCampaign, adWordsServices, session);
}
    

C#

// 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.
  if (retVal != null && retVal.value != null && retVal.value.Length > 0) {
    foreach (Campaign newCampaign in retVal.value) {
      Console.WriteLine("Universal app campaign with name = '{0}' and id = '{1}' was added.",
          newCampaign.name, newCampaign.id);

      // Optional: Set the campaign's location and language targeting. No other targeting
      // criteria can be used for universal app campaigns.
      SetCampaignTargetingCriteria(user, newCampaign);
    }
  } else {
    Console.WriteLine("No universal app campaigns were added.");
  }
} catch (Exception e) {
  throw new System.ApplicationException("Failed to add universal app campaigns.", e);
}
    

Python

# Construct operations and add campaigns.
operations = [{
    'operator': 'ADD',
    'operand': universal_app_campaign
}]

campaigns = campaign_service.mutate(operations)['value']
    

PHP

// Create a campaign operation and add it to the operations list.
$operations = [];
$operation = new CampaignOperation();
$operation->setOperand($campaign);
$operation->setOperator(Operator::ADD);
$operations[] = $operation;

// Create the campaign on the server and print out some information for the
// campaign.
$result = $campaignService->mutate($operations);
foreach ($result->getValue() as $campaign) {
  printf("Universal App Campaign with name '%s' and ID %d was added.\n",
      $campaign->getName(), $campaign->getId());
  // Optional: Set the campaign's location and language targeting. No other
  // targeting criteria can be used for Universal App campaigns.
  self::setCampaignTargetingCriteria(
      $campaign->getId(), $adWordsServices, $session);
}
    

Perl

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

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

# Display campaigns.
foreach my $new_campaign (@{$result->get_value()}) {
  printf "Universal app campaign with name \"%s\" and ID %s was added.\n",
    $new_campaign->get_name(), $new_campaign->get_id();
  # Optional: Set the campaign's location and language targeting. No other
  # targeting criteria can be used for universal app campaigns.
  set_campaign_targeting_criteria($client, $new_campaign->get_id());
}
    

Ruby

  # Construct the operation and add the campaign.
  operations = [{
    :operator => 'ADD',
    :operand => universal_app_campaign
  }]

  campaigns = campaign_srv.mutate(operations)[:value]

  if campaigns
    campaigns.each do |campaign|
      puts "Universal app campaign with name '%s' and ID %d was added." %
          [campaign[:name], campaign[:id]]
      set_campaign_targeting_criteria(adwords, campaign)
    end
  else
    raise new StandardError, 'No universal app campaigns were added.'
  end
end

def set_campaign_targeting_criteria(adwords, campaign)
  campaign_criterion_service =
      adwords.service(:CampaignCriterionService, API_VERSION)

  criteria = [
    {
      :xsi_type => 'Location',
      :id => 21137 # California
    },
    {
      :xsi_type => 'Location',
      :id => 2484 # Mexico
    },
    {
      :xsi_type => 'Language',
      :id => 1000 # English
    },
    {
      :xsi_type => 'Language',
      :id => 1003 # Spanish
    }
  ]

  operations = criteria.map do |criterion|
    {
      :operator => 'ADD',
      :operand => {
        :campaign_id => campaign[:id],
        :criterion => criterion
      }
    }
  end

  response = campaign_criterion_service.mutate(operations)

  if response and response[:value]
    # Display the added campaign targets.
    response[:value].each do |criterion|
      puts 'Campaign criteria of type "%s" and id %d was added.' % [
          criterion[:criterion][:criterion_type],
          criterion[:criterion][:id]
      ]
    end
  end
end

if __FILE__ == $0
  API_VERSION = :v201702

  begin
    add_universal_app_campaigns()

  # Authorization error.
  rescue AdsCommon::Errors::OAuth2VerificationRequired => e
    puts "Authorization credentials are not valid. Edit adwords_api.yml for " +
        "OAuth2 client ID and secret and run misc/setup_oauth2.rb example " +
        "to retrieve and store OAuth2 tokens."
    puts "See this wiki page for more details:\n\n  " +
        'https://github.com/googleads/google-api-ads-ruby/wiki/OAuth2'

  # HTTP errors.
  rescue AdsCommon::Errors::HttpError => e
    puts "HTTP Error: %s" % e

  # API errors.
  rescue AdwordsApi::Errors::ApiException => e
    puts "Message: %s" % e.message
    puts 'Errors:'
    e.errors.each_with_index do |error, index|
      puts "\tError [%d]:" % (index + 1)
      error.each do |field, value|
        puts "\t\t%s: %s" % [field, value]
      end
    end
  end
end

    

Uploading media

You can specify up to 10 image assets for a universal app campaign. These assets will be used by AdWords to create ads. You can use the MediaService.upload method to upload images.

Java

MediaServiceInterface mediaService =
    adWordsServices.get(session, MediaServiceInterface.class);

// Create image.
Image image = new Image();
image.setData(
    com.google.api.ads.common.lib.utils.Media.getMediaDataFromUrl("http://goo.gl/HJM3L"));
image.setType(MediaMediaType.IMAGE);

Media[] media = new Media[] {image};

// Upload image.
Media[] result = mediaService.upload(media);
    

C#

MediaService mediaService = (MediaService) user.GetService(
    AdWordsService.v201702.MediaService);

// Create the image.
Image image = new Image();
image.data = MediaUtilities.GetAssetDataFromUrl("http://goo.gl/HJM3L");
image.type = MediaMediaType.IMAGE;

try {
  // Upload the image.
  Media[] result = mediaService.upload(new Media[] {image});
    

Python

media_service = client.GetService('MediaService', version='v201609')

with open(image_filename, 'rb') as image_handle:
  image_data = base64.encodestring(image_handle.read()).decode('utf-8')

# Construct media and upload image.
media = [{
    'xsi_type': 'Image',
    'data': image_data,
    'type': 'IMAGE'
}]
media = media_service.upload(media)[0]
    

PHP

$mediaService =
    $adWordsServices->get($session, MediaService::class);

// Create an image and add it to the images list.
$image = new Image();
$image->setData(file_get_contents('http://goo.gl/HJM3L'));
$image->setType(MediaMediaType::IMAGE);
$images = [$image];

// Upload the image to the server.
$result = $mediaService->upload($images);
    

Perl

# Create image.
my $image_data = Google::Ads::Common::MediaUtils::get_base64_data_from_url(
  "http://goo.gl/HJM3L");
my $image = Google::Ads::AdWords::v201702::Image->new({
    data => $image_data,
    type => "IMAGE"
  }
);

# Upload image.
$image = $client->MediaService()->upload({media => [$image]});
    

Ruby

media_srv = adwords.service(:MediaService, API_VERSION)

# Create image.
image_url =
    'http://www.google.com/intl/en/adwords/select/images/samples/inline.jpg'
# This utility method retrieves the contents of a URL using all of the config
# options provided to the Api object.
image_data = AdsCommon::Http.get(image_url, adwords.config)
base64_image_data = Base64.encode64(image_data)
image = {
  # The 'xsi_type' field allows you to specify the xsi:type of the object
  # being created. It's only necessary when you must provide an explicit
  # type that the client library can't infer.
  :xsi_type => 'Image',
  :data => base64_image_data,
  :type => 'IMAGE'
}

# Upload image.
response = media_srv.upload([image])
    

Working with ListOperations

Universal App campaigns use ListOperations to set list fields such as imageMediaIds. ListOperations describes the behavior of elements in a list, and will always be defined alongside some list in an API object (for example, imageMediaIdsOps describes how to update imageMediaIds). The number of operators in the ListOperations must be equal to the number of elements in the corresponding list. Each operator, together with its corresponding list element, describes an intended change.

Assume that imageMediaIds contained the initial values [1000, 1001, 1002]. The table below shows a mutate call to update imageMediaIds using ListOperations.

Item index Image Media ID ListOperation Meaning
0 1003 PUT Item ID `1003` is being added since it was missing from the original list.
1 1002 REMOVE Item ID `1002` is being removed.

imageMediaIds will contain values [1000, 1001, 1003] after the mutate call.

Targeting

Universal app campaigns support only two forms of targeting: language and location criteria at the campaign level. By default, the campaign targets all locations and all languages. The following code snippet targets the campaign for California and Mexico, for English and Spanish.

Java

// Get the CampaignCriterionService.
CampaignCriterionServiceInterface campaignCriterionService =
    adWordsServices.get(session, CampaignCriterionServiceInterface.class);

// Create locations. The IDs can be found in the documentation or
// retrieved with the LocationCriterionService.
Location california = new Location();
california.setId(21137L);

Location mexico = new Location();
mexico.setId(2484L);

// Create languages. The IDs can be found in the documentation or
// retrieved with the ConstantDataService.
Language english = new Language();
english.setId(1000L);

Language spanish = new Language();
spanish.setId(1003L);

List<Criterion> criteria = Lists.<Criterion>newArrayList(california, mexico, english, spanish);

// Create operations to add each of the criteria above.
List<CampaignCriterionOperation> operations = Lists.<CampaignCriterionOperation>newArrayList();
for (Criterion criterion : criteria) {
  CampaignCriterionOperation operation = new CampaignCriterionOperation();

  CampaignCriterion campaignCriterion = new CampaignCriterion();
  campaignCriterion.setCampaignId(campaign.getId());
  campaignCriterion.setCriterion(criterion);
  operation.setOperand(campaignCriterion);

  operation.setOperator(Operator.ADD);

  operations.add(operation);
}

// Set the campaign targets.
CampaignCriterionReturnValue returnValue =
    campaignCriterionService.mutate(
        operations.toArray(new CampaignCriterionOperation[operations.size()]));

if (returnValue != null && returnValue.getValue() != null) {
  // Display added campaign targets.
  for (CampaignCriterion campaignCriterion : returnValue.getValue()) {
    System.out.printf(
        "Campaign criteria of type '%s' and ID %d was added.%n",
        campaignCriterion.getCriterion().getCriterionType(),
        campaignCriterion.getCriterion().getId());
  }
}
    

C#

// Get the CampaignCriterionService.
CampaignCriterionService campaignCriterionService =
  (CampaignCriterionService) user.GetService(
    AdWordsService.v201702.CampaignCriterionService);

// Create locations. The IDs can be found in the documentation or
// retrieved with the LocationCriterionService.
Location california = new Location() {
  id = 21137L
};

Location mexico = new Location() {
  id = 2484L
};

// Create languages. The IDs can be found in the documentation or
// retrieved with the ConstantDataService.
Language english = new Language() {
  id = 1000L
};

Language spanish = new Language() {
  id = 1003L
};

List<Criterion> criteria = new List<Criterion>() {
  california, mexico, english, spanish };

// Create operations to add each of the criteria above.
List<CampaignCriterionOperation> operations = new List<CampaignCriterionOperation>();
foreach (Criterion criterion in criteria) {
  CampaignCriterionOperation operation = new CampaignCriterionOperation() {
    operand = new CampaignCriterion() {
      campaignId = campaign.id,
      criterion = criterion
    },
    @operator = Operator.ADD
  };

  operations.Add(operation);
}

// Set the campaign targets.
CampaignCriterionReturnValue retVal = campaignCriterionService.mutate(operations.ToArray());

if (retVal != null && retVal.value != null) {
  // Display the added campaign targets.
  foreach (CampaignCriterion criterion in retVal.value) {
    Console.WriteLine("Campaign criteria of type '{0}' and id '{1}' was added.",
                      criterion.criterion.CriterionType, criterion.criterion.id);
  }
}
    

Python

campaign_criterion_service = client.GetService('CampaignCriterionService')

# Create locations. The IDs can be found in the documentation or retrieved
# with the LocationCriterionService.
criteria = [
    {
        'xsi_type': 'Location',
        'id': 21137  # California
    },
    {
        'xsi_type': 'Location',
        'id': 2484  # Mexico
    },
    {
        'xsi_type': 'Language',
        'id': 1000  # English
    },
    {
        'xsi_type': 'Language',
        'id': 1003  # Spanish
    }
]

operations = [{
    'operator': 'ADD',
    'operand': {
        'campaignId': campaign['id'],
        'criterion': criterion
    }
} for criterion in criteria]

response = campaign_criterion_service.mutate(operations)

if response and 'value' in response:
  # Display the added campaign targets.
  for criterion in response['value']:
    print ('Campaign criteria of type "%s" and id "%s" was added.'
           % (criterion['criterion']['type'],
              criterion['criterion']['id']))
    

PHP

$campaignCriterionService =
    $adWordsServices->get($session, CampaignCriterionService::class);

$campaignCriteria = [];
// Create locations. The IDs can be found in the documentation or retrieved
// with the LocationCriterionService.
$california = new Location();
$california->setId(21137);
$campaignCriteria[] = new CampaignCriterion($campaignId, null, $california);

$mexico = new Location();
$mexico->setId(2484);
$campaignCriteria[] = new CampaignCriterion($campaignId, null, $mexico);

// Create languages. The IDs can be found in the documentation or retrieved
// with the ConstantDataService.
$english = new Language();
$english->setId(1000);
$campaignCriteria[] = new CampaignCriterion($campaignId, null, $english);

$spanish = new Language();
$spanish->setId(1003);
$campaignCriteria[] = new CampaignCriterion($campaignId, null, $spanish);

// Create operations to add each of the criteria above.
$operations = [];
foreach ($campaignCriteria as $campaignCriterion) {
  $operation = new CampaignCriterionOperation();
  $operation->setOperand($campaignCriterion);
  $operation->setOperator(Operator::ADD);
  $operations[] = $operation;
}

// Set the campaign targets.
$result = $campaignCriterionService->mutate($operations);

// Display added campaign targets.
foreach ($result->getValue() as $campaignCriterion) {
  printf("Campaign criterion of type '%s' and ID %d was added.\n",
      $campaignCriterion->getCriterion()->getType(),
      $campaignCriterion->getCriterion()->getId()
  );
}
    

Perl

# Create locations. The IDs can be found in the documentation or retrieved
# with the LocationCriterionService.
my $california = Google::Ads::AdWords::v201702::Location->new({id => 21137});
push @criteria, $california;
my $mexico = Google::Ads::AdWords::v201702::Location->new({id => 2484});
push @criteria, $mexico;

# Create languages. The IDs can be found in the documentation or retrieved
# with the ConstantDataService.
my $english = Google::Ads::AdWords::v201702::Language->new({id => 1000});
push @criteria, $english;
my $spanish = Google::Ads::AdWords::v201702::Language->new({id => 1003});
push @criteria, $spanish;

# Create operations.
my @operations = ();
foreach my $criterion (@criteria) {
  my $operation =
    Google::Ads::AdWords::v201702::CampaignCriterionOperation->new({
      operator => "ADD",
      operand  => Google::Ads::AdWords::v201702::CampaignCriterion->new({
          campaignId => $campaign_id,
          criterion  => $criterion
        })});
  push @operations, $operation;
}

# Set campaign criteria.
my $result =
  $client->CampaignCriterionService()->mutate({operations => \@operations});

# Display campaign criteria.
if ($result->get_value()) {
  foreach my $campaign_criterion (@{$result->get_value()}) {
    printf "Campaign criterion of type '%s' and ID %s was added.\n",
      $campaign_criterion->get_criterion()->get_type(),
      $campaign_criterion->get_criterion()->get_id();
  }
}
    

Ruby

campaign_criterion_service =
    adwords.service(:CampaignCriterionService, API_VERSION)

criteria = [
  {
    :xsi_type => 'Location',
    :id => 21137 # California
  },
  {
    :xsi_type => 'Location',
    :id => 2484 # Mexico
  },
  {
    :xsi_type => 'Language',
    :id => 1000 # English
  },
  {
    :xsi_type => 'Language',
    :id => 1003 # Spanish
  }
]

operations = criteria.map do |criterion|
  {
    :operator => 'ADD',
    :operand => {
      :campaign_id => campaign[:id],
      :criterion => criterion
    }
  }
end

response = campaign_criterion_service.mutate(operations)

if response and response[:value]
  # Display the added campaign targets.
  response[:value].each do |criterion|
    puts 'Campaign criteria of type "%s" and id %d was added.' % [
        criterion[:criterion][:criterion_type],
        criterion[:criterion][:id]
    ]
  end
end
    

Reporting

Universal App campaign stats are available through Campaign Performance report; you can filter by the campaign's advertisingChannelType and advertisingChannelSubType as follows:

string query = "Select CampaignId, CampaignName, Clicks,
   Impressions, Cost from CAMPAIGN_PERFORMANCE_REPORT where
   AdvertisingChannelType = MULTI_CHANNEL and
   AdvertisingChannelSubType = UNIVERSAL_APP_CAMPAIGN during
   LAST_7_DAYS";

string fileName = ExampleUtilities.GetHomeDir() + Path.DirectorySeparatorChar +
    "CampaignPerformanceReport.gz";

ReportUtilities utilities = new ReportUtilities(user, "v201702", query,
    DownloadFormat.GZIPPED_CSV.ToString());
utilities.GetResponse().Save(fileName);

Starting with v201609, you may also get stats from the following reports:

Code examples

Complete code examples for adding a universal app campaign are available in each client library:

Mobile app installs campaigns

The AdWords Mobile app installs campaign is a campaign subtype optimized for getting more people to download your mobile app.

This section explains how to create a mobile app installs campaign, create ads for your mobile app, and monitor the campaign's performance using the AdWords API.

Create a campaign budget

To create a campaign, you must first have a Budget. You can create a budget using BudgetService, or pick an existing shared budget. The following code snippet shows how to create a budget of $5 per day with standard delivery:

// Get the BudgetService.
BudgetService budgetService =
    (BudgetService) user.GetService(AdWordsService.v201702.BudgetService);

// Create the campaign budget.
Budget budget = new Budget();
budget.name = "My App Budget 1";
budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD;
budget.amount = new Money();
budget.amount.microAmount = 5000000;

// Create the operation.
BudgetOperation budgetOperation = new BudgetOperation();
budgetOperation.@operator = Operator.ADD;
budgetOperation.operand = budget;

// Add the budget.
BudgetReturnValue budgetRetval = budgetService.mutate(
    new BudgetOperation[] {budgetOperation});
budget = budgetRetval.value[0];

Create a campaign

Once you've created a budget, you can create a mobile app installs campaign with CampaignService.

But first you must decide what audience you want your campaign to reach, by selecting an advertising network and a bidding strategy.

Select an advertising network

  • On the Search Network, you can show app install ads to people while they're looking for an app like yours, or trying to do something that your app makes easier.
  • On the Display Network, you can reach people while they're using other apps similar to yours. These campaigns typically generate a large number of impressions, which can increase awareness of your app and attract new app users who may not be actively searching for you.

In the AdWords web interface, you specify your app at the campaign level (in Settings) so you don't have to keep specifying your app every time you create a new ad. In the API, there is no equivalent setting: You'll need to specify an app ID for every app install ad you create. See Create ads below for details.

Choose a bid strategy

On the Search Network, mobile app installs campaigns support the following bidding strategies:

The Display Network supports these bidding strategies:

Installs of Android apps in Google Play are automatically tracked as conversions, so we recommend using Target CPA as the bidding strategy. You can set a Target CPA bid to match your app's cost-per-install (CPI) value, and the system will optimize your bids to help you get the most downloads. You can also set specific bids for your ad groups, or for individual targeting criteria.

This code snippet shows how to create an app install campaign for the Display Network:

// Get the CampaignService.
CampaignService campaignService =
     (CampaignService) user.GetService(AdWordsService.v201702.CampaignService);

Campaign campaign = new Campaign();
campaign.advertisingChannelType = AdvertisingChannelType.DISPLAY;
// 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.
campaign.status = CampaignStatus.PAUSED;

// Set the advertising channel subtype for mobile app install campaigns.
campaign.advertisingChannelSubType = AdvertisingChannelSubType.DISPLAY_MOBILE_APP;

campaign.name = "My App campaign 1";

BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
biddingConfig.biddingStrategyType = BiddingStrategyType.TARGET_CPA;

// Specify a BiddingScheme with a target CPA.
TargetCpaBiddingScheme biddingScheme =  new TargetCpaBiddingScheme();
biddingScheme.targetCpa = new Money();
biddingScheme.targetCpa.microAmount = 1000000;
biddingConfig.biddingScheme = biddingScheme;
campaign.biddingStrategyConfiguration = biddingConfig;

// Use the ID of the Budget created in the previous step. You can also
// reuse an existing budget.
campaign.budget = new Budget();
campaign.budget.budgetId = budget.budgetId;

// Optional: Set the campaign ad serving optimization status.
campaign.adServingOptimizationStatus = AdServingOptimizationStatus.ROTATE;

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

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

Campaign newCampaign = retVal.value[0];

Creating a campaign for the Search Network is similar. The main difference is that you must set a different value for the advertisingChannelType, advertisingChannelSubType, and networkSetting fields:

campaign.advertisingChannelType = AdvertisingChannelType.SEARCH;
campaign.advertisingChannelSubType = AdvertisingChannelSubType.SEARCH_MOBILE_APP;

// Target the networks you want your ads to serve on.
campaign.networkSetting = new NetworkSetting();
campaign.networkSetting.targetGoogleSearch = true;
campaign.networkSetting.targetSearchNetwork = true;

Create an ad group

You must create an ad group in your campaign using the AdGroupService.

An important setting to note here is the ad group's biddingStrategyConfiguration, which specifies how much you want to pay for your ads per click or per acquisition, depending on the bidding strategy you selected at the campaign level. The code sample below uses a bidding strategy of $10 per acquisition.

// Get the AdGroupService.
AdGroupService adGroupService =
    (AdGroupService) user.GetService(AdWordsService.v201702.AdGroupService);

// Create the ad group.
AdGroup adGroup = new AdGroup();
adGroup.name = "My Mobile adgroup 1";
adGroup.status = AdGroupStatus.ENABLED;
adGroup.campaignId = campaign.id;

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

CpaBid cpaBid = new CpaBid();
cpaBid.bid = new Money();
cpaBid.bid.microAmount = 10000000;

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

adGroup.biddingStrategyConfiguration = biddingConfig;

// Optional: Set targeting restrictions.
// These settings only affect serving for the Display Network.
TargetingSetting targetingSetting = new TargetingSetting();

TargetingSettingDetail placementDetail = new TargetingSettingDetail();
placementDetail.criterionTypeGroup = CriterionTypeGroup.PLACEMENT;
placementDetail.targetAll = true;

targetingSetting.details = new TargetingSettingDetail[] {
    placementDetail};

adGroup.settings = new Setting[] {targetingSetting};

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

// Create the ad group.
AdGroupReturnValue adGroupRetVal = adGroupService.mutate(new AdGroupOperation[] {adGroup});
AdGroup newAdGroup = retVal.value[0];

Create ads

Once your ad groups are set up, create app install ads (click-to-download ads) in your campaign. To make downloads easy, these ads are linked to your app's page in the app store.

App install ads can be created in the following formats:

  • App install ads (click-to-download ads) are automatically generated. We build this ad using your app icon and reviews of your app in Google Play or the Apple Store. This format is available on both the Search Network and the Display Network.

  • Image app install ads are created by uploading an image and filling in your text to create a custom app install ad using your own eye-catching graphics. This format is available only on the Display Network.

  • Video app install ads are video ads on the Display Network created using a link from your YouTube account, or automatically generated from your app's images, icons, and reviews.

Use the AdGroupAdService to create a click-to-download ad:

AdGroupAdService adGroupAdService =
    (AdGroupAdService) user.GetService(AdWordsService.v201702.AdGroupAdService);

// Create the template ad.
TemplateAd clickToDownloadAppAd = new TemplateAd();

clickToDownloadAppAd.name = "Ad for demo game";
clickToDownloadAppAd.templateId = 353;
clickToDownloadAppAd.url =
    "http://play.google.com/store/apps/details?id=com.example.demogame123";
clickToDownloadAppAd.displayUrl = "play.google.com";

// Create the template elements for the ad. You can refer to
// https://developers.google.com/adwords/api/docs/appendix/templateads
// for the list of available template fields.
TemplateElementField headline = new TemplateElementField();
headline.name = "headline";
headline.fieldText = "Enjoy your drive in Mars";
headline.type = TemplateElementFieldType.TEXT;

TemplateElementField description1 = new TemplateElementField();
description1.name = "description1";
description1.fieldText = "Realistic physics simulation";
description1.type = TemplateElementFieldType.TEXT;

TemplateElementField description2 = new TemplateElementField();
description2.name = "description2";
description2.fieldText = "Race against players online";
description2.type = TemplateElementFieldType.TEXT;

TemplateElementField appId = new TemplateElementField();
appId.name = "appId";
appId.fieldText = "com.example.demogame";
appId.type = TemplateElementFieldType.TEXT;

TemplateElementField appStore = new TemplateElementField();
appStore.name = "appStore";
appStore.fieldText = "2";
appStore.type = TemplateElementFieldType.ENUM;

TemplateElement adData = new TemplateElement();
adData.uniqueName = "adData";
adData.fields = new TemplateElementField[] {headline, description1,
    description2, appId, appStore};

clickToDownloadAppAd.templateElements = new TemplateElement[] {adData};

// Create the adgroupad.
AdGroupAd clickToDownloadAppAdGroupAd = new AdGroupAd();
clickToDownloadAppAdGroupAd.adGroupId = adGroupId;
clickToDownloadAppAdGroupAd.ad = clickToDownloadAppAd;

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

// Create the ad.
AdGroupAdReturnValue adRetval = adGroupAdService.mutate(
    new AdGroupAdOperation[] {operation});
AdGroupAd newAd = retval.value[0];

You can also create an image or video app install ad through the API. See our template ads documentation for relevant fields.

Target ads

Once you've created your ads, specify who to show your ads to by adding targeting criteria. On the Search Network, you can add keywords that correspond to search terms used by people looking for apps like yours on Google Search and Play.

You create an ad group criterion using AdGroupCriterionService.

The following code snippet shows how to add "android race game" as a keyword in your campaign:

AdGroupCriterionService adGroupCriterionService =
    (AdGroupCriterionService) user.GetService(
        AdWordsService.v201702.AdGroupCriterionService);

// Create the keyword.
Keyword keyword = new Keyword();
keyword.text = "android race game";
keyword.matchType = KeywordMatchType.BROAD;

// Create the biddable ad group criterion.
BiddableAdGroupCriterion keywordCriterion = new BiddableAdGroupCriterion();
keywordCriterion.adGroupId = adGroupId;
keywordCriterion.criterion = keyword;

// Optional: Set the keyword final url.
keywordCriterion.finalUrls = new string[] {
    "http://play.google.com/store/apps/demogame123" };

// Create the operations.
AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
operation.@operator = Operator.ADD;
operation.operand = keywordCriterion;

// Create the keywords.
AdGroupCriterionReturnValue criteriaRetVal = adGroupCriterionService.mutate(
    new AdGroupCriterionOperation[] {operation});

A lot more targeting options are available on the Display Network. They're created the same way using AdGroupCriterionService, but employ a different Criterion type.

Mobile app categories

You can specify mobile app categories in which to show your ads. For example, you can set your targeting to include certain types of apps, like "Games" or "Health". The following code snippet shows how to target your application to show ads in "Games" apps on Google Play.

MobileAppCategory category = new MobileAppCategory();
category.mobileAppCategoryId = 60008;

Refer to the mobile apps categories table for the complete list of supported mobile app categories.

Previously downloaded apps

You can show ads to people who've previously downloaded other apps in a category you want to target. For this type of targeting, you can choose to show ads only to people who bought an app or paid for an in-app purchase in the targeted category. The following code snippet shows how to target your app only to users who have installed at least one paid application from the "Puzzle Games" category.

// Target paid users. The list of valid IDs for this criteria can be found on
// https://developers.google.com/adwords/api/docs/reference/latest/AdGroupCriterionService.AppPaymentModel
AppPaymentModel paymentModel = new AppPaymentModel();
paymentModel.id = 30;

// Create the biddable ad group criterion.
BiddableAdGroupCriterion paymentModelCriterion = new BiddableAdGroupCriterion();
paymentModelCriterion.adGroupId = adGroupId;
paymentModelCriterion.criterion = paymentModel;

// Target users interested in Puzzle Games. See
// https://developers.google.com/adwords/api/docs/appendix/codes-formats#mobile-app-categories
// for the list of valid IDs.
CriterionUserInterest userInterest = new CriterionUserInterest();
userInterest.userInterestId = 87086;

// Create the biddable ad group criterion.
BiddableAdGroupCriterion userInterestCriterion = new BiddableAdGroupCriterion();
userInterestCriterion.adGroupId = adGroupId;
userInterestCriterion.criterion = userInterest;

// Create the operations.
AdGroupCriterionOperation operation1 = new AdGroupCriterionOperation();
operation1.@operator = Operator.ADD;
operation1.operand = paymentModelCriterion;

AdGroupCriterionOperation operation2 = new AdGroupCriterionOperation();
operation2.@operator = Operator.ADD;
operation2.operand = userInterestCriterion;

You can get the list of all valid user interests from the ConstantDataService:

CriterionUserInterest[] userInterests = constantDataService.getUserInterestCriterion(
    ConstantDataServiceUserInterestTaxonomyType.MOBILE_APP_INSTALL_USER);

These values are also available from the mobile app categories table.

New mobile devices

You can target ads to people who've recently activated phones, and who therefore may be interested in adding new apps. You can select this option under interest categories, then select the number of days since the device was activated--from a week up to three months.

The following code snippet shows how to construct a CriterionUserInterest criterion that targets users who activated a new device within the last seven days. You can find the valid user interest IDs from the new smartphone users table.

// Target users who activated a new device within the last 7 days. See
// https://developers.google.com/adwords/api/docs/appendix/codes-formats#new-smartphone-users
// for the list of valid IDs.
CriterionUserInterest userInterest = new CriterionUserInterest();
userInterest.userInterestId = 85002;

// Create the biddable ad group criterion.
BiddableAdGroupCriterion userInterestCriterion = new BiddableAdGroupCriterion();
userInterestCriterion.adGroupId = adGroupId;
userInterestCriterion.criterion = userInterest;

userInterestCriterion.biddingStrategyConfiguration.bids = new Bids[] { cpcBid };

Demographic targeting

You can target ads by demographics, such as audience age or gender. The following code snippet shows how to target users between 18 and 24 years old.

AgeRange ageRange = new AgeRange();
ageRange.ageRangeType = AgeRangeAgeRangeType.AGE_RANGE_18_24;

Similarly, you can restrict by gender by adding a Gender criterion.

Device targeting

By default, your ads will appear on compatible devices that don't have your app installed. If you're targeting the Display Network, you can restrict this to specific devices, operating system versions, or carriers. Device targeting is defined at the campaign level, using the CampaignCriterionService.

The following code snippet shows how to restrict your campaign to Android Jelly Bean 4.1 or later:

// Create the OS version restriction.
OperatingSystemVersion osVersion = new OperatingSystemVersion();
osVersion.id = 630257; // Android 4.1 Jelly Bean

CampaignCriterion osVersionCriterion = new CampaignCriterion();
osVersionCriterion.campaignId = campaignId;
osVersionCriterion.criterion = osVersion;

CampaignCriterionOperation operation = new CampaignCriterionOperation();
operation.@operator = Operator.ADD;
operation.operand = osVersionCriterion;

CampaignCriterionReturnValue campaignCriterionRetVal = campaignCriterionService.mutate(
    new CampaignCriterionOperation[] { operation });

The list of supported mobile operating system versions is available from the mobile platforms table, or through the ConstantDataService. Similarly, you can restrict by mobile device or carrier criteria as well.

Set custom bids

By default, your criteria use the bids from the ad group level. However, you can set custom bids at the criterion level, using your own custom bidding logic.

To enable custom bids at the criterion level in Display Network campaigns, you need to enable it at the ad group level first, by specifying the dimension on which you want to enable custom bidding. This step is not required for Search Network campaigns. The following code snippet sets this value to PLACEMENT, so you can have custom bidding on your Placement criteria:

// Get the AdGroupService.
AdGroupService adGroupService = (AdGroupService) user.GetService(
    AdWordsService.v201702.AdGroupService);

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

// Optional: Set the bidding group. This allows you to set absolute bids on
// this dimension. This setting only affects serving for the Display Network.
adGroup.contentBidCriterionTypeGroup = CriterionTypeGroup.PLACEMENT;
adGroup.id = adGroupId;

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

// Update the ad group.
AdGroupReturnValue adGroupRetVal = adGroupService.mutate(
   new AdGroupOperation[] {operation});

Next, you can update the bids of the criteria using the AdGroupCriterionService.

The following code snippet sets a custom bid of $3 per click for a placement:

// Get the AdGroupCriterionService
AdGroupCriterionService adGroupCriterionService =
    (AdGroupCriterionService) user.GetService(
         AdWordsService.v201702.AdGroupCriterionService);

// Since we are not updating any placement-specific fields, it is enough to
// create a criterion object.
Criterion criterion = new Criterion();
criterion.id = placementId;

// Create ad group criterion.
BiddableAdGroupCriterion biddableAdGroupCriterion =
    new BiddableAdGroupCriterion();
biddableAdGroupCriterion.adGroupId = adGroupId;
biddableAdGroupCriterion.criterion = criterion;

// Create the bids.
BiddingStrategyConfiguration biddingConfig =
     new BiddingStrategyConfiguration();

// You may use CpaBid instead of CpcBid if your campaign uses
// a cost-per-acquisition bidding strategy.
CpcBid cpcBid = new CpcBid();
cpcBid.bid = new Money();
cpcBid.bid.microAmount = 3000000;
biddingConfig.bids = new Bids[] {cpcBid};

biddableAdGroupCriterion.biddingStrategyConfiguration = biddingConfig;

// Create the operation.
AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
operation.@operator = Operator.SET;
operation.operand = biddableAdGroupCriterion;

// Update the placement.
AdGroupCriterionReturnValue agcRetVal = adGroupCriterionService.mutate(
    new AdGroupCriterionOperation[] {operation});

Conversion tracking

Once you've set up your ad campaign, you'll want to track its effectiveness. Mobile app installs campaigns are designed to track downloads of your app as conversions. There are two types of app conversions related to app installs:

  1. App installs (from Google Play):
  2. App installs (first open):
    • Available for both Android and iOS apps
    • appConversionType of FIRST_OPEN (Android) or DOWNLOAD (iOS)

In addition, you can track in-app actions for Android using the IN_APP_PURCHASE appConversionType.

You can find more information on app conversions in the Conversion Tracking guide and the AdWords Help Center articles on Android and iOS app conversion tracking.

Reporting

You can retrieve the conversion stats for your campaign using a Campaign Performance Report. The following code snippet shows how to run one:

string query = "SELECT CampaignId, Conversions, Cost, Impressions " +
    "from CAMPAIGN_PERFORMANCE_REPORT DURING LAST_7_DAYS";

string fileName = ExampleUtilities.GetHomeDir() + Path.DirectorySeparatorChar +
    "CampaignPerformanceReport.gz";

ReportUtilities utilities = new ReportUtilities(user, "v201702", query,
    DownloadFormat.GZIPPED_CSV.ToString());
utilities.GetResponse().Save(fileName);

See the Reports page for the list of supported report types.

The CAMPAIGN_PERFORMANCE_REPORT includes stats for universal app campaigns. These campaigns can be identified by filtering for AdvertisingChannelType = MULTI_CHANNEL and AdvertisingChannelSubType = UNIVERSAL_APP_CAMPAIGN as shown below:

string query = "SELECT CampaignId, Conversions, Cost, Impressions " +
    "from CAMPAIGN_PERFORMANCE_REPORT where " +
    "AdvertisingChannelType = MULTI_CHANNEL and " +
    "AdvertisingChannelSubType = UNIVERSAL_APP_CAMPAIGN DURING LAST_7_DAYS";

ReportUtilities utilities = new ReportUtilities(user, "v201702", query,
    DownloadFormat.GZIPPED_CSV.ToString());
utilities.GetResponse().Save(fileName);

Account for conversion delays

Conversion numbers may take several days to show up in reports due to delayed interactions between a person's device, Google, or any third-party tracking services you might use. When reviewing your conversion reports, note that the previous three days of conversion data may not have been completed.

Code examples

Mobile app engagement campaigns

Mobile app engagement campaigns focus on increasing user engagement with your app. This campaign subtype is geared toward getting people who have installed your app to try your app again, or to open your app to take a specific action.

This section explains how to create a mobile app engagement campaign, create ads for your mobile application, and monitor the campaign's performance using the AdWords API.

The code examples are in C#. Examples in other languages are available below.

Create a campaign budget

To create a campaign, you must first have a budget. You can either create a Budget using BudgetService or pick an existing shared budget. The following code snippet shows how to create a budget of $5 per day with standard delivery:

// Get the BudgetService.
AdWordsUser user = new AdWordsUser();
BudgetService budgetService =
    (BudgetService) user.GetService(AdWordsService.v201702.BudgetService);

// Create the campaign budget.
Budget budget = new Budget();
budget.name = "My App Budget 1";
budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD;
budget.amount = new Money();
budget.amount.microAmount = 500000;

BudgetOperation budgetOperation = new BudgetOperation();
budgetOperation.@operator = Operator.ADD;
budgetOperation.operand = budget;

BudgetReturnValue budgetRetval = budgetService.mutate(
    new BudgetOperation[] {budgetOperation});
budget = budgetRetval.value[0];

Create a campaign

Once you've created a budget, you can create a mobile app engagement campaign with CampaignService.

But before creating your campaign, you must select an advertising network and bid strategy.

Select an advertising network

You decide what audience you want to reach with your campaign by choosing an advertising network:

  • On the Search Network, ads appear in search results on mobile phones and tablets that already have your app installed.
  • On the Display Network, ads appear within other apps, specifically to people who have already installed your app.

In both cases, the app engagement ads can encourage your app's current users to interact with your app.

Choose a bid strategy

Bidding provides several ways to bid for your ads. In the BiddingStrategyConfiguration at the Campaign level, the biddingStrategyType defines the type of bidding, while the biddingScheme contains the bidding strategy metadata.

Search Network bidding

For the Search Network, we support the following bidding strategies:

Descriptive Name API Bidding Strategy Type API Bidding Strategy
Maximize clicks (default) TARGET_SPEND TargetSpendBiddingScheme
Target cost per acquisition (CPA) TARGET_CPA TargetCpaBiddingScheme
Target return on ad spend TARGET_ROAS TargetRoasBiddingScheme
Target search page location PAGE_ONE_PROMOTED PageOnePromotedBiddingScheme
Target outranking share TARGET_OUTRANK_SHARE TargetOutrankShareBiddingScheme
Manual CPC MANUAL_CPC ManualCpcBiddingScheme
Display Network bidding

For the Display network, we support the following bidding strategies:

Descriptive Name API Bidding Strategy Type API Bidding Strategy
Focus on clicks (default) - use maximum CPC bids MANUAL_CPC ManualCpcBiddingScheme
Focus on installs - use CPA bids TARGET_CPA TargetCpaBiddingScheme

Create a Search Network campaign

To create a Search Network campaign, change the campaign's advertisingChannelType and networkSetting fields, as shown below.

The NetworkSetting defines the networks the campaign will target. Setting the targetGoogleSearch and targetSearchNetwork options to true, will target the Search Network only.

campaign.advertisingChannelType = AdvertisingChannelType.SEARCH;

campaign.networkSetting = new NetworkSetting();
campaign.networkSetting.targetGoogleSearch = true;
campaign.networkSetting.targetSearchNetwork = true;
campaign.networkSetting.targetContentNetwork = false;
campaign.networkSetting.targetPartnerSearchNetwork = false;

In the AdWords user interface, you specify your app at the campaign level (in Settings) so you don't have to keep specifying your app every time you create a new ad. There is no equivalent setting in the API: You'll need to specify an app ID for every app engagement ad you create.

Create Display Network campaign

For the Display Network, optimizing on conversions becomes available as an option only after your campaign has reported enough conversions.

The following code snippet shows how to create a mobile app engagement campaign for the Display Network. To focus on mobile app engagement, make sure to set the campaign's advertisingChannelSubType to DISPLAY_MOBILE_APP.

// Get the CampaignService.
AdWordsUser user = new AdWordsUser();
CampaignService campaignService =
     (CampaignService) user.GetService(AdWordsService.v201702.CampaignService);

Campaign campaign = new Campaign();
campaign.advertisingChannelType = AdvertisingChannelType.DISPLAY;
campaign.advertisingChannelSubType =
    AdvertisingChannelSubType.DISPLAY_MOBILE_APP;
// 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.
campaign.status = CampaignStatus.PAUSED;

campaign.name = "My App Engagement campaign 1";

BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
biddingConfig.biddingStrategyType = BiddingStrategyType.TARGET_CPA;

// Specify a BiddingScheme with a target CPA.
TargetCpaBiddingScheme biddingScheme =  new TargetCpaBiddingScheme();
biddingScheme.targetCpa = new Money();
biddingScheme.targetCpa.microAmount = 1000000;
biddingConfig.biddingScheme = biddingScheme;
campaign.biddingStrategyConfiguration = biddingConfig;

// Use the ID of the Budget created in the previous step. You can also
// reuse an existing budget.
campaign.budget = new Budget();
campaign.budget.budgetId = budget.budgetId;

// Optional: Set the campaign ad serving optimization status.
campaign.adServingOptimizationStatus =
    AdServingOptimizationStatus.CONVERSION_OPTIMIZE;

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

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

Campaign newCampaign = retVal.value[0];

Create an ad group

Set up an AdGroup for the ads in this campaign using the AdGroupService.

First, create the ad group.

// Get the AdGroupService.
AdWordsUser user = new AdWordsUser();
AdGroupService adGroupService =
    (AdGroupService) user.GetService(AdWordsService.v201702.AdGroupService);

// Create the ad group.
AdGroup adGroup = new AdGroup();
adGroup.name = "My App Engagement adgroup 1";
adGroup.status = AdGroupStatus.ENABLED;
adGroup.campaignId = campaign.id;

Now it's time to set the ad group bids. The group's biddingStrategyConfiguration specifies how much you want to pay per click or acquisition. BiddingStrategyConfiguration inherits the bidding strategy that was set at the campaign level.

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

CpaBid cpaBid = new CpaBid();
cpaBid.bid = new Money();
cpaBid.bid.microAmount = 10000000;

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

adGroup.biddingStrategyConfiguration = biddingConfig;

Here are a few examples of how to set a targeting restriction on an ad group in the Display Network.

// Optional: Set targeting restrictions.
// These settings only affect serving for the Display Network.
TargetingSetting targetingSetting = new TargetingSetting();

TargetingSettingDetail placementDetail = new TargetingSettingDetail();
placementDetail.criterionTypeGroup = CriterionTypeGroup.PLACEMENT;
placementDetail.targetAll = true;

targetingSetting.details = new TargetingSettingDetail[] {
    placementDetail};

adGroup.settings = new Setting[] {targetingSetting};

// Optional: Set the bidding group. This allows you to set absolute bids on
// this dimension. These settings only affect serving for the Display Network.
adGroup.contentBidCriterionTypeGroup =
CriterionTypeGroup.USER_INTEREST_AND_LIST;

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

// Create the ad group.
AdGroupReturnValue retVal = adGroupService.mutate(new AdGroupOperation[]
{adGroup});
AdGroup newAdGroup = retVal.value[0];

AdWords can show your Display Network app install ads on mobile website ad placements, in addition to in-app ad placements. This can give your ads even more reach, while still achieving your target cost per install. Opt in to this feature through optimizerSetting:

ExplorerAutoOptimizerSetting optimizerSettings = new ExplorerAutoOptimizerSetting();
optimizerSetting.optin = true;

adGroup.settings = new Setting[] {optimizerSetting};

Keep in mind that you need to add at least one mobile targeting criteria in the ad group for this setting to work.

Create ads

Once you've created your ad groups, you can create app engagement ads. You need to set up the proper targeting so that your app engagement ads appear only to people who've already installed your app. When someone clicks on your ad, it will open the app and take them to the activity in your app you've specified with your deep link.

  • On the Search Network, you can use these ads to send people to the location in your app that relates most closely to what they were searching for on Google. App engagement for iOS ads on the Search Network is not currently supported.
  • On the Display Network, you can use these ads to display text encouraging a specific type of action in your app, such as checking in, making a purchase, or booking a flight. Ads can either deep-link users to a specific location in your app, or they can simply launch the app back to its most recent state.

App Engagement ads require a deep link as the final URL. Deep links are not automatically set up when you create your app. For app engagement campaigns on the Search Network, the system generates an app URI using your deep link, so your ads are compatible with Google Search. To learn how to create a deep link, see the following guides:

Once your deep links are set up, they should be represented in your final app URL in the following way:

android-app://{package_id}/{scheme}/{rest_of_url}

or

ios-app://{app_id}/{scheme}/{rest_of_url}

For example, a deep link like demogame://loadlevel?level=mars in the app com.example.demogame would be represented in your ad URL as follows:

android-app://com.example.demogame/demogame/loadlevel?level=mars

To learn about deep link formats, see the following guides:

The code snippet below shows how to create an app engagement ad using the AdGroupAdService. App engagement ads for search campaigns use template 453. App install ads for display campaigns use templates 445 (for text ads) or 455 (for image ads).

AdWordsUser user = new AdWordsUser();
AdGroupAdService adGroupAdService =
    (AdGroupAdService) user.GetService(AdWordsService.v201702.AdGroupAdService);
    // Create the template ad.
TemplateAd appEngagementAd = new TemplateAd();

appEngagementAd.displayUrl = "play.google.com";

appEngagementAd.name = "Ad for demo game";
appEngagementAd.templateId = 445;

// Define the ad's URL. You can refer to
// https://developers.google.com/app-indexing/webmasters/server
// for the right formatting to use on Android.
// Refer to https://developers.google.com/app-indexing/ios/app
// for the right formatting to use on iOS.
// Only one URL is allowed in the finalAppUrls array.
appEngagementAd.finalAppUrls = new string[] {
    "android-app://com.example.demogame/demogame/loadlevel?level=mars" };

// Create the template elements for the ad. You can refer to
// https://developers.google.com/adwords/api/docs/appendix/templateads
// for the list of available template fields.
TemplateElementField headline = new TemplateElementField();
headline.name = "promoHeadline";
headline.fieldText = "New levels are available";
headline.type = TemplateElementFieldType.TEXT;

TemplateElementField description = new TemplateElementField();
description.name = "promoDescription";
description.fieldText = "Race against players online";
description.type = TemplateElementFieldType.TEXT;

TemplateElementField appId = new TemplateElementField();
appId.name = "appId";
appId.fieldText = "com.example.demogame";
appId.type = TemplateElementFieldType.TEXT;

TemplateElementField appStore = new TemplateElementField();
appStore.name = "appStore";
appStore.fieldText = "2";
appStore.type = TemplateElementFieldType.ENUM;

TemplateElementField callToActionOpen = new TemplateElementField();
callToActionOpen.name = "callToActionOpen";
callToActionOpen.fieldText = "Play Now";
callToActionOpen.type = TemplateElementFieldType.TEXT;

TemplateElementField layout = new TemplateElementField();
layout.name = "layout";
layout.fieldText = "dark";
layout.type = TemplateElementFieldType.ENUM;

TemplateElement adData = new TemplateElement();
adData.uniqueName = "adData";
adData.fields = new TemplateElementField[] {headline, description, appId,
    appStore, callToActionInstall, callToActionOpen, layout};

appEngagementAd.dimensions = new Dimensions() {
    width = 320,
    height = 480
};

appEngagementAd.templateElements = new TemplateElement[] {adData};

// Finally, we get to tie the ad to the AdGroup!
// An AdGroupAd is a container that ties an ad to an
// AdGroup in the AdWords API.
AdGroupAd appEngagementAdAppAdGroupAd = new AdGroupAd();
appEngagementAdAdGroupAd.adGroupId = adGroupId;
appEngagementAdAppAdGroupAd.ad = appEngagementAd;

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

// Send the command to create the ad.
// The command returns the successfully created ad.
AdGroupAdReturnValue retval = adGroupAdService.mutate(
    new AdGroupAdOperation[] {operation});
AdGroupAd newAd = retval.value[0];

Image App Engagement ads and App Re-engagement ads can also be created through the AdWords API. See our template ads documentation page for details on fields.

Create user list for targeting (required for Display Network)

For mobile app engagement campaigns on the Display Network, you must target your campaign only to those users who already have your app, using user list targeting. To automatically set up a user list comprised of the people who have your app installed, link your Google Play account to your AdWords account. This automatically creates a user list of all the people who have your app installed. You also have the option of creating other, more granular, user lists in your AdWords account using AdwordsUserListService. Once you've defined your user lists, target each of your ad groups to a user list.

Target ads

Once the ads have been created, you can add target criteria to specify to whom the ad is shown.

Search Network targeting (optional)

On the Search Network, you can add keywords that correspond to search terms used by people looking on Google Search for app features like yours.

An ad group criterion can be created using the AdGroupCriterionService. The following code snippet shows how to add mars race event as a keyword in your campaign, and use its final URL to load a race event in your app.

AdWordsUser user = new AdWordsUser();
AdGroupCriterionService adGroupCriterionService =
    (AdGroupCriterionService) user.GetService(
        AdWordsService.v201702.AdGroupCriterionService);

// Create the keyword.
Keyword keyword = new Keyword();
keyword.text = "mars race event";
keyword.matchType = KeywordMatchType.BROAD;

// Create the biddable ad group criterion.
BiddableAdGroupCriterion keywordCriterion = new BiddableAdGroupCriterion();
keywordCriterion.adGroupId = adGroupId;
keywordCriterion.criterion = keyword;

// Optional: Set the keyword final url.
keywordCriterion.finalAppUrls = new string[] {
    "android-app://com.example.demogame/loadevent/mars/megarace" };

// Create the operations.
AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
operation.@operator = Operator.ADD;
operation.operand = keywordCriterion;

// Create the keywords.
AdGroupCriterionReturnValue criteriaRetVal = adGroupCriterionService.mutate(
    new AdGroupCriterionOperation[] {operation});

Display Network targeting (required)

If your ad is on the Display Network, target users who have your app installed using User List targeting. This targeting is created the same way using AdGroupCriterionService, but using the CriterionUserList type.

Audience targeting

You engage with your existing app users by creating a remarketing user list, and using that as a targeting criterion. App engagement ads must be targeted to existing users of your app.

The following code snippet shows how to retrieve the user list that you create in your AdWords account. If you've linked your Google Play account to your AdWords account, then a list has already been created and populated for you, and you simply need to target it. If not, follow these instructions to set up a user list.

This code snippet shows how to retrieve an existing user list by its name:

AdWordsUser user = new AdWordsUser();
AdwordsUserListService userListService =
    (AdwordsUserListService)
         user.GetService(AdWordsService.v201702.AdwordsUserListService);

Selector selector = new Selector() {
    fields = new string[] { "Id", "Name", "ListType"},
    predicates = new Predicate[] {
        new Predicate() {
            field = "Name",
            @operator = PredicateOperator.EQUALS,
            values = new string[] {"All users of Demo App (Google Play)"}
        }
    }
};

UserListPage page = userListService.get(selector);
UserList myUserList = page.values[0];

You can then use the UserList instance to modify targeting settings, or to set up custom bids.

Set custom bids

By default, your criteria use the bids from the ad group level. However, you can also set custom bids on the criterion level, using your own custom bidding logic.

Display Network custom bids

To enable custom bids at the criterion level in Display Network campaigns, you must enable it at the ad group level first, by specifying the dimension on which you want to enable custom bidding.

The following code snippet sets this value to PLACEMENT, so you can have custom bidding on your Placement criteria.

// Get the AdGroupService.
AdWordsUser user = new AdWordsUser();
AdGroupService adGroupService = (AdGroupService) user.GetService(
    AdWordsService.v201702.AdGroupService);

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

// Optional: Set the bidding group. This allows you to set absolute bids on
// this dimension. This setting only affects serving for the Display Network.
adGroup.contentBidCriterionTypeGroup = CriterionTypeGroup.PLACEMENT;
adGroup.id = adGroupId;

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

// Update the ad group.
AdGroupReturnValue adGroupRetVal = adGroupService.mutate(
   new AdGroupOperation[] {operation});

Next, you can update the bids of the criteria using the AdGroupCriterionService. This code snippet sets a custom bid of $6 per acquisition for a placement:

// Get the AdGroupCriterionService.
AdGroupCriterionService adGroupCriterionService =
    (AdGroupCriterionService) user.GetService(
         AdWordsService.v201702.AdGroupCriterionService);

// Since we are not updating any placement-specific fields, it is enough to
// create a criterion object. The placementId, in this case,
// is a pre-existing Placement targeting a website.
Criterion criterion = new Criterion();
criterion.id = placementId;

// Create ad group criterion.
BiddableAdGroupCriterion biddableAdGroupCriterion =
    new BiddableAdGroupCriterion();
biddableAdGroupCriterion.adGroupId = adGroupId;
biddableAdGroupCriterion.criterion = criterion;

// Create the bids.
BiddingStrategyConfiguration biddingConfig =
     new BiddingStrategyConfiguration();
CpaBid cpcBid = new CpaBid();
cpaBid.bid = new Money();
cpaBid.bid.microAmount = 6000000;
biddingConfig.bids = new Bids[] {cpaBid};

biddableAdGroupCriterion.biddingStrategyConfiguration = biddingConfig;

// Create the operation.
AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
operation.@operator = Operator.SET;
operation.operand = biddableAdGroupCriterion;

// Update the placement.
AdGroupCriterionReturnValue agcRetVal = adGroupCriterionService.mutate(
    new AdGroupCriterionOperation[] {operation});

Track campaign performance

Once you've set up your campaign, you'll want to track its effectiveness. The AdWords API supports multiple report types to track your campaign performance.

The following code snippet shows how to run a Campaign Performance Report to track your campaign's performance:

string query = "SELECT CampaignId, Conversions, Cost, Impressions from
CAMPAIGN_PERFORMANCE_REPORT DURING LAST_7_DAYS";

string filePath = ExampleUtilities.GetHomeDir() + Path.DirectorySeparatorChar
    + "CampaignPerformanceReport.gz";

ReportUtilities utilities = new ReportUtilities(user, "v201702", query,
    DownloadFormat.GZIPPED_CSV.ToString());
utilities.GetResponse().Save(fileName);

To measure how users interact with your application, set up in-app conversions. Create a conversion tracker for in-app conversions by following the instructions on setting up conversion tracking. Refer to the instructions on app conversion tracking to track user interactions in your application as conversions.

Code examples

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.