Step 1: consolidate and normalise
Before anything else, get the list into one file with one row per contact and consistent columns.
- Merge every source you plan to send to: the CRM export, the event list, the file someone kept in a spreadsheet.
- Normalise the address column: trim whitespace, strip the mailto prefix, lowercase the whole address.
- Keep the source of each row as a column. You will want to know which source produced the bounces.
- Keep every other column you need on the far side. A cleaning step that loses your custom fields is a cleaning step you will have to redo.
Step 2: deduplicate
Identical addresses collapse into one row. This is first because everything after it costs something per row.
Two subtleties are worth handling. The same person often appears under two addresses at the same company, usually an old pattern and a current one, and the older one is frequently dead. And the same address can appear with different capitalisation from different sources, which a naive comparison treats as two rows.
Step 3: apply the suppression list
Before any address is checked, remove everyone who must not be contacted.
- Anyone who unsubscribed, from any campaign, ever.
- Anyone who asked to be erased. This is a legal obligation, not a preference.
- Every address that hard bounced in a previous campaign.
- Competitors, current customers, or anyone else your own rules exclude from this send.
If you do not maintain a permanent suppression list, this is the step where you start one. A suppression list that only covers the current campaign is not a suppression list.
Step 4: remove what is structurally wrong
Now the cheap checks, which cost nothing and remove a surprising share of a bought or scraped list.
- Syntax failures: missing at sign, spaces inside the address, trailing commas from a spreadsheet, double dots.
- Domains that publish no mail servers. Nothing on them can receive mail, so the whole group goes at once.
- Disposable domains, which are throwaway mailboxes that were never meant to receive a second message.
- Obvious typos in large provider names, which are common enough in form submissions to be worth catching.
Step 5: verify the remaining addresses
This is the step that needs the receiving mail server, and it is the one that actually decides your bounce rate.
Each address is checked at the server that would receive it, and comes back as deliverable, undeliverable, catch-all or risky. Do this on the whole list, not on a sample, because the sample tells you about the sample.
Two rules on cost. You should not pay to check an address twice inside a period, and you should not pay for rows that come back undeliverable or catch-all, because nobody answered your question. That is how it works on every plan here, and it is on the bulk email verification page.
Step 6: segment by risk instead of deleting
The temptation is to delete everything that is not deliverable. That throws away real contacts, because the middle statuses are not failures.
| Status | What it is | Where it goes |
|---|---|---|
| Deliverable | The server confirmed the mailbox | The main send |
| Undeliverable | A permanent failure | The suppression list, permanently |
| Catch-all | The server accepts every address, so nobody can confirm this one | A separate list, sent to carefully or held |
| Role address | A shared department inbox | Its own list, with copy written for a shared inbox |
| Consumer mailbox | A personal account rather than a work address | Its own list, or out of a B2B campaign entirely |
Splitting the list this way lets you send confidently to the confirmed rows today and make a separate, deliberate decision about the rest, instead of one blanket decision about all of them.
Step 7: send in the right order
- Send to the deliverable rows first, and watch the bounce rate on that send.
- If the rate is where it should be, follow with the catch-all segment at lower volume from a domain with history.
- Never start a new sending domain with the catch-all segment. A new domain has no reputation to absorb anything.
- Feed every bounce from these sends back into the suppression list the same day.
Step 8: stop the list getting dirty again
Cleaning is not a project you finish. A B2B list decays continuously because people change jobs, and nothing in your database updates when they do.
- Verify at the point of capture, so a bad address never enters the database. The email verifier API runs this at form submission or on CRM write.
- Re-verify saved lists on a schedule, so decay is found between campaigns rather than by one.
- Re-verify anything older than a quarter before a large send, especially a CRM segment nobody has touched.
- Keep the suppression list permanent and check it on every send, without exception.
Done this way, the big cleaning project happens once, and after that each campaign starts from a list that is already clean.