Skip to content

Risk signals

Every Spaw answer that carries a risk score lists the signals that fired in risk_signals, each with the weight applied and the dataset it was read from, and the weights sum to risk_score, capped at 100. The score is arithmetic, not a model. Each product keeps its own list, and the same name can carry a different weight on each: disposable is +80 on an email answer and +70 on a phone one. So each list has its own pages.

  • Email · 21 signals, one page each at /docs/signals/{signal}
  • Phone · 18 signals, one page each at /docs/signals/phone/{signal}
  • IP and address · listed in their guides, no pages yet

Email signals

Every deliverable or risky email answer lists its signals; an undeliverable verdict is always 100 with an empty list. Four rules bind the list: catch_all_gateway replaces catch_all behind a security gateway, young_domain and new_domain are exclusive, no_reply is added on top of role, and relay cancels disposable. The decision is your sending policy. Each signal has its own page with the full explanation, an example and what to do with the input.

signal weight reads dataset meaning
disposable +80disposabledisposable-domainsThe mailbox lives at a disposable-address service, so it exists to be thrown away; this is the largest weight there is. reason: disposable
parked_domain +60parkedparking-nameserversThe domain is parked or for sale and still accepts mail, so whoever collects that mail is not your customer. reason: parked_domain
likely_typo +60did_you_meantypo-domainsThe domain is on the curated map of misspellings that resolve and run catch-alls to harvest misdirected mail, and did_you_mean carries the intended address. reason: likely_typo
mx_blocklisted +60mx_blocklistedthreat-blocklistsAt least one MX host resolves into a network on the threat blocklists the IP product installs — Spamhaus DROP and ASN-DROP, abuse.ch Feodo Tracker — a burner signal no domain list has caught yet. reason: mx_blocklisted
implicit_mx +30mx_implicitlive-dnsThe domain publishes no MX record, so mail would fall back to its own address under RFC 5321; such web-only domains rarely accept mail and are never probed. reason: implicit_mx
role +30rolerole-addressesinfo@, support@, billing@ and the rest of the open role-address list name a function, so the inbox may be shared, filtered or unread. reason: role, no_reply
catch_all +30catch_allmailbox-smtpThe handshake said yes to a recipient that cannot exist, so a yes for this one proves nothing; mailbox_confidence estimates the rest. reason: catch_all
young_domain +30domain_age_daysrdap-registrationThe registry's RDAP record puts the registration less than 30 days back — the age of a domain set up for one campaign.
recycled_mailbox +30previously_invalidmailbox-historyA definitive no-such-mailbox was recorded for the address earlier and the mailbox answers now — the shape of a recycled address, the spam-trap kind included. reason: recycled_mailbox
mailbox_full +20smtp_reasonmailbox-smtpThe handshake found the mailbox and was told it is full, so mail will bounce until the owner clears it. reason: mailbox_full
gibberish +20is_gibberishlocal-part-analysisSix letters or more with no vowel, or six consonants in a row, and nothing the bundled name lists recognise — deliberately conservative.
generated +20looks_generatedlocal-part-analysisA hex string, a UUID, a base64-looking run, one or two letters before four digits, a word before six digits, or a placeholder word such as test or asdf.
no_reply +20role_typerole-typesnoreply, donotreply, mailer-daemon and their kin are addresses mail is sent from and never read at; this weight is added on top of the role weight. reason: no_reply
widely_seen +20widely_seenlookup-velocityAt least three other Spaw accounts looked the address up in the last 24 hours — an address hitting many signup forms at once.
catch_all_gateway +15mx_provider_typemailbox-smtpThe domain accepts every address but its mail runs through Proofpoint, Mimecast or Barracuda, where accepting every recipient is the gateway's design; this lighter weight takes the place of the catch-all one. reason: catch_all
new_domain +10domain_age_daysrdap-registrationThe registration is between 30 and 179 days old — past its first month, not yet an established domain.
no_spf +10has_spflive-dnsThe domain has no SPF policy in DNS, which a maintained business domain almost always has; free providers are exempt because theirs is known.
unverified +10smtp_checkedmailbox-smtpThe handshake ran and did not settle the mailbox — greylisting, a timeout, an unreachable server, a partner outage — so smtp_checked is false and the verdict is risky. reason: unverified
expiring_domain +10domain_expires_atrdap-registrationRDAP puts the registration's end inside the next 30 days — a domain that may be about to lapse.
alias +5is_aliaslocal-part-analysismia+promo@ is the same inbox as mia@ under a disposable label — a favourite of signup-bonus farmers, and the reason to dedupe on normalized_email.
relay +5is_relayforwarding-servicesFirefox Relay, SimpleLogin, Addy.io, DuckDuckGo Email Protection and their kind deliver to a real person's mailbox under a name they control; the identity is withheld, not the mailbox.

Phone signals

Every valid phone answer lists its signals; an invalid number has no score and lists nothing. disposable and disposable_stale never fire together, disposable_range fires only for a number the lists do not carry, and range_burst and numbers_per_client come from nothing but your own account’s lookups. A dataset marked “regulator table” is whichever country’s allocation table answered, named in the answer. The decision is your SMS policy.

signal weight reads · dataset meaning
fictional +80is_fictionalfictional-rangesthe number sits in a range reserved for fiction blocked by the default SMS policy
disposable +70is_disposabledisposable_seen_atdisposable-phone-numberspublished by an SMS-receiving website blocked by the default SMS policy
disposable_stale +40is_disposabledisposable_seen_atdisposable-phone-numberspublished by an SMS-receiving website, but not recently
reported_abuse +60no field of its owndelivery-feedbackyour own account reported abuse for the number blocked by the default SMS policy
reported_undelivered +50no field of its owndelivery-feedbackyour own latest report for the number was a failed delivery
reported_abuse_widely +40no field of its owndelivery-feedbackthree or more accounts reported abuse for the number blocked by the default SMS policy
premium_rate +60line_typelibphonenumbera premium-rate number blocked by the default SMS policy
reserved_block +40block_statusregulator tablethe regulator's table marks the block reserved
virtual +40is_virtualregulator tablethe block is held by a virtual-number wholesaler or VoIP provider
range_burst +40range_seen_by_youaccount-velocityyour account looked up several numbers in the same range within the window
voip +30line_typelibphonenumberthe numbering plan types the number as VoIP
pager +30line_typelibphonenumberthe numbering plan types the number as a pager
digit_pattern +30e164digit-patternrepeated or sequential subscriber digits
numbers_per_client +30client_velocityaccount-velocityone client address tried several numbers within the window
disposable_range +30no field of its owndisposable-phone-numbersnot listed, but in a range crowded with SMS-receiving numbers
international_network +30calling_codelibphonenumberan international network or satellite number
shared_cost +20line_typelibphonenumbera shared-cost number
reported_unwanted_calls +20complaints_90dcomplaints_last_atus-complaint-reportsconsumers reported unwanted calls from the number

“Blocked by the default SMS policy” marks the default block_signals: a number carrying one is refused whatever the score. Every other signal only counts toward the default ceiling, which blocks a score above 60.

IP and address signals

These weights do not have pages of their own yet. Each guide lists them with the arithmetic:

Related