UTMs are a really valuable tool when it comes to understanding where your traffic is coming from, but not processing their data properly can get in the way of making them an effective data set.
In this post, I’m sharing some best practices for retaining your UTM data in Marketo and sharing that data with your CRM (namely Salesforce). Take a look.
Before you embark on your UTM journey, it’s important to make sure your team is using UTMs in a consistent and accurate way. On the one hand, this means ensuring you’re using UTM codes for anything you publish on your channels. On the other hand, it means creating consistent parameters and naming conventions, down to the case. If you change how you’ve named something from one campaign to the next, then your data isn’t going to group properly.
In Marketo’s native instance, UTMs are captured within hidden fields that live on a form that’s filled out by someone interested in your webinar, gated content, etc.
In this approach, you also need a process for consistently updating your forms to add those hidden fields, ensure they’re written properly, and confirm they’re pulling from the parameter correctly. This native process then stores the value in the field you’re leveraging and typically overwrites whatever the last parameter UTM or details were.
An option to improve your UTM tracking is to put a tracking code on the website, which inserts the UTM values and the rest of the field values directly without you needing to hide the fields on the form.
There are two benefits to this approach:
The script also allows you to capture multiple field sets. If you wanted to have a set of fields that include first and original UTMs, for instance, you would be able to capture the current set and then a set that was prior to them filling out a form. This makes it more informative as you look to understand what’s driving people to your brand.
For those with compliant Google Analytics set ups, it’s possible, along with this tracking code, to also layer in data from your Analytics platform where UTMs aren’t present. This means that we’re able to see other data that would never have UTMs against it to understand how people are coming in (e.g. someone finds a webinar via organic search). For marketers that aren’t very consistent in their use of UTMs, this can also create some additional redundancy.
As you’re setting up your UTM processor on the Marketing Activities page in Marketo, it’s key to think about your UTMs in a multi-faceted way. Many people will set up a single set of UTMs, but that can lead to issues where UTMs are used inconsistently as a group. Instead, thinking about them as groups, rather than individual fields is key to ensuring you have a clean data architecture.
To that end, what I recommend doing is maintaining four sets of UTM fields. Now, I know that might sound excessive, but bear with me.
The first set should be “temp” UTM fields. This would include one temporary holding field for each of the parameters you’re capturing, and would be used in your hidden fields or your API script to capture UTMs. These fields are then used to push that data into your more permanent holding data set values, after which they are nulled.
The key here is that they remain empty 99.9% of the time as they are used only for capture, not retention. By separating the caption function from the retention function, you automatically create a more maintained data set as anything that’s empty allows you to null it later. If the field is empty, then the most recent field that correlates with that should also become empty or nulled.
The second set of fields is your “most recent” or “current” UTM set, which holds the data most recently pushed from the temp set. And the third set is the “first/original” UTM set, which you may choose not to have.
The fourth set that I recommend leverages the Program Member field functionality that was introduced in Marketo last year. As the name implies, Program Member fields are specific to that unique program, allowing you to push data to and retain data on a specific program within Marketo.
In other words, if you’re hosting a webinar, you have your global form and it captures the temp UTMs. If you push that data into the “most recent” field, that will be retained until new data comes in to replace it. Meanwhile, if you push it to the “program” fields, you can see what drove people to that particular webinar in perpetuity. This ensures that you have a local data set of performance analysis for that particular webinar.
The one thing you do have to be careful with is that you’re only allowed a total of 20 Program Member fields for this system, and you’d be automatically dedicating five to 10 fields to this use case. It may feel like a big investment, but you’d be using the function for what it was primarily designed for.
The best practice for any Marketo program is to also have a linked SFDC campaign with which it can maintain a one-to-one reporting relationship on status and membership.
Prior to Marketo introducing the Program Member feature, the only way to look at a program by program (or campaign by campaign) process was to do it at the Campaign Member object inside of Salesforce. This meant pushing the data into the Lead/Contact object inside of Salesforce, and then using that to parse or process them onto the Campaign Member object in Salesforce via a nightly batch or triggered process.
For anyone still using this approach, I highly recommend that you continue to leverage your “temp” fields to drag that data, rather than your “most recent”.
I also recommend that you leverage Salesforce to null that data, rather than doing that inside of Marketo. This is because Marketo doesn’t have transparency as to when the data has or hasn’t been written inside of Salesforce, which can pose an issue if your data is nulled before it’s written.
The processes below both require Marketo to sync the Program Member over and sync the person to Salesforce so that the data can be acted on.
The challenge with this approach is that it can cause potential delays and potentially create data on the wrong campaign. For example, with the nightly batch approach, if someone registers for your webinar with UTMs and then registers for three more webinars, that fourth webinar is going to match the most recent campaign data that you have on that person. The UTMs would be written against that fourth webinar, rather than the trigger event for the other registrations.
As you consider this approach, it’s helpful to know what your ability to modify things inside of Salesforce is and how open your Salesforce admin is to allowing these types of developments. That said, they’re not going to require a heavy load on the system.
Because of the nature of Marketo, Program Member data does not write to Campaign Member data. So, in order to make this work, you have to write the data to the Person object inside Marketo and then translate it to the Lead/Contact object in Salesforce. That’s then pushed to the associated Campaign Member and nulled. To get this right, the name on your SFDC campaign must be an exact match to the naming parlance in Marketo, otherwise, you might break the setup.
The alternative to the processes above is to work outside of the native Marketo/Salesforce integration. You can do this with a third-party tool like Workato or Tray.io where you pass the Marketo campaign information into Salesforce via that software. Or you can build your own custom webhook.
The webhook is built on the Marketo side, and then the SFDC admin would have to surface a public REST API input on the Salesforce side. This public REST site is only going to point to the Campaign Member object—it won’t modify or update data related to the account, contact, lead, or opportunity. As such, the risks are relatively low, but they will still warrant a conversation with your SFDC admin.
A webhook build like this one removes the potential issue of binge behavior. Each call that’s made to push that data across is a packet of data that’s generated at that moment and then doesn’t change. So, if someone came in and binged four separate webinars, a separate packet for each of those four engagements would be pushed.
When you have a data setup where you’re leveraging your Program Member fields, and using an API connection to transfer that data, you can revert to nulling that information on the Marketo side instead of relying on Salesforce.
In this process, we request this campaign via the local Program process that is translating that data into the Program Member fields. Then, we push the webhook that’s going to tell us the timing is right for us to write the information into our Person or Contact/Lead fields and then null them.
In the flow, start by writing the Person field in Marketo that correlates to the Contact/Lead on the Salesforce side, using tokens based on the “temp” values for each data point.
Then set a short waiting period. Note that your system may take a bit longer than two seconds.
Then null those values.
If we were also writing to original fields using this process, we could insert a “request campaign” or “remove from flow” step prior to nulling these values, or have them nulled in a subsequent process.
Writing the original fields during that flow step would be a great use of the Execute Campaign process, in order to ensure that each of those flow steps was executed prior to requesting the null campaign. This step can also be pulled into the process.
In this case, the trigger is that our program status is changed.
The first step is to update people via a webhook, including an exception for people who have already been inserted.
Then the people that are on the list are removed from the flow.
We write a number of fields into this specific program—some of which are non-UTM fields. For example, the Program Actual Engagement Date is useful because Salesforce writes the campaign member engagement date based on when the person is added to the program. But if there’s a delay in the processing, or if you’re adding people from a list from an event, that could be off.
For program UTM fields, we’re using the temp fields to write in on each of them. Next, we run the webhook to insert the data into Salesforce and request the campaign to write those fields against our most recent fields.
Note that this second webhook is used to insert Person data instead of updating it, which is the function of the first webhook.
Once the program is live and we go in to look at our members, we can modify our view to only show data that’s relevant to UTM. This will be mirrored by what’s reflected in the SFDC campaign if your transfer of information is successful.
If you don’t have the time or resources to build a webhook, this data would give you the right insight to understand what drove people to a particular event.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.