Form prefill with Marketo: a complete introduction

You and your dev team have done it. You’ve got your Marketo forms embedded on your website. No more external landing pages! You’re ready to drive your lead experience fully integrated into your brand site. You’ve wrestled with Marketo’s unwieldy form markup and built-in styles, and it’s downright seamless! There’s only one step left: form prefill. It seems simple enough, but form prefill with Marketo is fraught with perils. In this article we’ll discuss your options, help you understand common stumbling blocks, and share tips on how to take that extra step for the best user experience.

Why are we focusing on Marketo?

Lots of marketing automation platforms offer form prefill, so why write a few thousand words on Marketo? Two reasons:

  1. Marketo is an enterprise-level platform with a huge user-base. Once a company reaches a certain size, or level of marketing maturity, they are all but guaranteed to have considered Marketo.
  2. Prefill with Marketo is complicated, but achievable. If we wrote an article about form prefill in Hubspot it would be one paragraph long. If we wrote it for Eloqua we’d read it to our kids to put them to sleep at night…

What is form prefill and why do you want it?

Form prefill means using known user information to fill form fields for them, so they don’t have to. There are a few key reasons you might want to do this:

  • Your site requires lots of form interactions to get to content, and you want to make the submission process as easy as possible.
  • You want to serve up different fields to a user based on the ones they’ve already filled in (progressive profiling).
  • Once you’ve gathered the lead information you need, you want to keep the form as short as possible (form shortening).
  • Lead information stored in Marketo is used to personalize the user’s web experience.

Note that this isn’t the same as form autofill, which is using a third-party service to pull in public company or industry data once the user has filled in an email address. That is a separate exercise that we’ll go into in a later post (spoiler alert, we like Clearbit for data quality and ease of use). Prefill is feeding the lead data that a user has already supplied back to them.

Here’s a use case. Your site includes lead generation forms that you’ve placed in front of key whitepapers. These whitepapers are chock full of industry insights, and to get to them you’re asking for basic contact information. However, you’ve realized that when a user wants one of your whitepapers, they usually want a few more. So instead of serving the same fields every time, you use prefill to tell Marketo which fields are already populated, and give you some new fields instead (Marketo’s conditional field logic is excellent for this). The first time a user submits a form you might ask for email, first and last name, and company. On the second you get a little bolder, and ask for phone number and what their key initiative is for this year. And so on.

Taken one step further, you can determine when they’ve filled out all the fields you need. And at that point either skip the form altogether, or just ask for email address to confirm their identity.

The Munchkin tracking script

an example of Marketo's Munchkin tracking code

First of all, the site visitors have to be known to Marketo. This means including the Munchkin tracking script throughout the site. Marketo lays out the steps in their documentation. If you’re working with us, we’d recommend integrating the script through Google Tag Manager. Not only does this provide more control over when and how the tag fires, but if need to comply with GDPR you can use GTM to ensure Munchkin doesn’t fire until after cookies are accepted.

Using the Marketo REST API for form prefill

Alright, time to get fancy. And by “get fancy,” we mean write some code. Marketo offers API endpoints that allow websites to pull lead information based on the user’s Marketo cookie. We’re not going to break down setting up and using the API in general, but we will show you the steps a developer can take to get to lead data via the API.

Make the request

Once the API is authenticated, you can send the Marketo cookie (named “_mkto_trk”) in a lead lookup request, called Get Leads by FilterType. Here’s a basic example:

<?php

function marketo_get_leads_by_cookie($cookie, $access_token) {
    $curl = curl_init();
    $params = [
        'access_token' => $access_token,
        'filterType' => 'cookie',
        'filterValues' => $cookie,
        'fields' => 'email,firstName,lastName'
    ];
    curl_setopt_array($curl, array(
        CURLOPT_URL => 'https://889-JWR-479.mktorest.com/rest/v1/leads.json?' . http_build_query($params),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'GET',
    ));

    $response = curl_exec($curl);
    curl_close($curl);

    return $response;
}

This is a basic request to Marketo with the cookie value, and Marketo will return a list of matching leads. But it’s just meant to show the concept, do not use it, it won’t work on its own!

Let’s look at what we’re passing:

  • access_token: We get this from the Marketo API after authenticating. It’s required for all API endpoints.
  • filterType: How we want to filter leads. We could also filter by other fields, such as email.
  • filterValue: Our Marketo tracking cookie goes here.
  • fields: A comma-separated list of the lead fields Marketo should return for any results it finds. Note that these field names are unique to the API, so you’ll need to consult the fields admin panel in Marketo to get the right names.

Push lead data into the form

{
  "requestId": "12951#15699db5c97",
  "result": [
    {
      "id": 174037,
      "updatedAt": "2020-05-17T22:11:45Z",
      "lastName": "Doe",
      "email": "example@test.com",
      "createdAt": "2020-03-17T00:18:40Z",
      "firstName": "John"
    }
  ],
  "success": true
}

Marketo will return a result like the above. Note that even if there is only one match for the cookie (there certainly shouldn’t be more than one), this endpoint still returns a list. Now that we have this data, we need to push it into the Marketo form. Marketo makes this pretty easy with their forms API.

Let’s assume we’ve gotten this data on the frontend and have it available in Javascript. Now we need to get the form and update field values.

MktoForms2.whenReady(function (form) {
    var lead_data = {};

    form.vals({
        FirstName: lead_data.firstName,
        LastName: lead_data.lastName,
        Email: lead_data.email
    });
});

MktoForms2 is Marketo’s reference to its internal form Javascript API. Definitely read up on it before attempting anything written here. Let’s break down what’s happening:

  • MktoForms2.whenReady fires when Marketo has finished loading an embedded form. Before this, we won’t be able to affect anything on our form.
  • form is a reference to the Marketo form object, and it is very malleable. This gets passed into our callback.
  • lead_data is our example variable of the lead data we requested from the Marketo Rest API. Obviously this is example code and skips some steps on how API requests work!
  • form.vals lets us push in key/value pairs of fields to be updated.

Now the form has been updated with lead data! If the form includes any conditional rules based on field values, Marketo will automatically fire these and update the form as needed. BUT, on its own, this approach is not scalable. Let’s talk about why.

The API approach is difficult to scale

Relying on the Marketo Rest API in this way is flawed because Marketo has very low API limits. The most important one for this discussion is the concurrency limit. Marketo only allows 10 requests to its API for an individual instance to be open at once. That means if 11 known leads visit a form page at the exact same time, one of them isn’t getting prefill. What can we do?

  • Cache lead data results in local storage to avoid hitting the API unnecessarily. This really only works if you’re prefilling non-personally-identifiable data, like industry. Otherwise you end up storing contact information in a cookie or in local storage, and that gets dangerous.
  • Cache lead data in your own database. Again, this is dangerous territory, and is not recommended.
  • Live with it. If your website doesn’t get a ton of traffic, it might not be a big deal. But, of course, that’s thinking pretty small, isn’t it?
  • Use an alternate method. We use the Marketo Landing Page method whenever possible. It requires more setup, but ensure prefill works with no cache and no API calls. Let’s discuss how it works.

Using the Marketo Landing Page method for form prefill

Before we jump into this method, note that we are getting deep in Marketo technical territory. If you do not have a Marketo technical resource available (someone who works within the Marketo UI and understands it very well), these approaches might not be best for you.

This method uses Marketo Landing Pages to pull known-user lead data, and it was pioneered by Sanford Whiteman on his blog, TEKNKL. Those who have spent any time in the Marketo community will recognize the name. Sanford is incredible active in the Marketo community and has been responsible for dozens of incredible solutions for integrating Marketo.

I won’t copy Sanford’s article here, please visit his blog for details on how to use this method. But here are the highlights:

  • Marketo tokens on a landing page are placed in parse-able meta tags to include lead data that we want in our forms.
  • A cross-site script can use the Marketo tracking cookie on your main site to load that landing page, and pull back the lead field values.
  • This requires that your main site and your Marketo landing pages share a main domain. If you don’t have a secured, branded Marketo LP subdomain, this won’t work. And that’s a good thing. Since this method requires matching domains, it keeps it secure.
  • The landing page is never shown to users. In fact, except for the meta tags and script necessary to make it work, it’s empty.
  • Since you are loading the landing page, you aren’t using the REST API and are not victim to its limitations.
  • Once the lead data is collected, it’s pushed into form fields using the same method as described above.

To sum up, this method is AMAZING but also COMPLICATED!

Using Marketo RTP to control form personalization

Marketo recently made their RTP (Real Time Personalization) product free to all its users. Or, more accurately, RTP is now pre-paid, as Marketo increased prices across the board to cover it. But either way! It’s an excellent product and well worth taking advantage of. We can’t use it for form prefill, but instead can use it for form personalization. Or, put another way, we can use RTP to control conditional fields in our form and whether or not they are shown to the user.

Like the previous method, we are in Marketo technical territory. For the purposes of this article, we’ll focus on how it works, especially on the web. But there are additional steps that need to occur within your Marketo account.

Setup segments

Marketo breaks down how to create web segments here. For our purposes, let’s assume we’ve created a segment for Opt In. The criteria is that a lead will be added to a segment if they’ve previously filled out a form and opted in to be contacted. Since they belong to this segment, we know they’ve filled out at least one form, and that we’ve already collected some basic information about them. We can also run this segment against existing leads, so that matches already have it applied.

Use the RTP Script

The RTP script is how Marketo interacts with RTP data on your website. It does not utilize the API, but rather uses Javascript web services, which are not limited. In addition, it doesn’t deal with lead contact data, just segmentation. This data can be invaluable for web personalization, either using content created within the RTP product itself, or integrated with a separate personalization solution like Logic Hop.

The RTP script needs to be placed on your site, and looks quite a lot like Marketo’s Munchkin script:

<!-- RTP tag -->
<script type='text/javascript'>
    (function(c,h,a,f,i,e){c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
        c[a].a=i;c[a].e=e;var g=h.createElement("script");g.async=true;g.type="text/javascript";
        g.src=f+'?aid='+i;var b=h.getElementsByTagName("script")[0];b.parentNode.insertBefore(g,b);
    })(window,document,"rtp","rtp.js","youraccount");

    rtp('send','view');
    rtp('get', 'campaign',true);
</script>
<!-- End of RTP tag -->

In addition, the RTP Javascript API provides methods for interacting with segmentation data. Here’s a very basic example of using the web service to return visitor data:

<script>
    $(document).ready(function(){
        function rtpCallback(data) {
            console.log(data);
        }
        rtp('get', 'visitor', rtpCallback);
    });
</script>

RTP will include some of its default data, as well as our Opt In segment. The result looks like this:

{
  "status": 200,
  "results": {
    "org": "Tiny Ships",
    "location": {
      "country": "United States",
      "city": "Atlanta",
      "state": "GA"
    },
    "industries": [
      "Telecommunications"
    ],
    "isp": false,
    "matchedSegments": [
      {
        "code": 1111,
        "name": "Enterprise",
        "lastMatchTimestamp": 1611933261339
      },
      {
        "code": 2222,
        "name": "OptedIn",
        "lastMatchTimestamp": 1611933261339
      }
    ],
    "abm": [],
    "category": "ENTERPRISE",
    "group": null
  }
}

As you can see, RTP has made a few determinations. It has a good idea of my location, has placed me in an Enterprise segment, and I’m in the OptedIn segment.

In Javascript, this result can be checked and, depending on the results, can be used to update the Marketo form. Much like the above examples, we’d push a value into a form field. In this case, the cleanest method is to update a hidden form value, and create conditional rules in Marketo that show and hide other fields if our hidden field has a value. Here’s what the process might look like:

  1. The Marketo form loads, and includes basic contact fields and the hidden “optedin” field, which is empty by default.
  2. RTP script loads.
  3. RTP returns visitor data. The visitor is in the OptedIn segment.
  4. Javascript is used to update the hidden “optedin” field value to “1.”
  5. Conditional rules on the Marketo form automatically fire. Basic contact fields are hidden, and other fields are shown. For example: industry, company size, phone number.

Now we’ve given the user a personalized form experience with little setup, no REST API calls, and no exposure of lead data.

UX Tips

The fun part is done! To wrap up, here are a few tips to consider when using form prefill for Marketo:

  • Test, test, test. Test every iteration of your form. Ensure that it meats functionality and design requirements no matter the state of prefill, its availability, or much data could be gathered.
  • If the user is known, give them a way to become unknown. For example, if the form is prefilled with an email address, include a button that says something like “Not you? Click here.” This button should delete the Marketo tracking cookies and reset the form.
  • Consider hiding prefilled fields, even if you only have one, static form. This makes the user experience that much nicer, and conversion friction that much lighter. The exception is email address. Always be clear to the user that they are known.

Form prefill is complex but the pay-off to user experience and form conversion can be huge. If you’ve got a project involving form prefill and personalization and need our help, send us a note to discuss it.

Scroll to Top