DEV Community

Delta Tools
Delta Tools

Posted on

How to Find Business Email Contacts Without Buying a Giant Database

How to Find Business Email Contacts Without Buying a Giant Database

TL;DR: You do not need to buy ten thousand stale addresses to reach fifty right companies. Build the list from the companies themselves. Pick a tight niche, visit each company website, check the contact page and the about page and the team page and the page footer, and record only the email addresses the company itself published. Save the exact page where you found each address, check that the domain still has mail set up, and throw away anything that looks like a placeholder. That manual pass gives you a short list you can defend line by line. If the same pass needs to happen for hundreds of domains, the Fresh Email Finder from Delta Tools does that crawl for you. It visits live company sites, pulls the published addresses, checks the mail records for each domain, and returns every address with the page it came from, at $0.005 for each verified address found.

I have bought the giant list before. Everybody I know who does outreach has. Mine arrived as a spreadsheet with thousands of rows and a feeling of instant progress. Then the real work started. A large share of the addresses bounced. Several contacts had left their companies months or years earlier. One memorable row named a chief executive who had retired before my own kid started school. The list was not lying exactly. It was just old, and it had been old on the day I paid for it, because a database that covers everyone gets refreshed for no one in particular.

What I needed was never volume. I needed thirty or forty current contacts in one niche, people at companies I could describe in one sentence, with addresses those companies were still publishing themselves. That is a completely different job from buying a database. It is smaller, slower at the start, and far more useful at the end. This article teaches that job properly, first by hand, then with a small script, and only then with the tool we built for the repetitive part.

One quick pointer before the manual method, because some readers came here for exactly this: if your list is already past the size where clicking through sites one by one makes sense, the Fresh Email Finder on Apify runs the website pass described below across a batch of domains and hands you the addresses with their source pages attached. Keep reading either way. Knowing how the manual pass works is how you judge whether any list, bought or built or scraped, is worth trusting.

Why giant databases go stale so fast

An email address is a claim about the present. It says this person or this team can be reached at this company today. Databases decay because companies refuse to hold still for them. People change jobs. Companies rename. Domains expire and get parked. A contact page gets redesigned and the old address quietly stops being the published one. Industry measurements of business data decay usually land around a quarter to a third of records going wrong each year, and my own bought list behaved exactly like that math said it would.

There is a second problem, and it is quieter. A giant database rarely tells you where an address came from. You get the address and a pile of confidence you did not earn. When a message bounces, you cannot tell whether the person left, the domain died, or the address was guessed by a pattern engine in the first place. A list you build from live company sites carries its own receipts. Every row points at a page you can reopen today. If the page changed, you learn something true. If the page still shows the address, you know why you believe it.

And there is a third problem that matters more than both. A list of ten thousand strangers invites spray. A list of forty companies you chose on purpose invites an actual sentence about why you are writing. In my experience the second list wins on replies, on dignity, and on not training yourself to sound like a bulk mail program.

What a good small list looks like

Forget fields you will never use. For each contact, keep exactly what you need to write a relevant message and to prove the row is fresh.

Company and domain. The business name and the bare website domain, like a local roaster or a regional accounting firm, written the way the company writes it.

Published email address. Only an address the company itself put on its own site. Not a guess built from a name pattern. Not an address copied from another database. If the company published it, you can cite the page.

Source page. The full address of the page where the email appears. Contact page, team page, press page, it does not matter. What matters is that you can click it next month and check again in seconds.

Who it likely reaches. A named person if the page names one. A team if the address is a team address, like a studio inbox or a sales inbox. Write down what the page says, not what you hope.

Date checked. The day you saw it live. Freshness you cannot date is just optimism.

One relevance note. A single plain sentence about why this company belongs on your list. A service they offer. A location they cover. A product line you actually looked at. That sentence does more for your reply rate than any clever subject line I have ever written.

If a row cannot carry those fields, it does not belong on the list yet. That one rule kills most of the junk that makes bought lists feel haunted.

The manual method, step by step

This is the whole job by hand. It works with a browser and a spreadsheet, it costs nothing, and for a list under about fifty companies it is honestly hard to beat.

Step 1: Define the niche so tightly it feels a little embarrassing.
Write the target in one sentence with a trade, a place or a clear category, and a size signal if you have one. Independent bookstores in New England. Wedding venues within driving distance of Austin. Small manufacturers that sell replacement parts online. The tighter the sentence, the easier every later decision gets. Companies are either plainly in or plainly out, and your relevance notes almost write themselves because you already know what these businesses share.

Step 2: Build the company list before you hunt for any email.
Resist the urge to collect addresses as you go. First collect companies. Trade association member directories are gold here, because membership itself is a relevance signal. So are local chamber listings, conference exhibitor lists, market and fair vendor pages, and the results pages of the search you would run if you were a customer. Aim for a company list about twice the size of the contact list you want. Some sites will publish no address at all, and that is fine. They have told you how they prefer to be reached.

Step 3: Visit each site and check the pages in a fixed order.
Consistency is what makes a manual pass trustworthy instead of vibes. I check in this order, every time. First the contact page, because most small companies put a real inbox there. Second the about page and any team or staff page, because named people with named addresses live there, especially at professional firms. Third the page footer, because plenty of sites print a general address at the bottom of every page where nobody thinks to look. Fourth any press or wholesale or partnerships page, because businesses that want a particular kind of inquiry often publish a particular address for it. A surprising number of good contacts sit on that fourth page, put there on purpose for people exactly like you.

Step 4: Record only what the company published.
When you find an address, paste it into your sheet with its source page the moment you see it. Do not keep a mental note. Mental notes are where source pages go to die. If a site shows a form and no address, record the form and move on. Do not invent an address from a name you saw on the team page. A constructed guess might occasionally land, but it is not a published contact, it bounces at the rates that made you hate bought lists, and it can put mail into the inbox of a stranger with a similar name at the same company. The discipline of this method is the entire point of this method.

Step 5: Sort named addresses ahead of general ones, but respect both.
A named person at a small company usually gives you the best conversation. A general inbox at a small company is often read by exactly one person anyway, and that person is frequently the owner. What I avoid is treating a general address at a large company as if it were a person. Match your message to what the address actually is.

Step 6: Check that each domain can receive mail at all.
A published address on a live page is a strong signal, but domains do get abandoned. The quick check is the MX record, which is the public mail routing record for a domain. Open a free MX lookup tool, type the domain, and confirm that at least one mail server answers. No MX record usually means the domain takes no mail and the address is a dead end no matter how fresh the page looks. This takes seconds per domain and it removes a whole category of bounce before you ever send anything.

Step 7: Read the list once like a skeptic.
Before you call it done, scan for placeholders and junk that pages carry. Addresses containing the words example or yourname or domain dot com are template text, not contacts. Addresses glued to image file names in page code are usually asset labels. Very old press addresses sometimes survive on archived pages long after a redesign. Ten skeptical minutes here save you the embarrassment of writing a warm personal note to a template.

That is the method. Done carefully, fifty companies take an afternoon, and you end with a list where every single row can answer the question, why do I believe this address is real and current. Almost no bought list survives that question.

The same pass as a small script

Once the manual order of pages is in your hands, the crawling part is easy to hand to a script. This one uses only the Python standard library. Give it domains, and it fetches the home page plus the usual contact and about and team paths, pulls out published addresses with a pattern match, drops obvious placeholders, and writes a spreadsheet ready file with the source page kept for every address.

import csv
import re
import urllib.request

DOMAINS = [
    "example.com",
    "example.org",
]

PATHS = ["", "/contact", "/contact-us", "/about", "/about-us", "/team"]

EMAIL_RE = re.compile(r"[A-Za-z0-9._%+]+@[A-Za-z0-9.]+\.[A-Za-z]{2,}")
JUNK_WORDS = ("example", "yourname", "yourdomain", "domain.com", "sentry", "wixpress")
JUNK_ENDINGS = (".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp")


def fetch(url):
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0 contact list builder"})
    with urllib.request.urlopen(req, timeout=30) as resp:
        return resp.read().decode("utf-8", errors="replace")


def looks_real(address):
    low = address.lower()
    if any(word in low for word in JUNK_WORDS):
        return False
    if low.endswith(JUNK_ENDINGS):
        return False
    return True


def main():
    seen = {}
    for domain in DOMAINS:
        for path in PATHS:
            url = "https://" + domain + path
            try:
                html = fetch(url)
            except Exception as exc:
                print("SKIP", url, exc)
                continue
            for match in EMAIL_RE.findall(html):
                address = match.strip(".,;:()<>").lower()
                if address not in seen and looks_real(address):
                    seen[address] = url
    with open("contacts.csv", "w", newline="") as fh:
        writer = csv.writer(fh)
        writer.writerow(["email", "source_page"])
        for address, source in sorted(seen.items()):
            writer.writerow([address, source])
    print("Wrote", len(seen), "published addresses to contacts.csv")


if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

Run it once and then do the two things the script cannot do for you. First, open a few source pages by eye and confirm the addresses sit on the page the way you expect. Scripts are confident even when a site does something strange, and your eyes are the audit. Second, run the MX check from Step 6 on each new domain before those rows join your real list. The script finds what companies publish. The mail check tells you the domain is still listening.

Be a polite guest while you run it. A handful of page fetches per company, once, is a lighter footprint than a normal human visit with a browser loading every image and script. Do not loop it hourly. Do not point it at sites that block you. A blocked response is an answer, and the respectful move is to visit that site by hand or leave it off the list. Also read each address in context before you write to it. An address published for press inquiries is an invitation to press, not to a sales pitch, and using published contacts for the purpose they were published for is both better manners and better business.

If the script version already feels like enough machinery, you have found your level and you should stop there happily. The manual method plus this script covers most small operators completely. The tool in the next section exists for one specific moment, which is when the company list stops being fifty and starts being five hundred, and the afternoon pass becomes a week.

Where the manual pass starts to break

Time is the obvious crack. At three to five minutes a company, which is a fair pace when pages hide their addresses in footers and subpages, one hundred companies eat most of a working day. Five hundred companies eat the week, and by the end of that week the earliest rows are already a week old. Nothing about the method got worse. It just does not scale past the size where one careful person can hold it.

Consistency is the second crack. On company ten you check four pages in order. On company ninety you check the contact page, feel done, and move on. The addresses you miss that way are not random. They are exactly the wholesale and partnership addresses that live on the fourth page, often the most valuable rows on the whole list.

That is the gap the Fresh Email Finder was built to close. You give it company domains. It crawls each live website the same way the script above does, across the home page and the contact and about and team pages, extracts the addresses the company published, filters out the placeholders and disposable junk, checks the mail records for each domain, and returns each verified address together with the source pages it was found on. The output reads like the spreadsheet from the manual method, because it is the manual method, run patiently at machine pace. You pay $0.005 for each verified address it finds and nothing as a flat run fee, so a batch of domains that publishes very little costs very little. The receipts stay attached. When a client or a partner or your own future self asks why an address is on the list, the source page is right there.

What it does not do matters as much. It does not guess addresses from names. It does not sell you a slice of a mystery database. If a company publishes no address, the result for that domain is empty, and empty is honest. I would rather hand you a short list I can defend than a long list I have to apologize for, which, if we are being honest, is the whole argument of this article in one sentence.

A realistic small pass, start to finish

Picture a freelance bookkeeper who wants twenty new conversations with independent retailers in her state.

She writes her niche sentence. She pulls forty five member shops from her state retail association directory. That is Step 2 done in under an hour, and every company on it is relevant by construction. She runs the manual order of pages on the first fifteen sites herself, because she wants to learn what these sites look like, and finds published addresses for eleven of them, mostly general inboxes plus two owners named on team pages. She feeds the remaining thirty domains to the script, or to the finder if she wants the mail checks folded in, and adds another twenty or so published addresses with sources. She runs MX checks, drops two domains that take no mail, deletes one placeholder the filters missed, and lands on a list of just under thirty contacts where every row has a source, a date, and a relevance note she can turn into a first line.

Twenty nine rows. A bought list would have given her two thousand rows and a warm feeling. Her list gives her twenty nine companies she can write to like a person, one at a time, with a sentence about their actual shop in each message. I know which list I would rather send from. I have sent from both.

Honest limits of building from published addresses

This method finds public business contacts. That is also its ceiling, and you should adopt it with your eyes open.

Some companies genuinely publish no address. They use forms on purpose, or they route everything through a platform page. The correct result for those companies is no row, not a guessed row.

An MX check proves a domain is set up to receive mail. It does not prove a specific mailbox exists or that the person named on a team page still works there. The published page plus the mail check is strong evidence, not certainty. Keep your first message easy to forward to the right person and you turn even a stale name into a warm introduction.

Pages change. A list built this way is a snapshot with a date on it, which is why the date checked field exists. Before any big send, spot check the oldest rows. Five minutes of clicking source pages beats one embarrassed apology.

And the obvious one. Published for one purpose is not published for every purpose. Stay inside the reason the address is public, follow the mail rules that apply where you and your recipients live, honor every opt out instantly, and never add people who wrote to you privately to a list like this. Restraint is not a growth hack here. It is just how this method stays clean.

FAQ

Is it okay to email addresses a company published on its own website?
Generally you are on far firmer ground than with bought or guessed addresses, because the company put the address out for business contact. You still own everything after the find. Identify yourself plainly, write only where your message fits the purpose the address was published for, include a simple way to opt out, and follow the anti spam and privacy rules that apply in your country and your recipient country. This is practical guidance from experience, not legal advice.

How many companies should I start with?
Start with twenty five to fifty. That is enough to learn whether your niche sentence is right and whether your messages earn replies, and small enough that you can build the list by hand in an afternoon and keep every row honest. Grow only after the small list proves itself.

What if a site only has a contact form?
Use the form, or leave the company off this list. Record that the company prefers forms, because that is real information about how they work. Do not construct an address from a staff name. The moment guessing enters the process, your list starts decaying into the thing you were trying to escape.

Does an MX check guarantee my message will be delivered?
No. It guarantees the domain publishes mail routing, which removes dead domains from your list. Delivery also depends on the specific mailbox existing and on your own sending reputation. Treat the check as a coarse filter that catches total failures early, which is exactly what it is good at.

Why not just buy a list and clean it?
Because cleaning a bought list means verifying each row against a live source anyway, at which point you are doing this method with extra steps and worse starting material. Most bought rows give you no source page to check against at all. Building from live sites starts at the source and skips the archaeology.

What does the Fresh Email Finder cost on a small batch?
It charges $0.005 for each verified address found, with no flat fee to start a run. One hundred verified addresses come to $0.50 in event charges. A batch of domains that publishes almost nothing costs almost nothing, which is the pricing shape a finder ought to have.

Can the finder find an address a company never published?
No, and that is deliberate. It crawls live company websites and returns published addresses with their sources. If nothing is published, nothing is returned. Any tool that promises to surface unpublished private addresses is working from a database or from guesses, and you already know how those stories end.

Build the list you can defend

The whole method fits in one breath. Choose the companies on purpose. Take only the addresses they publish themselves. Keep the source and the date with every row. Check the domain still takes mail. Write like the list is short, because it is, and that is its strength!

If your next list is fifty companies, do it by hand this afternoon and enjoy how solid it feels. If it is five hundred, run the same honest pass through the Fresh Email Finder and spend your afternoon on the messages instead of the clicking. Either way, you end with the one asset bought lists never gave me. A list where every single row can say where it came from!

Top comments (0)