Skip navigation
All Places > Products > Blog
1 2 3 Previous Next

Products

365 posts
Conner Hatfield

ABM Account Scoring

Posted by Conner Hatfield Employee Jul 9, 2019

***Posted on behalf of Tallie Belitz, Senior Manager of Sales & Marketing Operations at Kollective Technology.***

 

Marketo’s Account Based Marketing module is a powerful tool, but it can be intimidating if you don’t have a strategic plan to drive value from  it.

The key ABM insights lie in the Account Score, but there are a few things you need to set up first to ensure your Account Score is truly including everyone in your database associated with that company. Follow these five easy steps below:

  1. Start with a solid lead scoring model. Begin with the Definitive Guide to Lead Scoring to implement best practices. 
  2. Develop your Ideal Customer Profile (ICP) and create a Target Account List. We kept it simple and started with just 3 key characteristics:
  • Number of Employees
  • Geography
  • Industry
  1. Create a Smart List for your Target Account List. This list may take some time and focus to create, but it can be referenced in nearly all your campaigns, so it’s important that it is accurate. Be sure to include as many variables as possible to capture variations on the company name, but excludes similar names.

4. Build out your Named Accounts in the Account Based Marketing Module. The companies in your Target Account List may already exist in your CRM, but some may not. To add them to the ABM module, look for them first in the Discover CRM Accounts section. If you don’t find them there, search for them in the Discover Marketo Companies section, and add them.

5. Make fuzzy logic crystal clear! Marketo Lead-to-Account matching uses key information on the lead record, such as email domain, inferred company name from IP address and company name (learn more about this process in the Marketo Product Docs). This feature associates most people from that company to that account, but does not always capture everyone. If the company has multiple domain names or the person uses their personal email address they may not be automatically associated with that account. It’s imperative to associate everyone to the appropriate account to get an accurate Account Score. There are two things you can do to make sure this happens:

 

Option 1: 

  • Under the Named Account tab, click on the specific named account and navigate to the Potential People tab. This is where you find weak matches associated with the account. After analyzing the potential people, click the person or people you would like to add to the named account and click Add People. 

Option 2: 

  • Look at your Target Account List to see if anyone is missing. 
  • First create a customized view that includes the Named Account field.
  • Sort by Company name and look for any blanks in the Named Account field.

  • Highlight the names, then under Person Actions, select Marketing, and choose Add to Named Account.


With everyone associated with a company in the Named Account, you will have an accurate and actionable Account Score. From here you can begin monitoring the scores at a regular cadence to look for increases in activity at the account level, not just the isolated lead score for each person.

With Account Scoring set up, you can now unlock the power of ABM!

The post title is a bit of a mouthful, but if you've been bitten by a certain feature gap you'll know what I mean.

 

One of the first things you learn about Wait steps is they don't have a literal Add Choice option.

nelson pointing at marketo

 

This can be frustrating when you want to vary the Wait delay based on  runtime conditions (that is, conditions you can’t know until the person has qualified and entered the flow) importantly including no delay at all.

 

But with a tiny bit of work, you can simulate Wait step choices.

 

It’s a matter of managing a Date/DateTime field, earlier in the same flow, using Marketo’s simple plus/minus support.

 

Here’s such a field:

 

field mgmt

 

And here’s a flow that uses that field to manage a subsequent Wait step:

 

flow steps

 

This approach works because of 3 convenient truths:

 

  • Change Data Value is synchronous within a single flow[1]
  • Date tokens understand a few math operators
  • Wait steps using a Date token will be skipped if the Date token is empty

 

Truth be told, I don't always endorse this tack over multiple Smart Campaigns. Whatever’s making you want drastically variable Wait periods (other than implicitly variable periods like wait-until-anniversary) may mean the lifecycle is going to differ in other ways as well, in which case discrete SCs help you keep your sanity. But it's there if you want it.

 

P.S. Yes, you can also use a Number {{my.token}} for the delay itself, a setup that might be almost too cool to follow! Or a Text {{my.token}} (don’t know why you’d choose this over Number, though) as long as you don’t include the unit  (“days”, “hours”) in the value, keep that hard-coded in the Change Data Value box.

 




Notes
[1] “Synchronous” meaning the New Value is guaranteed to be readable in the next flow step. Contrast this with, for example, webhook-based updates, which are asynchronous (background) value changes.

Marketing Nation members, I’m thrilled to announce a new addition to my team, Jonathan Chen. Jon will be taking lead as Community Manager and, as such, will be working with all of you to ensure our Community remains the best community ever!

 

Here’s Jon’s message to you:

 

“Hello Marketing Nation,

 

My name is Jonathan, and I joined Marketo last week as a Community Manager for the Marketing Nation Community. I am so excited and grateful to be a part of such an innovative and quirky team at Marketo and can't wait to engage you all with interesting topics and ideas to further expand your knowledge of Marketo. Before joining this team, I was a product marketer at a prominent enterprise headset company, where I helped expand its innovation business by developing scalable marketing programs and communities to drive awareness and advocacy. I often used Marketo in my previous job to develop monthly consumer newsletters and quickly fell in love with the highly sophisticated, yet surprisingly intuitive platform. Of course, I learned that Marketo has countless solutions for every use case and was blown away by the Community's respectful users, vast database of creative ideas, and snappy responses to even the most complex of questions. The Marketing Nation is truly one of a kind, and it's because of every single one of you. From the daily posters to the occasional lurkers, know that I am here to support you on your Marketo journey. There are many great projects planned for the Community, and I can't wait to show you what's in store in the coming months. Please feel free to reach out to me at jonchen@adobe.com any time you have a question, complaint, or concern - I'm here to help!”

 

Jonathan Chen, Marketo Marketing Nation Community Manager@@@

 

Please join me in welcoming Jon to the most amazing nation of marketers on earth!

 

Janet

I recently received a request from a customer who was trying to update a person's email address via the API. He was trying to use the Create and Update Lead API, and because the lead had a new email address, he was getting a duplicate person record created with the new email address. What he wanted was to update the existing Person record with the new email address instead.

 

 Since I have had this question a few times, I thought it would be helpful to write a blog post about it.  The steps to follow are below, but...spoiler alert....the answer is to use the Sync Leads Using Post endpoint instead.

 

 In order to update the right Person record, I'll need the Marketo Person ID for that person.  I can get that using the Get Leads By Filter Type endpoint like this: 

 

 

Once I have the id of the Person record, I can call the Sync Leads Using Post endpoint to update that record. As you can see from the screenshot below, I’m passing in an action of “updateOnly” and  “id” for the “lookupField” value. Then I can pass the information in the “input” that I want to be updated; namely email in this case.

 

To verify that the email address was changed, I can make the  Get Leads By Filter Type call again and pass the new email address. 

 

Finally, there are several ways to get the person id that you’ll need to do this with.  You can either do a Bulk Lead Export if there are a lot of them or you can call Get Leads by Filter Type if it's a one-off, and you need to look it up by email address. 

 

Many of our customers have complex business requirements that require more than what the baseline Marketo data model can support. That's why we have Custom Objects in Marketo. Custom Objects allow the customer to support more advanced data models in Marketo, but there are some best practices to follow when using them.

 

Measure Twice. Cut Once

 

When you first design your Custom Object, we advise to take your time and get all of the fields correctly defined before you approve the object. The reason for this is data contiguity. When you approve the custom object, Marketo creates a table in the database for that object definition.

 

If, at a later time, you decide that you need another one or more columns, and you simply add them and approve the object again, the additional columns will not be stored in the same table as was created in the original object definition. Going forward, you'll have data in two different tables for that object, which will require Marketo to use a join whenever it access that object. This can have an adverse effect on the speed of data retrieval from Marketo instance, impacting script execution, data access via the API, and even the user experience in the Marketo web UI.

 

As an alternative, you could always drop and recreate the Custom Object with the correct columns, but then you would have to migrate the data from the old Custom Object to the new one which adds a level of complexity that most of our customers don't want to get into. The best option is to get it right the first time; like woodworkers say: "Measure twice. Cut Once."

 

Recreating a Custom Object

Just in case you find yourself in a position to need to rebuild your Custom Object, here are the steps you'll need to follow to do it correctly: 

  • Stop any third-party integrations that are using the Custom Object via the API.
    • This will prevent any third-party systems from trying to access the Custom Object via its API while you're rebuilding the object.
  • Remove all references to that object in filters, flow steps, smart lists etc. 
    • This will prevent any trigger campaigns from executing based on your work.
  • Write down the exact spelling of the Custom Object.
    • So you can recreate it later
  • Delete the Custom Object 
    • Depending on how many rows of data are in the Custom Object, you may have to ask support to do this.
  • Wait for about 15-30 minutes to allow Marketo to confirm that the Custom Object is fully deleted
    • This ensures you can recreate the object with the same API name.
    • If you just delete and recreate the object with the same API name, the recreate can fail.

 

Don't Use Custom Objects as a Data Land Fill

Many of our customers do regular bulk exports of their data for storage in a data warehouse of some other third-party analytic system. If your Marketo instance is full of Custom Object data that is not, and never will be useful for that analysis, your exports will take longer and have a more significant effect on your API rate limits. 

 

To avoid allowing your Marketo instance to fill up over time with useless data, it's best to make sure to use your Custom Objects to store only data that is useful now, or in the future. Things you should not store in a Custom Object include:

  • Transient information  - Activity data should be stored in a Custom Activity instead
  • Order history - Consider purging old data from time to time
  • Any data that will not be used for marketing activities

 

Deletion of Custom Object Data

If, after following the steps above, you still need to purge data from your Custom Objects you can do this through the API. Use the Delete Custom Objects endpoint, and remember to batch your calls in order to do up to 300 rows at a time. This will save you from using up your API rate limit.

Email marketing is the foundation of a lot of marketing strategies. With the help of Marketo Champion Beth Massura, this edition of Marketo Master Class puts a magnifying glass on the role that tokens, templates, and snippets play in the creation of a marketing email to help you achieve actionable insights and greater efficiency.

 

  1.     What are the benefits of using tokens, snippets, and templates in emails?

 

There are a few different benefits to using these features. First, tokens, snippets, and templates provide consistency across email communications, which is really important from a brand standpoint. We want the recipients to recognize the emails as coming from a single organization, and having standardized templates and snippets helps with this.

These elements also make it a lot easier to manage global changes. I will never forget when we had to manually update our social media profile links across 400+ HTML email files (in a pre-Marketo system) twice within just a few months. What a pain! Now we can just update a small number of snippets and the updates will appear in all the email assets using them.

 

Templates can help increase confidence that the emails will render well. If the templates have been thoroughly tested across dozens of recipient browser/email client/device combinations, and users are working within the templates, it may be sufficient to test each individual email message across a smaller set of recipient setup variations instead of all of them.

 

Tokens, snippets, and templates also help users create emails more easily. It can be overwhelming to start from scratch every time, and would likely lead to errors. We have the most popular modules and snippets appearing by default in the template, so there is less work for users to set up their email.

 

  1.     What are different use cases for using snippets? 

 

Snippets are good for any block of content that you want to have standardized, but with multiple variations that can be substituted for one another: branding elements, contact information, executive bios, common product descriptions or disclosures, etc. You can set areas in the template that can be replaced only with snippets, or users can replace rich text areas with snippets.

 

We use snippets for brand lockups at the top of the email template as well as for the email footer content such as legally required links and information. We have a couple dozen different departments, programs, and research centers sharing our Marketo instance, and many of them have a variation of the main logo (for the header) as well as their own contact information (for the footer). The central marketing team manages all snippets in the Default workspace, organized into subfolders for each department. These subfolders are then shared to the respective departmental workspaces so they have access to only the header and footer snippets that they should use, and they don’t have access to modify any of the snippets themselves.

 

 

For the header logos, previously our central designers and developers edited the rich text section of an email asset to drop in a logo with the right dimensions and styling and just hoped that the group would remember to clone that particular asset going forward. Unfortunately this meant that if the group cloned the wrong email asset, they’d have to reach out to the designers/developers to replace the logo again. There were also a few users who deleted or replaced the logo in the rich text editor with one that didn’t meet brand guidelines. Offering a snippet “library” of the approved logos/lockups makes it easy for the user to select the one that’s appropriate for the context while maintaining the brand standards. We have set guidelines for the logo sizing, etc., so having the snippets centrally managed helps with that as well.

 

Example header snippet:

 

Additional header snippets are created for logo variations such as these:

 

Our footer snippets contain the contact information for the respective group, as well as the mandatory unsubscribe, preference, and privacy policy links for compliance and user experience purposes. Because much of this information is required by law, it’s imperative that we ensure all these details appear correctly on every single email. Using snippets helps us keep this consistent and avoid variance from the standard.

 

Example footer snippet:

 

 

  1.     What are some under-utilized tokens? How do you leverage program-level vs. folder-level tokens differently?

 

We use a token for the copyright year at the bottom of the email. Previously we had it as a text token on the top folder level for each workspace; we just had to update the values at the start of the year. But now we use an email script token (also in the top level folder) so the year is automatically updated:

#set($timeZoneObject = $date.getCalendar().getTimeZone())$date.format("yyyy", $date.getDate(), $date.getLocale(), $timeZoneObject.getTimeZone("CST")) 

 

It’s a system token rather than a program token, but program ID is added in small text at the very bottom of the email footer snippets. We found this would help us locate the associated program if we were forwarded an email and asked to troubleshoot why a person did/didn’t receive it or to create a similar email.

 

You would want to use folder-level tokens for items that should appear in every single program, such as copyright year. We also have a folder-level token for a tracking code with a default value that is then updated on each program; it is referenced at the end of every url in the email to tie into our web metrics system. We want a tracking code for every program, so even though the value has to be updated on each program, having the token there on the program by default is a good reminder to the user.

 

In the below example, the highlighted “20190610-WEB sample program” inherited tokens from the “BethM Marketing Activities” and “Web Content Programs” folders. It will not inherit tokens created on “20190615-EM sample program”.

 

Program-level tokens can be useful when it’s relevant only to a specific program type, such as “event registration url” for an event program. Because folder-level tokens are inherited automatically by all programs within that folder, it wouldn't make sense to have this type of token in a folder. If you did, it may appear in an unrelated newsletter program through token inheritance. While tokens can be deleted in a program, you can't re-inherit a token once it's been removed

 

  1.     How do you use tokens, snippets, and templates together to fit within a larger strategy? 

 

Tokens, snippets, and templates can be integral parts of a Center of Excellence! We created an all-in-one module-based email template to accommodate a wide variety of layouts for all kinds of emails: newsletters, event invitations, announcements, etc. The template also includes the two areas for the header and footer snippets as well as the tokens as mentioned previously. This template is then used for the email assets in our cloneable standard email send program and the nested email sends within an event program.



  1.     What are the most common pitfalls you see when people are trying to use tokens, snippets, and templates?

 

Make sure you involve stakeholders at the beginning of any initiative to develop standardized tokens, snippets, and/or templates - which ideally is part of the Marketo implementation - in order to gather all requirements before anything is executed. You don’t want to waste time developing a template module that no one will ever use, or to miss one that would be used frequently. While a template can be edited, it won’t push those updates to email assets already created from the template.

 

Creating a template involves HTML/CSS coding and Marketo-specific syntax to define editable areas. Make sure you are working with a developer who is familiar with this. Having HTML/CSS alone won’t allow users to edit an email asset created from the template.

 

All snippets to which a user has access will show up in the Insert Snippet dropdown menu; you can’t select which snippets will be options for area A vs. area B. We use naming conventions to distinguish between header and footer snippets.

 

 

When making changes to a snippet, be sure to update the text version as well. Unlike an email asset, it won’t carry over the edits.

 

Consider whether a piece of information would be best served within a token or something else, like a variable within a template module or even just typing the content directly into the email asset. It can be confusing to enter some email content in tokens on the program level and then other pieces within the email editor. Tokens might be preferable when the content is listed in multiple places and is likely going to change, so all references can be updated at once.

 

It’s definitely possible to create an email asset that solely references program tokens so you don’t have to go into the email editor at all to customize images, colors, text, and links. This “Mad Libs” method can work well for emails that are straightforward and standard in format, such as form submission confirmations. But the moment you want to add in something special, you’re going to have to enter the email editor anyway. And the tokenized method may not be as intuitive to those users who would be more comfortable entering/selecting the elements in a WYSIWYG context. (We are not currently using the “Mad Libs” method, but one of our departments did in the past.)

 

Example tokens for a fully tokenized email:

 

The associated email asset’s editor view; it isn’t pretty!:

 

The preview of the above email asset:

 

  1.     Are you planning to try anything new with these features?

 

One next step could be for us to put dynamic content within our snippets. For example we have regional campuses/offices for some of the school’s departments. Instead of having separate snippets for each region, we could have the snippet dynamically populate the regional address based on the recipient’s region segment.

 

 

_________________________

 

You can find more insightful content in the June edition of The Fearless Forum!

Hi Marketing Nation! As you may have noticed, the look and feel of content within Community has changed. These changes were made during the release of a new build last week. Unlike former builds, we are unable to return to revert to the old layout. 

 

We wanted to communicate the permanency of these changes and work alongside our customers to ensure Community remains the best place for Marketo knowledge, best practices, and discussions.

 

If you have any questions about the new layout, feel free to leave a comment below.

Despite instructing a Community member to “search my posts” the other day, I ran a search myself and there wasn’t a one-stop explanation of what Do Not Track (DNT) means in Marketo (on a deeper technical level than you get on the official doc page). So here goes.

 

As you probably know already, there are 2 DNT options, Ignore and Support:

 

 

We won’t worry about Ignore.

 

But what does it really mean to choose Support? On a technical level, it means one specific thing:

 

If a user’s browser sends the DNT: 1 HTTP request header along with a Munchkin-logged pageview or link click, Marketo will not save the activity to the Activity Log database.

 

So here are some things Do Not Track = Support does not do:

  • it does not stop gathering Clicked Email stats: email clicks are still tracked unless you separately turn off link tracking
  • it does not stop Munchkin JS libraries from loading
  • it does not stop Munchkin from initializing and setting its _mkto_trk cookie
  • it does not stop Munchkin from sending a Visit Web Page (assuming you're using the default configuration which always sends a VWP on startup)
  • it does not stop Munchkin from sending a Clicked Link for <a> links on the page

 

But again, here's the very important thing it does do:

  • it stops the Marketo platform from storing the Visit Web Page and Clicked Link hits sent by Munchkin

 

 

Why not stop Munchkin completely?

It's not that Marketo would not like to be more proactive on the browser side, I'm sure. But the weirdest thing about DNT is there's no programmatic (let alone cross-browser) way to know if the user has set a preference! Ergo, you cannot know if the person would've wanted you to turn off Munchkin downloading/initialization/hit logging. You have to dumbly send the hit in all cases, then the server will discard it if it's accompanied by the “please ignore me” header.

 

The privacy appeal of having the DNT setting be unreadable in the browser is clear — it's the equivalent of an HTTP-only cookie that can't be seen from JavaScript — but it certainly creates confusion. For example, someone with DNT enabled who’s also running Ghostery or similar will still see that the Munchkin tracking JS was blocked, which is suboptimal: ideally, it wouldn’t show up at all. You might seem like you’re being worse corporate citizens than you actually are. (A link on your Privacy Policy confirming that you honor Do Not Track is useful.)

 

 

The browser's-eye view

The browser sending the DNT: 1 header is a prerequisite, of course. Privacy-oriented browsers do this by default; other browsers do it in Private/Incognito/InPrivate mode only; the the rest do it for all pages/tabs/windows when selected. Here's the setting in an older version of Chrome, for one of a zillion examples, which will send DNT: 1 for all pages viewed in this user profile:

 

 

And here’s a screenshot of the HTTP request for the main document, showing the header:

 

 

And Munchkin’s Visit Web Page XMLHttpRequest, showing the same HTTP request header and its acknowledgment in the response:

 

In this edition of Marketo Master Class, Marketo Champion Chelsea Kiko takes a deep dive into the process behind building a Center of Excellence (CoE). Chelsea covers various considerations for building a CoE in both a fresh Marketo instance and existing instance, among other tips and best practices. Read on to discover how to build and maintain your own CoE, from implementation to long-term execution.

 

1. What are the benefits of setting up a Center of Excellence (CoE) within Marketo?

 

Setting up a CoE in Marketo is great for consistency, accuracy, and scaling your Marketo instance. CoEs typically contain programs that are often repeated and have the same type of operational steps. Users can clone these to create their own programs, which provides easy access to high-quality programs and scalability for your strategies. The other great aspect about a CoE is it can be built by an expert (either internal or external) and used by new users in the instance with the same type of consistency across the board. This also saves time and increases efficiencies for your team.

 

2. What are the essential components of a CoE? What are aspects will vary based on use case?

 

 

The first essential component of a CoE program or folder is a naming convention. This is one of the most important pieces in my opinion for CoE programs because when programs are cloned out, the naming conventions are automatically adopted. You should set up naming conventions for all assets, including emails, landing pages, forms, smart campaigns, programs, etc. Having uniform naming conventions for each program is vital to keeping the instance clean and consistent even when various users are working in Marketo. As you can see in the above screenshots, everything is ready to go, even sample email naming conventions. This is all pre-canned so you can clone, update, and have a program done much quicker than if you were creating from scratch.

 

Next, it’s key to build out templates for any operational programs you want to run. This could include programs to: change program status, increase lead score for specific programs, sync to your CRM, send alerts, etc. Once you have them built in your CoE, they are ready for you to edit or optimize for each program right away.

 

Finally, it is helpful to create templates or template styles for specific programs in your CoE. Once you clone the template program and the modules or email layouts are ready, all you have to do is edit tokens or change content/swap images. Even though modular email 2.0 templates are easy to use, it still saves time to have the right modules and layout of your email ready for cloning, especially if it’s an event or nurture program where you have several emails.

 

Be mindful of the fact that when you’re building your CoE you will probably be using different program types. In the screenshot below, there is an email program for a one-time send, a basic nurture program, a more advanced nurture program, and a live event.

 

The aspects of the program templates that will vary based on use cases will be your tokens, operational programs, list arrangements, and reporting. If you have the structure set, changing these aspects is quick and easy. You can easily adapt your programs by editing your CoE program templates, allowing you to scale your instance.

 

 

 

 

**Tip: If you are an agency or consultant, it really helps to have operational programs in the CoE. You can even create these in your sandbox and import the programs into any of your clients to help them with data normalization, lead scoring (customize it on the client), deliverability programs, etc.

 

3. What are some best practices for creating a CoE in a fresh instance of Marketo vs. building a CoE in an existing instance?

 

Creating a CoE within a fresh instance is definitely a different strategy than building one in an existing instance. Both have their pros and cons but let’s start with the fresh instance. When you are new to an instance, sometimes it’s hard to decide what your CoE programs will be. What we normally do for clients is:

1) Host discovery sessions to see which programs they are envisioning

2) Map the programs out beforehand

3) Show the internal stakeholders or clients to gain approval before we build

 

This helps us ensure they are on the same page. Also, having a visual of how your CoE operates is a great training and educational tool to those stakeholders outside of the system who don’t need to know the details of the Marketo instance, but need to understand how it works.

 

For an instance that is already in use, it is important to measure first then determine what the CoE will contain. For example, are there any programs that need to be refreshed or changed? If so, incorporate that in your CoE. Check to see what programs are built over and over again and standardize these for your CoE so people can just clone a single template program and update minimally. This makes the CoE useful for each Marketo user and guarantees you’re looking at real data in your instance as you build your CoE out.

 

4. How do you recommend aligning with key stakeholders when planning out the CoE?

 

When aligning key stakeholders for a CoE, you don’t necessarily need to dive into the weeds of how it will operate in Marketo. What I normally do is map out an example program for them to understand and align it to their business needs.

 

For example, the screenshots below show a template map I put together for a healthcare client where the stakeholders own the cancer service line. The first image lays out the process template that would live in the COE, including a landing page and three different email streams for three different messaging focuses they could include for that line. The second image lays out a customized program that was cloned from that process template. You have to alter your message for which stakeholder you’re educating. Normally if it is a marketing manager, who won’t be spending much time in Marketo, mapping out higher-level strategy is the best method to get them on board.

 

 

5. What is important to consider when rolling the CoE out to your teams?

 

Make sure you host trainings for your Marketo users. Usually I have the flow maps ready and then host live trainings where I go into the instance and demonstrate how to clone and update certain programs. For example, you don’t need to train an event manager (who owns the Marketo event programs) on how to clone a nurture template, because it’s not relevant to their work. Customizing your training to your users is crucial for the success of your CoE.

 

6. How do you set up processes to maintain that CoE over time?

 

Setting up processes to maintain the CoE is important for the long-term health of your instance. Normally the Marketo expert/admin should bear the responsibility of updating and maintaining the CoE. For example, let’s say your Marketo users keep cloning a nurture template but are adding more operational programs and emails to it, that should denote a CoE change. Your CoE should always contain the most updated programs that are ready to be cloned for your team. Sure, customization is always going to be added, but if the same programs or emails or reports are being added time and time again, it’s time to refresh your CoE. Lastly, I recommend taking a quarterly look at your CoE – maybe you added a new reporting feature in Marketo that you forgot to take into account in your templates, or maybe you’ve altered your webinar strategy – all of those changes need to be audited and monitored in the CoE.

 

**Tip: when building out your CoE, always use the description field to explain what each program does. This ensures success and helps train Marketo users on each of your CoE programs. Example below.**

 

Customers often ask about exporting Marketo Activity Data. This can be accomplished using the bulk activity API or the standard activity API.

 

Some things you might consider are...

  • Is this a one-time or a recurring activity export?
  • What activities do I need?

 

The bulk API is a good option when you want to get activities in a maximum 31-day timeframe. This is a great approach for a recurring extract with a start_date and an end_date. Once the file is ready for download, you'll be able to download a CSV of the data with the activity jSON parsed into columns. This approach has the following limitations

  • By default, Marketo instances are limited to 500mb of downloaded bulk data per day
    • This API limit can be increased. You should speak to your CSM if you're interested.
  • Bulk api downloads are limited to a window of 31 day timeframe

 

The activity API is the better option for a wider window of activities "all activities in the past 12 months" for example. Up to 300 activities are returned per call, returned as jSON, along with a "has more records" flag and if appropriate, a "nextPageToken" to pass into a subsequent call This approach has the standard per- call limitations of the standard REST API, as follows

  • By default, Marketo instances are limited to 50,000 calls per day.
    • This API limit can be increased. You should speak to your CSM if you're interested.
  • You may have up to 10 concurrent calls
  • You may execute up to 100 calls in a rolling 20 second window

 


Activity Types don't change for the great majority of Marketo instances (the exception might be extremely old Marketo instances). I've created a list of those types, here Activity Type Attributes - Common - Google Sheets which you're welcome to download and use.

 

Activity Type Attributes are also shown to illustrate the fact that different activity types have different attributes.

 

Marketo Professional Services is happy to do this with or for you you, and for details you should reach out to your PS Engagement Manager who can help scope the effort.

Buried in a bunch of my Nation responses is this ginormously important guideline: whenever possible, use your Marketo LP domain in your form embed code instead of the default //app-something.marketo.com.

 

Once per week, I'd estimate, an admin solves their “forms sometimes not showing up” problem with this tiny tweak.

 

That is, if the embed code in the Marketo UI is:

 

<script src="//app-sj01.marketo.com/js/forms2/js/forms2.min.js"></script>
<form id="mktoForm_999"></form>
<script>MktoForms2.loadForm("//app-sj01.marketo.com", "123-ABC-456", 999);</script>

 

and your primary Marketo LP Domain (or a Domain Alias) is:

 

https://pages.example.com

 

then edit the embed code (after pasting on your external site) to be:

 

<script src="//pages.example.com/js/forms2/js/forms2.min.js"></script>
<form id="mktoForm_999"></form>
<script>MktoForms2.loadForm("//pages.example.com", "123-ABC-456", 999);</script>

 

The only and I mean only reason to avoid this change is if your external site requires SSL (https:) but your Marketo subscription does not yet include Marketo's SSL add-on. (Built-in browser security won't allow forms to load if you're in this unfortunate situation.)

 

In all other cases, you can and should switch over. Like, yesterday. That includes (1) when your external domain and Marketo LP domain both run over SSL (best practice in 2019); (2) when neither uses SSL (eh, it works); and (3) when the external site doesn't, but the Marketo domain does use SSL (strange but possible).

 

 

What's this about?

It's about tracking protection. If someone browses your site using Firefox with TP turned on, or with Ghostery or a similar plugin, they will not be able to load forms from app-*.marketo.com, because they can't load anything from domains matching *.marketo.*.

 

It makes sense that Munchkin (from munchkin.marketo.net) would be blocked, of course. That's what anti-tracking features/plugins are designed to do. But forms can be thrown out with the bathwater, if you will.

 

Yes, it's not really fair for all that matters! because form submissions require deliberate user action, and they don't inherently “track” anything but the Filled Out Form activity itself (assuming Munchkin cookies are blocked and all existing cookies were deleted).

 

But it's something we have to live with: Munchkin is fairly described as a tracker, Munchkin comes from the domain marketo.something and the major marketo.{tld} domains are of course all owned by Marketo. So, fair or not, privacy wins out... even if that means forms leave a blank space on your page for some end users.

 

By loading from your Marketo LP domain instead, you fully comply with the anti-tracking plugin (since you aren't dropping any new cookies or logging any more pageviews/clicks with Munchkin blocked) but also allow forms to be seen and be filled out. So do it!

 

 

Why isn't it the default?

Because of the SSL exception described above. Apparently, the Embed Code textbox in the UI and the underlying domain setup can't communicate. So the LP domain can't safely be the default, as not everyone can use it.

 

 

We're in the process of getting SSL on our Marketo LPs, but not sure if it's ready

If you have a pending order with Marketo, you can quick-check the state of affairs (for the purposes of this blog post) by loading the Forms 2.0 forms2.min.js in your browser. Here's Firefox's way of saying your custom cert isn't installed yet:

 

Here’s some information to help you sort things out when you hit an API limit.

 

First here’s a great article about API usage

http://developers.marketo.com/blog/best-practices-for-api-users-and-custom-services/

Summary of the article:

If you have multiple web services creating individual API users is recommended:

  • It is easier to understand what data each web service is being given access to and allows you to create different API roles with different permissions if necessary
  • Reporting on API call usage will be broken down by user

 

If you are not is not using the Bulk API the error is#607 “Daily quota reached” when you’ve hit the limit.

https://developers.marketo.com/rest-api/error-codes/

 

A temporary solution is to contact Marketo support and see if they will raise the limit. If you need a more permanent solution contact your Customer Success Manager and purchase more daily API calls.

 

For more info about API limits please check out

http://developers.marketo.com/rest-api/marketo-integration-best-practices/

 

If you are using the Bulk API according to the documentation the daily quota is a maximum of 500MB per day, which is shared between leads and activities. When the quota is exceeded, you cannot Create or Enqueue another job until the daily quota resets at midnight Central Time. Until that time, an error “1029, Export daily quota exceeded” is returned.  Aside from the daily quota, there is no maximum file size.

 

You can contact your Customer Success Manager and purchase a higher daily extract limit. The increase can be purchased for just a month.

Bulk Extract Additional 1GB

Bulk Extract Additional 3GB

Bulk Extract Additional 5GB

Bulk Extract Additional 10GB

 

For more info about the Bulk API check out

http://developers.marketo.com/rest-api/bulk-extract/

 

If you are using an ELT Extraction Tool and experiencing an issue you should check with the vendor since its most likely Marketo support isn't familiar with the tool you are using and won’t be able to troubleshoot it.

 

I hope this article helps you troubleshoot your issue faster. BTW, I'm not in charge of setting the limits or the prices. I'm also not in charge of what the error codes. Thanks! 

A clear symptom of broken custom JS is when you see form fields, in URL-encoded format, in the location bar after clicking Submit:

 

5c886b174c52a500bf5f9c28_fields_in_url_url.png

 

You should get to know the cause on sight: an uncaught error has been thrown in a custom Forms API onSubmit function.

 

To replicate this, just set up an otherwise empty page with your form embed and this purposely bad JS:

 

MktoForms2.whenReady(function(form){
form.onSubmit(function(form){
form.oohlala(); // the property `form.oohlala` will never exist
});
});

 

This code won't throw any early errors on page load, because it doesn't have a syntax error. There's no way for the JS engine to know that form.oohlala will end up being a nonexistent method at runtime, it just adds the onSubmit listener happily onto the form.

 

However, when the form is actually being submitted, Marketo runs your custom onSubmit function. Then the browser gets serious and throws a hard TypeError, as you can see in the Dev Tools console (make sure to check off Preserve Log or you'll miss it people don't realize this behavior is always, without exception, a JavaScript error because they fail to prepare their debugging environment ahead of time).

 

Here's the runtime error:

 

5c886b174c52a500bf5f9c28_fields_in_url_console_error.png

 

But why does a JS error result in fields in the URL?

It's simple. Marketo forms use a true HTML <form> tag (this is A Very Good Thing™) and standard <input>/<select>/etc. elements under the hood.

 

The Forms API, among many other things, is responsible for transforming the standard W3C submit event into an elegant cross-domain POST to your Marketo instance.

 

In an error-free environment, the standard submit is swallowed by the Forms API's robust set of handlers. The event is triggered, but its default action that is, sending fields to the form's action (destination URL) using its method (HTTP method) is turned off. The API's non-default actions take over.

 

But when there's an error thrown within the Forms API listener stack, the form reverts to standard HTML form behavior as the default action doesn't get a chance to be turned off.

 

The Marketo <form> element doesn't have a specific action or method[1], i.e. it looks basically like so:

 

<form>
<input name="Something">
<input name="SomethingElse">
<button type="submit">Submit</button>
</form>

 

The default value for method is GET, and the default value for action is the empty string which represents the current URL. So the effective markup is:

 

<form
method="GET"
action="https://whatever.example.com/the_current_page.html">
<input name="Something">
<input name="SomethingElse">
<button type="submit">Submit</button>
</form>

 

When the button is clicked with this markup, and there's a JS error, the browser reverts to a standard GET of the current URL with form fields in the query string:

 

https://whatever.example.com/the_current_page.html?Something=a%20value&SomethingElse=another%20value

 

Whenever you see this behavior in your browser, realize your forms aren't working at all (even though the form seemingly "posts" somewhere). So fix em!

 

 

 


Notes

[1] Nor does the <button> have the newfangled formaction or formmethod attributes, which would be used if present.

In this edition of Marketo Master Class, Marketo Champion Juli James took some time to share her expertise on the topic of forms and gated content. Specifically, she explores the best scenarios to utilize forms, gated content best practices, and leveraging progressive profiling to get the most out of your Marketing efforts. Read on to discover how Juli uses forms in conjunction with gated content to seamlessly gather data without disrupting the customer experience.

 

1. What are the benefits of Marketo forms?

The benefit of using Marketo forms is pretty simple. The forms are easy to create, plug into campaigns, and ensure that data is being captured for any of your content-driven campaigns, whilst also allowing you to monitor real time content downloads and report out on what content is getting the most engagement.

 

They’re also great to use for event registration as you can tie the form to your event campaign, put it onto the event registration landing page and the monitor real time registrations. I’ve also recently been playing around with real time content delivery at events.

 

The beauty of Marketo forms is that you can add any CSS you want to it, as well as add some cool Javascript to make the forms look and behave in the way that you want to, without needing to get developers or IT involved. And then you can use them to scale your campaigns.

 

There are obvious examples of when you must use a form, such as capturing event registration. Tracking of all event registrations is imperative, whether online or offline. Having the registrations via Marketo forms means that you can send out confirmations, reminders and updates automatically using trigger campaigns, rather than having to download registration information from somewhere else and uploading to Marketo.

 

2. What situations warrant global vs. local forms?

I will always lean towards global forms as much as possible. Purely down to a scalability factor. A bit like CSS for websites, if you need to make a change to a form and you’re using global forms, then you only need to make that change in one place and then bulk approve the landing pages from design studio. If you had only local forms then you would have to go into each campaign and adjust each form.

 

 

An example would be when GDPR was introduced. I’ve heard various horror stories of people having to go into 600+ forms to add the GDPR rules for opt-in, rather than just going into 1 form and bulk approving 600 landing pages, which takes minutes vs. hours.

 

However, there is sometimes a need for local forms. I would suggest using local forms if your program requires specific data to be collected. For example, say you have an event where you are required to ask guests their dietary needs, or t-shirt size, or your field marketing manager wants to collect specific interests that won’t be relevant elsewhere. A local form would fulfill that need.I would also suggest a local form if you have to do a specific campaign in a different language. I’ve worked on landing pages in multiple languages but they’ve only been created once or twice, so then I would only create local forms as its highly unlikely they’ll get used again. If I find that I’m using a form more than a few times, I’ll add it to the Design studio and start using as a Global Form, although I try to keep the number of Global Forms down as well.

 

3. What type of content do you leave ungated? What content is important to gate?

I try my hardest to not leave content ungated, but rather to use the ‘Known Person’ option on the form to provide a simple ‘download now’ button instead of a form, or I like to use a Marketo Partner such as Uberflip that will track content downloads without the need for too many forms.

 

The whole point of gating content is to track who is engaging with the content you are providing and creating. Moreover, having gated content will help with tracking which content is providing the most conversions to analyze which content is the most effective. If you left all content ungated (as is the suggestion of some industry experts), then there is no way to track and convert potential new customers. It also depends on the value of the content. I would not gate an infographic for example, but I would most definitely gate a whitepaper or analyst report.

 

4. How do you synchronize progressive profiles built from forms/gated content with your marketing campaigns at large?

I like to use progressive profiling forms to build up records user profilesto further segment and personalize the types of campaigns that are being sent out. For example, if I’m using ‘Industry’ on a form it’s because I want to further segment down the industries into Strategic Business Units using an approved segmentation. Having data segmented means that emails can now be sent out using dynamic content based on segments.

 

This is especially useful for Nurture campaigns if you work with multiple languages. You can set up your segmentation based on the country information that has been populated from the progressive profile form and then use those segments to create dynamic content to send the same email in the preferred language of each record.

 

 

 

5. What are some of the most underutilized features on forms?

Prior to GDPR I would have said the most underutilized feature on forms were the visibility rules. Having the ability to only show certain fields when other fields on the form are completed is a great feature! If you’re not using visibility fields for anything on your forms, and especially for GDPR you should look into it.

 

 

You can also set up field sets to be shown dynamically based on visibility rules too:https://docs.marketo.com/display/public/DOCS/Add+a+FieldSet+to+a+Form

 

Another feature that really isn’t used enough and that Sanford Whiteman has recently authored a post about is the use of the ‘known person’ option in the Settings section of the Form editor. He talks about not just showing a button rather than the form, but also how to set up an Auto Submit for known users, which will help to provide an excellent customer experience for those users who are already in your database, whilst at the same time recording the ‘Form Fill’.

 

One last feature that I don’t see utilized very often but could be helpful is Input Masking, to ensure that values being put into certain fields are formatted in the correct way for data cleanliness:https://docs.marketo.com/display/public/DOCS/Apply+Input+Masking+to+a+Field+in+a+Form

 

 

6. What’s one tip about forms/gated content that you wish you learned sooner?

Over the last few months I have be working more with CSS and JavaScript on forms to manipulate them in a way to perform exactly as requested. For example, Sanford also wrote a post a while ago about adding JavaScript to forms:

 

And there are some great tips for form manipulation for embedded forms using JavaScript on the Developer Site too:http://developers.marketo.com/rest-api/assets/forms/examples/

I really wish I’d learn that you could do more than just create a form and play with the CSS a long time ago.

 

I’ve also recently learnt how to add 2 forms to one page with some JavaScript, and that was a technique that I wish I had a long time ago. Below are how it looks on the Landing Page, the HTML on the landing page and the custom

 

Screen Shot 2019-02-19 at 11.17.41 AM.png

7. Are you planning to try anything new with forms/gated content in 2019?

For 2019 I plan on working more with Velocity Script in conjunction with Form fills so that real-time content delivery can happen at events. For example, having an iPad with a form on showing content related to that event, and then the users can select which content they find interesting and have that delivered in real time to them via email. This will save the need for a lot of collateral being printed, but it will also help to grow the database organically.

 

I’m also hoping to spend more time with form CSS to improve the customer experience and look of forms across various platforms. I think CSS alongside Javascript and Velocity Script can make for some really interesting user experiences for known and unknown records looking for content. For example, forms that auto submit in the background for known users so they get direct access to the content without having to resubmit the same information numerous times would allow for a more frictionless customer experience. Essentially, if less clicks are required between a lead and the content they are likely to consume, it’s much easier to move along the funnel.

 

 

We hope you enjoyed reading about how Juli James is leveraging forms and gated content seamlessly gather data without disrupting customer experience. If you have any examples of how you've used these features to better engage with your customers, please let us know in the comments!

 

You can find more informative content in the brand new edition of our customer newsletter, the Fearless Forum.

Printing fallback content when a Lead field is blank is a basic Velocity task. You can do it in a few lines of clunky code... but that's a few lines too many!

 

Seeking a one-liner, you might reach for Velocity's built-in $display.alt. But that won't fill the bill in Marketo-land. You see, $display.alt($field, $fallback) outputs the fallback if the field is null. But null isn't the same as the empty String that Marketo uses for unfilled Lead fields.

 

Therefore, the code

 

Dear ${display.alt($lead.FirstName,"Friend")},

 

will only ever output

 

Dear Joe,

 

or

 

Dear ,

 

It will never fall back to

 

Dear Friend,

 

because Marketo ensures $lead.FirstName is always a String of some kind, never null.[1]

 

So without any other tools at your disposal, you're left with a typically wordy #if block:

 

Dear ##
#if( $lead.FirstName.isEmpty() )
Friend,##
#else
$lead.FirstName,##
#end

 

This will work fine, but as your scripts get cluttered with repeats of this same structure, you start to go a little crazy.[2]

 

The good news is there's a short Velocimacro you can include globally that greatly lightens the load. Once you set up the #displayIfFilled macro, you can reduce the logic to one easy-to-read line:

 

Dear #displayIfFilled($lead.FirstName, "Friend"),

 

Building #displayIfFilled

Here's the macro definition:

 

#macro ( displayIfFilled $checkValue $fallbackValue )
#if( !($checkValue.isEmpty()) && !($checkValue == $context.get("0")) )
$!checkValue##
#else
$!fallbackValue##
#end
#end

 

As you can see, #displayIfFilled takes 2 self-explanatory arguments: the field to check for filled-ness, and the fallback value.

 

#displayIfFilled is designed to treat null the same as the empty String. It thus covers a superset of the cases covered by $display.alt, so you may never be tempted by the latter function again.

 

Step further out: #displayIf

We can abstract the functionality of #displayIfFilled into a more general #displayIf:

 

#macro ( displayIf $truePredicate $trueValue $falseValue )
#if( $truePredicate )
$!trueValue##
#else
$!falseValue##
#end
#end

 

#displayIf takes 3 arguments: a Boolean, the value to output if the Boolean is true, and the output if the Boolean is false.

 

To emulate #displayIfFilled, pass an isEmpty() check as the first arg (the $truePredicate):

 

Dear #displayIf($lead.FirstName.isEmpty(), "Friend", $lead.FirstName),

 

Lots of tricks up your sleeve with #displayIf.  Say you want to switch output based on a specific non-empty value

 

Your #displayIf($lead.trialType.equals("Other"), "VIP", ${lead.trialType}) trial is almost over!

 

or output based on a date/time property

 

Good #displayIf($calNow.get($calFields.AM_PM).equals($calFields.AM), "mornin'", "aft'noon")!

 

or anything that can be expressed as if-then-else!

 

Of course, #displayIf can be overused; past a certain point of complexity, you should be using #if-#else on separate lines. But where a one-liner doesn't hurt readability, I say use it. #displayIf is critical to my sanity (if I have any left) as an avid Velocity coder.

 

Stay functional

There's another detail that you'd eventually learn on your own, but I'll spoil it to save you time.

 

When passing macro arguments in parentheses, you can include any chain of function calls but not syntactical expressions. For example, though Boolean operators and expressions are valid in other parts of Velocity, you can't do:

 

#displayIf(!$lead.FirstName.isEmpty(), "${lead.FirstName}'s", "Your") special offer is ready!

 

That won't compile because of the !. Velocity's parser doesn't accept operators  in that place (nor would it accept <, > or == operators there).

 

Instead, either chain with the equals() function:

 

#displayIf($lead.FirstName.isEmpty().equals(false), "${lead.FirstName}'s", "Your") special offer is ready!

 

or as some programming style guides suggest anyway don't rely on negated Booleans and instead put your true case first:

 

#displayIf($lead.FirstName.isEmpty(), "Your", "${lead.FirstName}'s") special offer is ready!

 

To be clear, this doesn't mean you can't use all manner of operators and expressions to construct Boolean values, you just can't use them directly inside the parentheses when calling a macro. This will work fine:

 

#set( $hasCompany = !$lead.Company.isEmpty() && !$lead.Company.equals("N/A") )
Is #displayIf($hasCompany, $lead.Company, "your family") in the mood for pizza?

 

Disrupts the dream of a one-line solution, though.

 

What's with $context.get("0")?

Ah, yes. I don't want to overwhelm you earlier with the details of null checking in Velocity.

 

$context.get("0") (up above in the first #displayIfFilled macro) gets the value of a reference that is guaranteed to not exist, i.e. guaranteed to be null, in any Velocity context.

 

Why is it guaranteed to not exist? Because neither Java nor Velocity variable names are allowed to begin with a number.

 

Why not compare to the literal null? Because and this reality sneaks up in other important places in Velocity there is no four-letter keyword null! The null-ability of injected data is honored, even favored, in Velocity, like by $display.alt as noted above. But it doesn't have a keyword to create new null values easily.

 

So you have to find a roundabout way of getting a reference to a null value. Elsewhere on the net, people say "just use a variable you didn't #set anywhere else, like $abcdefg, as that will naturally be null." The flaw in this reasoning is nothing actually stops someone else (either a future coder or a current collaborator) from using $abcdefg for something else.  So I prefer to use a reference that cannot exist even by coincidence.

 

 


 

 

Notes

[1] In the Marketo Lead/Person world, you aren't gonna run into literal null values, but rather empty strings. This is true despite non-filled fields being represented as [null] or NULL in parts of the Marketo UI.  You can and will encounter null with Custom Objects, though. That's the stuff of another post.

 

[2] Yes, you could smush the VTL into one line. But if you think Dear #if($lead.FirstName.isEmpty())Friend#else${lead.FirstName}#end, is sufficiently readable, you're made of stronger stuff than me.

Filter Blog

By date: By tag: