Skip to main content
Validate email addresses before you send to reduce bounces, keep your sender reputation healthy, and avoid suppressing recipients unnecessarily. Telnyx runs five checks per address and returns a structured result you can act on. Typical uses:
  • 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.
All requests use the base URL 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 return pass: 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
Response (200):
This is the classic “likely typo” result: the address is technically deliverable (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
Response (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_removed is 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_url is omitted from both responses entirely (not null) 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
While processing (status: "pending" or "processing"):
When complete (status: "completed"), results and completed_at appear:
Batch status values: 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 a webhook_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:
Webhook delivery is best-effort: a non-2xx response or a network failure is logged but doesn’t fail the batch. The webhook is sent before the batch record is marked 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.