Asset-based extensions

Asset-based extensions will soon replace all feed-based extensions. Here are the current extensions that support assets, with more being added later:

  • Call
  • Callout
  • Hotel Callout
  • Lead Form
  • Location
  • Mobile App
  • Price
  • Promotion
  • Sitelink
  • Structured Snippet

Extension creation

There are two steps to creating an asset-based extension.

  1. Create a new asset.
  2. Associate the asset with a campaign, ad group, or customer.

We examine each of these steps by creating a lead form extension. Before using lead forms, you must accept the Lead form ads terms in your Google Ads account.

Create an asset

You can create a lead form asset by creating an Asset object and populating the lead_form_asset field. Call the AssetService::MutateAssets() method to execute an AssetOperation with the create field set to the new asset object.

Java

private static String createLeadFormAsset(GoogleAdsClient googleAdsClient, long customerId) {
  // Creates the lead form asset.
  Asset leadFormAsset =
      Asset.newBuilder()
          .setName("Interplanetary Cruise #" + getPrintableDateTime() + " Lead Form")
          .setLeadFormAsset(
              LeadFormAsset.newBuilder()
                  // Specify the details of the extension that the users will see.
                  .setCallToActionType(LeadFormCallToActionType.BOOK_NOW)
                  .setCallToActionDescription("Latest trip to Jupiter!")
                  // Define the form details.
                  .setBusinessName("Interplanetary Cruise")
                  .setHeadline("Trip to Jupiter")
                  .setDescription("Our latest trip to Jupiter is now open for booking.")
                  .setPrivacyPolicyUrl("http://example.com/privacy")
                  // Define the fields to be displayed to the user.
                  .addFields(
                      LeadFormField.newBuilder()
                          .setInputType(LeadFormFieldUserInputType.FULL_NAME)
                          .build())
                  .addFields(
                      LeadFormField.newBuilder()
                          .setInputType(LeadFormFieldUserInputType.EMAIL)
                          .build())
                  .addFields(
                      LeadFormField.newBuilder()
                          .setInputType(LeadFormFieldUserInputType.PHONE_NUMBER)
                          .build())
                  .addFields(
                      LeadFormField.newBuilder()
                          .setInputType(LeadFormFieldUserInputType.PREFERRED_CONTACT_TIME)
                          .setSingleChoiceAnswers(
                              LeadFormSingleChoiceAnswers.newBuilder()
                                  .addAnswers("Before 9 AM")
                                  .addAnswers("Any time")
                                  .addAnswers("After 5 PM")
                                  .build())
                          .build())
                  .addFields(
                      LeadFormField.newBuilder()
                          .setInputType(LeadFormFieldUserInputType.TRAVEL_BUDGET)
                          .build())

                  // Optional: You can also specify a background image asset.
                  // To upload an asset, see Misc/UploadImageAsset.java.
                  // .setBackgroundImageAsset("INSERT_IMAGE_ASSET_HERE")

                  // Optional: Define the response page after the user signs up on the form.
                  .setPostSubmitHeadline("Thanks for signing up!")
                  .setPostSubmitDescription(
                      "We will reach out to you shortly. Visit our website "
                          + "to see past trip details.")
                  .setPostSubmitCallToActionType(LeadFormPostSubmitCallToActionType.VISIT_SITE)
                  // Optional: Display a custom disclosure that displays along with Google
                  // disclaimer on the form.
                  .setCustomDisclosure("Trip may get cancelled due to meteor shower.")
                  // Optional: Define a delivery method for form response. See
                  // https://developers.google.com/google-ads/webhook/docs/overview for more
                  // details on how to define a webhook.
                  .addDeliveryMethods(
                      LeadFormDeliveryMethod.newBuilder()
                          .setWebhook(
                              WebhookDelivery.newBuilder()
                                  .setAdvertiserWebhookUrl("http://example.com/webhook")
                                  .setGoogleSecret("interplanetary google secret")
                                  .setPayloadSchemaVersion(3L)
                                  .build())
                          .build())
                  .build())
          .addFinalUrls("http://example.com/jupiter")
          .build();

  // Creates an operation to add the asset.
  AssetOperation operation = AssetOperation.newBuilder().setCreate(leadFormAsset).build();

  // Issues a mutate request to add the asset and prints its information.
  try (AssetServiceClient client =
      googleAdsClient.getLatestVersion().createAssetServiceClient()) {
    MutateAssetsResponse response =
        client.mutateAssets(String.valueOf(customerId), ImmutableList.of(operation));
    String resourceName = response.getResultsList().get(0).getResourceName();
    System.out.printf("Created asset with resource name '%s'.%n", resourceName);
    return resourceName;
  }
}
      

C#

private string CreateLeadFormAsset(GoogleAdsClient client, long customerId)
{
    AssetServiceClient assetService = client.GetService(Services.V13.AssetService);

    // Creates the lead form asset.
    Asset leadFormAsset = new Asset()
    {
        Name = $"Interplanetary Cruise #{ExampleUtilities.GetRandomString()} Lead Form",
        LeadFormAsset = new LeadFormAsset()
        {
            // Specify the details of the extension that the users will see.
            CallToActionType = LeadFormCallToActionType.BookNow,
            CallToActionDescription = "Latest trip to Jupiter!",

            // Define the form details.
            BusinessName = "Interplanetary Cruise",
            Headline = "Trip to Jupiter",
            Description = "Our latest trip to Jupiter is now open for booking.",
            PrivacyPolicyUrl = "http://example.com/privacy",

            // Define the fields to be displayed to the user.
            Fields = {
                new LeadFormField()
                {
                    InputType = LeadFormFieldUserInputType.FullName,
                },
                new LeadFormField()
                {
                    InputType = LeadFormFieldUserInputType.Email,
                },
                new LeadFormField()
                {
                    InputType = LeadFormFieldUserInputType.PhoneNumber,
                },
                new LeadFormField()
                {
                    InputType = LeadFormFieldUserInputType.PreferredContactTime,
                    SingleChoiceAnswers = new LeadFormSingleChoiceAnswers()
                    {
                        Answers = { "Before 9 AM", "Any time", "After 5 PM" }
                    }
                },
                new LeadFormField()
                {
                    InputType = LeadFormFieldUserInputType.TravelBudget,
                },
            },

            // Optional: You can also specify a background image asset. To upload an asset,
            // see Misc/UploadImageAsset.cs. BackgroundImageAsset =
            // "INSERT_IMAGE_ASSET_HERE",

            // Optional: Define the response page after the user signs up on the form.
            PostSubmitHeadline = "Thanks for signing up!",
            PostSubmitDescription = "We will reach out to you shortly. Visit our website " +
            "to see past trip details.",
            PostSubmitCallToActionType = LeadFormPostSubmitCallToActionType.VisitSite,

            // Optional: Display a custom disclosure that displays along with the Google
            // disclaimer on the form.
            CustomDisclosure = "Trip may get cancelled due to meteor shower.",

            // Optional: Define a delivery method for the form response. See
            // https://developers.google.com/google-ads/webhook/docs/overview for more
            // details on how to define a webhook.
            DeliveryMethods =
            {
                new LeadFormDeliveryMethod()
                {
                    Webhook = new WebhookDelivery()
                    {
                        AdvertiserWebhookUrl = "http://example.com/webhook",
                        GoogleSecret = "interplanetary google secret",
                        PayloadSchemaVersion = 3L
                    }
                }
            },
        },
        FinalUrls = { "http://example.com/jupiter" }
    };

    // Creates the operation.
    AssetOperation operation = new AssetOperation()
    {
        Create = leadFormAsset,
    };

    // Makes the API call.
    MutateAssetsResponse response = assetService.MutateAssets(customerId.ToString(),
        new[] { operation });

    string leadFormAssetResourceName = response.Results[0].ResourceName;

    // Displays the result.
    Console.WriteLine($"Asset with resource name = '{leadFormAssetResourceName}' " +
        "was created.");
    return leadFormAssetResourceName;
}
      

PHP

private static function createLeadFormAsset(
    GoogleAdsClient $googleAdsClient,
    int $customerId
): string {
    // Creates the lead form asset.
    $leadFormAsset = new Asset([
        'name' => 'Interplanetary Cruise #' . Helper::getPrintableDatetime() . ' Lead Form',
        'lead_form_asset' => new LeadFormAsset([
            // Specifies the details of the extension that the users will see.
            'call_to_action_type' => LeadFormCallToActionType::BOOK_NOW,
            'call_to_action_description' => 'Latest trip to Jupiter!',
            // Defines the form details.
            'business_name' => 'Interplanetary Cruise',
            'headline' => 'Trip to Jupiter',
            'description' => 'Our latest trip to Jupiter is now open for booking.',
            'privacy_policy_url' => 'http://example.com/privacy',
            // Defines the fields to be displayed to the user.
            'fields' => [
                new LeadFormField(['input_type' => LeadFormFieldUserInputType::FULL_NAME]),
                new LeadFormField(['input_type' => LeadFormFieldUserInputType::EMAIL]),
                new LeadFormField(['input_type' => LeadFormFieldUserInputType::PHONE_NUMBER]),
                new LeadFormField([
                    'input_type' => LeadFormFieldUserInputType::PREFERRED_CONTACT_TIME,
                    'single_choice_answers' => new LeadFormSingleChoiceAnswers([
                        'answers' => ['Before 9 AM', 'Any time', 'After 5 PM']
                    ])
                ]),
                new LeadFormField(['input_type' => LeadFormFieldUserInputType::TRAVEL_BUDGET])
            ],
            // Optional: You can also specify a background image asset.
            // To upload an asset, see Misc/UploadImageAsset.php.
            // 'background_image_asset' => 'INSERT_IMAGE_ASSET_RESOURCE_NAME_HERE',

            // Optional: Defines the response page after the user signs up on the form.
            'post_submit_headline' => 'Thanks for signing up!',
            'post_submit_description' => 'We will reach out to you shortly. '
                . 'Visit our website to see past trip details.',
            'post_submit_call_to_action_type' => LeadFormPostSubmitCallToActionType::VISIT_SITE,
            // Optional: Displays a custom disclosure that displays along with Google
            // disclaimer on the form.
            'custom_disclosure' => 'Trip may get cancelled due to meteor shower.',
            // Optional: Defines a delivery method for form response. See
            // https://developers.google.com/google-ads/webhook/docs/overview for more
            // details on how to define a webhook.
            'delivery_methods' => [new LeadFormDeliveryMethod([
                'webhook' => new WebhookDelivery([
                    'advertiser_webhook_url' => 'http://example.com/webhook',
                    'google_secret' => 'interplanetary google secret',
                    'payload_schema_version' => 3
                ])
            ])]
        ]),
        'final_urls' => ['http://example.com/jupiter']
    ]);

    // Creates an operation to add the asset.
    $assetOperation = new AssetOperation();
    $assetOperation->setCreate($leadFormAsset);

    // Issues a mutate request to add the asset and prints its information.
    $assetServiceClient = $googleAdsClient->getAssetServiceClient();
    $response = $assetServiceClient->mutateAssets($customerId, [$assetOperation]);
    $assetResourceName = $response->getResults()[0]->getResourceName();
    printf("Created an asset with resource name: '%s'.%s", $assetResourceName, PHP_EOL);

    return $assetResourceName;
}
      

Python

def create_lead_form_asset(client, customer_id):
    """Creates a lead form asset using the given customer ID.

    Args:
        client: An initialized GoogleAdsClient instance.
        customer_id: The Google Ads customer ID.

    Returns:
        A str of the resource name for the newly created lead form asset.
    """
    asset_service = client.get_service("AssetService")
    asset_operation = client.get_type("AssetOperation")
    asset = asset_operation.create
    asset.name = f"Interplanetary Cruise #{uuid4()} Lead Form"
    asset.final_urls.append("http://example.com/jupiter")

    # Creates a new LeadFormAsset instance.
    lead_form_asset = asset.lead_form_asset

    # Specify the details of the extension that the users will see.
    lead_form_asset.call_to_action_type = (
        client.enums.LeadFormCallToActionTypeEnum.BOOK_NOW
    )
    lead_form_asset.call_to_action_description = "Latest trip to Jupiter!"

    # Define the form details.
    lead_form_asset.business_name = "Interplanetary Cruise"
    lead_form_asset.headline = "Trip to Jupiter"
    lead_form_asset.description = (
        "Our latest trip to Jupiter is now open for booking."
    )
    lead_form_asset.privacy_policy_url = "http://example.com/privacy"

    # Define the fields to be displayed to the user.
    input_type_enum = client.enums.LeadFormFieldUserInputTypeEnum
    lead_form_field_1 = client.get_type("LeadFormField")
    lead_form_field_1.input_type = input_type_enum.FULL_NAME
    lead_form_asset.fields.append(lead_form_field_1)

    lead_form_field_2 = client.get_type("LeadFormField")
    lead_form_field_2.input_type = input_type_enum.EMAIL
    lead_form_asset.fields.append(lead_form_field_2)

    lead_form_field_3 = client.get_type("LeadFormField")
    lead_form_field_3.input_type = input_type_enum.PHONE_NUMBER
    lead_form_asset.fields.append(lead_form_field_3)

    lead_form_field_4 = client.get_type("LeadFormField")
    lead_form_field_4.input_type = input_type_enum.PREFERRED_CONTACT_TIME
    lead_form_field_4.single_choice_answers.answers.extend(
        ["Before 9 AM", "Anytime", "After 5 PM"]
    )
    lead_form_asset.fields.append(lead_form_field_4)

    # Optional: You can also specify a background image asset.
    # To upload an asset, see misc/upload_image.py.
    # lead_form_asset.background_image_asset = "INSERT_IMAGE_ASSET_HERE"

    # Optional: Define the response page after the user signs up on the form.
    lead_form_asset.post_submit_headline = "Thanks for signing up!"
    lead_form_asset.post_submit_description = (
        "We will reach out to you shortly. Visit our website to see past trip "
        "details."
    )
    lead_form_asset.post_submit_call_to_action_type = (
        client.enums.LeadFormPostSubmitCallToActionTypeEnum.VISIT_SITE
    )

    # Optional: Display a custom disclosure that displays along with the Google
    # disclaimer on the form.
    lead_form_asset.custom_disclosure = (
        "Trip may get cancelled due to meteor shower"
    )

    # Optional: Define a delivery method for the form response. See
    # https://developers.google.com/google-ads/webhook/docs/overview for more
    # details on how to define a webhook.
    delivery_method = client.get_type("LeadFormDeliveryMethod")
    delivery_method.webhook.advertiser_webhook_url = (
        "http://example.com/webhook"
    )
    delivery_method.webhook.google_secret = "interplanetary google secret"
    delivery_method.webhook.payload_schema_version = 3
    lead_form_asset.delivery_methods.append(delivery_method)

    asset_service = client.get_service("AssetService")
    response = asset_service.mutate_assets(
        customer_id=customer_id, operations=[asset_operation]
    )
    resource_name = response.results[0].resource_name

    print(f"Asset with resource name {resource_name} was created.")

    return resource_name
      

Ruby

def create_lead_form_asset(client, customer_id)
  operation = client.operation.create_resource.asset do |a|
    a.name = "Interplanetary Cruise #{(Time.new.to_f * 1000).to_i} Lead Form"
    a.final_urls << "http://example.com/jupiter"

    a.lead_form_asset = client.resource.lead_form_asset do |lfa|
      lfa.call_to_action_type = :BOOK_NOW
      lfa.call_to_action_description = "Latest trip to Jupiter!"

      lfa.business_name = "Interplanetary Cruise"
      lfa.headline = "Trip to Jupiter"
      lfa.description = "Our latest trip to Jupiter is now open for booking."
      lfa.privacy_policy_url = "http://example.com/privacy"

      lfa.fields << client.resource.lead_form_field do |lff|
        lff.input_type = :FULL_NAME
      end
      lfa.fields << client.resource.lead_form_field do |lff|
        lff.input_type = :EMAIL
      end
      lfa.fields << client.resource.lead_form_field do |lff|
        lff.input_type = :PHONE_NUMBER
      end
      lfa.fields << client.resource.lead_form_field do |lff|
        lff.input_type = :PREFERRED_CONTACT_TIME
        lff.single_choice_answers = client.resource.lead_form_single_choice_answers do |sca|
          sca.answers += ["Before 9 AM", "Anytime", "After 5 PM"]
        end
      end

      # Optional: You can also specify a background image asset.
      # To upload an asset, see misc/upload_image_asset.rb.
      # lfa.background_image_asset = "INSERT_IMAGE_ASSET_HERE"

      # Optional: Define the response page after the user signs up on the form.
      lfa.post_submit_headline = "Thanks for signing up!"
      lfa.post_submit_description = "We will reach out to you shortly. " \
        "Visit our website to see past trip details."
      lfa.post_submit_call_to_action_type = :VISIT_SITE

      # Optional
      # lfa.custom_disclosure = "Trip may get cancelled due to meteor shower."

      # Optional: Define a delivery method for the form response. See
      # https://developers.google.com/google-ads/webhook/docs/overview for more
      # details on how to define a webhook.
      lfa.delivery_methods << client.resource.lead_form_delivery_method do |lfdm|
        lfdm.webhook = client.resource.webhook_delivery do |wd|
          wd.advertiser_webhook_url = "http://example.com/webhook"
          wd.google_secret = "interplanetary google secret"
          wd.payload_schema_version = 3
        end
      end
    end
  end

  response = client.service.asset.mutate_assets(
    customer_id: customer_id,
    operations: [operation],
  )
  asset_name = response.results.first.resource_name

  puts "Asset with resource name #{asset_name} was created."
  asset_name
end
      

Perl

sub create_lead_form_asset {
  my ($api_client, $customer_id) = @_;

  # Create the lead form asset.
  my $lead_form_asset = Google::Ads::GoogleAds::V13::Resources::Asset->new({
      name          => "Interplanetary Cruise Lead Form #" . uniqid(),
      leadFormAsset => Google::Ads::GoogleAds::V13::Common::LeadFormAsset->new({
          # Specify the details of the extension that the users will see.
          callToActionType        => BOOK_NOW,
          callToActionDescription => "Latest trip to Jupiter!",

          # Define the form details.
          businessName => "Interplanetary Cruise",
          headline     => "Trip to Jupiter",
          description  => "Our latest trip to Jupiter is now open for booking.",
          privacyPolicyUrl => "http://example.com/privacy",

          # Define the fields to be displayed to the user.
          fields => [
            Google::Ads::GoogleAds::V13::Common::LeadFormField->new({
                inputType => FULL_NAME
              }
            ),
            Google::Ads::GoogleAds::V13::Common::LeadFormField->new({
                inputType => EMAIL
              }
            ),
            Google::Ads::GoogleAds::V13::Common::LeadFormField->new({
                inputType => PHONE_NUMBER
              }
            ),
            Google::Ads::GoogleAds::V13::Common::LeadFormField->new({
                inputType           => PREFERRED_CONTACT_TIME,
                singleChoiceAnswers =>
                  Google::Ads::GoogleAds::V13::Common::LeadFormSingleChoiceAnswers
                  ->new({
                    answers => ["Before 9 AM", "Any time", "After 5 PM"]})}
            ),
            Google::Ads::GoogleAds::V13::Common::LeadFormField->new({
                inputType => TRAVEL_BUDGET
              })
          ],

          # Optional: You can also specify a background image asset.
          # To upload an asset, see misc/upload_image_asset.pl.
          # backgroundImageAsset => "INSERT_IMAGE_ASSET_HERE",

          # Optional: Define the response page after the user signs up on the form.
          postSubmitHeadline    => "Thanks for signing up!",
          postSubmitDescription => "We will reach out to you shortly. " .
            "Visit our website to see past trip details.",
          postSubmitCallToActionType => VISIT_SITE,

          # Optional: Display a custom disclosure that displays along with the
          # Google disclaimer on the form.
          customDisclosure => "Trip may get cancelled due to meteor shower.",

          # Optional: Define a delivery method for the form response. See
          # https://developers.google.com/google-ads/webhook/docs/overview for
          # more details on how to define a webhook.
          deliveryMethods => [
            Google::Ads::GoogleAds::V13::Common::LeadFormDeliveryMethod->new({
                webhook =>
                  Google::Ads::GoogleAds::V13::Common::WebhookDelivery->new({
                    advertiserWebhookUrl => "http://example.com/webhook",
                    googleSecret         => "interplanetary google secret",
                    payloadSchemaVersion => 3
                  })})]}
      ),
      finalUrls => ["http://example.com/jupiter"]});

  # Create the operation.
  my $asset_operation =
    Google::Ads::GoogleAds::V13::Services::AssetService::AssetOperation->new({
      create => $lead_form_asset
    });

  my $assets_response = $api_client->AssetService()->mutate({
      customerId => $customer_id,
      operations => [$asset_operation]});

  my $lead_form_asset_resource_name =
    $assets_response->{results}[0]{resourceName};

  # Display the result.
  printf "Asset with resource name = '%s' was created.\n",
    $lead_form_asset_resource_name;
  return $lead_form_asset_resource_name;
}
      

Associate the asset with a resource

Next, associate the asset with a resource by creating a CampaignAsset, AdGroupAsset, or CustomerAsset object. This example demonstrates how to associate the asset with a campaign.

Set the field_type field to LEAD_FORM. Call the CampaignAssetService::MutateCampaignAssets() method to execute a CampaignAssetOperation with the create field set to the new CampaignAsset object.

Java

private static void createLeadFormExtension(
    GoogleAdsClient googleAdsClient,
    long customerId,
    long campaignId,
    String leadFormAssetResourceName) {
  // Creates the campaign asset for the lead form.
  CampaignAsset campaignAsset =
      CampaignAsset.newBuilder()
          .setAsset(leadFormAssetResourceName)
          .setFieldType(AssetFieldType.LEAD_FORM)
          .setCampaign(ResourceNames.campaign(customerId, campaignId))
          .build();

  // Creates an operation to add the campaign asset.
  CampaignAssetOperation operation =
      CampaignAssetOperation.newBuilder().setCreate(campaignAsset).build();

  // Issues a mutate request to add the campaign asset and prints its information.
  try (CampaignAssetServiceClient client =
      googleAdsClient.getLatestVersion().createCampaignAssetServiceClient()) {
    MutateCampaignAssetsResponse response =
        client.mutateCampaignAssets(String.valueOf(customerId), ImmutableList.of(operation));
    System.out.printf(
        "Created campaign asset with resource name '%s' for campaign ID %d.%n",
        response.getResultsList().get(0).getResourceName(), campaignId);
  }
}
      

C#

private void CreateLeadFormExtension(GoogleAdsClient client, long customerId,
    long campaignId, string leadFormAssetResourceName)
{
    CampaignAssetServiceClient campaignAssetService = client.GetService(
        Services.V13.CampaignAssetService);

    // Creates the campaign asset for the lead form.
    CampaignAsset campaignAsset = new CampaignAsset()
    {
        Asset = leadFormAssetResourceName,
        FieldType = AssetFieldTypeEnum.Types.AssetFieldType.LeadForm,
        Campaign = ResourceNames.Campaign(customerId, campaignId),
    };

    CampaignAssetOperation operation = new CampaignAssetOperation()
    {
        Create = campaignAsset
    };

    MutateCampaignAssetsResponse response = campaignAssetService.MutateCampaignAssets(
        customerId.ToString(), new[] { operation });

    foreach (MutateCampaignAssetResult result in response.Results)
    {
        Console.WriteLine("Created campaign asset with resource name =" +
            $" '{result.ResourceName}' for campaign ID {campaignId}.");
    }
}
      

PHP

private static function createLeadFormExtension(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    int $campaignId,
    string $leadFormAssetResourceName
) {
    // Creates the campaign asset for the lead form.
    $campaignAsset = new CampaignAsset([
        'asset' => $leadFormAssetResourceName,
        'field_type' => AssetFieldType::LEAD_FORM,
        'campaign' => ResourceNames::forCampaign($customerId, $campaignId)
    ]);

    // Creates an operation to add the campaign asset.
    $campaignAssetOperation = new CampaignAssetOperation();
    $campaignAssetOperation->setCreate($campaignAsset);

    // Issues a mutate request to add the campaign asset and prints its information.
    $campaignAssetServiceClient = $googleAdsClient->getCampaignAssetServiceClient();
    $response = $campaignAssetServiceClient->mutateCampaignAssets(
        $customerId,
        [$campaignAssetOperation]
    );
    printf(
        "Created a campaign asset with resource name '%s' for campaign ID %d.%s",
        $response->getResults()[0]->getResourceName(),
        $campaignId,
        PHP_EOL
    );
}
      

Python

def create_lead_form_extension(
    client, customer_id, campaign_id, lead_form_asset_resource_name
):
    """Creates the lead form extension.

    Args:
        client: An initialized GoogleAdsClient instance.
        customer_id: The Google Ads customer ID.
        campaign_id: The ID for a Campaign belonging to the given customer.
    """
    campaign_service = client.get_service("CampaignService")
    campaign_asset_service = client.get_service("CampaignAssetService")
    campaign_asset_operation = client.get_type("CampaignAssetOperation")
    campaign_asset = campaign_asset_operation.create
    campaign_asset.asset = lead_form_asset_resource_name
    campaign_asset.field_type = client.enums.AssetFieldTypeEnum.LEAD_FORM
    campaign_asset.campaign = campaign_service.campaign_path(
        customer_id, campaign_id
    )

    response = campaign_asset_service.mutate_campaign_assets(
        customer_id=customer_id, operations=[campaign_asset_operation]
    )
    for result in response.results:
        print(
            "Created campaign asset with resource name "
            f'"{result.resource_name}" for campaign with ID {campaign_id}'
        )
      

Ruby

def create_lead_form_extension(client, customer_id, campaign_id, lead_form_asset)
  operation = client.operation.create_resource.campaign_asset do |ca|
    ca.asset = lead_form_asset
    ca.field_type = :LEAD_FORM
    ca.campaign = client.path.campaign(customer_id, campaign_id)
  end

  response = client.service.campaign_asset.mutate_campaign_assets(
    customer_id: customer_id,
    operations: [operation],
  )

  puts "Created campaign asset #{response.results.first.resource_name} for " \
    "campaign #{campaign_id}."
end
      

Perl

sub create_lead_form_extension {
  my ($api_client, $customer_id, $campaign_id, $lead_form_asset_resource_name)
    = @_;

  # Create the campaign asset for the lead form.
  my $campaign_asset =
    Google::Ads::GoogleAds::V13::Resources::CampaignAsset->new({
      asset     => $lead_form_asset_resource_name,
      fieldType => LEAD_FORM,
      campaign  => Google::Ads::GoogleAds::V13::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
      )});

  my $campaign_asset_operation =
    Google::Ads::GoogleAds::V13::Services::CampaignAssetService::CampaignAssetOperation
    ->new({
      create => $campaign_asset
    });

  my $campaign_assets_response = $api_client->CampaignAssetService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_asset_operation]});

  printf
    "Created campaign asset with resource name = '%s' for campaign ID %d.\n",
    $campaign_assets_response->{results}[0]{resourceName}, $campaign_id;
}
      

Extension updates

To update the underlying extension properties, update the Asset using the MutateAssets method from AssetService. To remove the extension from a campaign, remove the CampaignAsset.

Reports

The contents of an individual asset can be fetched by issuing a Google Ads Query Language query to the asset report.

Asset-based extension performance statistics can be requested from the asset_field_type_view report.

Asset selection order

The asset selected for serving is determined by whether it had been linked at the ad group, campaign, or customer level:

  1. An asset linked at the ad group level serves in that ad group.
  2. If no assets are linked at the ad group level, but are linked at the campaign level, then the campaign level assets will serve.
  3. If no assets are linked at either the ad group or campaign level, then assets linked at the customer level will serve.

Asset removal

Assets can't be removed. To stop an asset from serving, remove the link to the campaign, ad group, and so on.

There is also no global quota on the number of assets allowed per account, though we are planning to add limits in the near future. For optimal performance, edit an existing asset rather than adding a new one.