Screen Shot 2017-04-21 at 11.04.38 AM.png

UTM Code Tracking and Reporting for Third Parties

Level 8

Hi All - I wanted to share something I've developed in conjunction with one of our paid inbound vendors.

The Problem: GE Healthcare works with an ad agency who places our digital ads. We use Google Analytics tracking which we found had a tendency to differ from Marketo reports and last year we spent a great about of time trying to tie out reports.

Requirements: We needed to produce end-to-end reporting to show how many people visited the site, filled out a form and then went through our sales funnel all the way to the Opportunity stage. Leadership wanted to see how much was created in Opportunities and wanted all reporting in one package. We also needed a way to track multiple UTM code responses and store as history in a way we could see what happened historically and this all needed to be done in Marketo. We also wanted the ability to pass this ID to the cloud in Google Tag Manager so it could be added to Google Analytics reports

Constraint: Because the vendor is a third party, and international at that, sharing personal information needs to be restricted. We wanted a way that would allow us to send them information WITHOUT sending over any personal tracked info, like name, email, etc but to be able to tie it out internally if needed.


What we came up with is a pretty simple, easy to deploy method that creates a unique identifier for a person that's not tied to any other system. Our first thought was to use Lead ID, but that's not generated quickly enough to tie to a form fill event that could be passed to GA to show a conversion. Also, we questioned whether we should be sending over any system IDs that could somehow be used maliciously.  Also, since there's no way to create n:1 tables in Marketo for historical tracking, like UTM history, we decided to create a process.

For UTMs:

We created a field in Marketo that aligns to each of the UTM parameters: utm_campaign, utm_content, utm_source, utm_term, utm_medium. I also created a field called utm_history.

Then I created a smart campaign that listens to any form fill where utm_campaign is not empty. In the Flow, utm_history has the following Change Data Value:

DateTime: {{system.datetime}} | Tracking ID: {{lead.flex field 1}} |  Campaign = {{lead.utm_campaign}}  |  Source = {{lead.utm_source}}  |  Medium = {{lead.utm_medium}} | Term = {{lead.utm_term}}  |  Content = {{lead.utm_content}}---- {{lead.utm_history}}

For the Tracking ID:

This was something we tried a few different times before agreeing on something we both liked.

On our webpage where we want this tracking method used, I put the following code in the header:


  var leadId = Math.random().toString(36).substr(2, 5);


    dataLayer = [{

   'trackedId': leadId,

   'pageName': '<page name>'



Here's what's hapening:

  var leadId = Math.random().toString(36).substr(2, 5); <!-- This creates a random 5 digit alpha-numeric string

  document.cookie="_trkRndId="+leadId; <!-- This writes a cookie called _trkRndId (track random ID) and stores the 5 digit alphanumeric created above

//This writes the data to the Data Layer is Google Tag Manager.  Please read up on it for an explanation.

    dataLayer = [{

   'trackedId': leadId,

   'pageName': '<page name>'


Now, on the form on the page, I have the UTM fields hidden (prefilled disabled) with the values pulled from their appropriate URL parameters, and I use something called Flex Field 1 as a hidden field field with its value pulled from the cookie, _trkRndId:

Screen Shot 2017-04-21 at 11.04.38 AM.png

I use fields called Flex Fields as temporary, all purpose fields. When I want to set something on a temporary basis that's stored in a notes field, I use one of my 5 flex fields.


Now, my UTM history field has a continuous, chronological summary of interactions with UTM encoded links along with a unique identifier to the person for each form fill. I could decide to make the cookie more persistent, but since there's no guarantee that the end user will be on the same device each time they interact, there's no guaranteed value to having the random user ID always be the same.

I can now build out a smart list with utm_history + opportunity value and status fields and send that to my international third party without worrying about personal identifying tracking information being shared. I also know that the value in that field would be pretty difficult to use maliciously since it's never exposed in the code on the page and it doesn't link back to an ID field in any system.

Now, because Sanford might read this....

Yes, there is a small probability that the 5 character code could be repeated. Given the amount of interactions I'm expecting, I'll take this risk.  Yes, the way I store the utm_history field could be better formatted, but we currently have no other uses for it. Yes, some super-sophisticated Russian spy hacker 14 year old probably can expose a bug in this system. Can't win 'em all.

In the end, this gives me and my agency something we're comfortable sharing and reporting. Our agency can use the UTM data to identify exactly which ad is helping us generate the most revenue and then make adjustments to the spend on the fly.

Level 8

The UTM history log will contain a log of the random IDs so no matter which device they use or what that variable is it'll write to UTM history.

As for Bullet 2, if it's a new lead you won't be able to get a lead ID fast enough.  Tried this.  You're asking for Marketo to create a new lead and ping back the ID in the time it takes the web page to submit the form and load the new page. I suppose this COULD work if I put a timeout in the onSuccess call or looped until Marketo pinged back a lead ID but this risks a page timeout since Marketo can sometimes take several minutes to process the lead if there's a campaign queue backlog (which we experienced during testing). Also, I'm going to go all Sanford Whiteman here and state that exposing the lead ID is dangerous because a 14 year old Russian Hacker could then get personal information and then corrupt our data or something.


(Literally, what I picture in my mind when I think of Sandie)

I'm not sure I fully understand stuffing the ID in the Activity log's benefit. I want to track conversions, which I define as a successful form fill out. If I save the random ID to the Activity Log "On Page Visit" and the lead doesn't convert, what good does that do for me? If they later re-visit the page a new ID will be created and stored in the History field.

What would really be helpful is an extensible schema with 1:n relationships for custom dimensions that could be populated with data through normal workflows instead of going through a 3rd party API.  Adobe Campaign and other products have workflow management tools that can do all sorts of magic, although they're exponentially more difficult to use.

Hi Robb,

Thx for these details, they are very useful and make a lot of sense.

I am not sure that anyone with a lead ID could do more than anyone with you random ID.

A few thoughts:

  • I agree that stuffing the ID in the activity log has no usage for conversion, but if you happen to want to measure engagement, then it might become helpful, since all visits become relevant.
  • The only thing I would probably change to your method is to have the Random ID duration set to 2 years instead of session. Although I understand why you do not need to keep it, there is not reason why you should change it neither


Have you seen these ideas:


Now that GDPR is in affect, what are your thoughts on updating this process to accommodate for the new legislation? If you instance isn't managing European's data, how would you go about ensuring someone who requests to not be tracked or have personally identifiable information on them be collected other than data required to ensure this request is met?(i.e. - keeping an associated ID or email or IP to ensure 3rd party data added later can be screened in the best way possible to prevent any previously removed personal data from re-entering the system)

Since stop tracking requests are frequent, it ads a whole layer to this great customization. I suppose it is possible that an additional program could be created to look for identifiers from the "opt-out euro" list in any newly created record regardless of source, then routing the new record to the ban list could make my first questions moot. Still curious if you or anyone has thought about these types of tracking customization and the new law?

Level 8

Well, if they're filling out a form aren't they consenting to have information stored?  I'll admit upfront that I know little about GDPR as I don't handle Europe but I am reading the recently submitted articles about it and have forwarded them to the European team