2
Record-triggered flows — live in production
3
Sandbox test scenarios — before a single demo
Zero
False "Net New" results shipped — blank-email bug caught pre-production
The Problem
Every lead landed the same way — whether the company was a stranger or a five-year customer.
Leads coming into Salesforce — from HubSpot forms, Salesloft outbound, or direct entry — all landed the same way, regardless of whether the person behind them worked at a company never seen before, or one already doing business with for years. There was no mechanism to tell the difference at the point a Lead was created.
Duplicate Accounts
- A new contact at an existing company could easily spawn a brand-new Account instead of attaching to the one that already existed.
Mistreated Relationships
- Someone from an existing customer reaching out for support could get funneled through a cold-outreach process meant for strangers.
Nobody had scoped this as "build a matching engine." It surfaced the way most real infrastructure gaps do — while working adjacent problems, attribution and lifecycle tracking, and noticing the same blind spot kept showing up.
The Insight
The company was already sitting in the data — in the email domain.
The starting point wasn't a data model — it was a simple observation from working leads day to day: most of the time, you already know who someone works for the moment they submit a form, because it's sitting right there in their email address. A company's email domain is, more often than not, the company's actual website domain. That's not a guess — it's a fact that already exists in the data, just not connected to anything yet.
That observation became the matching key. Domain_Key__c was built on Account as a formula field that strips the Account's Website down to its bare domain. On the Lead side, the same normalization runs on the email address. Line those two up, and you get a real, verifiable answer to "do we already know this company" — not a fuzzy name match, not a manual lookup, just two domains compared directly.
The Approach
A verifiable signal, not a guessable one.
Rather than guessing at company identity from a name — unreliable across casing, abbreviations, "Inc." vs not — the design centered on the one piece of data that's actually objective: the email domain. Core logic, built as a Salesforce Flow (NET_NEW_CLIENT_Lead):
- Free or personal email domains (Gmail, Yahoo, Outlook, etc.) get excluded entirely — a personal email tells you nothing reliable about what company someone works for, so the flow doesn't try to guess
- For everything else, the domain gets extracted from the email and compared against a normalized domain field on every existing Account, regardless of status — because the question isn't "are they a customer," it's "does this company already exist in our system"
- Match found → Company gets corrected to the real Account name, status is stamped "Existing Company – Pending Review," and a Task routes to a RevOps review queue for a human judgment call
- No match → status is stamped "Net New – Verified" — a confirmed, trustworthy signal rather than a guess
A companion flow solved a smaller but persistent operational annoyance: Inside Sales leads uploaded via Salesloft consistently arrived without Lifecycle Stage populated, requiring manual backfill. A second flow auto-stamps it on creation, removing that step entirely.
"The question isn't 'are they a customer' — it's 'does this company already exist in our system.' That's a different question, and it's the one the flow actually answers."
What Made This Hard
Four Salesforce quirks that would have cost hours blind.
The design was the easy part. The build surfaced a string of real Salesforce quirks worth documenting, because they're the kind of thing that costs hours if you don't already know them.
- Queues can't own every object by default — the review Task creation failed in testing with
INVALID_OPERATION: Queue not associated with this SObject type until the queue was explicitly configured to support Task, not just Lead
- Flow's resource picker doesn't reliably resolve Queue/Group records by name — the clean solution didn't work reliably, so the practical fix was hardcoding the queue's literal record ID, a tradeoff the team had already made once before elsewhere in the org
- "Is Null" operators don't take a comparison value — an easy mistake to make once, since every other operator in Flow expects one
- A blank email is not the same as a free email domain, and treating it that way is a real bug, not an edge case — testing surfaced that a Lead with no email at all was silently resolving to "Net New – Verified," the most confident status the flow can assign, despite having no data to verify anything against. Caught before production, fixed with a one-line
ISBLANK(...) addition to the exclusion check
Validation Before Trust
Tested against real data before it touched a single leadership decision.
- Three-scenario testing in sandbox (free domain, real domain / no match, real domain / match) using Salesforce's Debug mode against real Lead data
- A live demo to Inside Sales and Marketing stakeholders — positive reception, no objections
- Formal sign-off from leadership before production deployment
The Deploy Catch
The review queue's ID doesn't travel between sandbox and production.
Production deployment via Change Set surfaced one more thing worth flagging: the review queue's record ID is environment-specific — sandbox and production don't share IDs even for a queue with the identical name. Activating the flow with the sandbox ID still hardcoded in would have caused the exact same failure to reappear silently, in production, on real records. Caught and corrected before activation — the flow was updated with the production queue's real ID as a required step in the rollout, not an afterthought.
The Outcome
Two flows live. One SOP. A closed loop with the teams who live in these leads every day.
Two record-triggered flows are live in production. A documented SOP covers the process end to end — trigger conditions, field definitions, RACI, exception handling, and known limitations. And there's a closed feedback loop with the teams actually working these leads day to day.
What Was Built
- Domain_Key__c formula field on Account — normalizes Website into a bare, comparable domain
- NET_NEW_CLIENT_Lead flow — matches Lead email domain against every existing Account regardless of status, routes matches to a RevOps review queue
- Lifecycle Stage auto-stamp flow — removes manual backfill for Salesloft-sourced Inside Sales leads
- Blank-email edge case fix — ISBLANK() check added to the free-domain exclusion before production
- Environment-specific queue ID correction — sandbox ID swapped for production ID as a required rollout step
- Documented SOP — trigger conditions, field definitions, RACI, exception handling, known limitations
- Stack: Salesforce Flow Builder · HubSpot (OAuth) · Salesloft