Manage online click conversions

  • The Google Ads API allows managing online click conversions, particularly for tracking sales on websites.

  • Online conversions are primarily tracked using the Google tag but can be adjusted or enhanced via the Google Ads API.

  • Enhanced conversions for web, also known as Enhanced conversions for web, involves sending a click identifier and order ID to Google Ads upon conversion, which can be enhanced with user-provided data using the Google Ads API.

  • Implementing enhanced conversions through the Google Ads API requires accepting customer data terms, configuring tagging, and normalizing and hashing user-provided data before importing it as ConversionAdjustment objects.

  • Reviewing import diagnostics and following best practices like including multiple identifiers and batching adjustments are crucial for successful enhanced conversion implementation.

You can use the Google Ads API to manage online click conversions in Google Ads. Online click conversions help you track ads that led to sales in the online world, such as through a website.

Online conversions are tracked using the Google tag, but you can adjust or enhance them using the Google Ads API.

If you already have the Google tag set up and want to adjust your online conversions, see the conversion adjustments page. If you have the Google tag set up and you want to enhance your online conversions with user-provided data, also known as Enhanced conversions for web, continue reading.

Enhanced conversions for web

The following section explains how to enhance online click conversions, also known as Enhanced conversions for web.

Enhanced conversions for web requires setting up a tag that automatically sends a click identifier, like a GCLID, and an order ID to Google Ads when a user converts. You have the option of setting up enhanced conversions through Google Tag Manager, the Google tag, or the Google Ads API. Using the Google Ads API gives you the advantage of sending first-party conversion data within 24 hours of the 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.

How enhanced conversions for web works

Enhanced conversions for web in the Google Ads API supplements step 3 in the following flow.

Instead of sending the hashed user information when the user converts, the tag sends just the GCLID and the order ID, and you send hashed user information later by importing the order ID along with the hashed data. To learn more about enhanced conversions for web, see our Help Center.

Enhanced conversions for
web

Prerequisites

You must accept the customer data terms before you can use enhanced conversions for web. You can verify whether the customer data terms have been accepted by issuing the following query to the Google Ads conversion customer:

SELECT
  customer.id,
  customer.conversion_tracking_setting.accepted_customer_data_terms
FROM customer

If accepted_customer_data_terms is false, follow the instructions in the Help Center to complete this prerequisite.

Configure tagging

You can configure tagging for your website by following the instructions in the Help Center. It is recommended that you also add transaction IDs (order IDs) to your conversion tracking tag to assist with conversion matching.

API Implementation

Here is the overall flow for importing enhanced conversions for web in the Google Ads API.

  1. Normalize and hash the user-provided data, such as email address, phone number, and mailing address.

  2. Populate ConversionAdjustment objects with the normalized and hashed user-provided data.

  3. Import the ConversionAdjustment objects to the ConversionAdjustmentUploadService.

  4. Review your imports.

Normalize and hash user-provided data

For privacy considerations, the following data must be hashed using SHA-256 before being imported:

  • Email address
  • Phone number
  • First name
  • Last name
  • Street address

Don't hash the following data:

  • Country
  • State
  • City
  • Zip code

In order to standardize the hash results, do the following prior to hashing one of these values:

  • Remove leading and trailing whitespaces.
  • Convert the text to lowercase.
  • Format phone numbers according to the E164 standard.
  • For email addresses:
    • Remove all periods (.) in the username (before the @ symbol). For example, jane.doe@example.com becomes janedoe@example.com.
    • Remove the plus (+) symbol and any characters following it in the username (before the @ symbol). For example, janedoe+newsletter@example.com becomes janedoe@example.com.

Java

private String normalizeAndHash(MessageDigest digest, String s, boolean trimIntermediateSpaces)
    throws UnsupportedEncodingException {
  // Normalizes by first converting all characters to lowercase, then trimming spaces.
  String normalized = s.toLowerCase();
  if (trimIntermediateSpaces) {
    // Removes leading, trailing, and intermediate spaces.
    normalized = normalized.replaceAll("\\s+", "");
  } else {
    // Removes only leading and trailing spaces.
    normalized = normalized.trim();
  }
  // Hashes the normalized string using the hashing algorithm.
  byte[] hash = digest.digest(normalized.getBytes("UTF-8"));
  StringBuilder result = new StringBuilder();
  for (byte b : hash) {
    result.append(String.format("%02x", b));
  }

  return result.toString();
}

/**
 * Returns the result of normalizing and hashing an email address. For this use case, Google Ads
 * requires removal of any '.' characters preceding {@code gmail.com} or {@code googlemail.com}.
 *
 * @param digest the digest to use to hash the normalized string.
 * @param emailAddress the email address to normalize and hash.
 */
private String normalizeAndHashEmailAddress(MessageDigest digest, String emailAddress)
    throws UnsupportedEncodingException {
  String normalizedEmail = emailAddress.toLowerCase();
  String[] emailParts = normalizedEmail.split("@");
  if (emailParts.length > 1 && emailParts[1].matches("^(gmail|googlemail)\\.com\\s*")) {
    // Removes any '.' characters from the portion of the email address before the domain if the
    // domain is gmail.com or googlemail.com.
    emailParts[0] = emailParts[0].replaceAll("\\.", "");
    normalizedEmail = String.format("%s@%s", emailParts[0], emailParts[1]);
  }
  return normalizeAndHash(digest, normalizedEmail, true);
}
      

C#

/// <summary>
/// Normalizes the email address and hashes it. For this use case, Google Ads requires
/// removal of any '.' characters preceding <code>gmail.com</code> or
/// <code>googlemail.com</code>.
/// </summary>
/// <param name="emailAddress">The email address.</param>
/// <returns>The hash code.</returns>
private string NormalizeAndHashEmailAddress(string emailAddress)
{
    string normalizedEmail = emailAddress.ToLower();
    string[] emailParts = normalizedEmail.Split('@');
    if (emailParts.Length > 1 && (emailParts[1] == "gmail.com" ||
        emailParts[1] == "googlemail.com"))
    {
        // Removes any '.' characters from the portion of the email address before
        // the domain if the domain is gmail.com or googlemail.com.
        emailParts[0] = emailParts[0].Replace(".", "");
        normalizedEmail = $"{emailParts[0]}@{emailParts[1]}";
    }
    return NormalizeAndHash(normalizedEmail);
}

/// <summary>
/// Normalizes and hashes a string value.
/// </summary>
/// <param name="value">The value to normalize and hash.</param>
/// <returns>The normalized and hashed value.</returns>
private static string NormalizeAndHash(string value)
{
    return ToSha256String(digest, ToNormalizedValue(value));
}

/// <summary>
/// Hash a string value using SHA-256 hashing algorithm.
/// </summary>
/// <param name="digest">Provides the algorithm for SHA-256.</param>
/// <param name="value">The string value (e.g. an email address) to hash.</param>
/// <returns>The hashed value.</returns>
private static string ToSha256String(SHA256 digest, string value)
{
    byte[] digestBytes = digest.ComputeHash(Encoding.UTF8.GetBytes(value));
    // Convert the byte array into an unhyphenated hexadecimal string.
    return BitConverter.ToString(digestBytes).Replace("-", string.Empty);
}

/// <summary>
/// Removes leading and trailing whitespace and converts all characters to
/// lower case.
/// </summary>
/// <param name="value">The value to normalize.</param>
/// <returns>The normalized value.</returns>
private static string ToNormalizedValue(string value)
{
    return value.Trim().ToLower();
}
      

PHP

private static function normalizeAndHash(
    string $hashAlgorithm,
    string $value,
    bool $trimIntermediateSpaces
): string {
    // Normalizes by first converting all characters to lowercase, then trimming spaces.
    $normalized = strtolower($value);
    if ($trimIntermediateSpaces === true) {
        // Removes leading, trailing, and intermediate spaces.
        $normalized = str_replace(' ', '', $normalized);
    } else {
        // Removes only leading and trailing spaces.
        $normalized = trim($normalized);
    }
    return hash($hashAlgorithm, strtolower(trim($normalized)));
}

/**
 * Returns the result of normalizing and hashing an email address. For this use case, Google
 * Ads requires removal of any '.' characters preceding "gmail.com" or "googlemail.com".
 *
 * @param string $hashAlgorithm the hash algorithm to use
 * @param string $emailAddress the email address to normalize and hash
 * @return string the normalized and hashed email address
 */
private static function normalizeAndHashEmailAddress(
    string $hashAlgorithm,
    string $emailAddress
): string {
    $normalizedEmail = strtolower($emailAddress);
    $emailParts = explode("@", $normalizedEmail);
    if (
        count($emailParts) > 1
        && preg_match('/^(gmail|googlemail)\.com\s*/', $emailParts[1])
    ) {
        // Removes any '.' characters from the portion of the email address before the domain
        // if the domain is gmail.com or googlemail.com.
        $emailParts[0] = str_replace(".", "", $emailParts[0]);
        $normalizedEmail = sprintf('%s@%s', $emailParts[0], $emailParts[1]);
    }
    return self::normalizeAndHash($hashAlgorithm, $normalizedEmail, true);
}