Last updated: August 31, 2026

Ben Argeband, Founder & CEO of Heartbeat.ai — practical recipes and checklists for recruiting ops teams who are tired of copy/paste.
What’s on this page:
Who this is for
If you work in recruiting ops, or you’re a recruiter drowning in manual data entry, this playbook is built for you. It focuses on ATS enrichment workflows that cut down admin work, tighten dedupe, and keep outreach consistent across a team.
The goal is straightforward: get usable provider contact data and identifiers into your ATS record automatically, so outreach stays deduped, traceable, and measurable. This guide stays light on code and heavy on workflow fit, with Bullhorn and Apploi examples throughout.
Quick answer
- Core Answer
- Automate Trigger → Enrich → Log → Sequence so provider records get deduped by NPI or license, enriched with contact data, written to consistent fields, then routed to compliant outreach.
- Best For
- Recruiting ops teams and recruiters who want contact data flowing into the ATS without manual lookup work.
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.
The framework: Trigger → Enrich → Log → Sequence
- Trigger: a record is created or updated (candidate/provider/lead).
- Enrich: match the person using stable identifiers (NPI and license matching) and pull contact plus metadata.
- Log: write back to the ATS using a single field map, storing provenance and timestamps.
- Sequence: route to the right outreach motion (email/call/SMS) while honoring consent and opt-out.
Automation removes the copy/paste grind, and consistency is what actually improves outreach performance. The trade-off is discipline: you have to be deliberate about which fields you write, when you refresh them, and how you handle conflicts.
Step-by-step method
Step 1: Define “minimum viable enrichment” (MV-E) fields
Start with the smallest set of fields that changes recruiter behavior. Enrich 40 fields and recruiters only touch six of them, and you’ve created noise that breaks downstream reporting instead of fixing anything.
- Identifiers: NPI, license state, license number (or license ID), specialty taxonomy if available.
- Contact: best email, best mobile, best direct line if available.
- Provenance: enrichment source, last verified date, enrichment run ID.
- Compliance: consent status if tracked, opt-out flag, do-not-contact reason.
Step 2: Dedupe first (identifier-led), then enrich
In healthcare recruiting, names collide constantly — common surnames, shared specialties, overlapping geographies. Dedupe has to be identifier-led, not name-led.
Dedupe definition: dedupe is the process of determining whether two records represent the same person, then merging or linking them to avoid duplicate outreach and reporting distortion.
- Exact NPI match — best when the identifier is present.
- License match: license state plus license number (or state license ID).
- Fallback: name plus specialty plus geography — review-only, never auto-merge.
If you can’t confidently match, route the record to a review queue instead of writing questionable data into it.
Step 3: Choose stable triggers (and prevent loops)
- New record created: best for inbound leads and uploads.
- Record updated: run only when a recruiter adds NPI or license fields.
- Scheduled refresh: run nightly or weekly for records touched recently.
Loop protection matters here: don’t let your automation re-trigger itself when it writes back enrichment fields. Use a dedicated “Enrichment_Run_ID” and ignore updates where only enrichment fields changed.
Step 4: Implement the enrichment action (Zapier, Make, or API)
Pick the tool that matches your volume and branching needs:
- Zapier: fastest to ship, good for simple triggers and field updates.
- Make: better for branching logic, batching, and error handling.
- API: best when you need control, volume, or custom matching logic. Heartbeat has an API reference if you’re going that route.
Regardless of tool, the action should send identifiers (NPI/license) and receive contact fields plus metadata — verification timestamps, source tags — then return a status you can log: matched, partial, needs review, or no match.
Heartbeat.ai workflow note: for calling motions, Heartbeat.ai can support teams that want ranked mobile numbers by answer probability, so recruiters spend dial time where humans are more likely to pick up.
Step 5: Log back with a single ATS_FIELD_MAP
This is where most workflows break down — teams enrich data but don’t land it consistently. Use one field map that every workflow references, and define write rules so you don’t overwrite recruiter-sourced data by accident.
Governance note: version your ATS_FIELD_MAP (v1, v2, v3). When you change a field name or write rule, update the automation and the recruiter-facing SOP at the same time so reporting doesn’t drift out from under you.
ATS_FIELD_MAP worksheet (minimum viable enrichment)
| Enrichment Output | ATS Target Field | Type | Write Rule | Notes |
|---|---|---|---|---|
| NPI | Candidate.NPI (custom) | Text | Write if blank; never overwrite unless recruiter confirms | Primary dedupe key |
| License State | Candidate.License_State | Picklist/Text | Write if blank; else append to multi-state field | Supports license matching |
| License Number/ID | Candidate.License_Number | Text | Write if blank; else route to review | Do not auto-overwrite |
| Best Email | Candidate.Email | Write if blank; else write to Candidate.Alt_Email | Store deliverability outcomes later | |
| Best Mobile | Candidate.Mobile | Phone | Write if blank; else write to Candidate.Alt_Mobile | Preserve recruiter-sourced numbers |
| Opt-out Flag | Candidate.Do_Not_Contact | Boolean | Always write true if returned; never auto-clear | Suppress across channels |
| Last Verified Date | Candidate.Enrichment_Last_Verified | Date | Always write | Used for refresh cadence |
| Enrichment Source | Candidate.Enrichment_Source | Text | Always write | Audit trail |
| Enrichment Run ID | Candidate.Enrichment_Run_ID | Text | Always write | Debugging + rollback |
| Enrichment Status | Candidate.Enrichment_Status | Picklist/Text | Always write | matched / partial / review / no match |
Step 6: Route to the right outreach motion (Sequence)
Once the record is enriched, route based on what you actually got back:
- Matched + mobile present: create a call task and, if you use SMS, confirm consent is recorded before texting.
- Matched + email present: enroll in an email sequence with suppression rules attached.
- Needs review: assign to a recruiter or ops queue with match candidates attached.
- No match: request missing identifiers from the recruiter or candidate rather than forcing outreach on weak data.
Make consent and opt-out first-class fields, not something buried in a notes box. If someone opts out, suppress them everywhere, not just in the channel where they asked.
Suppression rules (email + phone)
- Opt-out: if Candidate.Do_Not_Contact is true, suppress email, call tasks, and SMS enrollment. Never auto-clear this flag.
- Email bounces: if an email bounces, stop emailing that address and write the bounce outcome back to the record so another recruiter doesn’t retry it blind.
- Channel gating: only enable SMS when consent is recorded for that specific channel; otherwise route to call or email instead.
- Global suppression: keep one suppression field that every downstream sequence respects, even across multiple tools.
Step 7: Add refresh cadence without creating churn
Contact data decays over time. Refresh should track pipeline speed, not run on a blanket schedule:
- Active pipeline (submitted/interviewing): refresh more frequently.
- Warm pool (touched recently): refresh on a steady schedule.
- Cold records: refresh only when reactivated.
Automate refresh using Candidate.Enrichment_Last_Verified plus a “last activity date” so you’re not burning cycles on records nobody is actually working.
Implementation notes: error handling and auditability
Build for the failure modes you’ll actually see — timeouts, partial matches, write-back conflicts.
- Retries: retry transient failures, but cap attempts and log the final status.
- Dead-letter queue: route failed runs to an ops queue with the record ID and error message attached.
- Conflict handling: if enriched data conflicts with recruiter-entered data, write to alternate fields and flag for review instead of overwriting.
For general automation patterns and troubleshooting, reference Zapier learning resources and Make help documentation.
Edge case: multi-state licenses and conflicting identifiers
Providers often hold multiple licenses. If your ATS only supports one license field, you’ll create false conflicts where none exist.
- Rule: store a primary license (state + number) in the main fields, and store additional licenses in a multi-value custom field or notes with a structured format.
- Conflict rule: if NPI matches but license differs, don’t overwrite — set Enrichment_Status to “review” and assign to ops.
- Outreach rule: route outreach based on the license state relevant to the job location, not simply the first license on file.
Step 8: Bullhorn use case
Goal: when a recruiter creates or updates a candidate in Bullhorn with NPI or license info, enrich and write back contact plus provenance fields.
- Trigger: Bullhorn candidate created/updated, via your automation tool’s connector or webhook.
- Filter: run only if Candidate.NPI is present OR (License_State AND License_Number present).
- Enrich: call Heartbeat.ai (or your enrichment step) with identifiers.
- Log: update Bullhorn candidate fields per ATS_FIELD_MAP.
- Sequence: create tasks (call/email) and apply suppression if opt-out is true.
If you’re starting from a spreadsheet or sourced list, use upload a file to standardize inputs before pushing records into Bullhorn.
Step 9: Apploi use case (high-volume applicant flow)
Goal: enrich applicants as they enter Apploi so recruiters aren’t chasing missing phone/email numbers, and duplicates don’t get contacted twice.
- Trigger: new applicant created in Apploi.
- Dedupe: check for an existing record by NPI/license matching; if there’s a match, link or flag it instead of creating a second outreach path.
- Enrich: pull best contact plus verification timestamps.
- Log: write back to Apploi custom fields, or notes and tags if fields are limited.
- Sequence: route to the right recruiter or team based on specialty/location and contact completeness.
For a deeper enrichment motion, see physician contact enrichment for how to structure verification and suppression.
Diagnostic table
| Symptom | Likely Cause | Fast Test | Fix (workflow-level) |
|---|---|---|---|
| Duplicates getting contacted twice | No identifier-led dedupe; name-based matching | Sample recent records; check whether the same NPI/license appears on multiple active records | Make NPI/license matching the first gate; route uncertain matches to review |
| Recruiters don’t trust enriched fields | No provenance/verification date stored | Check whether records show last verified date + source | Write Enrichment_Source + Enrichment_Last_Verified every run |
| Automation keeps re-triggering itself | Trigger fires on any update, including your write-back | Look for repeated run IDs on the same record within a short window | Add loop protection: ignore updates where only enrichment fields changed |
| Email outreach underperforms | Stale emails; no suppression; no deliverability tracking | Track bounces and replies by enrichment source | Refresh cadence + suppression rules; log outcomes back to the record |
| Call blocks are wasted | Bad numbers or wrong channel for that candidate | Compare connected calls vs total dials by source | Prioritize verified mobiles; create a “review” queue for weak matches |
Weighted checklist
Use this to score whether your workflow is ready to ship. Total 100 points.
- (20) Trigger is stable (new/updated record) and has loop protection
- (20) Dedupe uses NPI and/or license matching before enrichment writes
- (15) ATS_FIELD_MAP is documented and enforced (MV-E fields only)
- (10) Provenance stored: Enrichment_Source + Enrichment_Last_Verified + Run ID
- (10) Consent and opt-out are first-class fields; opt-out suppresses all sequences
- (10) Refresh cadence is automated based on last verified date and pipeline activity
- (10) Error handling exists: retries, dead-letter queue, and a manual review path
- (5) Reporting plan exists (connect/reply/deliverability tracked by source)
Outreach templates
These templates assume your enrichment writes back consistent fields and that you honor consent and opt-out. Customize to your brand.
Template 1: Email (first touch)
Subject: Quick question about your next role
Hi {{FirstName}} — I’m reaching out about a {{Role}} opportunity in {{Location}}. If you’re open to a quick call, what’s the best number and time window for you?
If you’d rather not hear from me, reply “opt out” and I’ll suppress future messages.
— {{RecruiterName}}
Template 2: Call task note (for recruiter workflow)
Call prep: Confirm specialty and current setting. If voicemail, leave a short message and follow with the email above. Log outcome and update opt-out if requested.
Template 3: SMS (only if you have consent)
Hi {{FirstName}} — this is {{RecruiterName}}. Are you open to a quick call about a {{Role}} role in {{Location}}? Reply STOP to opt out.
Common pitfalls
- Random field write-back: if recruiters can’t find data in the same place every time, they won’t use it. Fix with a documented ATS_FIELD_MAP.
- Overwriting recruiter-sourced contact info: preserve what your team sourced manually; write enriched values into alternate fields when there’s a conflict.
- No suppression discipline: if opt-out isn’t propagated across email, call, and SMS, you create compliance risk and brand damage.
- Refreshing everything: refresh cadence should follow pipeline activity. Refreshing cold records wastes budget and creates unnecessary churn.
- Measuring the wrong thing: “more enriched records” isn’t the goal — faster, cleaner outreach is.
How to improve results
Instrument the workflow so ops can debug fast
Add these fields (or equivalents) to every enriched record:
- Enrichment_Run_ID
- Enrichment_Last_Verified
- Enrichment_Source
- Enrichment_Status (matched / partial / review / no match)
Use canonical metric definitions so reporting stays consistent
Deliverability Rate = delivered emails / sent emails (per 100 sent emails).
Bounce Rate = bounced emails / sent emails (per 100 sent emails).
Reply Rate = replies / delivered emails (per 100 delivered emails).
Connect Rate = connected calls / total dials (per 100 dials).
Answer Rate = human answers / connected calls (per 100 connected calls).
Log outreach outcomes back to the record so you can route better
Store outcomes in consistent fields so you can segment by enrichment source and status later.
| Outcome | Suggested ATS Field | Write Rule | Why it matters |
|---|---|---|---|
| Email delivered | Candidate.Email_Delivered (boolean) + Candidate.Email_Last_Delivered_Date | Write on send result | Supports Deliverability Rate by source |
| Email bounced | Candidate.Email_Bounced (boolean) + Candidate.Email_Bounce_Reason | Write true on bounce; do not auto-clear | Prevents repeated bounces and protects sender reputation |
| Email reply | Candidate.Email_Replied (boolean) + Candidate.Email_Last_Reply_Date | Write on reply detection | Supports Reply Rate and routing to recruiter follow-up |
| Call connected | Candidate.Call_Connected (boolean) + Candidate.Call_Last_Connected_Date | Write on call disposition | Supports Connect Rate by source |
| Human answered | Candidate.Call_Human_Answered (boolean) + Candidate.Call_Last_Answered_Date | Write on call disposition | Supports Answer Rate and call-window optimization |
| Opt-out received | Candidate.Do_Not_Contact (boolean) + Candidate.Do_Not_Contact_Reason | Always write true; never auto-clear | Compliance and suppression across tools |
Define automation ROI the same way every time
Automation ROI definition: the value created by automation (time saved, increased throughput, reduced rework, improved outreach outcomes) minus the total cost to run it (tools, data, ops time), measured over a consistent period.
Measure this by tracking (a) minutes of manual admin removed per record, (b) duplicate-contact incidents avoided, and (c) outreach outcomes by enrichment source (deliverability, replies, connects). Convert time saved into capacity — more reqs per recruiter — without claiming guaranteed time savings.
Improve match confidence before you enrich
- Make NPI and license fields required for the pipelines where you can reasonably collect them.
- Standardize license state abbreviations.
- Normalize phone formats and email casing before write-back.
Legal and ethical use
- Consent: if you text, make sure you have appropriate consent for that channel. Store consent status in a structured field.
- Opt-out: treat opt-out as global suppression across channels. Never auto-clear an opt-out flag.
- Data minimization: store what you need for recruiting workflow and compliance auditing, not everything you can collect.
- Auditability: keep provenance (source, last verified date, run ID) so you can answer “where did this come from?” quickly.
Heartbeat.ai does not provide legal counsel. If you operate across jurisdictions, get your compliance team to sign off on your outreach and retention policies.
Evidence and trust notes
Workflows should be auditable, reversible, and measurable. For how we think about data quality, verification, and responsible use, see our trust methodology.
The branching, retries, and scenario patterns referenced in this playbook align with baseline guidance in the automation docs below:
If you’re deciding between approaches, use this sibling guide: extension vs API vs file upload for automation.
FAQs
What are ATS enrichment workflows in healthcare recruiting?
They’re automations that take a new or updated provider/candidate record, match it using identifiers like NPI or license, add contact fields plus provenance, and then route the record into compliant outreach.
What should I use for dedupe: NPI or license?
Use NPI when available because it’s stable and unique. Use license matching (state + license number/ID) as a strong secondary key. Name-based matching should be review-only.
How do I avoid overwriting recruiter-sourced data?
Set write rules in your ATS_FIELD_MAP: write into primary fields only when blank; otherwise write to alternate fields and route conflicts to a review queue.
How do I set a refresh cadence without spamming my database?
Refresh based on last verified date and pipeline activity. Active records refresh on your chosen schedule; inactive records refresh only when reactivated.
What should I track to know if enrichment is working?
Track deliverability, replies, and call outcomes by enrichment source and by enrichment status. Also track duplicate-contact incidents and the share of records with complete MV-E fields.
Next steps
- If you want to test quickly, start free search & preview data.
- If you’re building workflows now, decide whether you’ll run through Zapier/Make or go direct via the Heartbeat API.
- If you’re importing from spreadsheets or sourced lists, standardize inputs first with file upload for enrichment.
Operational rule: ship the smallest workflow that writes consistent fields, logs provenance, and respects consent/opt-out. Then iterate based on measured outcomes.
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.