+ Book
GTM Engineering

Identity Resolution & Deduplication in GTM: Matching Alphabet to Google & Stripe

How identity resolution actually works in a GTM data stack: fuzzy matching algorithms, domain normalization, corporate hierarchy mapping, and contact-level resolution across sources.

Identity Resolution & Deduplication in GTM: Matching Alphabet to Google & Stripe
On this page

I touched on deduplication mechanics briefly while walking through a specific TAM tiering build in Clay, but identity resolution deserves its own, deeper treatment, because it's genuinely one of the harder problems in GTM engineering, not a solved checkbox you handle once and move past.

Every data source, every enrichment provider, and every scraped list represents the same real-world companies and people slightly differently, and reconciling those differences correctly is what separates a genuinely clean, trustworthy dataset from one that looks clean until someone notices "Alphabet" and "Google" showing up as two unrelated accounts, or a rep working the same contact under two different email addresses without realizing it's the same person.

This guide covers identity resolution as its own discipline: the specific hard edge cases that make it genuinely difficult, the actual matching techniques worth knowing at both the account and contact level.

How to build a resolution system that produces a trustworthy, confident output rather than a plausible-looking one that's quietly wrong in ways nobody's checking for.

Why this Is genuinely hard, not just tedious?

The instinct is to treat deduplication as a mechanical cleanup task, remove exact duplicates, done. The actual problem is considerably harder, because most of the duplicates and mismatches a real GTM dataset contains aren't exact at all, they're the specific, structurally different kinds of ambiguity covered below, each requiring a different resolution technique.

Corporate hierarchy ambiguity.

Is "Google" the same account as "Alphabet," its parent company? For most GTM purposes, the honest answer is: it depends on your specific use case, and getting this wrong in either direction creates real problems, either fragmenting an account that should be treated as one relationship, or collapsing genuinely distinct business units that operate and buy independently into one account that misrepresents how the actual relationship works.

Rebrands and name changes.

A company that renamed itself, Facebook to Meta being the most visible recent example, leaves historical records under the old name scattered across older data sources and current records under the new one, and without an explicit mapping between the two, they'll be treated as entirely unrelated accounts by any naive matching logic.

Regional and subsidiary entities.

"Stripe Inc." and "Stripe UK Limited" are related but not necessarily identical for every purpose, sharing a global brand and product relationship while potentially operating as distinct legal entities with their own separate purchasing authority, billing relationship, or regional sales motion.

Whether these should be one account or two depends entirely on how your specific business actually sells to and manages them.

Contact-level identity across job changes and multiple email addresses.

A single person can appear in your data under a current work email, a previous employer's work email from before they changed jobs, and occasionally a personal email used for an early, informal interaction, three genuinely different identifiers all referring to the same real person, none of which share an obvious, automatic connecting key.

Account-level resolution techniques

Domain normalization as the primary matching key

As covered in the TAM tiering build, a company's domain is considerably more stable across data sources than its name, and normalizing it, stripping protocol, www prefix, and trailing paths, produces a reliable primary join key for the large majority of straightforward matches.

This should be your first-pass matching layer before any of the more complex techniques below, since it resolves the easy majority of matches cheaply and leaves only the genuinely hard cases for more sophisticated handling.

Fuzzy string matching for company names

For records without a clean, shared domain, or as a cross-check against domain matching, fuzzy string matching algorithms compare company names for similarity rather than requiring exact equality.

Levenshtein distance measures the number of single-character edits needed to transform one string into another, useful for catching typos and minor variations. Jaro-Winkler similarity, which weights matches at the beginning of a string more heavily, tends to perform better on company names specifically.

Since two companies with different suffixes but the same core name, "Acme Corporation" and "Acme Corp," share a strong prefix match that Jaro-Winkler captures well.

Before running either algorithm, normalize both strings: lowercase everything, strip common legal suffixes, Inc, LLC, Ltd, Corp, GmbH, and remove punctuation.

Comparing raw, unnormalized strings produces meaningfully weaker match rates than comparing normalized ones, since a large share of apparent name differences are just inconsistent suffix and punctuation handling across sources rather than a genuine naming difference.

Phonetic matching for catching transliteration and spelling variation

For names that sound similar but are spelled differently, common with company names transliterated from non-Latin scripts, or simply typed inconsistently across sources, phonetic algorithms like Soundex or the more refined Metaphone encode a string based on how it sounds rather than its exact spelling, catching matches a purely character-based comparison would miss.

This is a secondary technique worth layering in for datasets spanning international sources specifically, rather than a primary matching method for a domestic, single-language dataset where it adds complexity without much corresponding benefit.

Explicit hierarchy mapping, not inferred from name similarity alone

Corporate hierarchy relationships, which subsidiary belongs to which parent, which brand rebranded to which new name, aren't reliably inferable from name similarity alone, "Alphabet" and "Google" don't share enough string similarity for a fuzzy match to catch the relationship, and treating them as unrelated by default is the wrong assumption just as often as treating every subsidiary as identical to its parent would be.

This relationship needs an explicit, maintained mapping table, built from a combination of enrichment provider data that tracks corporate structure directly, and manual curation for your own highest-value or most ambiguous accounts, rather than left to emerge accidentally from whatever a fuzzy-matching algorithm happens to catch.

A defined rule for how hierarchy resolves into your actual account structure

Once you know a hierarchy relationship exists, you still need an explicit business rule for how it resolves into your CRM's account structure: does a subsidiary get its own distinct account record linked to its parent, or does it roll up entirely into the parent account.

This decision should be driven by how your business actually sells and manages the relationship, not defaulted arbitrarily. A company selling into large, decentralized enterprises where each subsidiary has independent purchasing authority generally wants subsidiaries tracked as distinct, linked accounts.

A company selling a single, centralized contract to one global buyer generally wants everything rolled into one parent account regardless of how many subsidiary names appear in the underlying data.

Want a read on how many duplicate or fragmented accounts are actually hiding in your current CRM? Get a free AI infrastructure audit and I'll help you find them.

Contact-level resolution techniques

Email as the primary key, with real limitations

A contact's email address is the most common primary matching key at the individual level, but it's considerably less stable over time than a company's domain, since a person changes jobs and therefore changes work email addresses, sometimes multiple times within the window your data spans.

Matching purely on current email will systematically fail to connect a contact's history across a job change, treating what's genuinely the same person as two entirely separate, unconnected records.

Cross-referencing name, company, and role together

Where email alone doesn't resolve a match, a combination of normalized full name, current company, and role provides a secondary matching layer, catching cases where the same person appears under a different email but consistent identifying details elsewhere.

This needs the same normalization discipline as company name matching, standardizing capitalization, handling common nickname variations, Bob and Robert, Bill and William, and stripping titles or credentials that sometimes get appended to a name field inconsistently across sources.

LinkedIn URL as a genuinely stable secondary identifier

A person's LinkedIn profile URL tends to be considerably more stable over time than their work email, surviving job changes in a way an email address never can.

Where available, using it as a secondary or tertiary matching key, particularly for reconciling a contact's identity across a job change specifically, tends to outperform name-and-company matching alone for exactly the case where email matching fails hardest.

Explicitly deciding how to handle a genuine job change

Unlike most identity resolution edge cases, a contact who changed jobs isn't really an ambiguous match to resolve, it's a business decision about how to treat a real, known transition.

Does the contact's history at their previous company merge into their new identity as one continuous person, or does your system intentionally treat the two as separate relationships, since your actual sales relationship was arguably with the company as much as the individual.

This is the same kind of deliberate rule this guide argues for at the account level, and it deserves the same explicit treatment rather than being left to whatever a matching algorithm happens to produce by default.

Building the Resolution System: Confidence Scoring and Human Review

Produce a match confidence score, not a binary match or no-match decision.

A domain-based exact match deserves high confidence. A fuzzy name match with a middling similarity score and no corroborating domain match deserves considerably lower confidence.

Treating every successful match with identical certainty, rather than scoring confidence explicitly, means a system can't distinguish its most reliable merges from its most speculative ones, which matters enormously for what happens next.

Auto-merge high-confidence matches, route low-confidence ones to human review.

Rather than either auto-merging everything, which risks incorrectly combining two genuinely distinct entities, or manually reviewing everything, which doesn't scale past a small dataset, set an explicit confidence threshold: matches above it merge automatically, matches below it, but still plausible enough to flag, route to a queue for a person to confirm or reject.

This is the same risk-scaled governance principle covered in more depth in AI agent design applied here to data matching specifically rather than autonomous action.

Define field survivorship rules for the merged, golden record.

Once two records are confirmed as the same entity, you still need a rule for which source's data wins for each specific field when they disagree, the most recently updated source, a specific source designated as authoritative for that field type, or a completeness-based rule favoring whichever record has more populated fields.

Without an explicit survivorship rule, a merge just creates a new, different ambiguity about which of the now-combined values is actually correct.

Preserve source lineage on every merged record.

Keep a record of which original source records contributed to a merged, golden record, and via what confidence score.

This is what makes a questionable merge debuggable later, rather than an opaque, unexplainable combination nobody can trace back to its original inputs if it turns out to be wrong.

Common Mistakes in Identity Resolution

Treating fuzzy name matching as sufficient on its own, without domain or hierarchy data layered in.

Name similarity alone produces both false positives, two genuinely different companies with similar names getting incorrectly merged, and false negatives, genuinely related entities like Alphabet and Google sharing too little string similarity to match at all.

Layering domain matching and explicit hierarchy data is what catches what fuzzy name matching alone systematically misses in both directions.

Auto-merging every match regardless of confidence.

This risks silently combining two genuinely distinct accounts or contacts based on a weak, coincidental match, an error that's often more damaging and harder to notice than simply leaving two records unmerged, since an incorrect merge actively corrupts data rather than just leaving it fragmented.

No explicit rule for corporate hierarchy resolution, leaving it inconsistent across different accounts.

Without a defined rule, whether a subsidiary rolls up into its parent or stays distinct ends up depending on which specific enrichment source happened to populate that particular record, producing an inconsistent, unpredictable account structure across your dataset rather than a deliberately designed one.

Ignoring contact-level resolution entirely and only deduplicating at the account level.

A clean, well-resolved account list sitting on top of a contact database still riddled with the same person appearing multiple times under different emails undermines a meaningful share of the value account-level resolution was supposed to provide, since outreach and relationship tracking still fragment at the individual level even when the company-level data is clean.

No source lineage preserved on merged records.

When a merge turns out to be wrong, and some eventually will be, no lineage means no way to trace back what happened or cleanly reverse it, turning a fixable data quality issue into a genuinely difficult reconstruction problem.

A worked example

A GTM engineer building a TAM list for an enterprise software company discovers, while reviewing early matching results, that their dataset contains "Meta," "Facebook," and "Facebook, Inc."

as three apparently distinct accounts, despite all three clearly referring to the same underlying company across different data vintages. Domain-based matching alone doesn't fully resolve this, since older records reference a facebook.com domain while newer ones reference meta.com, two genuinely different domains for the same evolving company.

Rather than relying on fuzzy name matching to catch this, which would likely miss the Facebook-to-Meta rebrand given the limited string similarity between the two names, the engineer builds an explicit rebrand and hierarchy mapping table, sourced partly from an enrichment provider that tracks corporate name history directly, and partly from manual research on the specific high-value accounts in their target list.

This mapping table becomes a required lookup step in the resolution pipeline, run after domain and fuzzy-name matching, specifically to catch exactly this category of edge case that neither of the more mechanical techniques would resolve reliably on its own.

The same project surfaces a separate, contact-level issue: a specific high-priority contact appears under two different email addresses, one tied to a previous employer, one current, discovered only because the two records happened to share an identical LinkedIn URL.

Adding LinkedIn URL as a secondary contact-matching key catches this specific case and several others like it across the dataset, merging what had been two disconnected, partial engagement histories into one accurate, complete picture of the relationship.

How I build identity resolution systems?

I build identity resolution as a layered system, domain matching first, fuzzy name matching second, explicit hierarchy and rebrand mapping third, each catching what the previous layer missed, rather than relying on any single technique to handle every case.

This connects directly to my broader work on what company intelligence actually requires and the ABM tiering systems that depend on genuinely resolved, non-fragmented account data to score and tier correctly in the first place.

Every resolution system I build includes explicit confidence scoring, a human review queue for the genuinely ambiguous cases, and preserved source lineage on every merge, so a questionable match is always traceable and correctable rather than an opaque, permanent combination.

Not sure how many fragmented or duplicate accounts are actually distorting your current reporting? See how my process works before your next data cleanup.

Conclusion

Identity resolution in GTM data isn't a mechanical cleanup pass, it's a genuine, layered discipline: domain normalization catching the easy majority, fuzzy string matching catching name variation, explicit hierarchy and rebrand mapping catching the cases neither of those techniques can, and contact-level resolution handling the specific instability of email addresses across job changes.

None of this works well without confidence scoring distinguishing a reliable match from a speculative one, and a human review queue for the matches genuinely too ambiguous to resolve automatically.

The teams with the cleanest, most trustworthy GTM data aren't the ones running the single most sophisticated matching algorithm, they're the ones layering multiple techniques deliberately, each catching a different category of edge case, with explicit rules for the genuinely judgment-based decisions, corporate hierarchy, contact identity across a job change, that no algorithm alone can resolve correctly on its own.

Ready to find out how much your current data is fragmented by unresolved duplicates? Book a call, no decks, no demos, just a working session on your data.

Frequently Asked Questions

Should a subsidiary always be merged into its parent company's account?

No, it depends entirely on how your business actually sells and manages the relationship. Companies selling to large, decentralized enterprises where subsidiaries have independent purchasing authority generally want them tracked as distinct, linked accounts. Companies with one centralized global contract generally want everything rolled into a single parent account. This should be a deliberate business rule, not a default left to whatever a matching algorithm happens to produce.

What's the difference between Levenshtein distance and Jaro-Winkler for name matching?

Levenshtein distance counts the minimum number of single-character edits needed to transform one string into another, treating all positions in the string equally. Jaro-Winkler weights similarity at the beginning of a string more heavily, which tends to perform better specifically for company names, since two related names often share a common prefix, like a base name with a different legal suffix, that Jaro-Winkler captures more effectively.

How do I catch a company rebrand, like Facebook becoming Meta, that fuzzy name matching would miss?

Fuzzy string matching alone won't catch most rebrands, since the old and new names often share limited literal string similarity. This requires an explicit, maintained rebrand and hierarchy mapping table, sourced from an enrichment provider that tracks corporate name history, supplemented by manual research for your own highest-value accounts, run as a distinct step in your resolution pipeline rather than relying on name-similarity algorithms to catch it automatically.

Should every matched pair of records be automatically merged?

No. Auto-merging should be reserved for high-confidence matches, typically domain-based exact matches or matches corroborated by multiple independent signals. Lower-confidence matches, a moderate fuzzy-name similarity with no corroborating domain match, should route to a human review queue rather than merging automatically, since an incorrect auto-merge actively corrupts data in a way that's often harder to detect and fix than simply leaving two records unmerged.

How do I resolve contact identity across a job change?

Email matching alone will fail here, since the person's email changes along with their employer. A LinkedIn profile URL, where available, tends to be a considerably more stable secondary identifier surviving a job change. You'll also need an explicit business rule for whether the contact's history at their previous company should merge into one continuous identity or be treated as a genuinely separate relationship, since this is a deliberate decision about how your business tracks people versus companies, not just a technical matching problem.

About Dima Bilous

Founder of Anfloy, an embedded AI engineering team. Designs, builds, and operates AI for agencies, tech companies, info businesses, and service teams, from simple automation to agentic systems to complex AI products, all shipped into your repo and owned by you forever. Forward-deployed AI engineering, not an agency.

[ 099 ]The next move

Let's build
what your
company needs.

Drop your email. We'll send The Custom Agent Blueprint on what we'd build first for a company like yours, before you ever take a meeting.

↳ Or skip ahead · book a call