Verify emails before cold outreach: a practical workflow
· 4 min read · Email validation
Verify a prospect list before it enters a sequence, because every address that bounces on step one is a cost you pay with your sending domain. A verifier sorts the list into four buckets: send to valid, drop invalid, quarantine risky and unknown in a separate, smaller segment. That one step keeps the first touch of a campaign from being the step that hurts your reputation.
Cold outreach is the case where verification matters most. Nobody on the list opted in, the data often came from a third party, and you can't rely on a confirmation email to filter out bad addresses the way a signup flow can.
Why bounces hurt more in cold outreach
Mailbox providers watch how senders behave. A sender who mails a lot of addresses that don't exist looks like someone working from a bought or scraped list, which is exactly what spam filters are built to catch.
The rules are public in places. Amazon SES, for example, says it places an account under review at a hard-bounce rate of 5% and may pause sending at 10%, and recommends staying below 2%. Google's email sender guidelines tell senders to reduce volume when messages start bouncing and to keep the spam rate shown in Postmaster Tools below 0.30%. Your sequencing tool and mailbox provider have their own thresholds, and many don't publish them. The safe assumption: a few percent of bounces on a cold campaign is already a warning.
Bounce damage also stacks with complaint damage. Cold recipients are more likely to hit "report spam", so you have less room for error on the bounce side.
The four buckets and what to do with each
Most verifiers return something close to this. These are pingutil's statuses, but the logic carries over:
| Status | What it means | Action for outreach |
|---|---|---|
valid |
The recipient's server accepted the address, and a random address on the same domain was rejected | Send |
invalid |
Bad syntax, disposable domain, no mail server, or the server said the mailbox doesn't exist | Remove. Don't retry. |
risky |
Catch-all domain (accept_all), role address, full mailbox, or a random-looking local part |
Separate segment, low volume, or skip |
unknown |
Greylisting, a block, a rate limit or a timeout stopped the check | Re-check later before deciding |
Catch-all is the risky case that needs a decision
A catch-all domain means the company's mail server accepts any address during the SMTP conversation and sorts it out later. Verification can't see past that. The address might be real, or it might bounce after the server accepts it. We explain why in catch-all email domains.
What we'd do: put catch-all contacts in their own segment, send to them in small batches after the valid segment has gone out cleanly, and stop the moment bounces rise. If the prospect is high-value, find a second signal first (a LinkedIn profile that matches the company, a reply from a colleague).
Role addresses like sales@ or info@ also land in risky. In outreach they rarely reach the person you want and tend to generate complaints. Role-based email addresses covers when to keep them.
Unknown is a timing problem
Don't read unknown as a soft invalid. Greylisting servers refuse unfamiliar senders on the first try by design, and corporate gateways sometimes block verification traffic outright. Re-run unknown addresses an hour or more later. Whatever is still unknown after that goes in the same cautious segment as catch-all.
A workflow that fits most outbound teams
- Export the prospect list from your data source as CSV.
- Dedupe on lowercased email.
- Verify every row, using a CSV upload or a batch API call.
- Fix obvious typos where the verifier suggests one, but only if you can confirm the intended address.
- Import
validinto the main sequence. Importriskyand re-checkedunknownas a separate, throttled sequence or hold them. - Feed hard bounces from the sequencer back into your suppression list so nobody re-imports them.
If you want the long version of steps 1 to 5 for sequencer imports, see cleaning a lead list before sequencing.
Doing it with pingutil
pingutil runs syntax, disposable-domain, DNS and MX checks, then an SMTP handshake (RCPT TO, then QUIT, so nothing is sent) and a catch-all probe. You can upload a CSV in the dashboard (50 rows per upload) or call the batch endpoint with up to 50 addresses per request:
curl -X POST https://pingutil.com/v1/verify/batch \
-H "Authorization: Bearer pk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "emails": ["jane@northwind-example.com", "info@contoso-example.com"] }'
Each item in results has status, reason, a 0-100 score, did_you_mean and a checks object (catch_all, role_based, disposable and so on). Catch-all domains come back risky with reason accept_all, never valid. Results are cached for 30 days, so re-checking a list you verified last week is quick. Accounts get 60 requests a minute and 300 verifications a day, which suits a rep or a small team verifying lists before each campaign. Try a few addresses in the email verification demo, and see the verify endpoint reference for every field.
Before your next campaign: verify, split by status, send to valid first, and watch the bounce rate on step one before releasing the rest.
Questions people ask
- Should I send cold email to catch-all addresses?
- Sometimes, but in small volumes. A catch-all server accepts every address at the SMTP stage, so verification can't tell you whether the person exists. Send to a few catch-all contacts at a time from a separate segment, and stop if bounces climb.
- How long is an email verification result good for?
- For prospect data, re-verify anything you haven't checked in the last few weeks before it enters a new sequence. People change jobs and companies close mailboxes, so a valid result from last quarter is weak evidence today.
- Does verifying an email send a message to the prospect?
- No. A mailbox check opens an SMTP session with the recipient's mail server, asks whether it would accept the address with RCPT TO, and then disconnects with QUIT before any message content is sent.