A friend running outbound for a small SaaS company called me last month to vent about Apollo. She'd renewed her seat for the year — $1,200 — and most of the contacts she pulled bounced. Some of the addresses were so old they belonged to people who had quit two jobs ago. She wanted to know if there was a cheaper way.
There is, and it's not particularly clever. Most of the emails she actually needed were already published on the websites of the companies she wanted to reach. The trick is reading those sites at the right scale.
This post is what I told her, written out longer. If you've never built an email list from website data, the workflow is straightforward. If you have, the part worth reading is the section on what you can't get this way.
What you actually need
Three things, in order:
A clear definition of who you want to email. Not "B2B companies" — something narrow enough that you can describe the universe in one sentence. "Dental clinics in the Phoenix metro." "Wedding photographers in Greater Boston." "Independent bookstores in the Pacific Northwest." If you can't draw the boundary, you can't make the list.
A way to find every website inside that boundary. This is the part that's annoying to do by hand and easy to automate. You want one tool that runs a bunch of search queries, deduplicates the results, and tells you which URLs are actual businesses versus blog posts and listicles.
A way to crawl each of those websites and pull out the contacts. Most websites publish phone, email, address, and sometimes a list of staff. A crawler that visits the contact page, the about page, and the team page covers about 90% of what's findable.
That's it. You can do all three with Extractly, or you can build it yourself with a scraping library and an LLM. The tool isn't the interesting part. The process is.
A worked example: Phoenix dentists
Let's run through this for a real query. I picked dental practices in Phoenix because dental websites are unusually well-structured (more on that in the other post).
I typed "dental clinics in Phoenix, Arizona" into the discovery wizard with a target of 500 leads. The tool generated around 30 search queries on its own — variations like "phoenix family dentist," "pediatric dentist phoenix," "emergency dental phoenix," "cosmetic dentistry phoenix." Each one ran against DuckDuckGo, Bing, and Google in parallel.
After deduplication and AI-classification (which filters out Wikipedia, "Top 10" articles, and Yelp category pages but keeps individual business listings), the discovery returned 287 unique practice websites. Not the full 500 — Phoenix simply doesn't have 500 distinct dental practice domains indexed, and that's worth knowing too. We'll come back to this.
Then the crawler visited each of those 287 sites and extracted whatever contact data was published. The full job took about 18 minutes and used 287 credits.
Here's what came back, on average per practice:
| Field | Found |
|---|---|
| Business name | 100% |
| Phone | 99% |
| Address | 97% |
| Office email (info@, contact@, etc.) | 87% |
| At least one named doctor | 76% |
| Specific doctor email (sarah@, dr.patel@) | 38% |
| Services list with prices | 24% |
| Social handles | 64% |
That's not a uniform list of high-quality leads. About 240 of the 287 records have a usable office email. About 105 have a named owner with a likely direct email. The rest are missing one or both — usually because the practice's website is older or smaller, or because they hide their team entirely.
The cost math
Doing this on Extractly's Pro plan costs $29 a month, which covers 1,000 leads. The 287-practice run above cost $0 marginal money since I was already on the plan.
For the same dataset, Apollo's basic seat starts around $99 a month. ZoomInfo's smallest paid plan is $7,500 a year. Both will give you data on Phoenix dentists, but the quality is uneven — partly because their data is months old, partly because for small local businesses they often only have the practice name and the receptionist's number, not the owner.
The honest tradeoff is time. Extractly takes about 20 minutes of your attention to set up and wait for. Apollo lets you download the CSV instantly. For one-off lists you might never repeat, Apollo's convenience wins. For any list you'll need to refresh or expand, the website-extraction approach pays for itself fast.
What you don't get this way
This part matters more than the marketing copy on most of these tools admits.
You won't get personal cell phone numbers. Practices don't publish those, and you shouldn't either. If the dentist's mobile is in Apollo's database, it got there through a CRM leak or a brokered list. Treat the absence of those numbers in your scraped data as a feature, not a bug.
You won't get internal org charts. You'll know who the doctors are and you might know who the office manager is, but you won't know who reports to whom or who controls the supply budget. For most outbound use cases this doesn't matter. For complex enterprise sales it does.
You won't get LinkedIn profiles cross-referenced. Apollo can tell you that Dr. Patel went to ASU dental school and worked at three previous practices. The website usually just says "Dr. Patel, our lead dentist." If LinkedIn context is essential to your pitch, you'll still want a paid tool layered on top.
You won't get every email working. Public-facing business emails get spam, get rotated, get abandoned. Plan for 8-15% bounce on cold runs. Either send through a sequencer that handles bounces gracefully (Smartlead, Instantly), or pre-verify with NeverBounce at $0.008 per check before you send.
The thing that surprised me
When I started doing this seriously, I assumed the bottleneck would be the search engines. It isn't. The bottleneck is geography and indexing.
Phoenix has lots of dental practices, but only about 300 of them have unique websites that show up in search engine results. The rest either don't have websites, or share a website with a larger DSO that owns several locations, or they're so new they haven't been indexed yet. There is no source — paid or free — that can give you 500 distinct Phoenix dental practice websites, because they don't exist in the form you'd want them.
Knowing this changes how you plan campaigns. If you want 1,000 dental contacts, you need to cover several cities, not push harder on one. If you want 1,000 contacts in one city, you need to relax the vertical — restaurants and salons have larger website populations than dentists.
The number you get from this kind of run isn't a measure of the tool. It's a measure of how many people are actually publishing what you're asking for in the territory you've chosen. The fact that paid databases sometimes claim to have 500 in your exact slice tells you they're guessing for the last 200 of those.
How to try this on a vertical you care about
Pick a vertical and a city. Run a discovery on the free tier — 50 leads, no card. See what the funnel looks like for your specific query. The number that comes back will tell you whether the rest of this approach is worth your time.
If the free run delivers 30+ leads with usable contact data, the paid tiers are basically a multiplier. If it delivers 5, your vertical is sparser than you thought and you should reconsider the segment before spending more money.
That's the whole workflow. Not magical, not new, just careful.