Tracking Bing PPC in Google Analytics

in Google Analytics

This article discusses how to track Bing PPC Ads in Google Analytics. I start by explaining how to use Google Analytics campaign tracking parameters to tag your ads, then I present some techniques to capture search queries using custom fields and dimensions.

Tagging Ads Using Query String Parameters

Google Analytics tracks custom campaigns using five tags inserted into your ad destination URL's:

  • utm_source: The ad network, such as Bing.
  • utm_medium: The type of ad program, such as CPC or CPM.
  • utm_campaign: The campaign containing your ads.
  • utm_term: The criterion that triggered your ad, such as the keyword on which you've placed a bid.
  • utm_content: The ad creative, such as the title of a text ad.

Google Analytics requires you to supply the utm_source and utm_medium parameters, but the rest are optional, so a minimal URL could look like this:

This will record visits from your Bing ads as bing / cpc in the Traffic Sources > Sources > All Traffic report:

Bing Ads Source & Medium in the All Traffic Report
Bing Ads Source & Medium in the All Traffic Report

However, you'll also want to include your keyword text and probably the ad and campaign using the utm_term, utm_content, and utm_campaign parameters:

Now you can view the keyword and ad in the Traffic Sources > Sources > Paid Search Traffic report:

Keywords and Ads in the Paid Search Traffic Report
Keywords and Ads in the Paid Search Traffic Report

This is displaying the ad text using the Traffic Sources > Ad Content secondary dimension.

You can view the campaign name in the Traffic Sources > Sources > Campaigns report:

Bing Ads Campaign in the Campaigns Report
Bing Ads Campaign in the Campaigns Report

Automatic Keyword Tagging using DKI

There's a problem with the last example URL: You can either tag your ads or your keywords, but not both, so it's not possible to track both the ad text and keyword at the same time. However, you can use Dynamic Keyword Insertion to automatically place the keyword that triggered an ad into the ad's destination URL without having to tag each keyword:{keyword}&utm_content=your+ad+text&utm_campaign=your+campaign+name

In this example, I've replaced the keyword text with the {keyword} placeholder that Bing will insert the keyword into when it displays your ad, so you only need to tag your ads and Bing will include the keywords when they appear in search results.

Tracking the Search Query

Bing also provides some other tokens you can use in your query strings—such as the {QueryString} parameter that contains the actual search term that the searcher used to find your ad; however, I haven't found a way to populate the Google Analytics Matched Search Query field, so you'll need to either replace the {keyword} token with the {QueryString} token, combine them both in some way, or use custom tracking.

Replacing the Keyword with the Search Query

If you want to see the real search query instead of the exact match in your account, just replace the tokens in the previous URL:{QueryString}&utm_content=your+ad+text&utm_campaign=your+campaign+name

You'll now see the search term in Google Analytics, but the keyword will no longer be available.

Combining the Keyword and the Search Query

If you want to see both the exact match keyword and the real search query, you can combine them both into a single field:{keyword}+({QueryString})&utm_content=your+ad+text&utm_campaign=your+campaign+name

You'll now see both the keyword and the search term in the same field of your reports:

A Combination of Keyword and Search Term
A Combination of Keyword and Search Term

Placing the Search Query into a Custom Field

If a combined field isn't sufficient, you can put the search term into a user defined field; either a custom variable if you're using ga.js, or a custom dimension if you're using analytics.js. This is slightly more complicated as you need to change your tracking code, but will give you more flexibility when producing reports.

Start by adding a new parameter to your query string: 

We now need some JavaScript to extract this new parameter:

var searchTerm = getParameterByName("utm_search_term");
function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
            results = regex.exec(;
    return results == null ? null :
            decodeURIComponent(results[1].replace(/\+/g, " "));

This script extracts the utm_search_term parameter from the query string using this function from StackOverflow. Now you need to add it to your tracking script. Here's how to do that using the ga.js asynchronous tracking script:

var searchTerm = getParameterByName("utm_search_term");
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
if (searchTerm != null) {
    _gaq.push(['_setCustomVar', 1, 'Search Term', searchTerm, 1]);}
(function() {
    var ga = document.createElement('script');
    ga.type = 'text/javascript';
    ga.async = true;
    ga.src = ('https:' == document.location.protocol ?
            'https://ssl' : 'http://www') + '';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(ga, s);

The important bit of code here is the highlighted line that calls the _setCustomVar operation: this line instructs GA to create a custom variable, called Search Term, in the first of the five available slots, and to place into it the term extracted from the utm_search_term query parameter. The last parameter of the operation sets the scope of the variable, which determines how long it should stay active; I've supplied a value of 1 to keep the variable active across visits from the same visitor (as opposed to limiting it to the current visit or page view).

You can now view the search term in the Audience > Custom > Custom Variables report:

The Custom Variables Report
The Custom Variables Report

This shows all the visits for our new variable, called Search Term, and you can drill-down to see the individual terms:

The Custom Variable Search Terms
The Custom Variable Search Terms

I've added the keyword as a second dimension to show the additional flexibility of the new report.

If you're using analytics.js, then you can do the same tracking using a custom dimension:

(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 
ga('create', 'UA-XXXXX-X', ''); 
var searchTerm = getParameterByName("utm_search_term"); 
if (searchTerm != null) { 
  ga('set', 'dimension1', searchTerm); } 
ga('send', 'pageview');

The highlighted code in this example is setting the first custom dimension slot, dimension1, to the value of the utm_search_term query parameter. Unlike custom variables, you don't set the name and scope in the tracking code, you set them within your account. This means that you need to explicitly create each dimension on the Custom Definitions tab of a web property's admin panel:

The Custom Dimensions Admin Panel
The Custom Dimensions Admin Panel

Press the New Custom Dimension button to open the Add Custom Dimension dialog:

Adding a Custom Dimension
Adding a Custom Dimension

Give your dimension a name and select the User scope, and then press Create:

Creating a User Level Dimension
Creating a User Level Dimension

Now you can create custom reports using your new field:

Using a Custom Dimension in a Report
Using a Custom Dimension in a Report

Your report should have a column containing the new custom dimension:

Visits by Search Term Custom Report
Visits by Search Term Custom Report

If you need any more advice on tracking Bing PPC in Google Analytics, then please post a comment.

← Authentication in the AdWords API Don’t Get Scroogled, Get Free Ads! →

To help me decide what to write about, I'd like to asses the value of my blog posts to see which ones people find most beneficial. If you found the information here useful then could you please +1 it, but if you didn't find what you were looking for then please leave a comment and I'll be happy to help where I can. Thanks!


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.