Create Conversion Actions

This guide provides a list of the different types of conversion actions you can create using the Google Ads API, information on how these map to the Google Ads web interface, and a detailed code example demonstrating how to create new conversion actions.

To measure conversions, set up a ConversionAction for the type of conversion action you want to track. For example, an online purchase and a phone call require different conversion actions.

The best way to set up new conversion actions in the API is to use the Add Conversion Action code example below. The sample handles all the background authentication tasks for you, and walks you through creating a ConversionAction.

Most conversion actions also require additional steps on your part to track them. For example, to track conversions on your website, you must add a code snippet called a tag to the conversion page on your website. For other conversion action requirements, see our Help Center article.

Website conversions

A website conversion lets you track website actions such as online sales, link clicks, page views, and sign-ups.

To track conversions on your website, you must create a ConversionAction with the ConversionActionType set to WEBPAGE, and add a code snippet called a tag to the conversion page on your website.

The ConversionAction encompasses several types of website conversions, distinguished within the API by the type field in each TagSnippet listed in the tag_snippets field of a ConversionAction.

A TagSnippet provides the tracking code that must be included in your website in order to track your conversion actions. Website and Phone number click conversions require the event_snippet, which should be placed on web pages that indicate a conversion action such as a checkout confirmation or lead form submission page, and global_site_tag, which must be installed on every page of your website. You can retrieve both of these attributes with the ConversionActionService. Check out our Help Center for more information on how to tag your pages.

The following table shows the equivalent API parameters to use for each Source in the Google Ads web interface:

Tracking Code Type Google Ads Source
WEBPAGE Website, Website (Google Analytics (GA4))
WEBPAGE_ONCLICK Website, Website (Google Analytics (GA4))
CLICK_TO_CALL Phone number clicks
--- Website (Google Analytics (UA))

App conversions

An app conversion lets you track mobile app installs or in app purchases from the Google Play Store.

The following table shows the equivalent ConversionActionType API parameters to use for each Source in the Google Ads web interface:

Conversion Action Type Google Ads Source
GOOGLE_PLAY_DOWNLOAD Google Play > Installs
GOOGLE_PLAY_IN_APP_PURCHASE Google Play > In-app purchases

If you are looking to track other mobile app actions using Google Analytics 4 properties or third-party app analytics. See Additional Conversion Action Types.

Phone call conversions

Phone call conversion tracking lets you tracks calls from ads, calls to a number on your website and clicks on numbers on mobile sites.

The following table shows the equivalent ConversionActionType API parameters to use for each Source in the Google Ads web interface:

Conversion Action Type Google Ads Source
AD_CALL Calls from ads using call extensions or call-only ads
WEBSITE_CALL Calls to a phone number on your website
CLICK_TO_CALL Clicks on a number on your mobile website

The CLICK_TO_CALL type differs from the AD_CALL type in that it does not track actual phone calls. Instead, CLICK_TO_CALL only tracks clicks on a phone number from a mobile device. This is useful when you're unable to use a Google forwarding number for tracking phone calls.

AD_CALL

An AD_CALL conversion action appears as a Calls from ads conversion in the Google Ads web interface. After you create your AD_CALL conversion action, specify its resource name in the call_conversion_action field when you create a CallAsset. Call assets let you show a phone number directly in your ads.

A call is reported as a conversion if it lasts longer than a specified duration. The default is 60 seconds.

WEBSITE_CALL

A WEBSITE_CALL conversion action appears as a Calls from a website conversion in the Google Ads web interface.

Unlike AD_CALL, this tracker requires event_snippet and global_site_tag to be added to your website to retrieve the dynamic Google forwarding number for call tracking on numbers listed on your website. In addition, you must set up a call asset and link it at the customer, campaign, or ad group level.

Import offline conversions

The following table shows the equivalent ConversionActionType API parameters to use for each Source in the Google Ads web interface and a link to the documentation for each specific conversion action type:

Conversion Action Type Google Ads Source API Setup Guide
UPLOAD_CLICKS Track conversions from clicks and enhanced conversions for leads Upload Clicks Guide
Enhanced Conversions for Leads Guide
UPLOAD_CALLS Track conversions from calls API Setup Guide
STORE_SALES Track conversions store sales API Setup Guide

Enhanced conversions for web

Enhanced conversions for web let you send first-party conversion data for WEBPAGE conversion actions within 24 hours of a conversion event instead of at the same time. This makes it possible to locate first-party data from a variety of sources, such as a customer database or CRM system.

Additional conversion action types

The Google Ads API makes additional types of conversion actions available in reports, but may limit or prohibit creation or modification of those actions.

SKAdNetwork conversions

If you run iOS App campaigns and have implemented SKAdNetwork, you can access SKAdNetwork data provided to Google at the Customer and Campaign level using the following resources:

Report field Description
metrics.sk_ad_network_conversions The number of conversions reported by Apple. This metric can only be segmented by any combination of segments.sk_ad_network_conversion_value and date-related segments.
segments.sk_ad_network_conversion_value

The value of a conversion reported by Apple. This segment cannot be applied to any metric other than metrics.sk_ad_network_conversions, and can only be combined with date-related segments.

A value of 0 is returned if Apple reports a value of 0 and no value otherwise. Check the field presence to distinguish between the two cases.

You can also save a SKAdNetwork conversion value mapping for specific linked customers with iOS apps through CustomerSkAdNetworkConversionValueSchema.

Sample Python code

#!/usr/bin/env python
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import sys

from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException

def main(client, customer_id):
    """Adds a keyword plan, campaign, ad group, etc. to the customer account.

    Also handles errors from the API and prints them.

    Args:
        client: An initialized instance of GoogleAdsClient
        customer_id: A str of the customer_id to use in requests.
    """

    res = update_skan_cv_schema(
        client, customer_id, "my_app_id", "account_link_id"
    )
    print(res)

def update_skan_cv_schema(client, customer_id, app_id, account_link_id):
    skan_service = client.get_service(
        "CustomerSkAdNetworkConversionValueSchemaService"
    )

    req = client.get_type(
        "MutateCustomerSkAdNetworkConversionValueSchemaRequest"
    )
    operation = client.get_type(
        "CustomerSkAdNetworkConversionValueSchemaOperation"
    )
    schema_instance = client.get_type(
        "CustomerSkAdNetworkConversionValueSchema"
    )

    new_schema = operation.update
    new_schema.resource_name = (
        skan_service.customer_sk_ad_network_conversion_value_schema_path(
            "customer_id", "account_link_id"
        )
    )
    new_schema.schema.app_id = app_id
    new_schema.schema.measurement_window_hours = 48

    skan_cv_mapping = (
        schema_instance.SkAdNetworkConversionValueSchema.FineGrainedConversionValueMappings()
    )
    skan_cv_mapping.fine_grained_conversion_value = 0  # 0 - 63
    skan_cv_mapping.conversion_value_mapping.min_time_post_install_hours = 0
    skan_cv_mapping.conversion_value_mapping.max_time_post_install_hours = 48

    skan_cv_event = schema_instance.SkAdNetworkConversionValueSchema.Event()
    skan_cv_event.mapped_event_name = "TEST"
    skan_cv_event.event_revenue_value = 10

    skan_cv_mapping.conversion_value_mapping.mapped_events.append(skan_cv_event)
    new_schema.schema.fine_grained_conversion_value_mappings.append(
        skan_cv_mapping
    )

    req.operation = operation
    req.customer_id = customer_id

    res = skan_service.mutate_customer_sk_ad_network_conversion_value_schema(
        req
    )
    return res

if __name__ == "__main__":
    # GoogleAdsClient will read the google-ads.yaml configuration file in the
    # home directory if none is specified.
    googleads_client = GoogleAdsClient.load_from_storage(
        version="v16"
    )

    parser = argparse.ArgumentParser(
        description="Creates a keyword plan for specified customer."
    )
    # The following argument(s) should be provided to run the example.
    parser.add_argument(
        "-c",
        "--customer_id",
        type=str,
        required=True,
        help="The Google Ads customer ID.",
    )
    args = parser.parse_args()

    try:
        main(googleads_client, args.customer_id)
    except GoogleAdsException as ex:
        print(
            f'Request with ID "{ex.request_id}" failed with status '
            f'"{ex.error.code().name}" and includes the following errors:'
        )
        for error in ex.failure.errors:
            print(f'\tError with message "{error.message}".')
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)
  

Google Analytics

Conversions from a linked Google Analytics property have one of the following type values:

  • GA4 property conversion:

    • GOOGLE_ANALYTICS_4_CUSTOM
    • GOOGLE_ANALYTICS_4_PURCHASE

    You can also retrieve the GA4 property ID, property name, and event name from the google_analytics_4_settings field.

  • Universal Analytics property conversion:

    • UNIVERSAL_ANALYTICS_GOAL
    • UNIVERSAL_ANALYTICS_TRANSACTION

You can make the following changes to a GA4 property conversion:

  • Import the conversion from your GA4 property into your Google Ads account by modifying its status field from HIDDEN to ENABLED.
  • Modify its primary_for_goal and category fields to indicate how it should impact Google Ads bidding and reports.
  • Update its name or value_settings.
  • Remove the conversion from your Google Ads account using a remove operation.

Any attempt to modify other attributes of an imported GA4 conversion or any attributes of an imported Universal Analytics conversion results in a MUTATE_NOT_ALLOWED error. You can only make those changes using the Google Ads UI.

Firebase and third-party app analytics

To import third-party app analytics or Firebase conversions, change the status of the ConversionAction from HIDDEN to ENABLED using the mutate method of ConversionActionService. Updating the app_id is not supported for these conversion actions.

  • FIREBASE_ANDROID_FIRST_OPEN
  • FIREBASE_ANDROID_IN_APP_PURCHASE
  • FIREBASE_ANDROID_CUSTOM
  • FIREBASE_IOS_FIRST_OPEN
  • FIREBASE_IOS_IN_APP_PURCHASE
  • FIREBASE_IOS_CUSTOM
  • THIRD_PARTY_APP_ANALYTICS_ANDROID_FIRST_OPEN
  • THIRD_PARTY_APP_ANALYTICS_ANDROID_IN_APP_PURCHASE
  • THIRD_PARTY_APP_ANALYTICS_ANDROID_CUSTOM
  • THIRD_PARTY_APP_ANALYTICS_IOS_FIRST_OPEN
  • THIRD_PARTY_APP_ANALYTICS_IOS_IN_APP_PURCHASE
  • THIRD_PARTY_APP_ANALYTICS_IOS_CUSTOM

Store sales

Although you cannot create STORE_SALES or STORE_SALES_DIRECT_UPLOAD conversion actions using the Google Ads API, the API does support uploading store sales transactions.

  • STORE_SALES
  • STORE_SALES_DIRECT_UPLOAD

Miscellaneous

The following conversion action types are read-only in the Google Ads API and provided for reporting purposes.

  • ANDROID_APP_PRE_REGISTRATION
  • ANDROID_INSTALLS_ALL_OTHER_APPS
  • FLOODLIGHT_ACTION
  • FLOODLIGHT_TRANSACTION
  • GOOGLE_HOSTED
  • LEAD_FORM_SUBMIT
  • SALESFORCE
  • SEARCH_ADS_360
  • SMART_CAMPAIGN_AD_CLICKS_TO_CALL
  • SMART_CAMPAIGN_MAP_CLICKS_TO_CALL
  • SMART_CAMPAIGN_MAP_DIRECTIONS
  • SMART_CAMPAIGN_TRACKED_CALLS
  • STORE_VISITS
  • WEBPAGE_CODELESS

Unknown

If your Google Ads account includes other types of conversion actions, you may find that queries and reports return conversion actions where the ConversionAction.type is UNKNOWN. The API does not support managing these conversion actions, but returns them in reports in order to provide complete results for key conversion metrics such as metrics.conversions and metrics.conversions_value.

Code example

The following code example walks you through the process of creating a new conversion action. Specifically, it creates a conversion action with the type set to UPLOAD_CLICKS. This is the same Google Ads UI flow as creating a new conversion action using Import > Manual import using API or uploads > Track conversions from clicks. It also sets the category to DEFAULT.

The following default settings apply:

Java

private void runExample(GoogleAdsClient googleAdsClient, long customerId) {

  // Creates a ConversionAction.
  ConversionAction conversionAction =
      ConversionAction.newBuilder()
          // Note that conversion action names must be unique. If a conversion action already
          // exists with the specified conversion_action_name the create operation will fail with
          // a ConversionActionError.DUPLICATE_NAME error.
          .setName("Earth to Mars Cruises Conversion #" + getPrintableDateTime())
          .setCategory(ConversionActionCategory.DEFAULT)
          .setType(ConversionActionType.WEBPAGE)
          .setStatus(ConversionActionStatus.ENABLED)
          .setViewThroughLookbackWindowDays(15L)
          .setValueSettings(
              ValueSettings.newBuilder()
                  .setDefaultValue(23.41)
                  .setAlwaysUseDefaultValue(true)
                  .build())
          .build();

  // Creates the operation.
  ConversionActionOperation operation =
      ConversionActionOperation.newBuilder().setCreate(conversionAction).build();

  try (ConversionActionServiceClient conversionActionServiceClient =
      googleAdsClient.getLatestVersion().createConversionActionServiceClient()) {
    MutateConversionActionsResponse response =
        conversionActionServiceClient.mutateConversionActions(
            Long.toString(customerId), Collections.singletonList(operation));
    System.out.printf("Added %d conversion actions:%n", response.getResultsCount());
    for (MutateConversionActionResult result : response.getResultsList()) {
      System.out.printf(
          "New conversion action added with resource name: '%s'%n", result.getResourceName());
    }
  }
}
      

C#

public void Run(GoogleAdsClient client, long customerId)
{
    // Get the ConversionActionService.
    ConversionActionServiceClient conversionActionService =
        client.GetService(Services.V16.ConversionActionService);

    // Note that conversion action names must be unique.
    // If a conversion action already exists with the specified name the create operation
    // will fail with a ConversionAction.DUPLICATE_NAME error.
    string ConversionActionName = "Earth to Mars Cruises Conversion #"
        + ExampleUtilities.GetRandomString();

    // Add a conversion action.
    ConversionAction conversionAction = new ConversionAction()
    {
        Name = ConversionActionName,
        Category = ConversionActionCategory.Default,
        Type = ConversionActionType.Webpage,
        Status = ConversionActionStatus.Enabled,
        ViewThroughLookbackWindowDays = 15,
        ValueSettings = new ConversionAction.Types.ValueSettings()
        {
            DefaultValue = 23.41,
            AlwaysUseDefaultValue = true
        }
    };

    // Create the operation.
    ConversionActionOperation operation = new ConversionActionOperation()
    {
        Create = conversionAction
    };

    try
    {
        // Create the conversion action.
        MutateConversionActionsResponse response =
            conversionActionService.MutateConversionActions(customerId.ToString(),
                    new ConversionActionOperation[] { operation });

        // Display the results.
        foreach (MutateConversionActionResult newConversionAction in response.Results)
        {
            Console.WriteLine($"New conversion action with resource name = " +
                $"'{newConversionAction.ResourceName}' was added.");
        }
    }
    catch (GoogleAdsException e)
    {
        Console.WriteLine("Failure:");
        Console.WriteLine($"Message: {e.Message}");
        Console.WriteLine($"Failure: {e.Failure}");
        Console.WriteLine($"Request ID: {e.RequestId}");
        throw;
    }
}
      

PHP

public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId)
{
    // Creates a conversion action.
    $conversionAction = new ConversionAction([
        // Note that conversion action names must be unique.
        // If a conversion action already exists with the specified conversion_action_name
        // the create operation will fail with a ConversionActionError.DUPLICATE_NAME error.
        'name' => 'Earth to Mars Cruises Conversion #' . Helper::getPrintableDatetime(),
        'category' => ConversionActionCategory::PBDEFAULT,
        'type' => ConversionActionType::WEBPAGE,
        'status' => ConversionActionStatus::ENABLED,
        'view_through_lookback_window_days' => 15,
        'value_settings' => new ValueSettings([
            'default_value' => 23.41,
            'always_use_default_value' => true
        ])
    ]);

    // Creates a conversion action operation.
    $conversionActionOperation = new ConversionActionOperation();
    $conversionActionOperation->setCreate($conversionAction);

    // Issues a mutate request to add the conversion action.
    $conversionActionServiceClient = $googleAdsClient->getConversionActionServiceClient();
    $response = $conversionActionServiceClient->mutateConversionActions(
        MutateConversionActionsRequest::build($customerId, [$conversionActionOperation])
    );

    printf("Added %d conversion actions:%s", $response->getResults()->count(), PHP_EOL);

    foreach ($response->getResults() as $addedConversionAction) {
        /** @var ConversionAction $addedConversionAction */
        printf(
            "New conversion action added with resource name: '%s'%s",
            $addedConversionAction->getResourceName(),
            PHP_EOL
        );
    }
}
      

Python

def main(client, customer_id):
    conversion_action_service = client.get_service("ConversionActionService")

    # Create the operation.
    conversion_action_operation = client.get_type("ConversionActionOperation")

    # Create conversion action.
    conversion_action = conversion_action_operation.create

    # Note that conversion action names must be unique. If a conversion action
    # already exists with the specified conversion_action_name, the create
    # operation will fail with a ConversionActionError.DUPLICATE_NAME error.
    conversion_action.name = f"Earth to Mars Cruises Conversion {uuid.uuid4()}"
    conversion_action.type_ = (
        client.enums.ConversionActionTypeEnum.UPLOAD_CLICKS
    )
    conversion_action.category = (
        client.enums.ConversionActionCategoryEnum.DEFAULT
    )
    conversion_action.status = client.enums.ConversionActionStatusEnum.ENABLED
    conversion_action.view_through_lookback_window_days = 15

    # Create a value settings object.
    value_settings = conversion_action.value_settings
    value_settings.default_value = 15.0
    value_settings.always_use_default_value = True

    # Add the conversion action.
    conversion_action_response = (
        conversion_action_service.mutate_conversion_actions(
            customer_id=customer_id,
            operations=[conversion_action_operation],
        )
    )

    print(
        "Created conversion action "
        f'"{conversion_action_response.results[0].resource_name}".'
    )
      

Ruby

def add_conversion_action(customer_id)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new


  # Add a conversion action.
  conversion_action = client.resource.conversion_action do |ca|
    ca.name = "Earth to Mars Cruises Conversion #{(Time.new.to_f * 100).to_i}"
    ca.type = :UPLOAD_CLICKS
    ca.category = :DEFAULT
    ca.status = :ENABLED
    ca.view_through_lookback_window_days = 15

    # Create a value settings object.
    ca.value_settings = client.resource.value_settings do |vs|
      vs.default_value = 15
      vs.always_use_default_value = true
    end
  end

  # Create the operation.
  conversion_action_operation = client.operation.create_resource.conversion_action(conversion_action)

  # Add the ad group ad.
  response = client.service.conversion_action.mutate_conversion_actions(
    customer_id: customer_id,
    operations: [conversion_action_operation],
  )

  puts "New conversion action with resource name = #{response.results.first.resource_name}."
end
      

Perl

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

  # Note that conversion action names must be unique.
  # If a conversion action already exists with the specified conversion_action_name,
  # the create operation fails with error ConversionActionError.DUPLICATE_NAME.
  my $conversion_action_name = "Earth to Mars Cruises Conversion #" . uniqid();

  # Create a conversion action.
  my $conversion_action =
    Google::Ads::GoogleAds::V16::Resources::ConversionAction->new({
      name                          => $conversion_action_name,
      category                      => DEFAULT,
      type                          => WEBPAGE,
      status                        => ENABLED,
      viewThroughLookbackWindowDays => 15,
      valueSettings                 =>
        Google::Ads::GoogleAds::V16::Resources::ValueSettings->new({
          defaultValue          => 23.41,
          alwaysUseDefaultValue => "true"
        })});

  # Create a conversion action operation.
  my $conversion_action_operation =
    Google::Ads::GoogleAds::V16::Services::ConversionActionService::ConversionActionOperation
    ->new({create => $conversion_action});

  # Add the conversion action.
  my $conversion_actions_response =
    $api_client->ConversionActionService()->mutate({
      customerId => $customer_id,
      operations => [$conversion_action_operation]});

  printf "New conversion action added with resource name: '%s'.\n",
    $conversion_actions_response->{results}[0]{resourceName};

  return 1;
}
      

This example can also be found in Remarketing folder of your client library and in the code examples collection: Add Conversion Action code example.

Validations

Google Ads and the Google Ads API support a wide variety of conversion actions, so some validation rules vary based on the type of action.

By far the most common error when creating a conversion action is DUPLICATE_NAME. Make sure you are using a unique name for each conversion action.

Here are some tips on setting the ConversionAction fields:

All enum fields
Attempting to set any enum field to UNKNOWN results in a RequestError.INVALID_ENUM_VALUE error.
app_id
The app_id attribute is immutable and can only be set when creating a new app conversion.
attribution_model_settings
Setting this to a deprecated option results in a CANNOT_SET_RULE_BASED_ATTRIBUTION_MODELS error. Google Ads only supports GOOGLE_ADS_LAST_CLICK and GOOGLE_SEARCH_ATTRIBUTION_DATA_DRIVEN.
click_through_lookback_window_days

Setting this attribute to a value outside of the allowed range results in a RangeError.TOO_LOW or RangeError.TOO_HIGH error.

This attribute must be in the range [1,60] for an AD_CALL or WEBSITE_CALL conversion action. For most other conversion actions, the allowed range is [1,30].

include_in_conversions_metric

Setting this value in a create or update operation fails with a FieldError.IMMUTABLE_FIELD error. Instead, set primary_for_goal as described in the Conversion goals guide.

phone_call_duration_seconds

Attempting to set this attribute on a conversion action that isn't for calls results in a FieldError.VALUE_MUST_BE_UNSET error.

type

The type attribute is immutable and can only be set when creating a new conversion.

Updating a conversion action with type equal to UNKNOWN results in a MutateError.MUTATE_NOT_ALLOWED error.

value_settings

The value_settings for a WEBSITE_CALL or AD_CALL conversion action must have always_use_default_value set to true. Specifying a value of false when creating or updating this value results in an INVALID_VALUE error.

view_through_lookback_window_days

Setting this attribute to a value outside of the allowed range results in a RangeError.TOO_LOW or RangeError.TOO_HIGH error. For most conversion actions, the allowed range is [1,30].

This attribute cannot be set on AD_CALL or WEBSITE_CALL conversion actions. Specifying a value results in a VALUE_MUST_BE_UNSET error.