Email guide · DNS and validation
Email validation has several different questions hiding behind one address. DNS can show whether a domain advertises mail servers; a disposable-domain list can identify temporary inbox providers; syntax checks can reject malformed input. None of these proves that a person owns a mailbox. The examples below are designed for scripts, CI jobs, and signup flows.
PRACTICAL · COMMAND LINE READYExtract the domain, query MX records, and inspect the exit status. If there is no MX record, RFC-style sending behavior may fall back to A/AAAA, so treat the result as a signal rather than an absolute verdict.
domain=example.com
dig +short MX "$domain" | sort -n
# API summary
curl -sG https://email.lifestep.io/validate --data-urlencode email=user@example.com | jq '{domain,has_mx}'Why it works: MX records name the hosts that accept mail for a domain and their preference order. A domain with no MX may still receive mail through its address records, while a published MX can be unreachable or misconfigured. DNS answers are cached and can change, so avoid making permanent account decisions from one lookup. The validator combines syntax, MX, and other heuristics and returns a practical “worth sending to” signal.
Normalize the domain and compare it with a maintained disposable-domain dataset. For a ready endpoint, call the validator and read `is_disposable`; for local enforcement, keep the list versioned and update it regularly.
curl -sG https://email.lifestep.io/validate \
--data-urlencode email=test@mailinator.com | jq '{normalized,is_disposable,verdict}'Why it works: Disposable providers rotate domains and aliases, so a static list is never complete. The useful engineering pattern is layered: validate syntax, identify the domain, check a curated list, and decide what your product actually needs. Blocking every temporary address can reject legitimate testers and privacy-conscious users; flagging it for review or limiting abuse-sensitive actions is often a better policy.
Perform syntax and DNS checks only. A regular expression can reject obvious errors, while an MX lookup checks domain mail routing. Do not use SMTP probing as a “validation” step.
python3 - <<'PY'
import re, socket
email="user@example.com"
if not re.fullmatch(r"[^@\s]+@[^@\s]+", email): raise SystemExit("bad syntax")
domain=email.rsplit("@",1)[1]
try: socket.getaddrinfo(domain, 25)
except socket.gaierror: raise SystemExit("domain does not resolve")
print("syntax and DNS look reasonable")
PYWhy it works: SMTP probing is unreliable because servers use catch-all mailboxes, greylisting, tarpits, and anti-abuse rules. It can also create privacy and reputation problems. “Valid without sending” should therefore mean a normalized address with acceptable syntax and a domain that has plausible mail routing. The validator intentionally does not contact a mailbox; use its result as a delivery-likelihood heuristic, then rely on normal bounce handling after a real, consented message.
Make the command deterministic before putting it in automation. Pin the input hostname or filename, set a timeout, capture the exit status, and emit a concise error that a build log can explain. Treat an empty answer differently from a transport failure: an empty DNS record, a workbook with no matching package member, and an unavailable endpoint are different states. Test one known-good fixture and one deliberately bad fixture so a future dependency or API change cannot silently turn a failure into a pass. Prefer machine-readable JSON when an API provides it, but retain the original command for local diagnosis. If the result controls a user-facing decision, show the reason and a timestamp rather than only a green or red label. Review the changed files in source control before publishing. These habits keep a useful one-liner understandable when it becomes a scheduled check.