Domain Posture & Intelligence
What every domain publishes for email authentication and transport security — SPF, DMARC, MTA-STS, DNSSEC and BIMI — and what those records actually say. One row per registrable domain.
Not yet on a cloud marketplace. Talk to us about access while the listing is in preparation.
- Grain
- One row per registrable domain
- Refresh
- Daily
- Free tier
- 16 of 21 columns
- Every domain, not a sample — paid adds columns, not rows
- License
- Clean for redistribution
Overview
One row per registrable domain, carrying the email-authentication and transport-security records that domain publishes in DNS, and what each record says. Not whether a domain looks secure — what it has actually published, read from the live record.
The distinction that makes it useful is between publishing a control and enforcing one. A domain can publish DMARC and ask receivers to do nothing about failures. This dataset separates the two: dmarc_present says a record exists, dmarc_policy and dmarc_enforced say whether it does anything. The same split runs through SPF, MTA-STS and BIMI.
The free tier is the whole estate, not a sample. Every domain we have observed is in it, with 16 of the 21 columns. The paid tier adds five columns of depth on the same rows — it does not add domains.
Observed by Datazag from public DNS. No third-party feed is redistributed through it, and every release passes an automated licensing gate that scans each published value before it leaves our boundary.
Datazag observes 370M+ live domains daily; this dataset is the posture layer of that corpus.
Schema reference
Table: domain_intel
| Column | Type | Description |
|---|---|---|
domainJoin key | VARCHAR | The registrable domain this row describes. Unique across the table. |
spf_present | BOOLEAN | Whether the domain publishes an SPF record. |
spf_qualifier | VARCHAR | How the domain's SPF record treats senders it does not list: -all rejects them, ~all marks them soft-fail, ?all is neutral, +all permits anyone, and no-all means the record ends without an all mechanism. Empty where no SPF record was published, or where the record ended in something we could not read as a valid qualifier. |
spf_include_count | INTEGER | Paid tier. How many include: mechanisms the SPF record chains to. SPF permits at most 10 DNS lookups, so a high count is a sign the record is close to failing. |
dmarc_present | BOOLEAN | Whether the domain publishes a DMARC record. |
dmarc_policy | VARCHAR | The action the domain asks receivers to take on mail that fails DMARC: none, quarantine or reject. Empty where no valid policy was published — an unrecognised p= is invalid under RFC 7489, and we do not guess an intent the domain never declared. |
dmarc_enforced | BOOLEAN | Whether the DMARC policy is actually enforcing, rather than published in monitor-only mode. This is the column to filter on when you want domains that are protected rather than domains that have a record. |
dmarc_rua | BOOLEAN | Paid tier. Whether the DMARC record requests aggregate reports, which indicates the owner is monitoring results rather than publishing and forgetting. |
dmarc_pct | INTEGER | Paid tier. The percentage of failing mail the domain asks receivers to apply its policy to. Below 100 the policy is only partially applied. A DMARC record that omits this value is applying its policy in full, and is published here as 100; this is empty only where there is no DMARC record at all. |
mta_sts | BOOLEAN | Whether the domain publishes an MTA-STS policy, which asks senders to require TLS when delivering to it. |
dnssec | BOOLEAN | Whether the domain is signed with DNSSEC. |
tlsrpt_present | BOOLEAN | Whether the domain publishes a TLS-RPT record requesting reports about delivery failures over TLS. |
bimi_present | BOOLEAN | Whether the domain publishes a BIMI record, used to display a brand logo in supporting mail clients. |
bimi_has_vmc | BOOLEAN | Paid tier. Whether that BIMI record references a Verified Mark Certificate, the stronger form that requires the trademark to have been verified. |
is_parked | BOOLEAN | Whether the domain appears to be parked rather than in active use. This is our assessment from the domain's DNS configuration on the snapshot date, not a fact the domain publishes, and the indicators behind it are maintained over time. |
primary_mx_host | VARCHAR | The hostname of the domain's primary mail exchanger, where it publishes one. A hostname only — this dataset carries no ASN, prefix or provider column. |
posture_first_seen_at | TIMESTAMP | When we first observed this domain's email posture. Posture capture began on 2026-08-20, so no value precedes that date. It is not the domain's registration date and not the first time the domain existed. |
last_observed_at | TIMESTAMP WITH TIME ZONE | When this posture was last observed, in UTC. Domains are re-observed on a rolling basis, so this varies across rows within a single release. |
snapshot_date | DATE | The date this row was built. Every row in a release carries the same date, so you can pin an analysis to a snapshot. |
tier | VARCHAR | Distribution tier this row belongs to. Every row is in the free tier; the paid tier adds columns, not rows. |
data_completeness | VARCHAR | Paid tier. Records, per signal, whether the domain published a value we could read, published nothing, or published something that could not be parsed. Most domains do not publish DMARC, SPF or MTA-STS at all, and that absence is a finding rather than a gap in our observation. |
16 of these 21 columns are in the free tier, on every domain. The five marked Paid tier — spf_include_count, dmarc_rua, dmarc_pct, bimi_has_vmc and data_completeness — are the correctness layer: how close an SPF record is to its lookup limit, whether the owner is collecting reports, how much of the policy is actually applied, whether the BIMI mark is verified, and what we could and could not read per signal. The paid tier adds no domains.
Join guide
The grain is the registrable domain and it is unique, so this is a plain equi-join against your own domain list. Normalise your side to the registrable domain first — a row for mail.example.com will not match, because the table keys on example.com.
Which of your domains publish DMARC but do not enforce it
The gap this dataset exists to show: a record is published, and it asks receivers to do nothing.
SELECT d.domain,
p.dmarc_policy,
p.spf_qualifier
FROM your_domains d
JOIN domain_intel p USING (domain)
WHERE p.dmarc_present
AND NOT p.dmarc_enforced
ORDER BY d.domain;dmarc_enforced is the column to filter on. dmarc_present only says a record exists.
Score an acquisition target's estate in one pass
Counts of what is published against what is enforced, across a domain list.
SELECT count(*) AS domains,
count(*) FILTER (WHERE spf_present) AS with_spf,
count(*) FILTER (WHERE dmarc_present) AS with_dmarc,
count(*) FILTER (WHERE dmarc_enforced) AS enforcing_dmarc,
count(*) FILTER (WHERE dnssec) AS signed,
count(*) FILTER (WHERE mta_sts) AS with_mta_sts
FROM domain_intel
JOIN your_domains USING (domain);Every column here is in the free tier.
Exclude parked domains before you count
Parked domains depress every posture rate, and they are rarely what the question is about.
SELECT count(*) FILTER (WHERE dmarc_enforced) * 100.0 / count(*) AS pct_enforcing
FROM domain_intel
WHERE NOT is_parked;is_parked is our assessment from DNS configuration, not a declaration by the domain.
Methodology & caveats
A domain that is absent has not been observed yet
Posture is captured by a rolling backfill that began on 2026-08-20 and is still working through the corpus. A domain missing from a release has not been observed yet — it does NOT mean the domain publishes nothing. Do not treat absence as a finding, and do not compute a percentage against your own list without accounting for the rows that are not there. last_observed_at and snapshot_date let you measure the coverage of any release yourself rather than taking a number from us.
Published is not enforced
Every control here is split between whether a record exists and what it says, because the two answer different questions. dmarc_present is true for a domain whose policy is p=none, which asks receivers to take no action at all. spf_qualifier distinguishes a record ending in -all from one ending in ?all. If you are measuring protection rather than adoption, filter on dmarc_enforced and on the qualifier, not on the presence flags.
Absent values mean absent records, not gaps in observation
Most domains do not publish DMARC, SPF or MTA-STS at all. Where a column is empty, the usual reason is that the domain published nothing — that is the finding. Where a domain published something we could not read as valid, we publish nothing rather than guessing: an unrecognised DMARC p= is invalid under RFC 7489, and inventing an intent the domain never declared would be worse than an empty cell. The paid data_completeness column records which of the two happened, per signal, per domain.
dmarc_pct is effective, not raw
RFC 7489 defines an absent pct= as 100, so a DMARC record without one is applying its policy in full. We publish that as 100 rather than as an empty cell, because publishing it raw made full application look like missing data on almost every row. dmarc_pct is empty only where there is no DMARC record. Where the distinction matters, data_completeness records whether the value was stated explicitly or defaulted.
is_parked is our assessment, and it moves
Parking is inferred from the domain's DNS configuration on the snapshot date against a maintained list of indicators. It is not something the domain declares, the indicator list changes as parking services come and go, and a domain can therefore change state between releases without its DNS changing. Treat it as a filter, not as a fact about the registrant.
What this dataset does not contain
There is no ASN, prefix, IP address or hosting-provider column here, and no remediation guidance. primary_mx_host is a hostname and nothing more. If you need the network layer behind a domain, that is IP to ASN Intelligence, and joining the two is your own step.
Changelog
Free and paid tiers defined by column. Every domain is in the free tier with 16 of 21 columns; the paid tier adds five columns on the same rows.
first_seen_at renamed posture_first_seen_at. It is the first posture observation, not the first sighting of the domain, and the old name said otherwise.
mta_sts_mode withdrawn. At 99.95% empty it promised a field it did not have; mta_sts (presence) still ships, and the paid data_completeness column still records whether a mode was published.
dmarc_pct is now effective rather than raw: a DMARC record with no pct= reads 100, per RFC 7489, instead of empty. It is empty only where there is no DMARC record.