Using the Google Ads API, you can leverage enhanced conversions by sending first-party customer data in the form of conversion adjustments. Google uses this additional data to improve the reporting of your online ad-initiated conversions.
As with other requests to the
ConversionAdjustmentUploadService
, you
can only upload enhanced conversions using the account that manages conversion
actions.
In addition, you must complete the setup and configuration
steps in that account,
including confirming that you have accepted the customer
data terms. You can confirm this
using the Google Ads UI, but if you'd prefer to use the Google Ads API, retrieve the
conversion_tracking_setting
from the account that manages conversion actions,
using the searchStream
or search
method of GoogleAdsService
and the
following query:
SELECT
customer.id,
customer.conversion_tracking_setting.accepted_customer_data_terms
FROM customer
Then verify that accepted_customer_data_terms
is true
.
Enhanced conversion as a conversion adjustment
The process for sending data through enhanced conversions is similar to other
conversion adjustments, but keep the
following key differences in mind when populating the
ConversionAdjustment
:
- An
order_id
is required. - The
adjustment_type
must beENHANCEMENT
. - The
conversion_action
is the resource name of aConversionAction
with atype
ofWEBPAGE
. - The
user_identifiers
collection must contain between one and five identifiers. - The
user_identifier_source
of each identifier is optional. A
gclid_date_time_pair
with aconversion_date_time
is optional but recommended. Set this to the date and time at which the conversion with the specifiedorder_id
occurred. Include the timezone offset, and use the formatyyyy-mm-dd HH:mm:ss+|-HH:mm
, for example:2022-01-01 19:32:45-05:00
(ignoring daylight saving time) .Setting the
gclid
of thegclid_date_time_pair
is also optional.The
user_agent
string is optional but recommended. This should match the user agent of the request that sent the original conversion so the conversion and its enhancement are either both attributed as same-device or both attributed as cross-device.Any
restatement_value
is ignored. To restate the value for a conversion, send a separate operation withadjustment_type
set toRESTATEMENT
. See the adjustments guide for more information.
An enhanced conversion should be uploaded within 24 hours of the original conversion. We recommend uploading at least several minutes before the end of the 24-hour period for a margin of safety from differences between system clocks.
Normalization and hashing
For privacy concerns, email addresses, phone numbers, first names, last names, and street addresses must be hashed using the SHA-256 algorithm before being uploaded. In order to standardize the hash results, prior to hashing one of these values you must:
- Remove leading/trailing whitespaces.
- Convert the text to lowercase.
- Format phone numbers according to the E164 standard.
- Remove all periods (
.
) that precede the domain name ingmail.com
andgooglemail.com
email addresses.
Java
private String normalizeAndHash(MessageDigest digest, String s) throws UnsupportedEncodingException { // Normalizes by removing leading and trailing whitespace and converting all characters to // lower case. String normalized = s.trim().toLowerCase(); // 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); }
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): string { return hash($hashAlgorithm, strtolower(trim($value))); } /** * 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); }
Python
def normalize_and_hash_email_address(email_address): """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" Args: email_address: An email address to normalize. Returns: A normalized (lowercase, removed whitespace) and SHA-265 hashed string. """ normalized_email = email_address.lower() email_parts = normalized_email.split("@") # Checks whether the domain of the email address is either "gmail.com" # or "googlemail.com". If this regex does not match then this statement # will evaluate to None. is_gmail = re.match(r"^(gmail|googlemail)\.com$", email_parts[1]) # Check that there are at least two segments and the second segment # matches the above regex expression validating the email domain name. if len(email_parts) > 1 and is_gmail: # Removes any '.' characters from the portion of the email address # before the domain if the domain is gmail.com or googlemail.com. email_parts[0] = email_parts[0].replace(".", "") normalized_email = "@".join(email_parts) return normalize_and_hash(normalized_email) def normalize_and_hash(s): """Normalizes and hashes a string with SHA-256. Private customer data must be hashed during upload, as described at: https://support.google.com/google-ads/answer/7474263 Args: s: The string to perform this operation on. Returns: A normalized (lowercase, removed whitespace) and SHA-256 hashed string. """ return hashlib.sha256(s.strip().lower().encode()).hexdigest()
Ruby
# Returns the result of normalizing and then hashing the string using the # provided digest. Private customer data must be hashed during upload, as # described at https://support.google.com/google-ads/answer/7474263. def normalize_and_hash(str) # Remove leading and trailing whitespace and ensure all letters are lowercase # before hasing. Digest::SHA256.hexdigest(str.strip.downcase) end # 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'. def normalize_and_hash_email(email) email_parts = email.downcase.split("@") # Removes any '.' characters from the portion of the email address before the # domain if the domain is gmail.com or googlemail.com. if email_parts.last =~ /^(gmail|googlemail)\.com\s*/ email_parts[0] = email_parts[0].gsub('.', '') end normalize_and_hash(email_parts.join('@')) end
Perl
sub normalize_and_hash { my $value = shift; $value =~ s/^\s+|\s+$//g; return sha256_hex(lc $value); } # 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'. sub normalize_and_hash_email_address { my $email_address = shift; my $normalized_email = lc $email_address; my @email_parts = split('@', $normalized_email); if (scalar @email_parts > 1 && $email_parts[1] =~ /^(gmail|googlemail)\.com\s*/) { # Remove any '.' characters from the portion of the email address before the # domain if the domain is 'gmail.com' or 'googlemail.com'. $email_parts[0] =~ s/\.//g; $normalized_email = sprintf '%s@%s', $email_parts[0], $email_parts[1]; } return normalize_and_hash($normalized_email); }
Building the enhancement adjustment
The following snippet demonstrates how to construct an enhancement adjustment that contains identifiers for email address and user address, with standardization and hashing applied as required.
Java
// Creates a builder for constructing the enhancement adjustment. ConversionAdjustment.Builder enhancementBuilder = ConversionAdjustment.newBuilder() .setConversionAction(ResourceNames.conversionAction(customerId, conversionActionId)) .setAdjustmentType(ConversionAdjustmentType.ENHANCEMENT) // Enhancements MUST use order ID instead of GCLID date/time pair. .setOrderId(orderId); // Sets the conversion date and time if provided. Providing this value is optional but // recommended. if (conversionDateTime != null) { enhancementBuilder.setGclidDateTimePair( GclidDateTimePair.newBuilder().setConversionDateTime(conversionDateTime)); } // Creates a SHA256 message digest for hashing user identifiers in a privacy-safe way, as // described at https://support.google.com/google-ads/answer/9888656. MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256"); // Adds user identifiers, hashing where required. // Creates a user identifier using sample values for the user address. UserIdentifier addressIdentifier = UserIdentifier.newBuilder() .setAddressInfo( OfflineUserAddressInfo.newBuilder() .setHashedFirstName(normalizeAndHash(sha256Digest, "Joanna")) .setHashedLastName(normalizeAndHash(sha256Digest, "Smith")) .setHashedStreetAddress( normalizeAndHash(sha256Digest, "1600 Amphitheatre Pkwy")) .setCity("Mountain View") .setState("CA") .setPostalCode("94043") .setCountryCode("US")) // Optional: Specifies the user identifier source. .setUserIdentifierSource(UserIdentifierSource.FIRST_PARTY) .build(); // Creates a user identifier using the hashed email address. UserIdentifier emailIdentifier = UserIdentifier.newBuilder() .setUserIdentifierSource(UserIdentifierSource.FIRST_PARTY) // Uses the normalize and hash method specifically for email addresses. .setHashedEmail(normalizeAndHashEmailAddress(sha256Digest, "joannasmith@example.com")) .build(); // Adds the user identifiers to the enhancement adjustment. enhancementBuilder.addUserIdentifiers(addressIdentifier).addUserIdentifiers(emailIdentifier); // Sets optional fields where a value was provided. if (userAgent != null) { // Sets the user agent. This should match the user agent of the request that sent the original // conversion so the conversion and its enhancement are either both attributed as same-device // or both attributed as cross-device. enhancementBuilder.setUserAgent(userAgent); }
C#
// Creates the enhancement adjustment. ConversionAdjustment enhancement = new ConversionAdjustment() { ConversionAction = ResourceNames.ConversionAction(customerId, conversionActionId), AdjustmentType = ConversionAdjustmentType.Enhancement, // Enhancements MUST use order ID instead of GCLID date/time pair. OrderId = orderId }; // Sets the conversion date and time if provided. Providing this value is optional but // recommended. if (string.IsNullOrEmpty(conversionDateTime)) { enhancement.GclidDateTimePair = new GclidDateTimePair() { ConversionDateTime = conversionDateTime }; } // Adds user identifiers, hashing where required. // Creates a user identifier using sample values for the user address. UserIdentifier addressIdentifier = new UserIdentifier() { AddressInfo = new OfflineUserAddressInfo() { HashedFirstName = NormalizeAndHash("Joanna"), HashedLastName = NormalizeAndHash("Smith"), HashedStreetAddress = NormalizeAndHash("1600 Amphitheatre Pkwy"), City = "Mountain View", State = "CA", PostalCode = "94043", CountryCode = "US" }, // Optional: Specifies the user identifier source. UserIdentifierSource = UserIdentifierSource.FirstParty }; // Creates a user identifier using the hashed email address. UserIdentifier emailIdentifier = new UserIdentifier() { UserIdentifierSource = UserIdentifierSource.FirstParty, // Uses the normalize and hash method specifically for email addresses. HashedEmail = NormalizeAndHashEmailAddress("joannasmith@example.com") }; // Adds the user identifiers to the enhancement adjustment. enhancement.UserIdentifiers.AddRange(new[] { addressIdentifier, emailIdentifier }); // Sets optional fields where a value was provided. if (!string.IsNullOrEmpty(userAgent)) { // Sets the user agent. This should match the user agent of the request that // sent the original conversion so the conversion and its enhancement are either // both attributed as same-device or both attributed as cross-device. enhancement.UserAgent = userAgent; } if (restatementValue != null) { enhancement.RestatementValue = new RestatementValue() { // Sets the new value of the conversion. AdjustedValue = restatementValue.Value }; // Sets the currency of the new value, if provided. Otherwise, the default currency // from the conversion action is used, and if that is not set then the account // currency is used. if (restatementCurrencyCode != null) { enhancement.RestatementValue.CurrencyCode = restatementCurrencyCode; } }
PHP
// Creates the conversion enhancement. $conversionAdjustment = new ConversionAdjustment([ 'conversion_action' => ResourceNames::forConversionAction($customerId, $conversionActionId), 'adjustment_type' => ConversionAdjustmentType::ENHANCEMENT, // Enhancements must use order ID instead of GCLID date/time pair. 'order_id' => $orderId ]); // Uses the SHA-256 hash algorithm for hashing user identifiers in a privacy-safe way, as // described at https://support.google.com/google-ads/answer/9888656. $hashAlgorithm = "sha256"; // Adds user identifiers, hashing where required. // Creates a user identifier using sample values for the user address. $addressIdentifier = new UserIdentifier([ 'address_info' => new OfflineUserAddressInfo([ 'hashed_first_name' => self::normalizeAndHash($hashAlgorithm, 'Dana'), 'hashed_last_name' => self::normalizeAndHash($hashAlgorithm, 'Quinn'), 'hashed_street_address' => self::normalizeAndHash( $hashAlgorithm, '1600 Amphitheatre Pkwy' ), 'city' => 'Mountain View', 'state' => 'CA', 'postal_code' => '94043', 'country_code' => 'US' ]), // Optional: Specifies the user identifier source. 'user_identifier_source' => UserIdentifierSource::FIRST_PARTY ]); // Creates a user identifier using the hashed email address. $emailIdentifier = new UserIdentifier([ // Uses the normalize and hash method specifically for email addresses. 'hashed_email' => self::normalizeAndHashEmailAddress( $hashAlgorithm, 'dana@example.com' ), // Optional: Specifies the user identifier source. 'user_identifier_source' => UserIdentifierSource::FIRST_PARTY ]); // Adds the user identifiers to the enhancement adjustment. $conversionAdjustment->setUserIdentifiers([$addressIdentifier, $emailIdentifier]); // Sets optional fields where a value was provided. if ($conversionDateTime !== null) { // Sets the conversion date and time if provided. Providing this value is optional but // recommended. $conversionAdjustment->setGclidDateTimePair(new GclidDateTimePair([ 'conversion_date_time' => $conversionDateTime ])); } if ($userAgent !== null) { // Sets the user agent. This should match the user agent of the request that sent the // original conversion so the conversion and its enhancement are either both attributed // as same-device or both attributed as cross-device. $conversionAdjustment->setUserAgent($userAgent); }
Python
conversion_action_service = client.get_service("ConversionActionService") conversion_adjustment = client.get_type("ConversionAdjustment") conversion_adjustment.conversion_action = conversion_action_service.conversion_action_path( customer_id, conversion_action_id ) conversion_adjustment.adjustment_type = ( client.enums.ConversionAdjustmentTypeEnum.ENHANCEMENT ) # Enhancements MUST use order ID instead of GCLID date/time pair. conversion_adjustment.order_id = order_id # Sets the conversion date and time if provided. Providing this value is # optional but recommended. if conversion_date_time: conversion_adjustment.gclid_date_time_pair.conversion_date_time = ( conversion_date_time ) # Creates a user identifier using sample values for the user address, # hashing where required. address_identifier = client.get_type("UserIdentifier") address_identifier.address_info.hashed_first_name = normalize_and_hash( "Joanna" ) address_identifier.address_info.hashed_last_name = normalize_and_hash( "Joanna" ) address_identifier.address_info.hashed_street_address = normalize_and_hash( "1600 Amphitheatre Pkwy" ) address_identifier.address_info.city = "Mountain View" address_identifier.address_info.state = "CA" address_identifier.address_info.postal_code = "94043" address_identifier.address_info.country_code = "US" # Optional: Specifies the user identifier source. address_identifier.user_identifier_source = ( client.enums.UserIdentifierSourceEnum.FIRST_PARTY ) # Creates a user identifier using the hashed email address. email_identifier = client.get_type("UserIdentifier") # Optional: Specifies the user identifier source. email_identifier.user_identifier_source = ( client.enums.UserIdentifierSourceEnum.FIRST_PARTY ) # Uses the normalize and hash method specifically for email addresses. email_identifier.hashed_email = normalize_and_hash_email_address( "dana@example.com" ) # Adds both user identifiers to the conversion adjustment. conversion_adjustment.user_identifiers.extend( [address_identifier, email_identifier] ) # Sets optional fields where a value was provided if user_agent: # Sets the user agent. This should match the user agent of the request # that sent the original conversion so the conversion and its # enhancement are either both attributed as same-device or both # attributed as cross-device. conversion_adjustment.user_agent = user_agent
Ruby
enhancement = client.resource.conversion_adjustment do |ca| ca.conversion_action = client.path.conversion_action(customer_id, conversion_action_id) ca.adjustment_type = :ENHANCEMENT ca.order_id = order_id # Sets the conversion date and time if provided. Providing this value is # optional but recommended. unless conversion_date_time.nil? ca.gclid_date_time_pair = client.resource.gclid_date_time_pair do |pair| pair.conversion_date_time = conversion_date_time end end # Creates a user identifier using sample values for the user address. ca.user_identifiers << client.resource.user_identifier do |ui| ui.address_info = client.resource.offline_user_address_info do |info| # Certain fields must be hashed using SHA256 in order to handle # identifiers in a privacy-safe way, as described at # https://support.google.com/google-ads/answer/9888656. info.hashed_first_name = normalize_and_hash("Joanna") info.hashed_last_name = normalize_and_hash("Smith") info.hashed_street_address = normalize_and_hash("1600 Amphitheatre Pkwy") info.city = "Mountain View" info.state = "CA" info.postal_code = "94043" info.country_code = "US" end # Optional: Specifies the user identifier source. ui.user_identifier_source = :FIRST_PARTY end # Creates a user identifier using the hashed email address. ca.user_identifiers << client.resource.user_identifier do |ui| # Uses the normalize and hash method specifically for email addresses. ui.hashed_email = normalize_and_hash_email("dana@example.com") ui.user_identifier_source = :FIRST_PARTY end # Sets optional fields where a value was provided. unless user_agent.nil? # Sets the user agent. This should match the user agent of the request # that sent the original conversion so the conversion and its enhancement # are either both attributed as same-device or both attributed as # cross-device. ca.user_agent = user_agent end end
Perl
# Construct the enhancement adjustment. my $enhancement = Google::Ads::GoogleAds::V13::Services::ConversionAdjustmentUploadService::ConversionAdjustment ->new({ conversionAction => Google::Ads::GoogleAds::V13::Utils::ResourceNames::conversion_action( $customer_id, $conversion_action_id ), adjustmentType => ENHANCEMENT, # Enhancements MUST use order ID instead of GCLID date/time pair. orderId => $order_id }); # Set the conversion date and time if provided. Providing this value is optional # but recommended. if (defined $conversion_date_time) { $enhancement->{gclidDateTimePair} = Google::Ads::GoogleAds::V13::Services::ConversionAdjustmentUploadService::GclidDateTimePair ->new({ conversionDateTime => $conversion_date_time }); } # Add user identifiers, hashing where required. # Create a user identifier using sample values for the user address. my $address_identifier = Google::Ads::GoogleAds::V13::Common::UserIdentifier->new({ addressInfo => Google::Ads::GoogleAds::V13::Common::OfflineUserAddressInfo->new({ hashedFirstName => normalize_and_hash("Dana"), hashedLastName => normalize_and_hash("Quinn"), hashedStreetAddress => normalize_and_hash("1600 Amphitheatre Pkwy"), city => "Mountain View", state => "CA", postalCode => "94043", countryCode => "US" } ), # Optional: Specify the user identifier source. userIdentifierSource => FIRST_PARTY }); # Create a user identifier using the hashed email address. my $email_identifier = Google::Ads::GoogleAds::V13::Common::UserIdentifier->new({ userIdentifierSource => FIRST_PARTY, # Use the normalize and hash method specifically for email addresses. hashedEmail => normalize_and_hash_email_address('dana@example.com')}); # Add the user identifiers to the enhancement adjustment. $enhancement->{userIdentifiers} = [$address_identifier, $email_identifier]; # Set optional fields where a value was provided. if (defined $user_agent) { # Set the user agent. This should match the user agent of the request that # sent the original conversion so the conversion and its enhancement are # either both attributed as same-device or both attributed as cross-device. $enhancement->{userAgent} = $user_agent; } # Upload the enhancement adjustment. Partial failure should always be set to true. my $response = $api_client->ConversionAdjustmentUploadService() ->upload_conversion_adjustments({ customerId => $customer_id, conversionAdjustments => [$enhancement], # Enable partial failure (must be true). partialFailure => "true" }); # Print any partial errors returned. if ($response->{partialFailureError}) { printf "Partial error encountered: '%s'.\n", $response->{partialFailureError}{message}; } else { # Print the result. my $result = $response->{results}[0]; printf "Uploaded conversion adjustment of '%s' for order ID '%s'.\n", $result->{conversionAction}, $result->{orderId}; } return 1; } # Normalizes and hashes a string value. # Private customer data must be hashed during upload, as described at # https://support.google.com/google-ads/answer/7474263. sub normalize_and_hash { my $value = shift; $value =~ s/^\s+|\s+$//g; return sha256_hex(lc $value); } # 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'. sub normalize_and_hash_email_address { my $email_address = shift; my $normalized_email = lc $email_address; my @email_parts = split('@', $normalized_email); if (scalar @email_parts > 1 && $email_parts[1] =~ /^(gmail|googlemail)\.com\s*/) { # Remove any '.' characters from the portion of the email address before the # domain if the domain is 'gmail.com' or 'googlemail.com'. $email_parts[0] =~ s/\.//g; $normalized_email = sprintf '%s@%s', $email_parts[0], $email_parts[1]; } return normalize_and_hash($normalized_email); } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Get Google Ads Client, credentials will be read from ~/googleads.properties. my $api_client = Google::Ads::GoogleAds::Client->new(); # By default examples are set to die on any server returned fault. $api_client->set_die_on_faults(1); # Parameters passed on the command line will override any parameters set in code. GetOptions( "customer_id=s" => \$customer_id, "conversion_action_id=i" => \$conversion_action_id, "order_id=s" => \$order_id, "conversion_date_time=s" => \$conversion_date_time, "user_agent=s" => \$user_agent ); # Print the help message if the parameters are not initialized in the code nor # in the command line. pod2usage(2) if not check_params($customer_id, $conversion_action_id, $order_id); # Call the example. upload_conversion_enhancement($api_client, $customer_id =~ s/-//gr, $conversion_action_id, $order_id, $conversion_date_time, $user_agent); =pod =head1 NAME upload_conversion_enhancement =head1 DESCRIPTION Adjusts an existing conversion by supplying user identifiers so Google can enhance the conversion value. =head1 SYNOPSIS upload_conversion_enhancement.pl [options] -help Show the help message. -customer_id The Google Ads customer ID. -conversion_action_id The conversion action ID associated with this conversion. -order_id The unique order ID (transaction ID) of the conversion. -conversion_date_time [optional] The date time at which the conversion with the specified order ID occurred. Must be after the click time, and must include the time zone offset. The format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", e.g. "2019-01-01 12:32:45-08:00". Setting this field is optional, but recommended. -user_agent [optional] The HTTP user agent of the conversion. =cut
Common errors
Use the enhanced conversions API diagnostics report to validate that your enhanced conversions are working effectively.
Here are some common errors that may occur during uploads:
ConversionAdjustmentUploadError.CUSTOMER_NOT_ACCEPTED_CUSTOMER_DATA_TERMS
- The customer data terms and conditions have not been accepted for the
customer_id
of the request. ConversionAdjustmentUploadError.CONVERSION_ACTION_NOT_ELIGIBLE_FOR_ENHANCEMENT
- The
conversion_action
supplied is not eligible for enhanced conversions. In the Google Ads UI, make sure you check the Turn on enhanced conversions box on the conversion action referenced in your request. ConversionAdjustmentUploadError.INVALID_USER_IDENTIFIER
- A
user_identifier
for a field that requires hashing was not hashed using the SHA-256 algorithm. ConversionAdjustmentUploadError.UNSUPPORTED_USER_IDENTIFIER
- A
user_identifier
of the adjustment contains a value that is not one of the allowed identifiers. CollectionSizeError.TOO_MANY
- The
user_identifiers
collection contains more than five elements.