Skip to content

2026-09-12

What the username and the domain look like, and two signals read from traffic

The email answer grows from 27 to 44 fields: the shape of the username and the name tokens in it, the domain's category, provider type, blocklist status, expiry and parking, relay services that are never burners, a no-reply reason, a mailbox that was dead and exists again, and how many other accounts checked an address in a day; the domain endpoint gains DKIM, MTA-STS, TLS-RPT, BIMI and the SPF and DMARC details; bulk runs finish with a summary.

  • Seventeen more fields on every email answer, 44 in all. About the username, with no network call: local_part_pattern names its shape (first.last, flast, a lone first name, digits, a plain word), first_name and last_name carry the name tokens the bundled name lists recognised — read from the address itself, never appended from outside, and never a promise of correctness — and looks_generated marks a hex string, a UUID, a placeholder word or a name glued to a run of digits. About the domain: domain_category sorts relay, disposable, webmail, academic, government and military domains from the rest; mx_provider_type says whether the provider hosts mailboxes, is a security gateway, a transactional relay, a web host or the domain's own servers; mx_blocklisted and mx_network_type run the mail hosts through the threat blocklists and network feeds the IP product already installs; domain_expires_at and parked read the registration's end and the parking nameservers. About the mailbox: role_type names the family a role address belongs to, previously_invalid and previously_invalid_at say whether a confirmed mailbox once answered "no such mailbox", and widely_seen says whether three or more other accounts looked the address up inside a day. risk_signals lists every weight that fired with the dataset it was read from, so the score is always recomputable from the answer; it is empty on an undeliverable verdict, where the verdict is the answer.
  • Relay addresses are real mailboxes. Firefox Relay, SimpleLogin, Addy.io, DuckDuckGo Email Protection and their kind sit on the open burner list because they hand out addresses on demand, and Spaw used to report them as disposable. An address there is a real person's real mailbox reached through a name they control and often kept for years, so it now answers is_relay: true with the service in relay_service, disposable is forced false, and the score carries 5 for the withheld identity instead of 80.
  • Four new reasons, all risky and all billed like any risky answer: parked_domain (the nameservers belong to a parking or for-sale service and the domain still accepts mail: whoever collects that mail is not your customer), mx_blocklisted (the mail hosts resolve into a Spamhaus DROP netblock or the abuse.ch botnet list — a burner signal no domain list has caught yet), no_reply (a noreply, donotreply or mailer-daemon shape, recognised by pattern even when the role list lacks the spelling; mail to it is discarded by design) and recycled_mailbox (the mailbox exists now and once answered that it did not — the shape of a recycled address, the spam-trap kind included). Every one has its own page under https://spaw.co/docs/reasons.
  • Twenty-one published weights. New rows: parked domain 60, blocklisted mail network 60, recycled mailbox 30, generated username 20, no-reply 20 (on top of the role row), widely seen 20, catch-all behind a security gateway 15 (instead of the catch-all 30, because behind Proofpoint, Mimecast or Barracuda a catch-all is the gateway's design rather than a squat), registration ending within 30 days 10, relay 5. The twelve rows that were there are unchanged. mailbox_confidence also reads whether a username follows the naming convention seen in the domain's confirmed deliveries: +15 when it does, −10 when a name shape breaks it, from pooled outcome counts per domain and never from an address.
  • The domain endpoint answers 31 keys. Beside what it answered before: domain_category, mx_provider_type, mx_blocklisted and mx_network_type; the SPF all qualifier and the DNS lookup count the policy needs (over ten is a permanent error at every receiver); the DMARC pct tag and whether aggregate reports are collected; the common DKIM selectors that publish a key; MTA-STS, TLS-RPT and BIMI; the registration's expiry, last change, registrar and whether the registrant is withheld; parked, is_relay and relay_service. All free DNS and the RDAP record already fetched, cached for a day so the twenty TXT queries behind the DKIM block are paid once per domain.
  • Bulk runs finish with a summary. A finished run carries rows and duplicates, the verdict and risk splits, every reason and domain category seen with its row count, the ten most frequent providers and domains, and how many rows carried each of the disposable, relay, role, catch-all, parked, blocklisted, previously-invalid, widely-seen and generated signals — built from the same rows the result file holds, so the two can never disagree. The result file carries the new columns in the answer's order, with risk_signals flattened to signal:weight pairs; the webhook body is unchanged.
  • What is stored, and what is deliberately not built. widely_seen is a keyed hash of the address with the account ids that saw it and when, kept for the day; the "no such mailbox" memory behind previously_invalid is a date under a keyed hash, kept for a year. Both are read cross-account as counts and dates only, neither says who asked, and both are erased with the address through the existing erasure route; the privacy page says so. Not built, on purpose: breach-exposure data, which would send every address to a third party; account enumeration through other sites' password-reset endpoints, which is exactly the enumeration this product tells its customers not to do; bought spam-trap lists, which no vendor can legitimately sell; and an opaque learned score in place of the published weights.
  • Every client follows. The Node SDK types the 44-field result, the 31-key domain answer and the bulk summary; the Python and PHP clients pass the new fields through; the Zapier app (1.9.0), the Make modules, the Google Sheets functions (0.9.0) and the MCP tools describe and map them.

markdown version: /changelog/2026-09-12-email-intelligence-round-two.md · atom feed: /changelog.atom

All releases