Linking events to a specific user in Google Universal Analytics

In this post I will show you how to send events for a specific user from both the JavaScript agent (Analytics.js) and the Measurement Protocol. I could not find any existing information about how to do so. After some research, I did, however, find a great presentation by @techpad that talks about improving e-commerce tracking using Universal Analytics. In one of the last slides, the presentation talks about this issue exactly (slide #31).


The Measurement Protocol enables you to send events from a non web-based system, including a native mobile application or a batch process. In order to be able to link an event to the right user, you have to present the user identification as part of the call. Following is an example:



curl –data "v=1&tid=UA-XXX-X&cid=12345&t=pageview&dp=%2Fhome"



In this call I tell Google Analytics that user ID no. 12345 viewed a page called “home”.


curl is used here to execute a post call to Google. Even if you are not familiar with curl, or are not a technical person, the call is pretty trivial: you have to pass:

  • The property ID you want to use for tracking this event (tid)
  • The client ID (cid)
  • The information about the pageview (t and dp)

I recommend you check out the Measurement Protocol Developer Guide for detailed information about the parameters that you can pass, and examples of how to send pageviews, events, e-commerce tracking and more.


Google documentation states that the client ID (cid) should be an anonymous ID



v=1 // Version.
&tid=UA-XXXX-Y // Tracking ID / Web property / Property ID.
&cid=12345 // Anonymous Client ID.
&t= // Hit Type.


(I’m guessing they mean that the ID should be anonymous to Google – not to you, obviously…) Using an email address as the client’s ID will enable Google to identify this user, whereas passing a client ID that you allocated/invented, and which does not hold any personal information, can only be linked to the actual user by yourself.


So far so good. Now we know how to send specific user events using the Measurement Protocol, but what about sending events using Analytics.js? Luckily, there is a way to send pageviews and other events on behalf of users:


Tell Analytics.js to use your own client ID (clientId) when creating the tracker:


ga(‘create’, ‘UA-XXXX-Y’, {
‘clientId’, ‘12345’

However, when using this method there are a few things you should keep in mind:

  • The default tracking code includes the domain as a 3rd parameter that is passed to the create command. Trying to set the clientId when the domain is passed did not work. I’m not sure why.[javascript]
    // does not work
    ga(‘create’, ‘UA-XXXX-Y’, ‘’, {‘clientId’: clientId });

    // does work
    ga(‘create’, ‘UA-XXXX-Y’, {‘clientId’: clientId });


  • The GA team says they have “two acceptable formats for a client ID: either a UUID Version 4 (recommended) or their legacy anonymous identifier format “X.Y”, where X and Y are each random 32-bit numbers”. Based on my own experiments, you can, in fact, pass anything you like as the clientId, but I assume that sooner or later they will change this and only accept these two formats.
  • If you already have a tracker and you want to change the clientId while the user is on the page (for example, if you use an Ajax call for the login process), the best way of doing so is by creating a second tracker and passing the clientId during the creation of that tracker:[javascript]
    // create a second tracker (called ‘identified’) with the
    // relevant client Id
    ga("create", "UA-XXXX-Y", {

    Now you have two trackers on the page – one with the wrong client Id (the tracker you had before the login) and another one with the right client Id (the one we called “identified”). All you have to do from now on (as long as the user does not leave the page) is make sure you send events using the right tracker:

    ga(function() {
    // look for a tracker called ‘identified’ (exists
    // only after login)
    var tracker = ga.getByName(‘identified’);
    if (typeof(tracker) == "undefined") {
    // if does not exist, send the event using
    // the default tracker
    ga(‘send’, ‘pageview’);
    } else {
    // if exists, send the event using that tracker
    ga(‘identified.send’, ‘pageview’);

    The second tracker overrides the clientId in _ga so from now on, new trackers will use the right clientId.

You should also note that the clientId is the ID that Google Analytics uses to identify the user. It is stored in a cookie (Universal uses the _ga cookie and Google Analytics uses __utma). The above call will tell Google to use your clientId instead of creating one (or using the one that is already in the cookie in the case of a returning user). Don’t confuse this method with the “alias” method available in Mixpanel where they link the current user ID to the one you pass. This might sound like a small nuance but it is actually a big deal. I will explain more about it in my next post.


You might also be interested in: A Different Approach to Cross Domain Tracking


It is also important to state that this is the exact equivalent to manually changing the ID in the cookie (changing the _ga and __utma cookies) – which I have done in the past when wanting to send offline events on behalf of my visitors. There are, however, two improvements: It is easier to do so using this method, and more importantly, if the offline events are sent during the 30 minute session (or any other time limit you specify), they will be part of the same session.


One last thing you should remember: In order to be able to send events using the measurement protocol, you have to store the clientId somewhere on your server so that later on you are able to send that ID back to Google via the measurement protocol.


I would be happy to hear your thoughts. Please feel free to email me or leave a comment.