Salesforce Lead to Account Matching in an ABM World

December 29, 2022

By Brad Boreing with Technical Documentation by Colin Price


What Are Leads?

Gather a group of sales, marketing, finance, and revenue operations professionals and ask them each to define the word “Lead”. In my experience, there is a good chance that you will end up with as many different definitions as you have people in the group. Everyone has a different perspective based on their experience and where they happen to be positioned within their organization.

My introduction to leads in the rev ops world was in an organization that used Salesforce leads as a landing place for newly identified individuals, and they were quickly converted or discarded. Before any contact was made or visibility given to a seller team of humans they:

  • manually checked the system for a matching record
  • decided whether the lead should be converted
  • used a spreadsheet to determine the next rep in line to receive the opportunity it created.

Just typing that makes me feel like a bit of a dinosaur, but this was less than a decade ago.

How Leads Are Used

In the time that has passed since those days much of that process has obviously been automated. Another thing that has changed is the prevailing wisdom around how to leverage Salesforce leads, particularly in an account-based marketing environment.

While a lead means different things to different people, the Salesforce core object is the version we are focusing on. As far as Salesforce objects go, it is unique in the out-of-the-box functionality that it offers and the role it plays in the sales process. Being the initial piece of the sales process, which creates Accounts, Contacts, and Opportunities upon conversion, makes it pleasantly diverse yet frustratingly ambiguous.

While the simplest structure treats leads as records who aren’t quite ready to be accounts and opportunities, many organizations have more complex needs.

What if the lead is not yet qualified, but a matching account already exists?

What if there are multiple leads that belong to the same company, but they aren’t qualified?

Account-Based Strategy

We want clear and consistent messaging to the entire account. However, we do not want to add leads as opportunities to the funnel if they’re not ready to be worked by sales reps. Furthermore, we don’t want to convert them to contacts and lose the tracking of the progress toward qualification that happens on the lead.

In order to compensate for these possibilities, we establish a relationship between leads and accounts by creating an account lookup field on the lead object. Of course, the simple outcome of this new field is that an account link is visible on the lead and a related list on the account page to see the connected leads. This new structure is great and all, but the inevitable question that follows is how to match a lead effectively to the appropriate account, or even create an account when necessary.

Salesforce Lead to Account Matching

One option for dependable lead-to-account matching is to purchase and install an additional tool. If you have the ability to go that route, there are some good choices out there, and we have had success implementing them. However, when your budget is a restriction, this can be done in a less sophisticated way using out-of-the-box Salesforce automation. Let’s start with some requirement definitions and take a look at how we go about constructing a flow to do this.

  1. Trigger: The lead should be assessed in order to find a corresponding account upon creation or any time that the Company Name is updated. Note: The default value for Company Name is “Your Organization” for the sake of marketing communication. An update to that field implies improved clarity on where the lead belongs.
  2. Match Fields: It’s best to start with a high-level definition of which fields should be leveraged to identify accounts that would potentially match your lead. This will be used to initially filter down a subset of accounts to pass through our flow without overwhelming it. In our case, we’re using unique company id matches from external systems (or data enrichment tools), domain (extracted from email address), website, and company name. We will only want to move forward with accounts that match on one of these dimensions.
  3. Spam Likely: Sometimes I get calls on my cell phone from unknown numbers, and my phone tells me it could be a scam with a banner that says, “Scam Likely”. As a play on that phrase, we created a field called “Spam Likely” as a way to weed spam leads out of certain processes. This is important for our account matching because it is based on marking leads with email domains on a list defined as junk, and we don’t want to match domains that are not valid.
  4. Match Field Weighting: We’ve defined the fields we will use to find accounts that match a lead, but what if there are several accounts that match on different fields? There needs to be some prioritization that helps rank field matches so that the relative strengths of multiple matches can be compared. Each account is scored according to a formula that applies a value to each valid field match. The lowest prioritized field match is assigned a value of 2, and the next is 3, then 5, and 8. This is a Fibonacci sequence that can continue on by adding the previous two numbers to find the next number in the pattern. This gives the more preferred field sufficient weight that it would require at least three field matches of lower priority in order to form a stronger match.
  5. Selecting the Correct Account: After applying the scoring algorithm to each account identified as a potential match from simple field comparisons applied in bullet 2, there must be a winner. The algorithm serves to not only compare the subset of accounts against one another, but to verify that any of them is a valid match. If it turns out that none of the matches is legitimate, then none of them will populate on the lead. Otherwise, the record with the highest match score will go into the account lookup.
  6. No Existing Accounts Match (Optional): If the goal is only to match to existing accounts, then the automation can end if none is found. However, in our case we want to require that each lead has a corresponding account. As mentioned earlier, this allows them to remain as leads to maintain the desired sales flow, but increase the chances that multiple individuals at a single company can be effectively linked through these relationships. As a result, we finish by creating an account from the details of the lead. If some of the basic information is missing, like the Company Name, we just use the domain as a placeholder, until more details are known.

This is the extent of the first automation that applies to this process of matching leads to accounts. One big question that remains is how to give end users (Sales Development Reps) the capacity to evaluate the potential matches and manually adjust, if needed. This is also automated using a flow, which we will cover in a future blog entry.

Technical Design:

We start with setting the Flow to fire on creation or update of a Lead. We are then bypassing the condition requirements and choosing to run with an After Save Flow.

Our first node is a decision element that checks if the Lead already has an Account and company is changed or the Lead is new.

We then check to see if the lead domain is part of a list of domains we have listed as junk. This list was found online as common domains that are junk and will sometimes need to be added to or removed from.

If the lead domain matches any of the domains in the previous list then we check a box on the lead labeled Spam Likely.

Next up we Get all Accounts where unique ID is not empty on account and matches the lead unique ID OR Domain is not empty on Account and matches the lead Domain OR Website Contains the Lead Domain OR the Account name equals the Lead Company. We then store those in a collection variable.

Then we check if we found any accounts in the previous Get Accounts node.

If we do not find any Accounts then we move to this Junk Domain Decision.

In here we check if the Lead was marked as spam from earlier in the flow.

If it did get caught in the Spam filter and doesnt match any accounts then we just assign the Lead to a Placeholder Account that we made.

If it was not a Spam domain and no Accounts in the system matched then we create an Account with domain as the lead domain, name as this formula:

(IF({!$Record.Company}="Your Organization",{!$Record.Domain__c},{!$Record.Company}))

We add text in notes to show that this account was created from L2A flow. The ownerid is this formula:

IF(LEFT({!$Record.OwnerId},3) = "00G", "0050900000AiWOA", {!$Record.OwnerId})

Then Website is just the Lead Website.

Then we just link that created account above to the Lead record.

If we do find Accounts in the beginning of the flow that match to the Lead then we want to loop through the Accounts that we found.

In the loop we first assign the current item to a record variable.

After we assign the current item in the loop we use a match score calculation to come up with a score of how closely the Account matches the Lead and add that to a field on account called Lead Match Score.

In the Match Score Calculation we check all of the same fields from the first Get Account node earlier in the flow. Since we know that those accounts we got earlier match in some way to the Lead we want to grab a score for how closely the account matches. If it matches on Unique Id it is the highest score at 13 points. If it matches on a non-spam domain it is 8 points. If it matches on a non-spam domain that is in website it is 5 points. If it matches on website 1-1 then its 3 points and lastly if company field on Lead is not blank or Your Organization and it match lead company then its 2 points.

We then add that record variable to a collection variable called FinalAccountsCollection.

After we loop through all accounts and score them we want to run that through a collection sort descending by Lead match Score and then keep the top one. This will give us the Account that best matches the Lead.

Since we know have only one Account in our Collection we need to pass it back out to a record variable and need to use a loop.

We take the 1 Account we have in the collection and pass it back out to a Record Variable called FinalAccountRecordVar.

The last thing we need to do is check if the lead match score is greater than 0.

If the Lead match score is greater than 0 then we add the account to the Lead.

If the lead match score is not greater than 0 we may have a spam domain and so we run it through the same decision we used earlier in the flow where if it is a spam domain we add to a placeholder account and if it is not a spam domain we create an Account and link it to the Lead.