Client Success
The machine that carries ReadTomato from ~20 to 200 clients with four human touchpoints — everything else is automation, Malcolm, and self-serve. Assigned at Band Camp Jun 24 · verified against Drive SOPs & onboarding transcripts Jul 14.
The Four Human Gates
🤝 Sales call
›
🎉 Welcome Party
›
🎙️ HTE interviews
›
🛟 Save-the-deal
— everything between is automation + Malcolm + self-serve, with backflows: referrals feed sales, saves rejoin the loop, escapes grow the machine.
Targets Once Live
< 1h
First response (Malcolm)
≥ 80%
Resolved without a human
1 : 60
Clients per CSM (AI-leveraged)
⏳ Decisions waiting on Marshall
- Volume forecast — monthly onboarding numbers Q3–Q4
- Ratio target — 1:60 AI-leveraged vs 1:40 high-touch
- The CS Lead — formal offer to Ashley, or external hire
- Backup content policy — one per quarter as courtesy
- Partner-delivered CS — do 25%-tier clients live inside the machine
- Save budget — CSM's per-account discretionary ceiling
🗺️ Rollout
Days 1–30 — decisions locked · FAQ box into Malcolm · Welcome Party piloted · manual health list starts
Days 31–60 — engagement tracking · chase sequences · first monthly CS report · guide library 1–6
Days 61–90 — health dashboard live · save playbook exercised · deflection ≥70% · ratio reviewed against real volume
📥 Intake responses — interviewers & sales, due one week from send
Rob — pending
Jody — pending
Marshall — pending
Jim — pending
Sherry — pending
Update these by hand for now — the tracker automates when the CS build starts (Phase A).
Dental Lead Generation Pipeline
Zero-cost strategy · 14 US cities · Built June 2026 · Due June 30
Lemlist Export4,981 contacts
+
NPPES DownloadAll US dentists, free
↓
Phase 1verify_npi.py
→
Phase 2find_websites.py
→
Phase 3find_emails.py
→
Masterlistbuild_masterlist.py
Before You Run Anything — Two Setup Steps
This is the US registry of every licensed dentist. It's a free download from the Centers for Medicare & Medicaid Services. About 500MB zipped.
Go to this URL → download "Full Replacement Monthly File" → unzip it → save the big CSV as:
data/nppes_full.csv inside the marketing-platform folder
https://download.cms.gov/nppes/NPI_Files.html
The ZIP extracts to ~6GB. That's normal — it has every healthcare provider in the US. The script filters it down to dentists in your 14 cities.
Save the 4,981 contacts you already scraped from Lemlist as a CSV file. Name it:
data/lemlist_export.csv
The script auto-detects column names — whatever Lemlist exports (First Name, Last Name, LinkedIn URL, City, State) it will pick up correctly.
First check: open the file and count the rows for Sarasota. If Sarasota only has 100 rows instead of 178, Lemlist's "select all" only got the first page. You'll need to re-export page by page for any city that looks capped at exactly 100.
Phase 1 — Verify Every Contact Against NPPES
Reads the NPPES file (~6GB) and extracts every licensed dentist in your 14 cities. Then fuzzy-matches them against your Lemlist export by name. Any contact that matches gets a "NPI Verified" flag — meaning they're a real, licensed practitioner.
What it produces
- Every licensed dentist in all 14 cities (from NPPES) — even ones Lemlist missed
- NPI number, specialty, practice address, phone number — straight from the government
- LinkedIn URL merged in where names match your Lemlist data
- Output: data/masterlist_phase1.csv
Run command
cd /home/gly/projects/marketing-platform
venv/bin/python verify_npi.py \
--nppes=data/nppes_full.csv \
--lemlist=data/lemlist_export.csv
Test run first (fast — stops at 500K rows)
venv/bin/python verify_npi.py \
--nppes=data/nppes_full.csv \
--lemlist=data/lemlist_export.csv \
--dry-run
Takes 60–90 seconds on the full file. Normal — it's scanning millions of healthcare records to pull out your 14 cities.
Phase 2 — Find Every Practice Website
For each verified dentist, searches DuckDuckGo using their name + city to find their practice website. No API key needed. The website domain is what we need to find their email in Phase 3.
How it searches
- "Dr. Smith" dentist Sarasota FL → DuckDuckGo → finds drsmithdental.com
- Also tries phone number search → often surfaces Google Maps listing with website
- Skips directories (Yelp, Healthgrades, ZocDoc) — we want the practice's own domain
- Output: data/masterlist_phase2.csv
Run command
venv/bin/python find_websites.py \
--input=data/masterlist_phase1.csv
Test on one city first
venv/bin/python find_websites.py \
--input=data/masterlist_phase1.csv \
--city=Sarasota \
--limit=20
Runs at 2 seconds per contact to be respectful. For 5,000 contacts this takes a few hours — run it overnight or use --limit to do it in batches. Use --resume to pick up where you left off.
Phase 3 — The Email Hack
This is the core of the strategy. For every dentist with a practice website, it tries four methods in order to find their email address. Zero paid tools required.
Method 1 — Scrape the Contact Page (confidence: 90–95%)
Goes to the practice website's contact page and looks for:
- mailto: links in the HTML (e.g. <a href="mailto:info@drsmithdental.com">)
- Plain email addresses visible in the page text
- Checks: homepage, /contact, /contact-us, /about, /about-us
Method 2 — Email Pattern Prediction (confidence: 40–80%)
Generates every plausible email pattern for the domain and optionally verifies via SMTP (checks if the mailbox exists without sending anything):
- info@domain.com — most common for dental practices
- contact@domain.com, office@domain.com, appointments@domain.com
- dr.smith@domain.com — solo practitioners
- jsmith@domain.com, john.smith@domain.com, john@domain.com
Method 3 — Footprint Search (confidence: 70%)
- Searches DuckDuckGo for: site:drsmithdental.com email
- Also searches for: "@drsmithdental.com" across the web
- Catches emails published in directories, review sites, and PDF documents
Method 4 — SMTP Verify (optional — confirms pattern emails)
- Pings the mail server directly using SMTP RCPT TO command
- Server responds whether the mailbox exists — no message is sent
- ~70% of servers allow this check. Not 100% but raises confidence from 40% to 80%
Run commands
# Basic (scrape + pattern — no SMTP verify, faster)
venv/bin/python find_emails.py --input=data/masterlist_phase2.csv
# With SMTP verification (slower, higher confidence on pattern emails)
venv/bin/python find_emails.py --input=data/masterlist_phase2.csv --verify
# Test on Sarasota only
venv/bin/python find_emails.py --input=data/masterlist_phase2.csv --city=Sarasota --limit=20
Output: data/masterlist_phase3.csv — every contact now has an email field, email source (scraped/pattern/footprint), and confidence score 0–100.
Phase 4 — Build the Campaign-Ready Masterlist
Takes all verified data and scores every contact. Assigns a tier for campaign sequencing. Exports the final CSV with all columns Hey Gen and Lemlist need.
Contact Tiers
| Tier | What it means | Action |
| A |
NPI verified + scraped/confirmed email + phone |
Send immediately — highest priority for Hey Gen batch video |
| B |
NPI verified + pattern email (unverified) + phone |
Send with Lemlist warm-up — good volume, small bounce risk |
| C |
NPI verified + LinkedIn URL, no email |
Enrichment queue — use Apollo.io (50 free/mo) or Hunter.io (25 free/mo) |
| D |
Name + phone only — no email, no LinkedIn |
Low priority — manual verify or skip |
Run commands
# Export Tier A + B only (campaign ready)
venv/bin/python build_masterlist.py \
--input=data/masterlist_phase3.csv \
--tier=A,B
# Stats only — see breakdown without writing file
venv/bin/python build_masterlist.py \
--input=data/masterlist_phase3.csv \
--stats
Output: data/MASTERLIST_FINAL.csv — this is what you upload to Hey Gen and Lemlist. Also creates city-split files under data/by_city/ so you can upload Sarasota, Jacksonville, etc. separately.
What to Tell Marshall
The 100,000 number is not achievable for private practice owners specifically. The addressable pool of licensed, privately-owned dental practices across these 14 cities is 10,000–18,000.
What we are building delivers a smaller, verified list — every contact is a confirmed licensed practitioner with a real email address and phone number. A 15,000-person list where every contact is a confirmed practice owner will outperform 100,000 unverified names every time for Hey Gen batch videos.
Before spending any money — the NPPES file is free and gives us phone numbers for every dentist. Website scraping is free. The only cost question is email enrichment for Tier C contacts (Apollo.io free tier: 50/mo, Hunter.io free tier: 25/mo).
Current Status Checklist
-
✓
Lemlist manual export done — 4,981 contacts across 14 cities scraped from Jim's Lemlist account. Saved in Google Sheet.
-
✓
sync_lemlist_dental.py built — API automation script exists but requires Lemlist Enterprise plan ($39 plan blocked). Script is committed for future use.
-
✓
verify_npi.py built — Phase 1 script ready. Waiting on NPPES file download.
-
✓
find_websites.py built — Phase 2 script ready. Runs after Phase 1.
-
✓
find_emails.py built — Phase 3 script ready. 4-method email discovery.
-
✓
build_masterlist.py built — Final scoring + tiering + CSV export ready.
-
Download NPPES file — Go to download.cms.gov/nppes/NPI_Files.html → Full Replacement Monthly File → save as data/nppes_full.csv
-
Export Lemlist list as CSV — Download from Google Sheet or Lemlist → save as data/lemlist_export.csv. Check Sarasota tab: should be 178 rows, not 100.
-
Run Phase 1 — verify_npi.py — confirms real licensed practitioners, adds phone numbers
-
Run Phase 2 — find_websites.py — discovers practice domains
-
Run Phase 3 — find_emails.py — extracts emails from websites + patterns
-
Run Phase 4 — build_masterlist.py — score, tier, export final CSV
-
Deliver to Marshall — Final CSV with Tier A+B contacts uploaded to Hey Gen. Share count and breakdown. Due June 30.
14 Target Cities
| City | State | Lemlist Location Format | Lemlist Contacts |
| Sarasota | FL | Sarasota, Sarasota County, Florida, United States | 178 |
| Jacksonville | FL | Jacksonville, Duval County, Florida, United States | ~varies |
| Raleigh | NC | Raleigh, Wake County, North Carolina, United States | ~varies |
| Charleston | SC | Charleston, Charleston County, South Carolina, United States | ~varies |
| Dallas | TX | Dallas County, Texas, United States | ~varies |
| San Antonio | TX | San Antonio, Bexar County, Texas, United States | ~varies |
| Phoenix | AZ | Phoenix, Maricopa County, Arizona, United States | ~varies |
| Scottsdale | AZ | Scottsdale, Maricopa County, Arizona, United States | ~varies |
| San Diego | CA | San Diego, San Diego County, California, United States | ~varies |
| Sacramento | CA | Sacramento, Sacramento County, California, United States | ~varies |
| Seattle | WA | Seattle, King County, Washington, United States | ~varies |
| Portland | OR | Portland, Multnomah County, Oregon, United States | ~varies |
| Nashville | TN | Nashville, Davidson County, Tennessee, United States | ~varies |
| Denver | CO | Denver, Denver County, Colorado, United States | ~varies |
Email Patterns the Script Tries
Generic practice emails (tried first — most common)
info@domain.com
contact@domain.com
office@domain.com
appointments@domain.com
reception@domain.com
frontdesk@domain.com
hello@domain.com
admin@domain.com
Doctor-specific patterns
dr.smith@domain.com
drsmith@domain.com
dr.john@domain.com
Personal name patterns
john@domain.com
smith@domain.com
johnsmith@domain.com
john.smith@domain.com
jsmith@domain.com
j.smith@domain.com
Vendor Research Note (Jim's research doc, June 2026)
| Platform | Score | Best For | Cost | Decision |
| OpenMart AI | 92/100 | Local SEO lead discovery — 200M+ local profiles, intent-based natural language search |
$105–149/mo (5K credits) |
Skip for now — use NPPES free first |
| Lemlist | 90/100 | Outbound campaign execution |
$55–109/user/mo |
Already have Jim's account |
| AI Ark | 88/100 | High-volume B2B data, real-time verification |
$27/mo (5K credits) |
Pilot if NPPES volume is not enough |
Recommendation from Jim's research: OpenMart (discovery) + Lemlist (outreach). Our approach achieves the same with zero cost using NPPES + website scraping. If email yield is below 50% after Phase 3, revisit AI Ark at $27/mo.