{"id":54145,"date":"2026-02-01T12:23:09","date_gmt":"2026-02-01T18:23:09","guid":{"rendered":"https:\/\/heartbeat.ai\/healthcare\/how-to-dedupe-a-provider-list-npi\/"},"modified":"2026-08-30T09:55:48","modified_gmt":"2026-08-30T14:55:48","slug":"how-to-dedupe-a-provider-list-npi","status":"publish","type":"post","link":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/","title":{"rendered":"Dedupe provider list by NPI: recruiter-proof SOP + CSV rules"},"content":{"rendered":"<p class=\"article-last-updated\"><strong>Last updated:<\/strong> August 30, 2026<\/p>\n<p><img decoding=\"async\" loading=\"false\" class=\"aligncenter\" src=\"http:\/\/hc.heartbeat.ai\/wp-content\/webp-express\/webp-images\/uploads\/2026\/02\/how-to-dedupe-a-provider-list-npi-6ca39603.png.webp\" alt=\"54144\" \/><\/p>\n<p><strong>Ben Argeband, Founder &amp; CEO of Heartbeat.ai<\/strong> \u2014 Very operational; reduce rework and candidate annoyance.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\r\n<div class=\"ez-toc-title-container\">\r\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">What\u2019s on this page:<\/p>\r\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\r\n<nav><ul class='ez-toc-list ez-toc-list-level-1' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Who_this_is_for\" >Who this is for<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Quick_answer\" >Quick answer<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#One_person_one_record_stop_double-tapping_candidates\" >One person, one record: stop double-tapping candidates<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Step-by-step_method\" >Step-by-step method<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Step_0_Make_a_safe_working_copy_and_add_audit_columns\" >Step 0: Make a safe working copy and add audit columns<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Step_1_Normalize_NPI_as_the_primary_key\" >Step 1: Normalize NPI as the primary key<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Step_15_Separate_individual_vs_organization_records_before_you_dedupe\" >Step 1.5: Separate individual vs. organization records before you dedupe<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Step_2_Group_by_NPI_and_choose_a_survivor_record\" >Step 2: Group by NPI and choose a survivor record<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Step_3_Fallback_keys_when_NPI_is_missing_or_invalid\" >Step 3: Fallback keys when NPI is missing or invalid<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Step_4_Build_and_keep_the_duplicate_log\" >Step 4: Build and keep the duplicate log<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Diagnostic_table\" >Diagnostic table<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Weighted_checklist\" >Weighted checklist<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Outreach_templates\" >Outreach templates<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Template_1_Apology_and_reset_same_person_duplicate_record\" >Template 1: Apology and reset (same person, duplicate record)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Template_2_Internal_note_to_recruiter_handoff_after_dedupe\" >Template 2: Internal note to recruiter (handoff after dedupe)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Template_3_Source_escalation_bad_upstream_feed\" >Template 3: Source escalation (bad upstream feed)<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Common_pitfalls\" >Common pitfalls<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#How_to_improve_results\" >How to improve results<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#1_Build_a_CSV_RULES_worksheet_you_reuse_on_every_list\" >1) Build a CSV_RULES worksheet you reuse on every list<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#2_Key_choice_matrix_precision_vs_coverage\" >2) Key choice matrix: precision vs. coverage<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#3_Add_measurement_so_you_can_prove_the_dedupe_worked\" >3) Add measurement so you can prove the dedupe worked<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#4_Export-ready_output_for_recruiters\" >4) Export-ready output for recruiters<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#5_Where_Heartbeatai_fits_after_dedupe\" >5) Where Heartbeat.ai fits after dedupe<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Legal_and_ethical_use\" >Legal and ethical use<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Evidence_and_trust_notes\" >Evidence and trust notes<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#FAQs\" >FAQs<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Is_NPI_always_the_best_way_to_dedupe_provider_records\" >Is NPI always the best way to dedupe provider records?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#What_should_I_do_when_two_rows_have_the_same_NPI_but_different_emails_or_phones\" >What should I do when two rows have the same NPI but different emails or phones?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#What_do_I_do_with_rows_that_fail_NPI_validation\" >What do I do with rows that fail NPI validation?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#How_do_I_prevent_dedupe_from_breaking_recruiter_ownership_and_attribution\" >How do I prevent dedupe from breaking recruiter ownership and attribution?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-31\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Whats_the_minimum_I_need_to_keep_for_an_audit_trail\" >What&#8217;s the minimum I need to keep for an audit trail?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-32\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#Next_steps\" >Next steps<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-33\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#About_the_Author\" >About the Author<\/a><\/li><\/ul><\/nav><\/div>\r\n<h2><span class=\"ez-toc-section\" id=\"Who_this_is_for\"><\/span>Who this is for<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Ops and recruiters cleaning lists before outreach or enrichment. If you&#8217;re about to upload a file, assign recruiter ownership, or start outreach, this SOP prevents double-taps, duplicate submissions, and reporting noise.<\/p>\n<p>Scope: you have a spreadsheet or CSV with some mix of <strong>NPI<\/strong>, name, specialty, practice location, and sometimes a <strong>state license<\/strong>. Treat this as <strong>identity resolution<\/strong> \u2014 deciding when two rows represent the same provider, then keeping one survivor record with an audit trail.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Quick_answer\"><\/span>Quick answer<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<dl>\n<dt>Core answer<\/dt>\n<dd>To dedupe a provider list by NPI, normalize NPI to 10 digits, group by NPI, select one survivor per group, and log duplicates with source and recency.<\/dd>\n<dt>Key insight<\/dt>\n<dd>NPI is the safest primary key. When it&#8217;s missing or invalid, fall back to state license, then name+city with strict normalization and a duplicate log.<\/dd>\n<dt>Best for<\/dt>\n<dd>Ops and recruiters cleaning lists before outreach or enrichment.<\/dd>\n<\/dl>\n<blockquote>\n<p><strong>Compliance &amp; safety<\/strong><\/p>\n<p>This method is for legitimate recruiting outreach only. Respect candidate privacy, opt-out requests, and local data laws. Heartbeat does not provide medical advice or legal counsel.<\/p>\n<\/blockquote>\n<h2><span class=\"ez-toc-section\" id=\"One_person_one_record_stop_double-tapping_candidates\"><\/span>One person, one record: stop double-tapping candidates<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Duplicates don&#8217;t just waste time. They create candidate annoyance from multiple calls or emails, internal confusion when two recruiters both think they &#8220;own&#8221; a physician, and messy economics \u2014 more dials per submittal, lower connect rates, and broken attribution.<\/p>\n<p><strong>What this SOP produces:<\/strong><\/p>\n<ul>\n<li><strong>SURVIVORS<\/strong>: one row per provider identity, ready for outreach or enrichment.<\/li>\n<li><strong>DUPLICATES_LOG<\/strong>: a mapped audit trail (duplicate_of, tier, reason, source, timestamp).<\/li>\n<li><strong>Before\/after snapshot<\/strong>: duplicate rate and collision rate so ops can show the cleanup worked.<\/li>\n<\/ul>\n<ul>\n<li>One <strong>identity<\/strong> \u2014 the actual person \u2014 can have many attributes: emails, phones, locations, licenses.<\/li>\n<li>Your working file should carry one survivor row per identity, plus a duplicate log that preserves where the other rows came from.<\/li>\n<li>Every dedupe decision should be explainable later to ops, compliance, or a recruiter picking up someone else&#8217;s list.<\/li>\n<\/ul>\n<p>In this SOP, <strong>recency<\/strong> is the tie-breaker: when two rows disagree, keep the most recently updated or verified attribute, and record what changed.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Step-by-step_method\"><\/span>Step-by-step method<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"Step_0_Make_a_safe_working_copy_and_add_audit_columns\"><\/span>Step 0: Make a safe working copy and add audit columns<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Duplicate the file and add these columns, even if blank at first:<\/p>\n<ul>\n<li><strong>row_id<\/strong> \u2014 a stable unique ID; create one if you don&#8217;t have it<\/li>\n<li><strong>dedupe_key<\/strong> \u2014 the key used to group<\/li>\n<li><strong>dedupe_tier<\/strong> \u2014 NPI, state license, or name+city<\/li>\n<li><strong>survivor_flag<\/strong> \u2014 TRUE\/FALSE<\/li>\n<li><strong>duplicate_of<\/strong> \u2014 row_id of the survivor<\/li>\n<li><strong>duplicate_reason<\/strong> \u2014 why the rows were grouped<\/li>\n<li><strong>source<\/strong> \u2014 where the row came from<\/li>\n<li><strong>last_updated<\/strong> \u2014 a date field, if you have one<\/li>\n<\/ul>\n<p>This is how you log duplicates without losing traceability.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Step_1_Normalize_NPI_as_the_primary_key\"><\/span>Step 1: Normalize NPI as the primary key<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><cite index=\"3-1\">A National Provider Identifier (NPI) is a unique 10-digit identification number issued to health care providers in the United States by the Centers for Medicare and Medicaid Services (CMS).<\/cite> <cite index=\"9-6\">The number itself is 10 digits long, contains no letters, and carries no embedded information about the provider.<\/cite><\/p>\n<p>Normalization rules to apply before grouping:<\/p>\n<ul>\n<li>Strip spaces, hyphens, and any non-numeric characters.<\/li>\n<li>After cleaning, accept only values that are exactly 10 digits.<\/li>\n<li>Anything else counts as a missing NPI and routes to a fallback tier.<\/li>\n<\/ul>\n<p>One extra check worth building in: <cite index=\"9-8,9-9\">the tenth digit of an NPI is a check digit calculated using the Luhn algorithm, the same formula used to validate credit card numbers, which lets software catch typing errors like a transposed pair of digits<\/cite>. A simple length check catches formatting garbage; a Luhn check catches typos that still happen to land on 10 digits \u2014 worth adding if your list volume justifies the extra formula.<\/p>\n<p><strong>Copy\/paste rules (Google Sheets examples):<\/strong><\/p>\n<ul>\n<li><strong>NPI_CLEAN (digits only)<\/strong>: <em>=REGEXREPLACE(A2,&#8221;[^0-9]&#8221;,&#8221;&#8221;)<\/em><\/li>\n<li><strong>NPI_VALID (10 digits)<\/strong>: <em>=IF(LEN(B2)=10,TRUE,FALSE)<\/em><\/li>\n<li><strong>NPI_FOR_KEY (blank if invalid)<\/strong>: <em>=IF(C2,B2,&#8221;&#8221;)<\/em><\/li>\n<\/ul>\n<p>Set <strong>dedupe_tier<\/strong> to &#8220;NPI&#8221; when NPI_VALID is TRUE.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Step_15_Separate_individual_vs_organization_records_before_you_dedupe\"><\/span>Step 1.5: Separate individual vs. organization records before you dedupe<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>A common ops failure is mixing individual providers with organization records in the same file. Don&#8217;t try to fix this during dedupe \u2014 split it first.<\/p>\n<ul>\n<li>If your source labels record type, split into two tabs, INDIVIDUAL and ORGANIZATION, and run this SOP on INDIVIDUAL only.<\/li>\n<li>If there&#8217;s no label, use a practical rule: if the name field is clearly a facility or clinic name rather than a person&#8217;s name, route it to ORGANIZATION and exclude it from this person-level dedupe run.<\/li>\n<\/ul>\n<p>This keeps the &#8220;one person, one record&#8221; logic clean and prevents nonsense groupings.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Step_2_Group_by_NPI_and_choose_a_survivor_record\"><\/span>Step 2: Group by NPI and choose a survivor record<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Dedupe means identifying rows that represent the same real-world provider and keeping one survivor record while preserving an audit trail of the rest.<\/p>\n<p>Group rows where NPI_FOR_KEY matches. For each group:<\/p>\n<ul>\n<li>Pick one survivor row \u2014 best contactability and freshest data.<\/li>\n<li>Mark all other rows as duplicates and set duplicate_of to the survivor&#8217;s row_id.<\/li>\n<li>Set duplicate_reason to &#8220;Same NPI after normalization.&#8221;<\/li>\n<\/ul>\n<p>Survivor selection order:<\/p>\n<ol>\n<li>Row with the most recently verified direct contact fields, if you track a verification date or last_updated.<\/li>\n<li>Row with the most complete contact set \u2014 email, phone, and location.<\/li>\n<li>Row with the newest last_updated date.<\/li>\n<li>If still tied, keep the row from your most trusted source and log why.<\/li>\n<\/ol>\n<p><strong>Multiple locations under one NPI (common):<\/strong><\/p>\n<ul>\n<li>Keep one identity \u2014 one survivor row_id \u2014 and treat locations as attributes.<\/li>\n<li>If your system needs multiple location rows, link them to the same survivor row_id rather than creating multiple identities.<\/li>\n<li>If two rows disagree on specialty, keep one identity, log the conflict, and prefer the most recent source for the primary specialty field.<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"Step_3_Fallback_keys_when_NPI_is_missing_or_invalid\"><\/span>Step 3: Fallback keys when NPI is missing or invalid<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>A match key is the standardized identifier, or composite of fields, used to decide whether two records refer to the same provider. Not every row will have a valid NPI, so keep the fallback tiers strict and documented:<\/p>\n<ul>\n<li><strong>Tier 2 \u2014 state license.<\/strong> Remove spaces and punctuation, uppercase the result, and group by license state plus license number. Set dedupe_tier to &#8220;state license.&#8221;<\/li>\n<li><strong>Tier 3 \u2014 name + city.<\/strong> Use only when NPI and state license are both missing. Normalize name and city\/state, then group by last name + first initial + city + state. Set dedupe_tier to &#8220;name+city.&#8221;<\/li>\n<\/ul>\n<p>The deeper you go into fallback tiers, the higher the risk of false positives \u2014 two different people who look similar on paper. That&#8217;s exactly why the duplicate log matters and why the rules need to stay strict.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Step_4_Build_and_keep_the_duplicate_log\"><\/span>Step 4: Build and keep the duplicate log<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Don&#8217;t delete duplicates. Move them to a separate tab called DUPLICATES_LOG and keep these fields:<\/p>\n<ul>\n<li>survivor row_id<\/li>\n<li>duplicate row_id<\/li>\n<li>dedupe_tier used (NPI, state license, or name+city)<\/li>\n<li>duplicate_reason<\/li>\n<li>source for both rows<\/li>\n<li>timestamp of the dedupe run<\/li>\n<\/ul>\n<p>This prevents ops headaches later when you need to reconcile submissions, outreach history, or suppression lists.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Diagnostic_table\"><\/span>Diagnostic table<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><strong>Use this to figure out what kind of duplicates you&#8217;re looking at and what to do about each pattern.<\/strong><\/p>\n<div class=\"table-scroll\" style=\"overflow:auto;-webkit-overflow-scrolling:touch;width:100%\">\n<table class=\"separated-content\">\n<thead>\n<tr>\n<th>Symptom in your file<\/th>\n<th>Likely cause<\/th>\n<th>Best match key<\/th>\n<th>What to do (CSV rules)<\/th>\n<th>What to log<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Same NPI appears on multiple rows<\/td>\n<td>Multiple sources, repeated exports, or prior enrichment runs<\/td>\n<td>NPI<\/td>\n<td>Normalize to 10 digits; group; pick survivor by recency + completeness<\/td>\n<td>duplicate_of survivor row_id; reason &#8220;Same NPI&#8221;<\/td>\n<\/tr>\n<tr>\n<td>NPI missing on many rows<\/td>\n<td>Older lists, partial exports, inconsistent upstream fields<\/td>\n<td>state license<\/td>\n<td>Normalize license; group by state+license; keep best contact row<\/td>\n<td>Tier used + source priority<\/td>\n<\/tr>\n<tr>\n<td>Two rows share name but different cities<\/td>\n<td>Different people or provider moved<\/td>\n<td>NPI (if present), otherwise keep separate<\/td>\n<td>Do not dedupe unless NPI\/license matches; treat as separate identities<\/td>\n<td>Flag for review<\/td>\n<\/tr>\n<tr>\n<td>Same name+city but different NPIs<\/td>\n<td>Data entry error or two providers with similar names<\/td>\n<td>NPI<\/td>\n<td>Keep separate; validate NPI source; do not force consolidation<\/td>\n<td>Conflict note<\/td>\n<\/tr>\n<tr>\n<td>Facility\/clinic names mixed into person rows<\/td>\n<td>Organization records mixed into individual workflow<\/td>\n<td>Pre-filter<\/td>\n<td>Split into INDIVIDUAL vs ORGANIZATION tabs before dedupe<\/td>\n<td>Filter rule used<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2><span class=\"ez-toc-section\" id=\"Weighted_checklist\"><\/span>Weighted checklist<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><strong>Score each dedupe run before you upload, enrich, or start outreach.<\/strong> Total is 100 points; if you&#8217;re under 80, fix the file first.<\/p>\n<ul>\n<li><strong>30 pts<\/strong> \u2014 NPI normalized to 10 digits and validated; invalid NPIs routed to fallback tiers<\/li>\n<li><strong>15 pts<\/strong> \u2014 Individual vs. organization records separated before dedupe<\/li>\n<li><strong>15 pts<\/strong> \u2014 Fallback keys implemented: state license normalization + name+city normalization<\/li>\n<li><strong>15 pts<\/strong> \u2014 Survivor rules documented (recency + completeness + trusted source)<\/li>\n<li><strong>15 pts<\/strong> \u2014 DUPLICATES_LOG created with duplicate_of mapping, reasons, and timestamp<\/li>\n<li><strong>10 pts<\/strong> \u2014 Suppression-ready: opt-outs and &#8220;do not contact&#8221; flags carried to the survivor record<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Outreach_templates\"><\/span>Outreach templates<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Use these when you discover you&#8217;ve already contacted a provider under a different row. The goal is to stop double-taps and keep suppression clean.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Template_1_Apology_and_reset_same_person_duplicate_record\"><\/span>Template 1: Apology and reset (same person, duplicate record)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><strong>Subject:<\/strong> Quick correction \u2014 one thread going forward<\/p>\n<p>Hi Dr. {{LastName}} \u2014 I realized we had you in our system twice and you may have gotten more than one message from us. Sorry about that.<\/p>\n<p>To keep it clean, I&#8217;m consolidating to one record and one point of contact on our side. If you&#8217;d prefer no outreach from us, reply &#8220;opt out&#8221; and I&#8217;ll suppress it.<\/p>\n<p>If you&#8217;re open to a quick call, what&#8217;s the best number and time window?<\/p>\n<p>\u2014 {{YourName}}, {{Role}}<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Template_2_Internal_note_to_recruiter_handoff_after_dedupe\"><\/span>Template 2: Internal note to recruiter (handoff after dedupe)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><strong>Subject:<\/strong> Dedupe complete for {{ListName}} \u2014 use survivor IDs only<\/p>\n<p>Team \u2014 dedupe on the provider list is complete. Use only rows where survivor_flag=TRUE. Duplicates are in DUPLICATES_LOG with duplicate_of mapping and reasons.<\/p>\n<p>Reminder: don&#8217;t outreach from duplicate rows; it double-taps the same physician and breaks attribution.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Template_3_Source_escalation_bad_upstream_feed\"><\/span>Template 3: Source escalation (bad upstream feed)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>We&#8217;re seeing repeated duplicates caused by inconsistent NPI formatting and missing license fields. Please standardize NPI to 10 digits and include state license where available. We can share our CSV rules if helpful.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Common_pitfalls\"><\/span>Common pitfalls<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li><strong>Using name-only dedupe.<\/strong> Name alone is not a key. If you must use name+city, treat it as a last resort and keep groups small and reviewable.<\/li>\n<li><strong>Deleting duplicates instead of logging them.<\/strong> When someone asks why a candidate got two emails, you need the audit trail.<\/li>\n<li><strong>Letting spreadsheets auto-format NPIs.<\/strong> Store the cleaned NPI as text to avoid dropped leading digits or scientific notation.<\/li>\n<li><strong>Mixing organization records into person workflows.<\/strong> Split first, dedupe second.<\/li>\n<li><strong>Collapsing multiple locations into multiple identities.<\/strong> One provider can practice at several sites. Keep one identity record and store locations as attributes, or link multiple location rows to the same survivor row_id.<\/li>\n<li><strong>Specialty conflicts across duplicates.<\/strong> Keep one identity, log the conflicting values, and prefer the most recent source for the primary specialty field.<\/li>\n<li><strong>Not carrying suppression forward.<\/strong> If any duplicate row has an opt-out or do-not-contact flag, the survivor must inherit it.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"How_to_improve_results\"><\/span>How to improve results<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"1_Build_a_CSV_RULES_worksheet_you_reuse_on_every_list\"><\/span>1) Build a CSV_RULES worksheet you reuse on every list<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This is the piece you can standardize across every inbound file: same normalization, same keys, same log format, every time.<\/p>\n<p><strong>Recommended CSV column headers:<\/strong><\/p>\n<ul>\n<li><strong>npi_raw<\/strong> (text)<\/li>\n<li><strong>npi_clean<\/strong> (text; digits only)<\/li>\n<li><strong>npi_valid<\/strong> (boolean)<\/li>\n<li><strong>license_state<\/strong> (text)<\/li>\n<li><strong>license_number_raw<\/strong> (text)<\/li>\n<li><strong>license_clean<\/strong> (text)<\/li>\n<li><strong>first_name<\/strong>, <strong>last_name<\/strong> (text)<\/li>\n<li><strong>city<\/strong>, <strong>state<\/strong> (text)<\/li>\n<li><strong>source<\/strong> (text)<\/li>\n<li><strong>last_updated<\/strong> (date)<\/li>\n<li><strong>dedupe_tier<\/strong> (text)<\/li>\n<li><strong>dedupe_key<\/strong> (text)<\/li>\n<li><strong>row_id<\/strong> (text)<\/li>\n<li><strong>survivor_flag<\/strong> (boolean)<\/li>\n<li><strong>duplicate_of<\/strong> (text)<\/li>\n<\/ul>\n<p><strong>Copy\/paste rules (Google Sheets examples):<\/strong><\/p>\n<ul>\n<li><strong>LICENSE_CLEAN<\/strong>: <em>=UPPER(REGEXREPLACE(E2,&#8221;[^A-Za-z0-9]&#8221;,&#8221;&#8221;))<\/em><\/li>\n<li><strong>NAME_KEY<\/strong>: <em>=UPPER(H2)&amp;&#8221;|&#8221;&amp;LEFT(G2,1)<\/em><\/li>\n<li><strong>CITY_KEY<\/strong>: <em>=UPPER(I2)&amp;&#8221;|&#8221;&amp;J2<\/em><\/li>\n<li><strong>DEDUP_KEY<\/strong>: <em>=IF(C2,&#8221;NPI|&#8221;&amp;B2,IF(F2&lt;&gt;&#8221;&#8221;,&#8221;LIC|&#8221;&amp;D2&amp;&#8221;|&#8221;&amp;F2,&#8221;NAMECITY|&#8221;&amp;K2&amp;&#8221;|&#8221;&amp;L2))<\/em><\/li>\n<\/ul>\n<p><strong>Example dedupe_key outputs:<\/strong><\/p>\n<ul>\n<li><strong>NPI tier<\/strong>: <em>NPI|1234567890<\/em><\/li>\n<li><strong>state license tier<\/strong>: <em>LIC|CA|A12345<\/em><\/li>\n<li><strong>name+city tier<\/strong>: <em>NAMECITY|SMITH|J|AUSTIN|TX<\/em><\/li>\n<\/ul>\n<p>Sort by dedupe_key along with your best-record signals \u2014 last_updated and completeness \u2014 so the survivor lands as the first row in each group.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"2_Key_choice_matrix_precision_vs_coverage\"><\/span>2) Key choice matrix: precision vs. coverage<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div class=\"table-scroll\" style=\"overflow:auto;-webkit-overflow-scrolling:touch;width:100%\">\n<table class=\"separated-content\">\n<thead>\n<tr>\n<th>Tier<\/th>\n<th>When to use<\/th>\n<th>Main risk<\/th>\n<th>What to log<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>NPI<\/td>\n<td>Default when a valid 10-digit NPI is present<\/td>\n<td>Bad upstream NPI entry or org\/person mixing<\/td>\n<td>Normalization applied + survivor rule used<\/td>\n<\/tr>\n<tr>\n<td>state license<\/td>\n<td>When NPI is missing or invalid but license is present<\/td>\n<td>License formatting differences across sources<\/td>\n<td>State + cleaned license + source priority<\/td>\n<\/tr>\n<tr>\n<td>name+city<\/td>\n<td>Last resort only<\/td>\n<td>False positives from similar names<\/td>\n<td>Exact normalization rules + review flag<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3><span class=\"ez-toc-section\" id=\"3_Add_measurement_so_you_can_prove_the_dedupe_worked\"><\/span>3) Add measurement so you can prove the dedupe worked<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Run a before\/after report on duplicates removed and outreach collisions prevented, then track downstream contactability metrics over time.<\/p>\n<ul>\n<li><strong>Duplicate Rate<\/strong> = duplicate rows \/ total rows, reported per 1,000 rows and tracked by source.<\/li>\n<li><strong>Collision Rate<\/strong> = outreach attempts to duplicate identities \/ total outreach attempts, per 100 attempts.<\/li>\n<li><strong>Connect Rate<\/strong> = connected calls \/ total dials, per 100 dials.<\/li>\n<li><strong>Answer Rate<\/strong> = human answers \/ connected calls, per 100 connected calls.<\/li>\n<li><strong>Deliverability Rate<\/strong> = delivered emails \/ sent emails, per 100 sent emails.<\/li>\n<li><strong>Bounce Rate<\/strong> = bounced emails \/ sent emails, per 100 sent emails.<\/li>\n<li><strong>Reply Rate<\/strong> = replies \/ delivered emails, per 100 delivered emails.<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"4_Export-ready_output_for_recruiters\"><\/span>4) Export-ready output for recruiters<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><strong>Outreach\/enrichment file<\/strong>: include only rows where survivor_flag=TRUE.<\/li>\n<li><strong>Required columns to keep<\/strong>: row_id, npi_clean (or NPI_FOR_KEY), dedupe_tier, source, last_updated, and your contact fields.<\/li>\n<li><strong>Audit file<\/strong>: keep DUPLICATES_LOG as a separate tab or CSV with survivor mapping and timestamp.<\/li>\n<\/ul>\n<h3><span class=\"ez-toc-section\" id=\"5_Where_Heartbeatai_fits_after_dedupe\"><\/span>5) Where Heartbeat.ai fits after dedupe<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Once you have one record per provider, enrichment and outreach behave better: fewer wasted lookups, fewer duplicate touches, cleaner attribution. Heartbeat.ai can support this by keeping identity resolution consistent and ranking mobile numbers by answer probability, so recruiters spend dials where they&#8217;re most likely to connect.<\/p>\n<ul>\n<li><a href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/upload-a-physician-list-for-enrichment\/\">Upload a physician list for enrichment (workflow + file prep)<\/a><\/li>\n<li><a href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/bulk-physician-lookup\/\">Bulk physician lookup (when you need fast coverage)<\/a><\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Legal_and_ethical_use\"><\/span>Legal and ethical use<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This is operational guidance for recruiting workflows, not legal advice. Use dedupe and identity resolution to reduce duplicate outreach and respect candidate preferences.<\/p>\n<ul>\n<li>Honor opt-outs immediately and propagate suppression flags to the survivor record.<\/li>\n<li>Limit access to raw lists; keep the duplicate log for audit purposes, but don&#8217;t over-share it.<\/li>\n<li>Only contact providers for legitimate recruiting opportunities and keep messages relevant.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Evidence_and_trust_notes\"><\/span>Evidence and trust notes<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><cite index=\"10-2\">An NPI is a unique 10-digit number used to identify health care providers.<\/cite> <cite index=\"10-4,10-5\">Once assigned, an NPI remains the same even if the provider changes name, address, or other information, and NPIs do not carry information about a provider such as geographic location or specialty.<\/cite> That&#8217;s part of why NPI works better as a dedupe key than name or address fields \u2014 it&#8217;s stable by design.<\/p>\n<ul>\n<li><a href=\"https:\/\/nppes.cms.hhs.gov\/\">NPPES (CMS) \u2014 NPI source<\/a><\/li>\n<li><a href=\"https:\/\/www.cms.gov\/medicare\/regulations-guidance\/administrative-simplification\/national-provider-identifier-npi\">CMS \u2014 National Provider Identifier (NPI) overview<\/a><\/li>\n<\/ul>\n<p>For how Heartbeat.ai evaluates data quality and operational trust, review: <a href=\"http:\/\/heartbeat.ai\/resources\/trust-methodology\/\">Heartbeat.ai trust methodology and definitions<\/a>.<\/p>\n<p>If your workflow includes matching NPI to licensing, use this sibling playbook next: <a href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/npi-license-matching\/\">NPI to state license matching (ops workflow)<\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"FAQs\"><\/span>FAQs<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"Is_NPI_always_the_best_way_to_dedupe_provider_records\"><\/span>Is NPI always the best way to dedupe provider records?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>For individual providers, NPI is usually the cleanest primary key because it&#8217;s designed as an identifier. When NPI is missing or invalid, use state license next, then name+city as a last resort with strict normalization and logging.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"What_should_I_do_when_two_rows_have_the_same_NPI_but_different_emails_or_phones\"><\/span>What should I do when two rows have the same NPI but different emails or phones?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Keep one survivor record per NPI and treat emails\/phones as attributes. Prefer the most recent, most verified contact points, and keep the other values in notes or an attribute table if your system supports it. Always keep the duplicate log.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"What_do_I_do_with_rows_that_fail_NPI_validation\"><\/span>What do I do with rows that fail NPI validation?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Route them to the fallback tiers: try state license first, then name+city only if you have no better key. Flag name+city groups for review and keep the dedupe_tier in your log so you can audit false positives later.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"How_do_I_prevent_dedupe_from_breaking_recruiter_ownership_and_attribution\"><\/span>How do I prevent dedupe from breaking recruiter ownership and attribution?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Run dedupe before assignment. Use survivor row_ids as the only assignable records, and map duplicates to survivors in DUPLICATES_LOG so historical activity can be reconciled without creating new &#8220;owners&#8221; for the same person.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Whats_the_minimum_I_need_to_keep_for_an_audit_trail\"><\/span>What&#8217;s the minimum I need to keep for an audit trail?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Survivor row_id, duplicate row_id, dedupe tier used, reason, source, and timestamp. That&#8217;s enough to explain what happened and to debug upstream list quality.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Next_steps\"><\/span>Next steps<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li>If you&#8217;re about to enrich: <a href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/upload-a-physician-list-for-enrichment\/\">prep and upload your physician list for enrichment<\/a> after you dedupe.<\/li>\n<li>If you need fast coverage first: <a href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/bulk-physician-lookup\/\">run a bulk physician lookup<\/a>, then dedupe the combined output before outreach.<\/li>\n<li>If you want this running as a repeatable workflow in Heartbeat.ai: <a href=\"https:\/\/heartbeat.ai\/signup\">create an account and set up your list workflow<\/a>.<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"About_the_Author\"><\/span><b>About the Author<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><a href=\"http:\/\/heartbeat.ai\/resources\/author\/ben-argeband\"><span style=\"font-weight: 400;\">Ben Argeband<\/span><\/a><span style=\"font-weight: 400;\"> is the Founder and CEO of Swordfish.ai and Heartbeat.ai. With deep expertise in data and SaaS, he has built two successful platforms trusted by over 50,000 sales and recruitment professionals. Ben&#8217;s mission is to help teams find direct contact information for hard-to-reach professionals and decision-makers, providing the shortest route to their next win. Connect with Ben on <\/span><a href=\"https:\/\/www.linkedin.com\/in\/ben-m-argeband-2427a8a3\/\"><span style=\"font-weight: 400;\">LinkedIn<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>","protected":false},"excerpt":{"rendered":"<p>A recruiter-proof SOP to dedupe provider lists by NPI: normalize to 10 digits, use fallback keys, pick a survivor by recency, log duplicates.<\/p>","protected":false},"author":5,"featured_media":54144,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_custom_permalink":"provider-contact-data\/how-to-dedupe-a-provider-list-npi","footnotes":""},"categories":[1],"tags":[],"class_list":["post-54145","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\r\n<title>Dedupe provider list by NPI (SOP + CSV rules) | Heartbeat.ai<\/title>\r\n<meta name=\"description\" content=\"Normalize NPI to 10 digits, dedupe with fallback keys (state license, name+city), choose a survivor by recency, and keep a duplicate audit log before outreach or enrichment.\" \/>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"Dedupe provider list by NPI (SOP + CSV rules) | Heartbeat.ai\" \/>\r\n<meta property=\"og:description\" content=\"Normalize NPI to 10 digits, dedupe with fallback keys (state license, name+city), choose a survivor by recency, and keep a duplicate audit log before outreach or enrichment.\" \/>\r\n<meta property=\"og:url\" content=\"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/\" \/>\r\n<meta property=\"og:site_name\" content=\"Heartbeat.ai\" \/>\r\n<meta property=\"article:published_time\" content=\"2026-02-01T18:23:09+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2026-08-30T14:55:48+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2026\/02\/how-to-dedupe-a-provider-list-npi-6ca39603.png\" \/>\r\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\r\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\r\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\r\n<meta name=\"author\" content=\"Ben Argeband\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ben Argeband\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#article\",\"isPartOf\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/\"},\"author\":{\"name\":\"Ben Argeband\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#\\\/schema\\\/person\\\/7b323ddce9b211907423482e2f9db173\"},\"headline\":\"Dedupe provider list by NPI: recruiter-proof SOP + CSV rules\",\"datePublished\":\"2026-02-01T18:23:09+00:00\",\"dateModified\":\"2026-08-30T14:55:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/\"},\"wordCount\":2829,\"commentCount\":0,\"publisher\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#organization\"},\"image\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/hc.heartbeat.ai\\\/wp-content\\\/uploads\\\/2026\\\/02\\\/how-to-dedupe-a-provider-list-npi-6ca39603.png\",\"articleSection\":[\"News\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/\",\"url\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/\",\"name\":\"Dedupe provider list by NPI (SOP + CSV rules) | Heartbeat.ai\",\"isPartOf\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#primaryimage\"},\"image\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/hc.heartbeat.ai\\\/wp-content\\\/uploads\\\/2026\\\/02\\\/how-to-dedupe-a-provider-list-npi-6ca39603.png\",\"datePublished\":\"2026-02-01T18:23:09+00:00\",\"dateModified\":\"2026-08-30T14:55:48+00:00\",\"description\":\"Normalize NPI to 10 digits, dedupe with fallback keys (state license, name+city), choose a survivor by recency, and keep a duplicate audit log before outreach or enrichment.\",\"breadcrumb\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#primaryimage\",\"url\":\"http:\\\/\\\/hc.heartbeat.ai\\\/wp-content\\\/uploads\\\/2026\\\/02\\\/how-to-dedupe-a-provider-list-npi-6ca39603.png\",\"contentUrl\":\"http:\\\/\\\/hc.heartbeat.ai\\\/wp-content\\\/uploads\\\/2026\\\/02\\\/how-to-dedupe-a-provider-list-npi-6ca39603.png\",\"width\":1024,\"height\":1024},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/provider-contact-data\\\/how-to-dedupe-a-provider-list-npi\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Dedupe provider list by NPI: recruiter-proof SOP + CSV rules\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#website\",\"url\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/\",\"name\":\"Heartbeat.ai\",\"description\":\"\",\"publisher\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#organization\",\"name\":\"Heartbeat.ai\",\"url\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/hc.heartbeat.ai\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/Heartbeat.ai-logo.png\",\"contentUrl\":\"https:\\\/\\\/hc.heartbeat.ai\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/Heartbeat.ai-logo.png\",\"width\":704,\"height\":126,\"caption\":\"Heartbeat.ai\"},\"image\":{\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/#\\\/schema\\\/person\\\/7b323ddce9b211907423482e2f9db173\",\"name\":\"Ben Argeband\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9cdd6acf262740ced0b6a1c76378e93640df32a98d2f4d29507f31fbce6817e7?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9cdd6acf262740ced0b6a1c76378e93640df32a98d2f4d29507f31fbce6817e7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9cdd6acf262740ced0b6a1c76378e93640df32a98d2f4d29507f31fbce6817e7?s=96&d=mm&r=g\",\"caption\":\"Ben Argeband\"},\"url\":\"http:\\\/\\\/heartbeat.ai\\\/resources\\\/author\\\/ben-argeband\\\/\"}]}<\/script>\r\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Dedupe provider list by NPI (SOP + CSV rules) | Heartbeat.ai","description":"Normalize NPI to 10 digits, dedupe with fallback keys (state license, name+city), choose a survivor by recency, and keep a duplicate audit log before outreach or enrichment.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/","og_locale":"en_US","og_type":"article","og_title":"Dedupe provider list by NPI (SOP + CSV rules) | Heartbeat.ai","og_description":"Normalize NPI to 10 digits, dedupe with fallback keys (state license, name+city), choose a survivor by recency, and keep a duplicate audit log before outreach or enrichment.","og_url":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/","og_site_name":"Heartbeat.ai","article_published_time":"2026-02-01T18:23:09+00:00","article_modified_time":"2026-08-30T14:55:48+00:00","og_image":[{"width":1024,"height":1024,"url":"https:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2026\/02\/how-to-dedupe-a-provider-list-npi-6ca39603.png","type":"image\/png"}],"author":"Ben Argeband","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Ben Argeband","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#article","isPartOf":{"@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/"},"author":{"name":"Ben Argeband","@id":"http:\/\/heartbeat.ai\/resources\/#\/schema\/person\/7b323ddce9b211907423482e2f9db173"},"headline":"Dedupe provider list by NPI: recruiter-proof SOP + CSV rules","datePublished":"2026-02-01T18:23:09+00:00","dateModified":"2026-08-30T14:55:48+00:00","mainEntityOfPage":{"@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/"},"wordCount":2829,"commentCount":0,"publisher":{"@id":"http:\/\/heartbeat.ai\/resources\/#organization"},"image":{"@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#primaryimage"},"thumbnailUrl":"http:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2026\/02\/how-to-dedupe-a-provider-list-npi-6ca39603.png","articleSection":["News"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#respond"]}]},{"@type":"WebPage","@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/","url":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/","name":"Dedupe provider list by NPI (SOP + CSV rules) | Heartbeat.ai","isPartOf":{"@id":"http:\/\/heartbeat.ai\/resources\/#website"},"primaryImageOfPage":{"@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#primaryimage"},"image":{"@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#primaryimage"},"thumbnailUrl":"http:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2026\/02\/how-to-dedupe-a-provider-list-npi-6ca39603.png","datePublished":"2026-02-01T18:23:09+00:00","dateModified":"2026-08-30T14:55:48+00:00","description":"Normalize NPI to 10 digits, dedupe with fallback keys (state license, name+city), choose a survivor by recency, and keep a duplicate audit log before outreach or enrichment.","breadcrumb":{"@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#primaryimage","url":"http:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2026\/02\/how-to-dedupe-a-provider-list-npi-6ca39603.png","contentUrl":"http:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2026\/02\/how-to-dedupe-a-provider-list-npi-6ca39603.png","width":1024,"height":1024},{"@type":"BreadcrumbList","@id":"http:\/\/heartbeat.ai\/resources\/provider-contact-data\/how-to-dedupe-a-provider-list-npi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/heartbeat.ai\/resources\/"},{"@type":"ListItem","position":2,"name":"Dedupe provider list by NPI: recruiter-proof SOP + CSV rules"}]},{"@type":"WebSite","@id":"http:\/\/heartbeat.ai\/resources\/#website","url":"http:\/\/heartbeat.ai\/resources\/","name":"Heartbeat.ai","description":"","publisher":{"@id":"http:\/\/heartbeat.ai\/resources\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/heartbeat.ai\/resources\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"http:\/\/heartbeat.ai\/resources\/#organization","name":"Heartbeat.ai","url":"http:\/\/heartbeat.ai\/resources\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"http:\/\/heartbeat.ai\/resources\/#\/schema\/logo\/image\/","url":"https:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2021\/04\/Heartbeat.ai-logo.png","contentUrl":"https:\/\/hc.heartbeat.ai\/wp-content\/uploads\/2021\/04\/Heartbeat.ai-logo.png","width":704,"height":126,"caption":"Heartbeat.ai"},"image":{"@id":"http:\/\/heartbeat.ai\/resources\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"http:\/\/heartbeat.ai\/resources\/#\/schema\/person\/7b323ddce9b211907423482e2f9db173","name":"Ben Argeband","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/9cdd6acf262740ced0b6a1c76378e93640df32a98d2f4d29507f31fbce6817e7?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9cdd6acf262740ced0b6a1c76378e93640df32a98d2f4d29507f31fbce6817e7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9cdd6acf262740ced0b6a1c76378e93640df32a98d2f4d29507f31fbce6817e7?s=96&d=mm&r=g","caption":"Ben Argeband"},"url":"http:\/\/heartbeat.ai\/resources\/author\/ben-argeband\/"}]}},"_links":{"self":[{"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/posts\/54145","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/comments?post=54145"}],"version-history":[{"count":2,"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/posts\/54145\/revisions"}],"predecessor-version":[{"id":65902,"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/posts\/54145\/revisions\/65902"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/media\/54144"}],"wp:attachment":[{"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/media?parent=54145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/categories?post=54145"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/heartbeat.ai\/resources\/wp-json\/wp\/v2\/tags?post=54145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}