A domain monitor is a saved list of up to 500 domains that Spaw re-checks daily, weekly or monthly through the same domain lookup the API sells, and reports on when something about a domain's mail setup changes for the worse. The alert names each domain and the reason, and the run's summary counts how many domains are fine, flagged, dead or invalid. This guide explains every status and flag, the rule that decides when an alert goes out, and what each one is asking you to do.
What a run reads for each domain
Every run asks the domain endpoint the same question for every domain on the list, and keeps a compact entry per domain: its status, the flags that fired, whether it changed since the previous run, and the facts the next run will compare against. Those facts are the provider and its type, whether SPF is published and its all qualifier, the DMARC policy, the DKIM selectors found, MTA-STS, whether the domain is parked, whether its mail hosts sit on a threat blocklist, and the registration's expiry date.
Billing is the domain lookup's: one credit when a domain accepts mail, nothing for a dead or invalid domain, and repeats inside the seven-day window free. That last rule is why a daily cadence is allowed on domain lists and not on address lists. A run is DNS and a registry record with no mailbox handshake, and a domain checked daily is still billed at most once a week.
The four statuses
| Status | Meaning |
|---|---|
ok |
The domain accepts mail and no flag fired. |
flagged |
The domain accepts mail and at least one flag fired. |
dead |
The domain has no usable mail servers. Mail sent there will not arrive. |
invalid |
The entry is not a hostname at all, typically a typo in the list. |
The statuses are ordered: invalid wins over dead, which wins over flagged, which wins over ok. A dead domain shows no flags, because the flags are read from a mail setup the domain no longer has.
The ten flags
Five are standing flags, read from the domain as it is on the day of the run.
| Flag | It fires when |
|---|---|
parked |
The nameservers belong to a parking or for-sale service, and the domain still accepts mail. Whoever collects that mail is not the company you knew. |
blocklisted |
At least one mail host resolves into a network the Spamhaus DROP lists or the abuse.ch botnet list name. |
expiring |
The registration ends within the next 30 days, read from the registry's RDAP record. |
no_spf |
The domain publishes no SPF record. |
no_dmarc |
The domain publishes no DMARC record. |
Five compare the domain with what the previous run recorded, and can only fire from the second run on.
| Flag | It fires when |
|---|---|
provider_changed |
The mail provider read from the MX records is not the one recorded last time. |
spf_changed |
SPF appeared, disappeared, or changed its all qualifier. |
dmarc_changed |
The DMARC policy is not what it was: reject loosened to none, or a record removed. |
dkim_lost |
The previous run found DKIM selectors and this one found none of the common ones. |
mta_sts_lost |
The MTA-STS record was there and is gone. |
Every flag that fires is listed, in that order, so an entry can carry ["no_dmarc", "provider_changed", "dmarc_changed"] after a migration that moved the domain to a new provider and dropped its DMARC record on the way.
When an alert goes out
The first run only sets the baseline. It records every domain's entry and sends nothing, because there is nothing yet to compare against; a domain that is already parked on the first run is flagged in the results but not announced.
From the second run on, an alert email goes out for a domain that was ok and no longer is, that went dead or invalid from any other status, that fired one of the five comparison flags, or that gained a standing flag it did not have before. A domain that stays flagged for the same reason run after run is not announced again; the flag stays visible in the results, but the alert is for change.
A new domain added to the list behaves like a first run for itself: it is baselined, not announced.
The summary of each run counts total, ok, flagged, dead, invalid, changed, newly_flagged and credits_used, with stopped_reason set when the run could not finish: out of credits, a key's daily cap, or a run that died and is re-checked by the hourly sweep once 45 minutes have passed. newly_flagged is the number of domains the alert names.
The same run can be posted to a webhook as { "event": "domain_monitor.run", "monitor": …, "summary": …, "changes": [ … ] }, signed like every other delivery, with changes naming the domains the email names. By default only runs that found something post; every_run posts each one, which doubles as a heartbeat.
What each flag is asking you to do
dead. The domain has lost its mail servers. If it is one of your own sending domains, your DNS or your provider has changed under you and nothing addressed there arrives. If it is a customer's domain, every address at it is now undeliverable; a bulk run of those addresses will confirm it and add them to your suppression list for free.
parked. The domain has been given up and is sitting on a parking service, yet its mail servers still answer. Whatever you send there is collected by whoever runs the page. Stop sending to the domain's addresses; the per-address answers carry the same fact as the parked_domain reason.
blocklisted. The domain's mail now lives on a network the blocklists name. For a domain you own, that is a hosting problem to raise with the provider today. For a domain on your list, it is the strongest available sign that the addresses at it are not worth mailing.
expiring. Thirty days from the end of the registration. For your own domain, renew it. For a customer's, expect the domain to go dead or parked within the month if nobody acts, and treat mail to it as time-limited.
no_spf, no_dmarc. The domain sends mail without the records receivers use to authenticate it. For your own domains that is a deliverability problem to fix in the order the MTA-STS, TLS-RPT and BIMI guide describes. For a domain you mail, it is information about how carefully it is run, not a reason to stop.
provider_changed. The domain moved its mail. Often that is a planned migration, but it is also what a domain that changed hands looks like, and what a takeover looks like. Check the new provider in the results; a move from Google or Microsoft to other deserves a look.
spf_changed, dmarc_changed. A policy was loosened or removed. A DMARC record dropping from reject to none is the change attackers benefit from most, since mail spoofing the domain stops being rejected.
dkim_lost, mta_sts_lost. A key or a transport policy disappeared, typically during a DNS migration that copied some records and not others. Both are worth fixing the same day for a sending domain.
Keeping the baseline
The baseline is the whole value of a monitor, and two things protect it. Editing the list through the dashboard or PATCH keeps what was recorded about every domain that stays, so a rename or a cadence change never resets the comparison; deleting a monitor and creating it again throws the baseline away and buys a full cycle of silence. And a run that stops early, out of credits or after a failure, carries the previous answers forward for the domains it never reached, so those still compare correctly on the next run.
A list nobody runs for a year is deleted with everything it stored; a list in use never is, because every run moves the clock.
What to do next
- Read the domain monitor section of the email verification docs for the API contract.
- Create a monitor for your sending domains with
POST /api/v1/email/domain-monitors, or from the Domains tab. - Look up any single domain with the domain intelligence endpoint before adding it to a list.