- Pre-send hygiene — check an address a user just typed in before you send to it, and offer a correction if they mistyped their provider.
- List cleaning before import — run a batch over a list you’re about to import so you don’t seed suppressions with addresses that can’t deliver.
- Reducing bounces — a high hard-bounce rate hurts your domain reputation and can trigger suppression of otherwise-good recipients; validating first lets you drop the ones that fail.
https://api.telnyx.com/v2 and an Authorization: Bearer *** header.
What’s checked
Every address is run through five checks. A failed syntax check short-circuits the rest (no DNS lookup is performed), and those checks returnpass: false with a details note that they were skipped.
A result is
valid: true only when syntax, mx, and disposable all pass. role_based and typo never flip valid to false — they’re signals you choose how to act on.
Validate one address
POST /email_validations validates a single address and returns synchronously. Any non-empty string is accepted; invalid syntax returns valid: false rather than a request error.
curl
200):
valid: true, syntax and MX pass), but the domain is one edit away from gmail.com, so the typo check fails and contributes 0.1 to risk_score. Prompt the user to confirm did_you_mean before sending.
A typo domain is not automatically a valid domain. Some common misspellings —
gmial.com among them — are on the disposable blocklist, which makes disposable.pass: false and flips the whole result to valid: false with risk_score: 0.7 (0.6 disposable + 0.1 typo). Always read valid and the individual checks rather than assuming a typo suggestion implies an otherwise-good address.Result fields
When syntax fails, the remaining checks are skipped and return
pass: false with details: "Skipped: syntax failed". risk_score is 1.0 in that case.Validate in batch
POST /email_validations/batch creates an asynchronous job for up to 1,000 addresses. The request returns immediately (202) with a batch ID you poll for results. Optionally pass a webhook_url to receive a POST when the batch completes.
curl
202):
Batch input rules
- Max size: 1,000 emails. Requests with more (before or after dedup) return
400. - Deduplication: emails are trimmed, blank strings are dropped, and the remainder is deduplicated case-insensitively (so
"User@Example.com"and"user@example.com"count as one).duplicates_removedis the number of duplicates plus blanks discarded. - All-blank input: returns
400(emails array must contain at least one email address). webhook_url: optional HTTP(S) URL, max 2048 characters. Empty string is treated as omitted. SSRF-protected — private/reserved IPs and internal hostnames are rejected at creation and re-checked at delivery time.webhook_urlis omitted from both responses entirely (notnull) when unset.
Poll for results
GET /email_validations/batch/{id} returns the batch status and, once completed, a results map keyed by email address.
curl
status: "pending" or "processing"):
status: "completed"), results and completed_at appear:
pending, processing, completed, failed. If the worker exhausts its retries, the batch is marked failed; a failed batch has no results map. Each result object has the same email, valid, risk_score, did_you_mean?, and checks shape as the single-address response. Note that the GET response does not include duplicates_removed (that’s only on the create response).
Completion webhook
When you provide awebhook_url, the worker sends a POST to it once the batch finishes processing. The payload is a summary — the full per-address results come from polling the GET endpoint:
completed, so a worker crash during delivery can cause Oban to retry and resend the webhook.
Interpreting results
Use the checks to decide what to do with an address — validation is a strong signal, not a delivery guarantee.Validation checks DNS records and known blocklists at validation time. It does not verify that a mailbox exists or that a message will be accepted by the receiving server. A
valid: true address can still bounce if the mailbox is full, disabled, or behind a greylisting/accept-all policy. Treat validation as pre-send hygiene, not a delivery guarantee.