Spam-trap detection on every verify.
Authenticated Spamhaus DBL probes on every /v1/check call. Hits self-persist so future calls short-circuit at 1ms — and vrfymail returns the listing code so you can distinguish .2 spam from .4 phish and .5 malware. Most APIs flatten this to a boolean.
A flag, a list, a code
When the domain is on Spamhaus DBL or our customer-consensus list, the verdict carries spam_trap: true plus a trap object naming the source and the listing code.
{
"result": "undeliverable",
"reason": "spam_trap",
"reason_message": "This address is on a spam-trap list. Sending here will damage your sender reputation.",
"spam_trap": true,
"trap": {
"listed": true,
"lists": ["spamhaus_dbl"],
"code": "127.0.1.2"
},
"disposable": false,
"mx_found": true,
"score": 0.0
} Code matters. Most APIs lose it.
Spamhaus returns three distinct threat codes. A "this domain is a spam source" verdict means something different from "this domain hosts phishing." vrfymail returns the code so your handling can differ — block spam, flag phish, alert security on malware.
# Spamhaus DBL listing codes
127.0.1.2 spam General spam source
127.0.1.4 phish Phishing source
127.0.1.5 malware Malware distribution source
# Most APIs flatten all three into spam_trap: true.
# vrfymail returns the code so you can distinguish severity. Real-time probe, edge cache.
Every cache miss fires a DNS query against Spamhaus DBL via authenticated DQS. Spamhaus's free public-resolver tier is blocked by policy; the DQS-authenticated tier (free up to 100k queries/day) returns the listing code.
On a hit, we persist the domain to the domains table with is_spam_trap=1 and listing_code. The second customer asking about the same domain hits a D1 row in ~1ms — no Spamhaus query, no rate limit pressure, no double-bill on your end.
Customer-consensus promotion adds a second channel: ≥3 distinct customers POSTing hard_bounce or spam_complaint on the same domain within 30 days promotes it to is_spam_trap=1 globally. Catches traps Spamhaus hasn't seen yet.
- spamhaus_dbl Spamhaus's authoritative list. ~150ms cold probe, 1ms cached.
- customer_consensus Your bounces + spam complaints, aggregated. Catches new traps before they're DBL-listed.
- trap.code Always returned when listed: 127.0.1.2 spam, .4 phish, .5 malware.
Other signals on the same call
Every /v1/check request runs the DBL probe alongside disposable detection (269K+ domains), B2C strict-mode flags, and your per-customer bounce overlay. One call, every signal, 50ms p50 on cache hits.
How spam-trap detection actually scales
Production-side posts on the detection stack — false-positive safety nets, infrastructure clustering, and operator fingerprinting.
Spam-trap detection, answered
- How does the Spamhaus DBL probe work on every verify?
- Every /v1/check request that doesn't hit the per-customer cache fires a DNS query against Spamhaus DBL (Domain Block List) via their authenticated DQS (Data Query Service) endpoint. If the domain is listed, DBL returns a 127.0.1.X code naming the threat type — .2 spam, .4 phish, .5 malware. We persist every hit to our domains table so the second customer asking about the same domain short-circuits at 1ms (no DNS query, no DBL load, no double-bill).
- What's the difference between disposable detection and spam-trap detection?
- Disposable detection flags domains operated by temp-mail providers — users intentionally giving you a throwaway address. Spam-trap detection flags addresses that mail servers monitor to identify senders with bad list hygiene. Sending to a disposable hurts your engagement; sending to a spam-trap damages your sender reputation across every ESP you use. vrfymail returns both signals on every call.
- Do I need my own Spamhaus DQS key?
- No — vrfymail handles the DQS subscription. Spamhaus blocks public resolvers by policy (you can't just query DBL from a regular DNS lookup) and the authenticated tier requires a DQS key. We carry the DQS key on the verifier; your verdict includes the DBL result without you handling rate limits or key rotation.
- What happens when a domain is on the customer-consensus list but not on Spamhaus?
- It still returns spam_trap: true with trap.lists including customer_consensus. The consensus list comes from your bounce/complaint reports — if ≥3 distinct customers POST hard_bounce or spam_complaint on the same domain within 30 days, the domain promotes to is_spam_trap=1 across the database (free-mail providers excluded). Catches the traps Spamhaus hasn't seen yet.
- Will the spam-trap check slow down my signup form?
- First call on a never-seen domain: ~150-250ms cold path (DNS + DBL + MX probes run in parallel, never serialized). Every subsequent call on the same domain: ~1ms (database hit, no probe). Most production signup forms see 80%+ cache hits — the verifier learns your traffic shape after the first hour.
DBL probes, edge-cached. One verdict.
5,000 verifies/month free, no card. Paid plans start at $9/mo — see pricing.
Get my API key