DEV Community

Cover image for Use DNS evidence to clean email lists without claiming mailbox verification
Tim Zinin
Tim Zinin

Posted on

Use DNS evidence to clean email lists without claiming mailbox verification

An email address can have valid syntax and belong to a domain with working mail servers while the named mailbox does not exist. A single valid boolean hides this distinction. It encourages an operations team to treat a DNS observation as a promise of delivery.

Email Verifier build 0.5.2 returns tiered syntax and DNS/MX verdicts. It does not perform a live mailbox probe. The mailboxChecked field remains false, including when the verdict is valid_syntax_and_mx. That boundary lets you use strong negative evidence for list hygiene without inventing positive mailbox evidence.

Start with mixed cases

Use a small input containing different kinds of uncertainty before connecting a larger list:

{
  "emails": [
    "test@gmail.com",
    "not-a-real-email",
    "someone@this-domain-zzq123.example"
  ],
  "maxConcurrency": 3
}
Enter fullscreen mode Exit fullscreen mode

These are illustrative values from the supported input shape. No message is sent by this example, and no fresh DNS result is asserted here. The direct email list is limited to 100 entries. Keep the original requested string in your staging data so a normalization step remains auditable.

The Actor also supports a source Dataset as an alternative input. Do not combine emails and datasetId. For Dataset extraction, emailFields names explicit dot paths rather than asking the Actor to search every field. A path such as contacts[].email describes a nested array. This makes the ingestion boundary understandable when a source row contains unrelated personal fields.

Interpret the verdict rather than a green badge

valid_syntax_and_mx means the address passed syntax checks and the domain has observed mail-routing evidence. It does not establish that the local part names a mailbox, that delivery will succeed, or that a recipient agreed to receive mail.

invalid_syntax is a deterministic input finding. domain_not_found and no_mx are different observed domain conditions. In particular, a null-MX record can explicitly indicate that a domain does not accept email. unknown is different again: an infrastructure problem prevented a supported verdict. Do not place unknown records in the same suppression bucket as confirmed negative findings.

Retain syntaxValid, domainResolves, mxFound, mxRecords, verdict, error, and checkedAt when building a review table. A DNS observation ages. Store the timestamp with the finding so a later refresh can be compared without rewriting the earlier evidence.

Provider, disposable, roleAccount, and catchAllRisk add context rather than certainty. A role label identifies a shared-looking local part such as support; it does not identify the person reading it. Disposable-domain detection uses a finite list. The catch-all warning is based on known provider behavior, not a fresh per-domain mailbox experiment.

Preserve the counting and payment unit

A checked negative verdict can still be a completed, billable result. The useful service is the classification, so invalid syntax is not automatically an operational failure or a free outcome. Resolver infrastructure failures yielding unknown have a different meaning and are not claimed as completed verdicts.

Case handling also matters for deduplication. The domain is case-normalized, while local-part case is retained. Avoid rewriting all addresses to lowercase in an upstream step unless that transformation is an explicit policy you can justify separately. Keep source-row provenance when multiple rows refer to the same checked address.

For acceptance, inspect a mixed fixture containing malformed syntax, a documented non-mail domain, a normal mail domain, and a simulated resolver error. Confirm that unknown remains retryable operational uncertainty and that positive MX never becomes mailboxChecked:true. Those are proposed checks rather than newly executed observations. Use the output to maintain a reviewable suppression process; permission, recipient identity, and sending decisions require their own evidence.

Cost and source boundary

The live FREE-tier event prices checked on 20 October 2026 are $0.001 per result-found event and $0.005 per automatic Actor-start event. The start event is memory-scaled: one event per GB, with a minimum of one event. A free result outcome therefore does not make an entire run free. Other account tiers have their own rates; check the live pricing panel before execution. These prices describe the installed contract, not measured customer revenue or a new runtime test.

Inspect the Actor, input, and current pricing.

AI-assisted drafting; technical statements reviewed against the installed Actor source and current API metadata. Examples are illustrative unless explicitly identified as saved observations.

Top comments (0)