Back to Heartbeat Blog

CSV import template for physician contacts (ATS-ready header + NPI dedupe rules)

0
(0)
February 3, 2026

What’s on this page:

0
(0)

54314

CSV import template for physician contacts (ATS-ready header + NPI dedupe rules)

Ben Argeband, Founder & CEO of Heartbeat.ai — Painfully clear and copy/paste ready.

What’s on this page:

Who this is for

Recruiters and ops teams importing physician contact data into an ATS who need clean records: no duplicate providers, no broken date/boolean fields, and clear provenance (where each row came from). This is built around CSV hygiene, NPI-first identity, and recency tracking so your outreach performance doesn’t quietly decay.

This page is a supporting template. For enrichment after upload, use the primary workflow: upload a physician list for enrichment.

Quick Answer

Core Answer
Use an NPI-first CSV with normalized phones/emails, explicit source + refresh date, and strict dedupe keys so your ATS import stays clean and searchable.
Key Statistic
Heartbeat observed typicals: include required header and mapping; do not claim native ATS integrations unless true.
Best For
Recruiters/ops importing physician contact data into ATS without duplicates/broken fields.
Primary page for this topic
https://heartbeat.ai/resources/provider-contact-data/upload-a-physician-list-for-enrichment/

Compliance & Safety

This method is for legitimate recruiting outreach only. Always respect candidate privacy, opt-out requests, and local data laws. Heartbeat does not provide medical advice or legal counsel.

Framework: The “No Mess Imports” Standard: Unique Key → Clean Fields → Log Dates

Most import failures aren’t “CSV problems.” They’re identity problems (no stable unique key), format problems (inconsistent fields), and freshness problems (no way to tell what’s current). The “No Mess Imports” Standard fixes those in order:

  • Unique Key: pick one field that represents the provider across systems. For physicians, that’s usually NPI.
  • Clean Fields: normalize names, phones, emails, and addresses so your ATS doesn’t split records or reject rows.
  • Log Dates: store a refresh date so you can suppress stale contacts and prioritize recent ones.

The trade-off is… you’ll spend a few minutes up front on structure, but you’ll avoid contaminating your ATS with duplicates you can’t unwind later.

Step-by-step method

Step 1) Start with the exact header row (copy/paste)

Paste this header row into row 1 of your CSV. Keep the column names exactly as written to reduce mapping mistakes.

Spreadsheet setup tip: set NPI and postal_code columns to text before you save/export so leading zeros don’t get dropped.

Copy/paste CSV header:

NPI,first_name,last_name,credential,specialty_primary,organization_name,practice_site_name,address_line1,address_line2,city,state,postal_code,country,phone_main,phone_mobile,email_work,email_personal,preferred_contact_channel,do_not_contact,source_system,source_detail,refresh_date,notes

Example row (synthetic):

1234567890,Priya,Shah,MD,Internal Medicine,Northside Medical Group,Northside Clinic – Midtown,123 Main St,Ste 400,Chicago,IL,02110,US,+13125551212,+13125559876,pshah@northside.org,,phone,FALSE,Heartbeat.ai,IM Midwest outreach list,2026-01-05,Prefers calls 12-2pm local

Step 2) Use the field definitions (don’t improvise formats)

Imports break when the same “type” of data shows up in multiple formats (dates, phones, booleans). Use the definitions below and enforce them before you import.

Diagnostic Table:

Column Required? Definition / Allowed values Example ATS mapping notes (Bullhorn / Apploi)
NPI Yes NPI definition: National Provider Identifier; a unique 10-digit identifier for covered health care providers in the U.S. Store as 10 digits, no dashes. 1234567890 Map to a custom field if your ATS doesn’t have a native NPI field. Use as your primary dedupe key.
first_name Yes Given name only. No titles. Priya Standard candidate/contact first name.
last_name Yes Family name only. No suffixes unless your ATS requires them. Shah Standard candidate/contact last name.
credential No Short credential string. MD Often maps to “Suffix” or “Credential” custom field.
specialty_primary No One specialty only (avoid comma-separated lists). Internal Medicine Map to specialty field or tags. Keep one value for filtering.
organization_name No Employer/health system/group name. Northside Medical Group Map to “Company” or “Employer” field if available.
practice_site_name No Clinic/site label (optional). Northside Clinic – Midtown Useful for multi-site groups; map to location/site custom field.
address_line1 No Street address line 1. 123 Main St Map to address fields if your ATS supports them; otherwise store in notes.
address_line2 No Suite/unit. Ste 400 Same as above.
city No City. Chicago Standard address mapping.
state No 2-letter state code if U.S. IL Standard address mapping.
postal_code No ZIP or postal code as text (preserve leading zeros). 02110 Import as text, not number.
country No Country name or ISO code; be consistent. US Optional unless you recruit internationally.
phone_main No Primary office line. Store as E.164 if possible (+1XXXXXXXXXX). If not, digits only. +13125551212 Map to “Phone” or “Work Phone.” Avoid mixing extensions into the number field.
phone_mobile No Mobile number (E.164 preferred). Keep separate from office line. +13125559876 Map to “Mobile Phone” if available; otherwise custom field. Heartbeat.ai can use ranked mobile numbers by answer probability.
email_work No Work email. Lowercase. One email per field. pshah@northside.org Map to primary email if you prioritize work outreach.
email_personal No Personal email (only if you have a legitimate recruiting purpose and honor opt-outs). Lowercase. priya.shah@gmail.com Consider mapping to secondary email/custom field; apply suppression rules.
preferred_contact_channel No One of: phone,email,unknown phone Map to a tag or custom field; helps routing and cadence selection.
do_not_contact No Boolean: TRUE or FALSE (uppercase). Default FALSE. FALSE Map to your ATS DNC/opt-out field if available. Never overwrite TRUE with FALSE.
source_system No Where the row came from (system name). Heartbeat.ai Map to “Source” or custom field for auditability.
source_detail No Free text: list name, campaign, or query used. If it includes commas, ensure proper CSV quoting. IM Midwest outreach list Store for traceability when complaints or bounces happen.
refresh_date Yes Recency definition: the date you last verified/updated the contact row. Use ISO format YYYY-MM-DD. 2026-01-05 Map to “Last Updated” custom field. Use it to suppress stale contacts.
notes No Short notes. If notes include commas, ensure your CSV exporter properly quotes the field. Prefers calls 12-2pm local Map to notes/comments field.

Step 3) Set your dedupe policy before you import

Import failures come from inconsistent fields and missing unique keys. For physicians, NPI is the best primary key. Emails and phones are volatile: people change employers, domains change, and numbers get reassigned. Your dedupe policy should reflect that reality.

  • Primary dedupe key: NPI
  • Secondary match signals (for review, not auto-merge): last_name + first_name + state, or email_work
  • Never auto-merge solely on phone or email (they can be shared, forwarded, or recycled)

For a deeper walkthrough, link this into your SOP: how to dedupe a provider list by NPI.

Step 4) Map fields into Bullhorn / Apploi (pilot first)

Two rules keep your ATS usable:

  • Don’t overload one field (for example, multiple emails in one email field). Keep one value per field.
  • Keep structured data structured (dates as YYYY-MM-DD, booleans as TRUE/FALSE, state as 2-letter code).

Do a 10-row pilot import, verify how Bullhorn/Apploi stored each field, then import the full file.

CSV column Bullhorn target Apploi target Field type Common failure mode
NPI Custom text field (e.g., NPI__c) Custom field (text) Text Imported as number and loses leading zeros (treat as text)
refresh_date Custom date field Custom field (date) Date Rejected due to non-ISO formats (use YYYY-MM-DD)
do_not_contact DNC/opt-out field (or custom boolean) Opt-out field (or custom boolean) Boolean TRUE/FALSE mismatch (don’t use Yes/No)
phone_main Phone (work) Phone Text Extensions included in number field (put ext in notes)
phone_mobile Mobile phone (or custom) Mobile phone (or custom) Text Mobile overwritten by office line due to single phone mapping
email_work Email Email Text Multiple emails in one cell causing parse issues
source_system Source/custom Source/custom Text Missing provenance makes complaints hard to investigate

If you’re using Heartbeat.ai workflows, you can also start from your existing file and upload it for enrichment: upload your file.

Step 5) Run a pre-import validation pass

  1. Check NPI format: 10 digits, no blanks for rows you intend to dedupe reliably.
  2. Normalize emails: lowercase; remove spaces; one email per field.
  3. Normalize phones: pick E.164 (+1…) or digits-only and stick to it.
  4. Validate refresh_date: ISO YYYY-MM-DD only.
  5. Confirm do_not_contact: TRUE/FALSE only; never overwrite TRUE with FALSE on re-import.

Weighted Checklist:

Use this as a go/no-go gate before you import. Score each item 0 (missing), 1 (partial), 2 (clean). If you’re under 12/16, fix the file first.

  • (2) NPI present and 10-digit for the rows you plan to keep long-term.
  • (2) Dedupe rule written: “NPI = unique; never auto-merge on phone/email.”
  • (2) refresh_date populated for every row (YYYY-MM-DD).
  • (2) Phone split: office vs mobile in separate columns.
  • (2) Email split: work vs personal in separate columns.
  • (2) do_not_contact respected: TRUE never overwritten by FALSE on re-import.
  • (2) Source traceability: source_system + source_detail filled in.
  • (2) ATS field mapping tested with a 10-row pilot import and rollback plan.

Common pitfalls

Pitfall 1: Treating email/phone as the unique key

Emails and phones change. If you dedupe on them, you’ll either merge the wrong people or create duplicates when a physician changes systems. Use NPI as the stable identity key and treat contact points as attributes that can rotate.

Pitfall 2: No refresh_date (you can’t tell what’s stale)

If you don’t store recency, you can’t suppress old contacts, and your team will waste cycles on dead emails and wrong numbers. Add refresh_date to every row and keep it updated when you re-verify.

Pitfall 3: Multi-value fields that break parsing

Comma-separated specialties, multiple emails in one cell, or “(312) 555-1212 ext 9” inside a phone field will cause import errors or make your ATS search unreliable. Keep one value per field and store extensions/notes separately.

Pitfall 4: Importing the full file without a pilot

The fastest way to create a cleanup project is to import the full file before you confirm mapping. Do a 10-row pilot, verify how your ATS stored each field, then import the full file.

Pitfall 5: Overwriting opt-outs on re-import

If your ATS has a do-not-contact flag, treat it as write-protected. Your import process should never flip TRUE back to FALSE because a source file didn’t carry the opt-out forward.

Import error decoder (symptom → cause → fix)

Symptom Likely cause Fix
refresh_date rejected Date not in YYYY-MM-DD Convert to ISO format; ensure the column is mapped as a date field
ZIP/postal_code loses leading zeros Spreadsheet saved it as a number Set the column to text before saving; keep postal_code as text in the ATS
Duplicates created on re-import No match key (or ATS match not configured) Match/update on NPI; quarantine rows missing NPI for review
Phone fields look scrambled Extensions or multiple numbers in one cell Keep one number per field; put extensions in notes
Emails bounce immediately Stale contacts or typos/spaces Lowercase + trim; use refresh_date to suppress older rows until re-verified

How to improve results

CSV_TEMPLATE worksheet: import-ready row validator

This is the fastest way to keep your ATS clean while still moving quickly. Create a second tab in your spreadsheet called QUARANTINE and apply these rules before every import:

  • Rule A (identity): If NPI is blank or not exactly 10 digits, move the row to QUARANTINE (do not import into the main ATS table).
  • Rule B (freshness): If refresh_date is blank or not YYYY-MM-DD, move to QUARANTINE.
  • Rule C (opt-out safety): If do_not_contact is TRUE, keep the row but ensure your import cannot overwrite TRUE with FALSE.
  • Rule D (contact hygiene): If email_work or email_personal contains spaces or multiple emails, split into separate fields or move to QUARANTINE.
  • Rule E (phone hygiene): If phone fields contain “ext”, “x”, or multiple numbers, move to QUARANTINE and store the extension in notes.

Dedupe decision tree:

  • If NPI matches an existing record → update contact attributes (phones/emails), update refresh_date, preserve do_not_contact if TRUE.
  • If NPI does not match → create a new record.
  • If NPI missing → do not auto-merge; quarantine for review.

If your ATS can’t update records by NPI

Some ATS setups can import but can’t reliably update existing records based on a custom key. In that case, use a staging workflow:

  1. Import the CSV into a staging list/table (or a temporary project) instead of your main database.
  2. Match staging rows to existing records using NPI.
  3. Apply updates (phones/emails/refresh_date/source fields) to the matched records.
  4. Create new records only for NPIs that don’t exist yet.

Track the right metrics (and define them consistently)

Measure this by… running a weekly scorecard on a fixed cohort (for example, the last imported batch) and comparing outcomes by refresh_date band and channel.

  • Deliverability Rate = delivered emails / sent emails (per 100 sent emails).
  • Bounce Rate = bounced emails / sent emails (per 100 sent emails).
  • Connect Rate = connected calls / total dials (per 100 dials).
  • Answer Rate = human answers / connected calls (per 100 connected calls).
  • Reply Rate = replies / delivered emails (per 100 delivered emails).

Measurement instructions:

  1. Tag every imported record with source_system, source_detail, and refresh_date.
  2. Run outreach in a consistent cadence for 7–14 days (same number of touches per record).
  3. Export outcomes (delivered, bounced, replies; dials, connected, human answers) and compute the rates above using the stated denominators.
  4. Compare performance for records refreshed recently vs. older refresh_date values to decide when to re-verify or suppress.

Suppression SOP (so you don’t re-contact opt-outs)

Keep opt-outs in two places: your ATS record (do_not_contact = TRUE) and a suppression list used by your outreach tools. On every re-import, treat TRUE as write-protected and never overwrite it with FALSE.

Use NPI to keep your ATS clean across re-imports

If you’re building lists repeatedly, don’t rely on ATS “duplicate detection” defaults. Make NPI the anchor, then update contact attributes (phones/emails) as they change. If you need the upstream list-building workflow, use: how to build a physician call list.

Outreach Templates:

These templates assume you have NPI, specialty, and a recent refresh_date. Keep them short and operational.

Template 1: Phone opener (office line)

  • You: “Hi, this is [Name]. I’m trying to reach Dr. [Last Name] about a physician opportunity. What’s the best way to get a message through—direct line, email, or a good time window?”
  • If asked details: “It’s a [specialty] role with [high-level location/setting]. I can send a 3-line summary—what email should I use?”

Template 2: Email (work email)

  • Subject: Dr. [Last Name] — quick question
  • Body: “Dr. [Last Name], I recruit physicians for [organization/type]. Are you open to a brief call about a [specialty] role in [location]? If not you, who’s best to contact? — [Name], [Phone]”

Template 3: Follow-up (after no response)

  • Body: “Circling back, Dr. [Last Name]. If timing’s bad, I can send details and close the loop. Preferred channel: phone or email?”

Ops note: tie each outreach attempt back to refresh_date so you can see whether stale records are dragging down deliverability and connect rates.

Legal and ethical use

Use physician contact data for legitimate recruiting outreach with a clear business purpose. Respect opt-outs immediately, keep suppression lists, and follow applicable privacy and communications laws in the jurisdictions you operate in. If you’re unsure about a specific rule (texting, calling hours, email compliance), get counsel—this article is operational guidance, not legal advice.

Evidence and trust notes

We treat provider identity and contact hygiene as an operations problem: stable keys, clean fields, and logged recency. For how we evaluate data quality and sourcing practices, see our methodology: trust methodology.

External reference: NPI is defined and maintained via the NPPES system: https://nppes.cms.hhs.gov/.

FAQs

What’s the minimum set of columns I need for a clean import?

At minimum: NPI, first_name, last_name, and refresh_date. Then add at least one contact channel (phone_main or email_work) plus source_system for traceability.

Why is NPI the best dedupe key for physicians?

NPI is designed as a unique provider identifier. Phones and emails are attributes that change; NPI is the stable identity anchor for dedupe and record updates.

How should I format phone numbers in the CSV?

Pick one standard and enforce it. E.164 (+1XXXXXXXXXX) is the cleanest for systems that support it. Otherwise use digits-only consistently and keep extensions out of the number field.

What should I do when two rows share the same NPI but different phones/emails?

Keep one provider record (by NPI) and treat phones/emails as updatable attributes. Preserve the most recent refresh_date and store older contact points in notes or secondary fields if your ATS supports it.

How do I avoid breaking my ATS with duplicates on re-import?

Write the rule: NPI is unique. Import updates should match on NPI and update fields without creating a new record. Pilot with 10 rows, confirm behavior, then run the full import.

Next steps

About the Author

Ben Argeband 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’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 LinkedIn.


Access 11m+ Healthcare Candidates Directly Heartbeat Try for free arrow-button