How to clean an email list before a cold outreach campaign
This is the pre-send hygiene pass that strips the avoidable hard bounces from a cold list — and an honest account of the ones validation can't catch.
Contents
You bought a list, or scraped one, or exported it from a form that never validated a thing. Now you want to run a cold outreach campaign against it. Before you load it into your sending tool, clean the email list before cold outreach starts — because every hard bounce you send is a vote against your sender reputation, and mailbox providers count votes. This is the hygiene pass that happens before warm-up, before sequencing, before you touch send. It removes the bounces you can see coming.
The bounces you can see coming, and the ones you can't
A hard bounce is a permanent rejection. Some are predictable from the address alone: it's malformed, the domain publishes no mail server, it's a throwaway domain, or it's a shared inbox nobody reads. Others stay invisible until the receiving server tells you — the mailbox was deleted last month, the account is full, the server accepts everything and reads none of it. Validation handles the first group. It cannot handle the second, and any tool that claims otherwise is guessing. That split matters, and we'll come back to it.
Four checks that remove avoidable bounces
POST /v1/verify/email runs four checks and reports each one:
- Syntax — is the address well-formed at all?
valid_syntax. - MX — does the domain actually publish a mail server?
mx_found. No MX record means nothing there is set up to accept mail. Near-certain bounce. - Disposable — is this a throwaway domain (mailinator, ten-minute-mail and friends)?
disposable. These evaporate before your first follow-up. - Role account — is it
info@,sales@,support@?role_account. A desk, not a person, and usually an unattended distribution list.
Example:
curl -X POST https://api.boundstone.io/v1/verify/email \
-H "Authorization: Bearer bs_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"info@example.com"}'
Response (trimmed):
{
"valid_syntax": true,
"domain": "example.com",
"mx_found": true,
"disposable": false,
"role_account": true,
"free_provider": false,
"checks": {
"performed": ["syntax", "mx", "disposable_list", "role_list"],
"not_performed": ["smtp_mailbox", "catch_all"]
}
}
The checks block rides on every response and tells you exactly what was measured. free_provider is returned too (gmail, outlook, and the rest) — handy for segmenting personal from business addresses, not a reason to drop anyone on its own.
Run the whole list in one pass
You don't validate a cold list one address at a time. Send the entire file to the bulk endpoint as raw CSV.
email
jordan@acme.com
info@vendor.io
temp@mailinator.com
notanemail
Then:
curl -X POST https://api.boundstone.io/v1/bulk/email \
-H "Authorization: Bearer bs_live_YOUR_KEY" \
-H "Content-Type: text/csv" \
--data-binary @list.csv
You get back HTTP 202 and a job_id. Pull the results when it finishes:
curl https://api.boundstone.io/v1/bulk/JOB_ID/results.csv \
-H "Authorization: Bearer bs_live_YOUR_KEY"
One credit is reserved per row and refunded for any row that errors, so the address that breaks the parser costs you nothing. Free jobs run up to 250 rows; paid jobs up to 10k. Prefer no code at all? The dashboard has a CSV upload and a paste box that runs the same job. The bulk flow is covered step by step in our bulk email validation walkthrough, and the hosted email validator checks a single address in the browser when you just want a spot check.
What "clean" actually means here
Here's the part most vendors skate past. Boundstone confirms the address is well-formed, the domain can receive mail, it isn't disposable, and it isn't an obvious role account. It does not knock on the mailbox door. SMTP mailbox verification and catch-all detection are not_performed, and we print that on every response instead of implying a certainty we don't have. It also doesn't flag spam traps or predict inbox placement — those ride on sending-reputation signals that live nowhere in an address.
So a clean result means "no reason to bounce that we can see from the outside." It does not mean "this specific person still works there and reads this inbox." The mailbox could have closed yesterday. The domain could be a catch-all that accepts everything and forwards nothing. Only the receiving server knows, and it only tells you when you send. Validation shrinks the avoidable-bounce pile — it does not promise zero. If you want the longer argument for why we won't fake a mailbox-level prediction, read how we think about bounce rate.
Validation is hygiene, not warm-up
Removing dead addresses protects your reputation. It does not build one. If your sending domain is cold, a clean list still needs the unglamorous disciplines: warm the domain up, ramp volume gradually, keep SPF, DKIM, and DMARC in order, and watch your reply and complaint signals. Validation is the first gate, not the whole gauntlet. Clean the list, then send like you have something to lose — because you do.
The short version
- Sender reputation is the whole game. Cold outreach lives or dies on it, and hard bounces are the fastest way to spend it.
POST /v1/verify/emailremoves the avoidable bounces. Bad syntax, no MX, disposable, role account — and every response listschecks.performedandchecks.not_performed.- Bulk-validate the whole file with
POST /v1/bulk/email— one credit per row, refunded on error, up to 10k rows on a paid plan. - Validation does not confirm the mailbox exists. It does not flag spam traps or predict inbox placement either.
smtp_mailboxandcatch_allarenot_performed; the bounces only the receiving server knows stay invisible until you send. - Clean first, then warm up and ramp. Hygiene isn't reputation.
- Free tier: 250 credits a month, no card, and they never expire.