Forcing a Marketo form to create a new person on every fillout

Level 10 - Community Moderator
Level 10 - Community Moderator

By default, when a form is submitted, Marketo looks up the system Email Address field (the form field named Email ) and merges the submitted values into an existing Person record, if there is one.[1]


If the address is not found, a new Person is created.


The default behavior is desirable in the vast majority of cases. But for specific forms, you may want each submission to result in a brand new Marketo Person. This may not be a marketing-driven request, but sales-driven: for example, a new CRM Lead can be worked separately by sales instead of merging with the Contact.


Tweaking the behavior is almost shockingly easy (at least compared to how many people assume the default can’t be avoided!).


  • Show a secondary Email type field on the form, like Email Address Proxy, instead of the system field.
  • Add the system Email Address field as a hidden field.
  • When the form is submitted, set the hidden Email Address to a guaranteed-unique random value.
  • Have a trigger Smart Campaign listening for the form fillout.
  • In the SC Flow, set the system Email Address to the current value of the Email Address Proxy, using standard {{lead.token}} syntax.


This specific order of operations will create a new Person record, then immediately change its Email Address to the value entered by the end user. (The random value is discarded.) Presto! Duplicates on demand.


Setting up the form

You’ll need to create a secondary Email type field like Email Address Proxy if you don’t already have one. My lab instance has one called Email Address 2 that I decided to reuse.


As you can see here, the Marketo-standard Email Address is hidden, while Email Address 2 is shown to the end user:


Form fields, showing system Email Address field is Hidden


Details for visible field labeled “Email Address”


The JS code

Add this code to the page after the form embed.


The top part is a function to generate a random string GUID (like f07495fe-9aac-4451-abc1-cc70114e7f07). The other part is just setting the system Email Address to a fresh GUID @ a known-invalid domain.[2]

 * @author 30 Seconds of Code
 * @license CC-BY-4.0
function uuid(){
  return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function(c){
    let browserCrypto = window.crypto || window.msCrypto;
    return (c ^ (browserCrypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16);

/* set hidden Email field to UUID, to be adjusted in Flow */
      Email: uuid() + "@email.invalid"


The Smart Campaign

Set up a trigger SC that listens for the form fillout:


Trigger Campaign Smart List


And changes the system Email Address to what the person entered:


Trigger Campaign Flow


The qualification rules can be left at the default (“run through the flow once”) because each new form fillout is a new person, by definition:


Trigger Campaign Setup


The setup in action

Here’s a screenshot of the Smart Campaign Results tab:


Smart Campaign results


And a database search for the Email Address:


Database search results

[1] If more than one lead with that Email Address is found, there’s additional logic to determine which one gets merged into, but that’s beyond the scope of this post.
[2] As I seem to mention over and over again, email.invalid is dictated by the IETF as an unused domain that can never be privately registered.