Validate email addresses before you send
The deliverability-health guide covers what the traffic you have already sent says about a contact. This guide is the other half: what to check about an address before the first send, when you have no history to rely on. Two endpoints cover it — a single-address check (POST /api/v1/email/validate) and a batch scrub
(POST /api/v1/email/validate/bulk) — and this page shows where each one
belongs in a launch workflow.
1. Why scrub before you send
Every hard bounce you mail chips away at sender reputation, and every dead address costs a quota slot and a delivery attempt. Scrubbing a list before the campaign means you only pay for addresses that can actually receive mail, and a complaint-prone row (a disposable inbox, a role mailbox) gets a human decision instead of an automated one. That matters most while your domain is still warming up: the ramp schedule in the email lifecycle guide is sized for engaged, working recipients. Feeding a run of hard bounces into an early warmup day degrades the deliverability signal the ramp reads to adjust today’s cap, so you slow down exactly at the moment you were trying to speed past. Scrub first; ramp clean traffic.2. Pre-flight sweep — single addresses at the capture edge
Reject obvious typos where the address enters, not after it reaches your CRM. CallPOST /api/v1/email/validate from your signup form or edge
worker and decide the row before you import it.
valid: false address (a definitive
no-MX domain or broken syntax) is rejected outright, and a
suggested_correction either re-prompts the user with the fix or corrects
the row before it lands in the contact list. A mx_found: null result (a
DNS resolver timeout) is not a rejection — validation treats it as unknown
and keeps the address eligible for a retry a few seconds later.
The single-address endpoint also needs the authentication you would attach
to a form. If the capture point is a public page, run the check through your
own proxy with the API key held server-side — the same pattern your web
hooks already use.
3. Bulk scrub before a campaign
For an existing segment — a CSV you are importing or an audience you are about to launch — send the whole list in one call toPOST /api/v1/email/validate/bulk (up to 1,000 addresses per call,
de-duplicated case-insensitively). Slot this into the send gate between the
audience selection and the suppression check described in the
pre-flight checklist: the scrub is
where a row fails before it costs anything.
total
far above your import count means the list de-duplicated correctly; a
non-zero invalid means at least one row failed definitively; risky
counts deliverable-but-flagged rows (possible typo, disposable, role
account) that want a human decision. Only after the summary passes do you
walk the per-row results to fix or drop the offending rows.
Chunk longer lists into sequential calls of up to 1,000 addresses, and do
not parallelize: the batch endpoint is rate-limited per tenant (see the
error section below), so a fan of parallel requests just burns the same
quota faster. Input order is preserved across the results rows, so map them
back to your CSV one row at a time.
4. Validation and suppression order
Validation and the suppression list answer different questions, and the order matters:- Validate first. The scrub reads only the address itself — it decides “can this destination receive mail at all?”. Run it on every row you are about to accept.
- Then check suppression. A clean verdict does not mean the address is
sendable — the deliverable address may still be on your blocklist (a
hard bounce, complaint, unsubscribe, or manual entry). Check the row
against the Email → Suppressions list via
GET /api/v1/email/suppressions
(paged
entries, withsearchandreasonfilters), and remove what returns a hit before the send gate decides for itself.
5. What the verdict actually reports
Only what the endpoint can honestly derive gets returned — these are the verdict buckets the API really answers, and no SMTP mailbox probing means no claim of “this mailbox exists”.invalid_syntax— the address failed dot-atom validation (missing@, a malformed label, a non-2-letter TLD). Reject; a corrected suggestion may be lower-cost than a bounce.no_mx_record— the domain published neither a usable MX nor an A/AAAA fallback (RFC 5321 §5.1), or published an RFC 7505 null MX declaring it will not accept mail. A definitive verdict, not a guess. Drop these rows.disposable_domain— the domain is a known throwaway provider. Deliverable, but complaints-prone on marketing traffic. Review or re-permission.role_account— the local part is a group mailbox (info@, support@, sales@, …). Deliverable, but engagement is low and complaint risk is high. Review before marketing sends.possible_typo— a near-miss domain correction was found.suggested_correctioncarries the fix; apply or confirm it.mx_unknown— the MX lookup timed out. Validation does not treat a timeout as a verdict; the row stays eligible and should be retried.deliverable— none of the above. Sendable subject to the suppression check in section 4.
valid is syntax-driven and only flips false on a
definitive no-MX; mx_verified is stricter and only flips true on a
definitive MX. A row can be valid: true with mx_verified: false when
the lookup was unknown — treat that as an honest unknown, not a failure.
6. Common errors
- Empty batch → 422.
POST /email/validate/bulkrejects an emptyemailsarray with422 VALIDATION_ERRORand an issues list pointing at the missing rows. Send at least one address per call. - Too many addresses → 422. The array cap is 1,000 addresses per bulk call; longer lists must be chunked into sequential requests.
- Rate limit → 429. Bulk scrubs share a tight per-tenant bucket (5
calls per minute on
POST /email/validate/bulk, sized for list imports, not refresh loops). Back off when the response carriesretry_after(or aRetry-Afterheader, on suppression-list endpoints) and retry. - Suppression-list reads → 429. The
/suppressionspage/export routes run on the per-route read budget; a 429 there means pause rather than hammering the same filter.
Next steps
- Send-gating pre-flight checklist — where the scrub slots in between audience selection and the suppression check.
- Email channel lifecycle — warmup, suppression, and the error catalog around this workflow.
- Contact deliverability health — the deliverability overlay validation never answers (consent + history).
- Suppression management — page, add, remove, and export entries after the scrub.