Using the AdWords API Offline Conversion Import Tool

in AdWords API

This post explains how to use the AdWords API Conversion Import Tool to track your offline conversions. You store a click id that Google appends to your destination URLs then use it to upload the clicks once they convert offline. There's three steps you need to follow to get started using the tool:

  • Create a new conversion type in AdWords for the upload.
  • Collect the click ids and store them in your database.
  • Upload each click that converts using the AdWords API.

I'll explain each step in the rest of the article.

Creating a New Conversion Type in AdWords

Before you can start importing conversions into AdWords, you need to create a new conversion type with a source of Import. You can create this using either the Tools and Analysis > Conversions screen in your AdWords account, or the AdWords API Conversion Tracker service:

$conversionName = "Phone Call";
 
$conversionTrackerService = $user->GetService("ConversionTrackerService", API_VERSION);
 
$uploadConversion = new UploadConversion();
$uploadConversion->name = $conversionName;
$uploadConversion->category = "LEAD";
$uploadConversion->ctcLookbackWindow = 90;
$uploadConversion->viewthroughLookbackWindow = 30;
 
$operations = array(new ConversionTrackerOperation($uploadConversion, "ADD"));
$result = $conversionTrackerService->mutate($operations);
Creating an Import Conversion Tracker

The script creates a new conversion with the following parameters:

  • name: The name of the new conversion, which must be unique within the account.
  • category: The conversion category; chosen from DEFAULT, PAGE_VIEW, PURCHASE, SIGNUP, LEAD, or REMARKETING.
  • ctcLookbackWindow: The maximum amount of days after a click that a conversion can be registered. The must be an integer between 7 and 90.
  • viewthroughLookbackWindow: The maximum amount of days after a click that a view through conversion can be registered. The must be an integer between 1 and 30.

After running this code, you should see a new conversion in your AdWords account:

A New Import Conversion Type
A New Import Conversion Type

Once you've set up the conversion, you don't need to run the code again (you'll get a ConversionTrackingError.DUPLICATE_NAME if you do).

Collecting the Click Ids on Your Website

You link your offline conversions to AdWords clicks using a click id that Google appends to your destination URLs. This is the same GclId that Google has used with Analytics for a long time, but you can now use it in your own tracking systems. Note that if your Google Analytics account isn't already linked to your AdWords account, then you'll need to enable URL auto-tagging in AdWords (there's no way to do this in the API at the moment).

Once you've enabled auto-tagging, Google will send you a URL parameter, called gclid, that you need to extract and store. It's out of the scope of this article to explore how to connect the parameter with an offline conversion, which is often somewhat challenging, so I'll just store it in a cookie then insert the cookie into a form. You can store the cookie using some JavaScript on your landing page:

<script type="text/javascript"> 
    function saveClickId(cookieName) { 
        var queryString = document.location.search; 
        var gclidStart = queryString.indexOf("gclid="); 
        if (gclidStart > -1) { 
            gclidStart += 6; 
            var gclidEnd = queryString.indexOf("&amp;", gclidStart); 
            if (gclidEnd > -1) { 
                var gclid = queryString.substring(gclidStart, gclidEnd); 
            } else { 
                var gclid = queryString.substring(gclidStart); 
            } 
            var gclidExpireDate = new Date(); 
            gclidExpireDate.setDate(gclidExpireDate.getDate() + 90); 
            document.cookie = cookieName + "=" + gclid + 
            "; expires=" + gclidExpireDate.toUTCString(); 
        } 
    } 
 
    try { 
        saveClickId("gclid"); 
    } catch (e) { 
        // error 
    } 
</script>
Capturing the 'gclid' Parameter

This code's quite rudimentary, but should capture the click id in a cookie called gclid that you can use in a PHP form:

<form action="<?php print $_SERVER["PHP_SELF"]; ?>" method="POST">
    <input type="text" name="fullname"/>
    <input type="hidden" name="gclid" value="<?php print $_COOKIE["gclid"]; ?>"/>
    <input type="submit" value="Submit Conversion"/>
</form>
A Lead Capture Form with a Click Id

Uploading the Conversions to AdWords

However you have stored your click ids, for the next step I'll assume you have it in an associative array:

$conversions = array(
    array(
        "gclid" => "CMbBkZi12roCFZlq1tAdwaXYADD",
        "date" => 1384127111,
        "value" => 5.12
    ),
    array(
        "gclid" => "SJFKS23a12roCFZMdtAodeaaYAaQ",
        "date" => 1384127292,
        "value" => 10
    )
);
Array of Conversions with Click Ids

This represents each conversion using an associative array with three entries:

  • gclid: The click id extracted from the landing page.
  • date: The timestamp of the conversion event.
  • value: The revenue associated with the conversion. You can omit this if you don't want to assign a value to the conversion.

You can upload each conversion by sending an OfflineConversionFeed to the OfflineConversionFeedService:

$conversionName = "Phone Call";
$offlineConversionService = $user->GetService("OfflineConversionFeedService", API_VERSION);
 
$operations = array();
foreach ($conversions as $conversion) {
    $gclid = $conversion["gclid"];
    $convDate = date("Ymd His", $conversion["date"]);
    $convValue = isset($conversion["value"]) ? $conversion["value"] : 0;
    $offlineConversion = new OfflineConversionFeed(
            $gclid, $conversionName, $convDate, $convValue
    );
    $operations[] = new OfflineConversionFeedOperation($offlineConversion, "ADD");
}
 
$result = $offlineConversionService->mutate($operations);
Uploading Conversions into AdWords

This code just creates an OfflineConversionFeed for each of your offline conversions and uploads them using the mutate() operation of the OfflineConversionFeedService. The script formats each conversion timestamp as required by the API, so the 12:30 on the 9th of November, 2013 becomes 20131109 123000.

The conversions will take a while to turn up in your account, but after around three hours you should see the conversion appearing in reports:

Offline Conversions Report
Offline Conversions Report

Common Issues with Conversion Uploads

There's a few things you should note about the uploads in case you have any problems:

  • You need to wait around four to six hours after a click before uploading its gclid, or you will get an OfflineConversionError.TOO_RECENT_CLICK error.
  • The conversion date needs to be after the time of the click—or you'll get an OfflineConversionError.CONVERSION_PRECEDES_CLICK error—before the end of the ctcLookbackWindow—or you'll get an OfflineConversionError.EXPIRED_CLICK error—and not a future date—or you'll get a DateError.LATER_THAN_MAXIMUM_DATE error. You should check that you're using the same timezone as the AdWords account into which you're importing conversions as that can cause these types of problem.
  • AdWords will only register the first successful uploaded conversion for a single click, conversion type, and time, but you can upload multiple conversions for the same click with a different conversion type/time. So, for example, if you upload a conversion for a click on the Phone Calls type on the 9th of November, 2013 at 18:35 with a value of $10, and another for the Phone Calls type on the 9th of November, 2013 at 18:35 with a value of $5, only the $10 value will be registered (both one-per-click and many-per-click); however, if you change the time to 18:36, there will be two many-per-click conversions with a total value of $15.
  • You need to ensure that the name of the conversion type you use is exactly the same as the one in your AdWords account, including the same case; Phone Calls is not the same as phone calls or phone call etc. You'll get an OfflineConversionError.INVALID_CONVERSION_TYPE error if there's a problem.

AdWords Conversion Import Script

Here's a full version of the script including the boilerplate AdWords API authentication code, which you can find out about in my OAuth Playground Tutorial:

<?php
set_include_path(get_include_path() . PATH_SEPARATOR .
        dirname(__FILE__) . "/adwords_api_php_4.6.1/src");
require_once("Google/Api/Ads/AdWords/Lib/AdWordsUser.php");
 
define("OAUTH_CLIENT_ID", "[YOUR CLIENT ID]"); 
define("OAUTH_CLIENT_SECRET", "[YOUR CLIENT SECRET]"); 
define("OAUTH_ACCESS_TOKEN", "[YOUR ACCESS TOKEN]"); 
define("OAUTH_REFRESH_TOKEN", "[YOUR REFRESH TOKEN]"); 
define("CUSTOMER_ACCOUNT_ID", "[YOUR ACCOUNT ID]"); 
define("DEVELOPER_TOKEN", "[YOUR DEVELOPER TOKEN]"); 
define("API_VERSION", "v201309");
$conversionName = "[YOUR_CONVERSION_NAME]";
 
$user = new AdWordsUser();
$user->SetDeveloperToken(DEVELOPER_TOKEN);
$user->SetClientCustomerId(CUSTOMER_ACCOUNT_ID);
 
$user->SetOAuth2Info(array(
    "client_id" => OAUTH_CLIENT_ID,
    "client_secret" => OAUTH_CLIENT_SECRET,
    "access_token" => OAUTH_ACCESS_TOKEN,
    "refresh_token" => OAUTH_REFRESH_TOKEN
));
 
$handler = $user->GetOAuth2Handler();
$oauth2Info = $handler->RefreshAccessToken($user->GetOAuth2Info());
$user->SetOAuth2Info($oauth2Info);
 
/** 
 * Creating a new conversions (only run once)
 */
$conversionTrackerService = $user->GetService("ConversionTrackerService", API_VERSION);
 
$uploadConversion = new UploadConversion();
$uploadConversion->name = $conversionName;
$uploadConversion->category = "LEAD";
$uploadConversion->viewthroughLookbackWindow = 30;
$uploadConversion->ctcLookbackWindow = 90;
 
$operations = array(new ConversionTrackerOperation($uploadConversion, "ADD"));
$result = $conversionTrackerService->mutate($operations);
 
/** 
 * Your list of clicks and conversions from your database
 */
$conversions = array(
    array(
        "gclid" => "CMbBkZi12roCFZlq1tAdwaXYADD",
        "date" => 1384127111,
        "value" => 5.12
    ),
    array(
        "gclid" => "SJFKS23a12roCFZMdtAodeaaYAaQ",
        "date" => 1384127292,
        "value" => 10
    )
);
 
/**
 * Uploading the offline conversions using the OfflineConversionFeedService
 * Run this regularly for clicks that are at least six hours old 
 * (eg run at 6AM local time for the previous day's conversions)
 */
$offlineConversionService = $user->GetService("OfflineConversionFeedService", API_VERSION);
 
$operations = array();
foreach ($conversions as $conversion) {
    $gclid = $conversion["gclid"];
    $convDate = date("Ymd His", $conversion["date"]);
    $convValue = isset($conversion["value"]) ? $conversion["value"] : 0;
    $offlineConversion = new OfflineConversionFeed(
            $gclid, $conversionName, $convDate, $convValue
    );
    $operations[] = new OfflineConversionFeedOperation($offlineConversion, "ADD");
}
 
$result = $offlineConversionService->mutate($operations);
Uploading Conversions to the AdWords API

Comments

I'm keen to get feedback on my posts, so if you have any questions or comments, then please send me a message and I'll be happy to help.