What's New
Recent features, improvements, and fixes.
June 2026
Managed SPF activation now verifies the whole chain — and status surfaces stop second-guessing your DNS edits
Managed SPF won't report Active until both your record and ours answer end to end; status surfaces trust the freshest authoritative read after a change; the DMARC Verify DNS button actually verifies DNS; and waits are honest, naming the stuck step and whose side it's on.
Four fixes to the minutes right after you (or we) touch DNS:
- Managed SPF won't report Active until the whole chain answers. Activation now verifies both your apex record and the managed record on our side, end to end. If our side isn't answering, the card says so plainly — "we're re-publishing it; nothing to change on your side" — and the system re-publishes automatically instead of silently retrying lookups.
- No more false "restore your include" right after a clean activation. Status surfaces now trust the freshest authoritative read of your record, so a just-published change can't be contradicted by a stale cached lookup.
- The DMARC "Verify DNS" button actually verifies DNS. It runs the check against your nameservers and tells you the result — "Found it" or "not visible yet" — instead of doing nothing.
- Waits are honest. The reporting setup screen updates itself, and a Managed DMARC activation that runs past its promised window now names the stuck step and whose side it's on.
Activations are no longer silent, and the notification pipeline is repaired
Managed SPF and DMARC activations now send a confirmation the moment your delegation goes live. The welcome email pipeline is fixed so newer enrollments aren't blocked. DNS changes we instructed you to make no longer trigger monitoring alerts. Pro plans now see the managed CNAME path first when enabling DMARC reporting.
Several fixes from a deeper review of the activation and notification journey:
Activations now confirm themselves. The moment your Managed SPF or Managed DMARC delegation goes live — the instant your DNS is pointing correctly — you get an in-app notification and a confirmation email. Previously, the smoothest activations were completely silent. You'd published the record, it resolved correctly, and then: nothing. That silence is gone.
The welcome email pipeline is repaired. A longstanding issue where certain accounts with incomplete channel setup could block the delivery queue for everyone behind them is fixed. If you've been waiting on a welcome email or an onboarding follow-up, the pipeline will clear.
Monitoring no longer alerts on DNS edits we asked you to make. When you follow the activation instructions — replacing your SPF record with the one we provide, or publishing the DMARC CNAME — that DNS change no longer fires a "record changed" notification. The change was expected; the alert was noise. Same for mail server IP rotation: providers like Google regularly cycle the IP addresses behind their MX hostnames, which isn't a meaningful DNS change. That noise is also gone.
DMARC reporting setup on Pro+ leads with the managed path. When enabling DMARC reporting on an account with a Managed DMARC enrollment, the enable dialog now offers the managed CNAME route first — one delegation that covers both the record and the reports, with no TXT to publish and then replace later. The self-managed TXT path is still available as an explicit alternative.
Choosing a paid plan before signing up now lands you back at checkout. If you clicked "Start with Pro" from the Managed SPF page and then completed the email login, you were previously dropped onto the free dashboard with no path back to the plan you'd selected. The "Start with Pro" link now carries your intent through signup so you arrive at the right checkout after your first login.
Reports no longer error before your first reports arrive — and plan gates now say what they are
Fixed a crash on the Reports page for brand-new accounts, made the enforcement dialog show an upgrade path instead of an error on plans without DMARC reporting, corrected the gradual-rollout confirmation text, and made the upgrade confirmation accessible to screen readers.
Four fixes from our end-to-end journey review, all aimed at moments where the product told you the wrong thing:
Reports works from day one. Aggregate DMARC reports usually take 24–48 hours to start arriving after a domain begins reporting — and during that window, the Reports page could fail with an error instead of rendering. It now shows a clear "No reports yet" notice with that timeline, and the Executive Summary renders its full layout so you can see what the report will look like while you wait.
Plan gates look like plan gates. On plans without DMARC reporting, the "Start sending fakes to spam" dialog used to show a loading error that retrying could never fix. It now explains that policy changes are guided by DMARC report evidence and shows where reporting is included — an answer, not an error.
Honest gradual-rollout text. The confirmation checkboxes for partial (pct) policy rollouts previously said mail outside the sample is "not delivered." That was wrong: under the DMARC standard, non-sampled mail falls back to the next-lower policy and is still delivered — quarantine falls back to normal delivery, reject falls back to spam placement. The confirmation text now says exactly that.
Accessible upgrade confirmation. The subscribe confirmation on the pricing page is now announced properly to screen readers: focus moves into the dialog when it opens, stays there while it's open, and returns to where you were when it closes.
One reporting-address list, told the same way everywhere
Every DMARC record mxio generates or publishes now keeps your existing reporting addresses and never repeats one — and the dashboard says plainly when we've preserved a third-party address you were already using.
Your DMARC record carries a list of addresses that receive reports about who's sending mail as your domain. Three different places in mxio could produce that list, and they didn't all agree.
Now there is one rule, everywhere: we keep your existing reporting addresses and add mxio's — never replace, never repeat. The record suggestion that says it "adds the reporting address" now genuinely adds it to your current record (keeping your policy and your own addresses exactly as they are). Changing your enforcement policy keeps every reporting address you had. And Managed DMARC records can no longer list the same address twice — domains that already published a doubled address are being corrected automatically; no action needed from you.
The dashboard tells this story honestly, too. Where reports are sent now labels each address — yours vs. mxio's reporting address — never lists one twice, and no longer claims "no address is set" while showing you the address two inches above. And when you move a domain to Managed DMARC while already using another reporting service, the page now says what we've always done: we kept your existing reporting address — reports continue to flow there as well as to mxio.
We now say what we know — named SPF changes, honest coverage, and a real enforcement checklist
The Managed SPF comparison names its entries instead of counting them, sender lists ask what's missing instead of claiming completeness, the free SPF checker names what your record authorizes, pricing surfaces stop naming a plan that no longer exists, managed monitoring domains read 'Watching', and the active Managed DMARC page lists exactly what has to clear before the next enforcement step.
When Managed SPF showed "We've added 8 entries to your managed record," it never said which eight — and they were never new senders at all, just your existing senders' addresses written out the way receivers need them. The comparison now says exactly that ("Same senders (Google Workspace), written out the way receivers need — 8 address blocks") and every entry is one click away behind Show the entries.
Your Senders list used to claim "this is everyone who sends email as you." It can't know that — it's seeded from your SPF record. It now says where the list came from and asks the question that actually catches gaps: send from anything else — a newsletter service, invoicing app, CRM? Add it so we can check its coverage. The free SPF checker got the same honesty: its score is now labeled Syntax & lookup health (it grades the record, not your domain), and the result names what the record authorizes so a missing sender can finally click.
Pricing got a plain-language pass: the plan chooser answers real needs ("Email going to spam → Monitor", "Want it handled for you → Pro"), no surface names the retired "Core" plan anymore, upgrade links land highlighted on the plan they name, plan-gated buttons show their from-price before you click, and the subscribe confirmation states the exact charge — with a one-click switch between annual and monthly — before Stripe does.
Two more truths: a domain whose DMARC mxio manages at the monitoring stage now reads DMARC: Watching on your domain list (not "DMARC: none" next to an "mxio DMARC" badge), and the active Managed DMARC page replaces "we'll guide you forward when you're ready" with the actual checklist — including the part only you can do, like publishing a DKIM record for a sender that isn't signed yet. Nothing advances without your approval; now you can see exactly what it's waiting on.
Managed-service setup prompts now only go to customers who started setup
We no longer prompt you to finish activating a managed service you never started. Copying the setup record now registers that you're in the process of activating.
When mxio prepares a Managed SPF or Managed DMARC record for your domain, it sets up everything on our side first — then waits for you to publish the record in your DNS. Previously, the "ready to activate" reminder emails and the admin follow-up queue would fire based on that preparation alone, even for accounts that had never opened the setup page. That meant some customers received prompts about a feature they'd never touched.
Now, mxio tracks whether you've actually started setup. Copying the delegation record or clicking Verify registers your intent. Reminders only go out after that signal — so if you haven't looked at the setup page yet, you won't hear from us until you do. The setup flow itself is unchanged; this is a timing fix.
Managed-service status now tells one consistent story
After you publish a managed DMARC record we show a calm 'Confirming…' instead of flickering states, the Advisor stops telling you to add a DMARC record you already have, and the managed-service indicators now read from shared sources across your domain list, domain page, and Advisor.
When you hand a service to mxio to manage, there's a short gap between publishing the record and that change being visible in DNS everywhere. We used to fill that gap with whatever we'd last seen — which could briefly read as "not set up" right after you'd set it up. Now, for a few minutes after you publish your managed DMARC record, the DMARC card shows a calm "Confirming…" while the change propagates, then settles into the real state once we can see it. No more contradictory flicker during the moment you most want reassurance.
The Advisor is more honest about what's already in place, too. It no longer tells you to "add a DMARC record" when your domain already has one — if we can see a record in your DNS, it says so, and points you at the actual next step instead of an action you've already taken.
And the managed-service indicators now read from shared sources. Whether a managed DMARC record is active, drifting, or still self-managed is decided once — so your domain list, the domain's page, and the Advisor stay in step. Managed SPF indicators on the domain list and domain pages draw on the same observed-DNS signals, so disagreements there are now rare edge cases rather than everyday flicker.
Your health digest now leads with status, not a score
The recurring domain health digest email now shows a clear categorical status — healthy, or how many domains need attention — and per-domain Healthy / Warning / Failing labels, instead of a 0–100 number.
Your recurring health digest email is clearer. It used to lead with a 0–100 "Overall Health Score." That number answered "how do I feel?" but not "what do I do?" — so we replaced it with a categorical status that points straight at action.
Now the digest opens with one plain line — "All domains are healthy" or "2 of 5 domains need attention" — and each domain carries a Healthy / Warning / Failing badge with the specific checks that changed. The 0–100 score stays where it belongs: on the free diagnostic tools and public domain report, where a single comparable number is genuinely useful. On your operational surfaces — the dashboard, the Advisor, and now this digest — we lead with status and the next step.
We now confirm DKIM setup for more sending services
Senders that use Mailgun, Brevo, Zoho, or Klaviyo now show whether their DKIM is set up correctly — and HubSpot, Salesforce, SparkPost and Mimecast now prompt for the right value.
Your sender list now confirms DKIM setup for more services. For Mailgun, Brevo, Zoho, and Klaviyo, mxio knows exactly which DKIM record to look for — so instead of "can't confirm," each sender now tells you whether its DKIM is set up, set up correctly, or still needs a record published.
A few services (HubSpot, Salesforce, SparkPost, Mimecast) give every customer a different DKIM selector, so there's no single record we can check for in advance. For those, the Add-a-sender step now prompts you to paste your own selector — once you do, mxio confirms it the same way. We don't guess at a selector that might not exist: if a service genuinely doesn't expose a predictable record, we say "can't confirm" rather than show you something misleading.
DNS-recognized senders now roll up across your whole account
The 'Found in your DNS' senders we recognize per domain now also appear account-wide on the Reports Overview, grouped by vendor with the domains each was found on — and a one-click path to confirm them.
The senders we recognize in your DNS now roll up across your whole account. On the Reports Overview, a "Found in your DNS" group lists every vendor we've recognized in your domains' DNS that isn't on your verified sender list yet — one row per vendor, showing which of your domains it was found on.
From there it's the same one-click path: pick a domain and Confirm / Add opens that domain's sender list with the vendor highlighted. Recognizing a vendor in your DNS still isn't the same as authorizing it — nothing is added until you confirm. This is the account-wide companion to the per-domain view: if a sender shows up on five of your domains but you've only confirmed it on two, you can see and fix that from one place.
Senders we recognize in your DNS now show up for review
When we find a known email vendor configured in your domain's DNS, it now appears in a 'Found in your DNS' group on your sender list and the DMARC Sources tab — one click to confirm and add it.
Senders we recognize in your DNS now surface for your review. When you add a domain, we look at its DNS for the signatures of known email vendors. Anything we recognize but that isn't on your verified sender list yet now appears in a "Found in your DNS" group — on the sender map for the domain and on the DMARC Sources tab.
Each one shows the vendor we recognized and a single Confirm / Add action that opens your sender list with that vendor highlighted, so you can authorize it in one step. Until you do, it's just a suggestion: recognizing a vendor in your DNS isn't the same as authorizing it to send as you, and nothing is added on your behalf. Once you confirm it, it moves to your verified senders and leaves the review group automatically.
Get an email when a new sender starts using your domain
When a recognized email vendor first starts sending as one of your domains and isn't on your sender list yet, we now email you so you can add it to SPF — with a per-account toggle and a one-step unsubscribe.
We now reach out when a new sender starts using one of your domains. If a recognized email vendor (SendGrid, Mailgun, and the like) begins sending as your domain and isn't on your authorized sender list yet, you'll get a short email naming the sender and how much it's sent in the past week — with a one-click path to review it and add it to your SPF record if it's yours.
It's built to be quiet and useful, not noisy:
- Named senders only. You only hear about vendors we can recognize and name — never anonymous traffic, and never a "blocked" or "spoofing" claim. Suspicious mail stays where it belongs, on your in-app sender and Reports surfaces.
- New arrivals only. The email fires when a sender first shows up, not every week for a sender that's been there a while.
- At most one email per domain per week, and it batches every new sender it found into a single message.
You're opted in by default, but there's a New-sender alerts toggle on your notification settings, and every email carries a dedicated unsubscribe link that turns only these alerts off — your digest and other emails are untouched. Your monthly account summary now also shows how many new senders started using your domains that month.
Senders we recognize by their DKIM signature now show on the sender map and Reports Overview
Vendors we recognize in your DMARC reports by their DKIM signature — even when they're not on your verified sender list — now appear on the per-domain sender map and account-wide on the Reports Overview, clearly labeled and never alarming.
When a vendor sends as your domain through a shared platform (think a tool that signs with its own DKIM key on Amazon SES), we can often recognize it by that DKIM signature in your DMARC reports — even when it isn't on your verified sender list. That signal already showed on the DMARC Sources tab; now it also appears in a "Recognized in unverified mail" group on the per-domain sender map and account-wide on the Reports Overview.
These rows are informational. We recognize the vendor by its DKIM signature, which is an identity hint — not proof it's a configured sender for you, and never a claim that anything was blocked. So there's no one-click action here: if you recognize a vendor and want it on your list, the regular "Add a sender" flow is the place to do it. On the account view, each vendor is one row with the domains it was seen on, so you can spot a shared-platform sender showing up across several of your domains at a glance.
Senders now finds more of who sends as you, from your DKIM setup
When you add a domain, mxio checks its DKIM setup and names services that authenticate through a shared platform — so they appear in Senders ready to add, even when they're invisible in your SPF record.
Senders now finds more of who sends as you. When you add a domain, we check its DKIM setup and name services that authenticate through a shared platform (Resend, SendGrid, Mailgun and more) — so they show up in Senders ready to add, even when they're invisible in your SPF record.
Many services send your mail through a shared platform and prove it's really you with their own DKIM signature rather than an entry in your SPF record. Those senders used to be hard to spot. Now, when you add a domain — or re-scan an existing one — mxio reads your DKIM setup and surfaces each recognized service by name, marked "found in your DNS," ready for you to add to your authorized sender list.
Adding a sender now guides you through per-account values
For services that give each customer their own SPF include or DKIM selector — Mimecast, Amazon SES, Postmark and others — the Add-a-sender picker now prompts you to paste your specific value, so the record is set up correctly the first time.
Adding a sender that uses a custom value is now guided. For services that give each customer their own SPF include or DKIM selector — Mimecast, Amazon SES, Postmark and others — the Add-a-sender picker now prompts you to paste your specific value, so it's set up right the first time.
Some email services issue every customer a unique SPF include host or DKIM selector, rather than a shared one. Before this change, adding one of those senders required knowing to find and enter that value separately — easy to miss, and easy to get wrong. Now the picker recognizes when a vendor works that way, shows you what to look for, and validates the format before saving. The right value ends up in your record without a separate step.
DMARC Sources names more senders via DKIM signature
Services that sign your mail with their own DKIM signature — even when sending from a shared platform like Amazon SES or SendGrid — now appear by name in the unverified section of your DMARC Sources.
DMARC Sources now names more of your senders. When a service signs your mail with its own DKIM signature — even from a shared sending platform like Amazon SES or SendGrid — we now recognize it by name in the "unverified mail" section of your DMARC Sources, so you can spot and add legitimate senders faster.
Previously, a sender using a shared IP would show up as an anonymous source in the unknown group, even if its mail was signed with a recognizable DKIM domain. Now, when we see mail signed with a known sender's domain, we surface that sender by name — so you know what it is before deciding whether to add it to your authorized list.
Tell us if managed setup is confusing — right from the activation page
A new 'is this clear? / I'm stuck' affordance on the Managed SPF and Managed DMARC activation pages lets you flag confusion in one click, so we can help before you give up.
Activating a managed service is one DNS record — but if the instructions aren't landing, we'd rather hear it from you than have you stall.
- A one-click "is this clear? / I'm stuck" prompt now sits at the bottom of the Managed SPF and Managed DMARC activation pages. Say "Yes" and it gets out of your way; say "I'm stuck" and you can tell us what's tripping you up in a sentence.
- We see it immediately. A "stuck" note flags your domain and where you are in setup for us, so we can reach out and help rather than leaving you to figure it out alone. You only send the domain — we fill in the rest on our side.
- It asks once per service per domain, so it never nags.
Why a sender shows SPF 0% — explained where it matters
When a sender authenticates through DKIM but shows SPF alignment of 0%, the dashboard now explains that this is normal — DKIM is carrying the authentication — so a healthy sender no longer reads as broken. The 'likely spoofing' label is now reserved for senders that fail DKIM too.
A common, healthy pattern looks alarming at first glance: a sender shows SPF alignment 0% next to DKIM 100% and DMARC passing. That's normal — many email services sign with your DKIM key but send from their own address, and forwarded mail breaks SPF while the DKIM signature survives. DMARC passes when either SPF or DKIM lines up, so the mail is authenticated as yours.
- A "Why is SPF 0%?" explainer now appears wherever per-sender SPF/DKIM/DMARC alignment is shown — the account-wide sender roster, the per-domain DMARC Sources view, and the sender-discovery list — but only when a sender actually exhibits the pattern. It explains, in plain language, that DKIM is doing the authenticating and that SPF 0% is only a problem when DKIM is failing too.
- "Likely spoofing" is now reserved for senders that fail DKIM. A forwarder keeps a valid, aligned DKIM signature; a spoofer can't forge one. So an unrecognized source that's actually authenticating through DKIM is no longer labeled a probable impersonator — the spoofing call is gated on DKIM not aligning.
- The per-domain Sources verdict explains the SPF 0% case instead of a generic "monitor for regressions," so you can see at a glance why a recognized service is fine.
The net effect: a legitimate sender that authenticates via DKIM reads as healthy, and the impersonation warning is saved for traffic that genuinely can't prove it's you.
Executive PDF: world map shows where your mail came from
The downloadable Executive PDF report now includes a world map colored by per-country mail volume and DMARC alignment — a quick visual complement to the existing country table.
The Executive PDF (Reports → Executive Summary → Download PDF) now includes a geography map showing where your mail came from, by sending-source country.
- Countries are colored by mail volume and DMARC alignment — teal for well-aligned traffic, red for low alignment.
- The map sits above the existing per-country breakdown table and gives you an at-a-glance picture of your global authentication posture.
- As with all the report's figures, the map shows alignment as reported by receiving mail servers — what your DMARC policy directs them to do, not a guaranteed outcome.
Honest, contradiction-free managed onboarding
Duplicate SPF records now read as 'remove the extra one' everywhere, managed-service setup converges without a manual reload, the advisor shows one DMARC path instead of two, and self-managers get the full SPF record to publish plus a heads-up when a sender isn't covered.
A sweep of fixes so every screen tells the same honest story while you set up and manage email authentication.
- A duplicate SPF record now reads as "remove the extra one" — everywhere. Publishing two
v=spf1records is a permanent error that stops receivers from evaluating SPF at all. The hub card, the advisor, the delivery-foundation panel, and the focused SPF page now all say the same thing — and never tell you to "add a record," which would only deepen the problem. - Managed setup converges on its own. If you leave the domain page open after publishing your record, it now confirms and updates by itself (bounded, and only while the tab is in front of you) instead of waiting for a manual reload.
- One DMARC path, not two. When Managed DMARC is set up, the advisor no longer also tells you to add a reporting address by hand — the managed record carries it. And the "set up Managed DMARC" suggestion now reads as an available option, not an "action needed" defect.
- Over-budget SPF? Here are your options. A record over the 10-lookup limit now shows two clear paths: let mxio manage it (recommended — it flattens the record and auto-tracks vendor IP changes), or trim senders yourself with a live "you'd be at N/10" as you consider each one.
- Self-managers get the whole record. When a sender isn't covered by your SPF record, we now show the complete, copy-pasteable record to publish — plus an in-app heads-up so you know a sender is uncovered without having to go looking.
- Calmer, truer signals. A brand-new domain's mild soft-fail reads "Recommended next step," not "Action needed," on the domain list (matching the per-domain page); a
~allsoft-fail no longer flags your real-mail delivery as a problem (it's a DMARC-enforcement note); and a DKIM coverage gap reads "Setup," not "Warning." - Handing a domain back is easy to find. "Take back control" of Managed DMARC is now reachable on the focused DMARC page, and the handback warns you if you'd stop receiving reports unless you add your own
rua=address.
Managed SPF sets itself up once your DNS is in place
Managed SPF now provisions automatically the moment your domain's SPF record is live — even if you added the domain before configuring DNS — instead of only at the instant you add it.
Managed SPF now reliably offers you an activation path once your domain's SPF record is published — not just at the exact moment you add the domain.
- Add the domain first, configure DNS later — and it still works. Previously, Managed SPF was set up in a single pass when you added a domain. If your SPF record wasn't published yet (a brand-new domain, or DNS that hadn't propagated), there was nothing to set up — and nothing tried again later. Now a routine check that observes your live SPF record automatically completes the setup, so the per-domain page shows you the record to publish within a short window.
- No more "no SPF record" on a domain that clearly has one. When we look at your domain to set up Managed SPF, we now read your SPF record straight from your domain's nameservers rather than a shared cache — so a record you just published is seen right away instead of being missed for up to half an hour.
This is part of a standing automated check that verifies, end to end, that the activation instructions we show you are valid and followable: what we tell you to publish, when published exactly as shown, produces a working setup — and the common wrong move (a duplicate or wrong record) is caught rather than silently accepted.
Your SPF status now reads the same on every screen
Opening the SPF page no longer shows a false 'Confirming' before you've published, a domain with two SPF records says 'remove the extra one' everywhere, panels converge the moment a managed service activates, and an already-protected domain leads with 'you're protected' instead of a setup pitch.
A follow-up sweep so the SPF and DMARC surfaces tell one consistent, honest story — during setup, after activation, and when something drifts.
- Opening the SPF page no longer claims you've published when you haven't. The page checks your DNS quietly in the background; that background check no longer flips the card into a "Confirming — you've published the record / nothing else to do" state before you've actually published. The activation instructions stay in front of you until your record is live. (The same fix applies to Managed DMARC.)
- Two SPF records reads as "remove the extra one" — on every surface. Publishing two
v=spf1records is a permanent error. The advisor, the delivery-foundation panel, the SPF card, and the published-record strip now all say "You have N SPF records — remove one" and the same wording everywhere — never "No SPF record." - Panels converge the moment a managed service activates. After you publish your record, the advisor and the "Will your real mail be trusted?" panel update in lockstep with the card instead of one of them lingering on a stale "broken" until the next background cycle.
- A freshly-added domain doesn't flash false failures while DNS propagates. If you add a domain seconds after setting up its DNS, the page now shows a calm "we're still checking — propagation can take a few minutes" instead of hard red "no SPF record" failures that resolve on their own.
- An already-protected domain leads with reassurance. A domain already at the strongest DMARC policy now leads with "All clear — impersonators are blocked," with the Managed DMARC offer kept as a quiet, secondary option rather than a top "action needed."
- A
_dmarcconflict shows on the hub card. If your_dmarcrecord has both a CNAME and a TXT (or points at another DMARC service), the hub card now flags it directly, not only when you click Verify. - DKIM setup reads consistently. A recommended DKIM setup step now reads "Setup" on both the hub and the focused page; a key that's actually broken reads "Warning" on both — they no longer disagree.
- Smaller polish: the "real mail trusted?" summary no longer overclaims when there's a soft-fail caveat, the DMARC card no longer briefly says "Setting up…" while its body says "Available," and the "Skip for now" option on the sign-in setup screen is easier to find.
A step-by-step walkthrough for activating Managed SPF and Managed DMARC
A new plain-language guide walks you through exactly what happens when you turn on a managed service — what mxio sets up, the one DNS record you publish, how we confirm it, and how to switch back anytime. It's linked right where you activate.
Turning on a managed service is one DNS record — but it helps to see the whole flow before you make the change.
- New guide: How Managed SPF and Managed DMARC actually work — step by step. It walks the real flow in plain language: what mxio already set up on our side, the single record you publish (the SPF include / the DMARC CNAME), how we confirm it, what Available, Activating…, and Active mean, and how to hand it back anytime. You keep ownership of your zone throughout.
- Linked right where you activate. A "How does this actually work?" expander now sits on the SPF and DMARC activation pages, with a link straight to the matching section of the walkthrough — so the explanation is one click from the record you're about to publish.
Reports that link you to the fix
The account Reports Overview now has a domain picker and turns suspicious/unregistered senders into one-click links to the right domain's Senders page — and at the portfolio level, a row expands to the domains it touched so you're never stuck.
The account Reports Overview stops being a dead end — it routes you to where the fix lives.
- A domain picker on the Overview. Scope the whole view to one domain (or keep "All domains"). Picking a domain makes its sender rows directly actionable.
- Suspicious and unregistered senders are now links. A recognized sender that's failing DMARC links straight to that domain's Senders page with the sender highlighted, so you can authorize it (if it's really yours) or leave it (your DMARC policy already handles spoof). An unregistered-but-passing sender links the same way, framed "Add."
- At "All domains," a row hands you the door. Because a portfolio-wide row can touch several domains, it expands to the domains it appeared on — each a one-click jump into that domain to act. No more seeing a problem at the account level with no way to act on it.
- Honest by design. The "Unidentified senders" bucket — unrecognized IPs with no single sender to add — stays informational (with an optional "Investigate in DMARC sources" at a single domain), never a misleading link to an empty page. The Executive Summary and its PDF stay read-only.
Suspicious means suspicious — not one stray failure
The account Reports no longer flag a legitimate, well-authenticated sender as an impersonator over a single forwarded message. 'Suspicious' now means a sender that's materially failing DMARC and isn't already crypto-established.
A sharper, more honest definition of "suspicious" on the account Reports — so your real senders stop being accused.
- One stray failure no longer brands a legit sender. Before, any sender with even a single failing message landed under "Senders failing DMARC" — so your own Google Workspace mail (98% authenticated) could show up as a suspicious impersonator over one forwarded message. Now a sender only counts as suspicious if it's materially failing and not already established — a high DMARC pass rate is cryptographic proof the mail is really yours (an impersonator can't forge DKIM), so its occasional failures are forwarding noise, not spoofing.
- The headline number matches the list. The "suspicious messages" count is now the sum of just those materially-failing senders, so the number and the senders behind it always agree — and it stops counting forwarded legitimate mail as impersonation.
- Legit senders aren't sitting under a "Suspicious" header anymore. The panel is now "Who's sending as your domains," with the suspicious count as the lead alarm inside it. Senders that weren't flagged carry a clear "Not flagged" marker, and your authorized senders are marked "Authorized" — so nothing reads as accused when it isn't.
Reports: a clearer, honest impersonation picture
The account Reports now separate senders that are actually failing DMARC from legitimate senders you simply haven't added yet, label the unidentified-sender bucket, and call the headline 'Suspicious messages' consistently.
The account-wide Reports (Overview, Executive Summary, and the downloadable Executive PDF) now tell a straighter story about who's sending mail as your domains.
- Two groups, not one mixed list. The senders behind the "Suspicious messages" number are now split into Senders failing DMARC (the ones that make up the number — each shown with its failing count) and Not on your authorized-sender list (senders that pass DMARC fine but aren't in your registry yet). Previously a fully-passing sender like a forgotten Barracuda or Fastmail could appear under an "impersonation" heading it didn't belong to.
- The headline number is traceable. Each suspicious sender row leads with its failing-message count, so the totals add up to the headline instead of being buried under each sender's total volume.
- The unidentified-sender bucket has a name. Mail from unrecognized senders now reads "Unidentified senders" instead of an unlabeled row.
- Consistent wording. The headline is "Suspicious messages" across the Overview and the Executive Summary (it previously read "Spoofing attempts detected" on one tab). As always, we never claim mail was "blocked" — only what your DMARC policy directs receivers to do.
Unrecognized senders are flagged to investigate — not added
On the per-domain page, the 'who sends mail as you' list now separates recognized services you can add from unidentified sources that fail authentication. Unidentified senders get an 'Investigate' link to the full forensics, instead of an 'Add' button that would have authorized a possible impersonator.
The "Who sends mail as you" list on each domain now tells two different stories apart.
- Recognized but not on your list — a service we can identify (e.g. an email platform) that you haven't added yet. These keep the + Add button: you know what it is, so adding it to your authorized senders makes sense.
- Seen sending — not verified as you — an unidentified source with no recognizable identity that isn't authenticating. These no longer offer + Add (adding one would have authorized a possible impersonator). Instead, each row shows the message volume, how many IP addresses it came from, and an Investigate → link that opens the full DMARC source detail — IP, reverse DNS, network, and country — so you can decide what it is. When a source is actually failing DMARC, the row says plainly that it's being seen impersonating you and that your DMARC policy is handling it.
This makes the list safe to act on: the only thing you can "add" is something we recognize, and anything that looks like spoofing routes you to the evidence instead of the authorize button.
Managed DMARC now front-and-center on the homepage
The homepage gained a Managed DMARC section — reach enforcement when your senders are ready — and the page now flows from seeing who sends as you, to managing it, to monitoring.
Managed DMARC now has its own section on the homepage, symmetric with Managed SPF. It shows the path from monitoring to enforcement — Watching every sender, then fakes sent to spam, then fakes refused — advanced automatically as your authorized senders come into alignment, with the Advisor telling you the one next step.
We also reordered the homepage so it reads in one line: see who sends as your domain (DMARC Reporting) → we keep it right (Managed SPF, Managed DMARC) → always-on monitoring → your dashboard.
A clearer hero, consistent service pages, and two ways to use mxio
The homepage leads with 'We manage SPF and DMARC for you — or show you exactly how,' the three service-page heroes now line up, and Managed SPF/DMARC make clear you can keep managing your own records with our guidance.
A few refinements to how we explain mxio:
- The homepage hero now says it straight: We manage SPF and DMARC for you — or show you exactly how. A three-point summary sits right under it — see every sender by name, SPF & DMARC managed or self-served, reach DMARC enforcement safely.
- The three service-page heroes (DMARC Reporting, Managed SPF, Managed DMARC) now share one consistent layout — same alignment, spacing, and eyebrow order — so nothing shifts as you move between them.
- Managed SPF and Managed DMARC each gained a "Two ways to use mxio" section: hand the record to us, or keep managing it yourself with our reporting and the Advisor telling you exactly what to publish and when it's safe to enforce. It's not all or nothing — and you own your records either way.
A clearer story: who sends mail as your domain
The homepage, the three service pages, and pricing now lead with the one idea everything is built on — your Senders, the list of who sends mail as your domain — plus a new guide on how it ties SPF, DKIM, and DMARC together.
We've sharpened how the site explains what mxio actually does. The thread running through all of it is your Senders — the list of services that send mail as your domain.
- The homepage now leads with the managed story built around that list: see every sender by name, make one last change to your SPF and DMARC, and we keep them right from there — while you still own the records.
- The three service pages (DMARC Reporting, Managed SPF, Managed DMARC) now read as one platform built on your Senders list, not three separate tools. Each links to the other two.
- Pricing opens with the same idea: every paid plan is built on your Senders, and from that list we keep your SPF and DMARC right for you — or tell you exactly what to publish.
- A new guide, Who Sends Mail as Your Domain, explains why your senders are the foundation of SPF, DKIM, and DMARC, how to find the ones you didn't know about, and how mxio either advises you or takes on the upkeep.
- The Managed Email Authentication guide gained a plain section on how the handover actually works — record by record, what stays yours, and how to take it back. The honest version: you delegate the upkeep, not the ownership.
No features changed — this is about making the story match the product.
Executive Summary now works per-domain
The Executive Summary report can scope to a single domain, not just your whole account — pick a domain from the new selector and print a one-page summary for just that one.
The Executive Summary tab in Reports now has a domain selector. Leave it on All domains for the account-wide picture, or pick a single domain to print a one-page summary scoped to just that one — the verdict, pass rate, delivery, and senders all narrow to the domain you chose. Same honest framing throughout. Available on DMARC Starter and up.
Managed SPF & DMARC onboarding now tells one clear story
The per-domain DMARC card no longer shows two conflicting DNS changes at once, the 'let mxio manage it' path can't strand you on a blank record, the advisor stops claiming you have 'no DMARC record' when one is published, and a few smaller papercuts across senders, SPF and DKIM are fixed.
We walked the whole "set up a domain, then try the managed services" flow end to end and fixed the places where it told you two different things at once.
What changed
-
One DMARC instruction, not two. When Managed DMARC is provisioned for a domain, the DMARC card now shows only the managed path (publish the
_dmarcCNAME to activate). It no longer also asks you to add a self-managed reportingTXTrecord — two mutually-exclusive changes at the same DNS name — and it never reverts to asking for theTXTafter you've published the CNAME. -
"Let mxio manage it" can't strand you. On a plan that doesn't include Managed DMARC (or before it's provisioned), the "Let mxio manage it" button now takes you to the right place to enable or upgrade, instead of opening a wizard that asked you to publish a blank record and then waited forever.
-
The advisor stops contradicting the card. If your domain has a published
p=noneDMARC record but mxio reporting is off, the SPF soft-fail tip no longer claims you have "no DMARC record" — it correctly says your DMARC isn't enforcing yet. -
Plan label fixed. The DMARC reporting upgrade prompt now says DMARC reporting is available on DMARC Starter or higher (it was incorrectly saying "Pro").
-
"Check DNS" for Managed SPF is reliable. Right after you publish your SPF record, the check now confirms it immediately instead of saying it can't see the record for a few minutes.
-
Your senders show up right away. A newly added domain now lists the senders found in your SPF record immediately, instead of staying blank until you added one by hand.
-
Smaller fixes: the SPF comparison now counts DNS "entries" instead of mislabeling IP ranges as "senders"; the DKIM card shows an at-a-glance health pill; a duplicate "Add sender" button was removed; a just-published handover now shows a brief "confirming…" note instead of momentarily showing the old record; and a dead "Set up Managed SPF" link was fixed.
Turning on Managed SPF & DMARC now flows without false alarms
When you publish the DNS record we ask for, the card now says 'Confirming…' and flips to active on its own — instead of briefly flashing that your SPF is broken. DMARC setup tells you to replace your existing record (not add a conflicting one), and the plan gates and copy are honest throughout.
Activating Managed SPF or Managed DMARC should feel like the system is on your side the moment you make the change. A round of fixes makes that true end to end.
No more false "you broke it" right after you did it right. Previously, the instant you published your Managed SPF record, the page could flash a red "SPF is broken — restore the include" warning — pointing at the exact record you'd just added — and the refresh button didn't clear it. That was a timing artifact: we flipped the service to active off live DNS, but the card was reading a moments-old cached observation. Now the card shows an honest "Confirming…" state, checks the real record at your nameserver, and flips to active on its own within a minute or two. "Check DNS" actually re-checks.
The card stops contradicting itself. A correctly-flattened SPF record no longer reports a phantom "policy mismatch," and the "is your mail trusted?" summary and the SPF card now always agree — they read from one source of truth.
Managed DMARC tells you to replace, not add. If you already have a _dmarc record, turning on Managed DMARC now says "Replace your existing _dmarc TXT with this CNAME" and shows the record you're replacing — because a name can't carry both. If both are present, "Verify" tells you to remove the old one instead of falsely reporting success.
Honest plan gates and honest value. On a plan without Managed DMARC, "Let mxio manage it" now leads to a clear "Managed DMARC requires Pro or higher — Upgrade to Pro" instead of quietly dropping you into self-managed setup. And we no longer claim Managed SPF "fixes" a soft-fail it doesn't change — its real value is stated plainly: it keeps your record under the 10-lookup limit and updates vendor IPs for you.
Calmer first impression. A brand-new domain with a normal monitoring baseline now leads with "Recommended next step" rather than a red "Action needed" — we save the alarm for things that are genuinely broken.
Deleting several domains at once now shows progress and updates the list immediately
Bulk delete on the Domains page used to look frozen while it worked — no progress, no change on screen until you reloaded. It now removes the selected rows right away, shows a clear "Deleting N domains…" indicator, and surfaces a visible error if anything fails.
If you selected several domains and clicked Delete, the page gave almost no sign anything was happening. The only cue was a tiny "Deleting…" label on a button, and the rows didn't change until you reloaded — so a delete that takes a few seconds (domains with managed services and lots of report history take longer to tear down) looked like it had silently failed.
What changed
- The selected rows disappear immediately. When you confirm a bulk delete, those domains are removed from the list right away so the page reflects what you asked for instead of sitting still.
- A clear in-progress indicator. While the delete runs you now see a "Deleting N domains…" status with a spinner — not just a 4px text change on a button.
- Failures are visible and the list stays honest. If a delete doesn't fully succeed, an error is shown and the list is refreshed against the server, so any domains that weren't actually deleted come back instead of vanishing.
- Same treatment for bulk Pause, Resume, and Check Now, which share the in-progress indicator and the always-refresh behavior.
- The monitored-hosts list got the identical fix — bulk actions there behaved the same way and now give the same feedback.
Newly added domains are checked immediately
When you add a domain, mxio now runs its first health check right away — MX, SPF, DKIM, and DNS hygiene results appear within seconds instead of waiting for the next monitoring cycle.
Adding a domain used to leave the per-domain page on "Running first health checks…" for up to a few minutes — the domain was queued for the next monitoring sweep rather than checked on the spot.
What changed
- The first health check fires the moment you add a domain. MX, SPF, DKIM, and DNS hygiene results now appear within seconds, and the per-domain page fills in on its own as they land.
- Normal monitoring continues as before. After the first check, the domain follows its regular recurring schedule.
A brand-new domain no longer claims it's set up correctly before any check has run
On a just-added domain, the per-domain page used to show a green ✓ SPF / ✓ Delivery and 'Your real mail is set up correctly' before the first health check had even run — contradicting the cards below it. It now reads honestly, refreshes on its own as results land, and stops implying a 30-day sender history that doesn't exist yet.
When you added a brand-new domain, the per-domain page would briefly claim your email was "set up correctly" — green checks on SPF and Delivery — before a single health check had run. The records below it honestly said "the check hasn't run yet," so the page told two opposite stories at once. It also froze on "Running first health checks…" until you manually reloaded.
What changed
- No more false all-clear. A protocol shows a green ✓ only when its check has actually passed. Before the first checks land, each shows a neutral em-dash (—) and the page says "We're still checking your records" — never "set up correctly."
- Results now appear on their own. While the first checks are running, the page refreshes itself and fills in MX, SPF, DKIM, and DNS results as they complete — no manual reload needed. It stops refreshing once everything's in.
- No phantom history. The sender list no longer says "last 30 days" on a domain that has no DMARC reporting yet — there's no 30-day window of data to summarize, so it just shows your sender list.
A freshly-added domain no longer claims "Managed by mxio" before you've delegated DNS
The SPF and DMARC "Managed by mxio" badge now appears only once your DNS actually points at us — a domain that's provisioned on our side but not yet delegated reads "Self-managed."
On Pro and Business plans we set up the behind-the-scenes records for Managed SPF and Managed DMARC the moment you add a domain — but that's provisioning on our side. Until you actually point your DNS at us, the record is still yours to maintain. The per-domain SPF and DMARC cards used to jump straight to the teal "Managed by mxio" badge as soon as we'd provisioned, which overstated what was live.
What changed
- The badge now tracks observed delegation, not provisioning. The SPF and DMARC cards read "Managed by mxio" only once your DNS is actually delegated to us — your apex SPF includes our record, or your
_dmarcCNAME points at our zone and is verified. - Provisioned-but-not-delegated domains read "Self-managed." A brand-new domain whose managed service is set up on our side but not yet wired up in your DNS now honestly shows "Self-managed" alongside the "activate with one DNS change" offer — the offer and the badge agree.
- No change to what's actually published. This is a labelling fix only; your records and the activation flow are unchanged.
May 2026
Managed SPF: one honest verdict when your apex drops our include
A Managed-SPF domain whose apex SPF lost (or never had) the mxio include used to show two contradictory advisor verdicts at once — 'No SPF record, add SPF' and 'managed record stale, redeploy.' Now it shows a single, accurate 'restore your SPF include' verdict, and the false 'hasn't been redeployed in a week' alarm is gone.
When mxio manages your SPF, we maintain the flattened record we publish — but you still own your apex, and the apex has to keep pointing at us with an include:. If that pointer goes missing, the advisor needs to tell you plainly. It wasn't.
What changed
- One verdict instead of two contradictory ones. A Managed-SPF domain whose apex SPF no longer included our managed record used to surface both "No SPF record — anyone can send mail as your domain" (add SPF) and "SPF record may be out of date" (redeploy) on the same domain. Those can't both be true. There's now a single verdict — "Your SPF record no longer includes your managed SPF" (or, if the apex record is gone entirely, "Your domain has no SPF record") — with one clear action: Restore SPF include →.
- The false "stale" alarm is gone. The old verdict claimed your managed record "hasn't been redeployed in over a week." That was misleading: we re-check your senders every cycle and only rewrite the record when something actually changes, so a stable record legitimately goes weeks without a rewrite while staying perfectly correct. The "weeks since last redeploy" trigger is removed — the only thing we flag now is the real condition: your apex no longer carries our include.
- The verdict is now treated as urgent. A missing include means your authorized senders may not be covered (or, if the whole record is gone, anyone can send as you). It's surfaced in Needs attention, not as a low-priority watch item.
Why
"Managed SPF" means we run the flattened record — not that we own your apex zone. You keep full control of the apex, which means you (or a DNS change on your side) can remove the pointer to us, and we can't silently fix that for you. The honest thing is one accurate verdict that names the real problem and the real fix — not two verdicts that contradict each other, one of which prescribes a "redeploy" that wouldn't even address it.
The advisor now leads with your real problems — DMARC reads as 'available', not a pending task
A domain's actual issues (broken or over-budget SPF, blacklist hits, DKIM problems) now come first. DMARC monitoring you haven't turned on shows up as a calm, optional 'available' item instead of an alarm or a clock you never started.
What changed
The per-domain Advisor and the portfolio domain list now prioritize by demonstrated need instead of a fixed protocol order:
- Your real problems lead. If a domain's SPF is broken or over the 10-lookup limit, it's on a blacklist, or its DKIM is misconfigured, that's the top recommendation — it's no longer pushed below DMARC setup prompts you never asked for.
- DMARC reads as available, not pending. For a domain where you haven't set up DMARC, the advisor now shows a single calm item — "DMARC monitoring is available for this domain" — instead of "No DMARC record — your domain isn't protected" or "Managed DMARC is ready — activate now." A domain runs fine without DMARC; the offer is there when you want it.
- DMARC still leads when it's the only gap. If everything else is healthy and DMARC is the one thing missing, it's still your top item — just framed as an option rather than an alarm.
Why
The advisor used to rank DMARC above SPF unconditionally. For someone who came to fix an over-budget SPF record, that buried their actual problem under two DMARC nudges — for a capability that auto-provisions in the background and that they may not want. Driving priority from what's demonstrably wrong (or what you've actually engaged with) fixes both cases from one rule: the broken thing leads for the person with a broken thing, and DMARC leads for the person whose only gap is DMARC. "Engagement" means a DMARC record we can actually observe in your DNS (or reports we've received) — not just that your plan includes it.
The advisor now fixes your SPF/DKIM foundation before suggesting DMARC
When a domain has both an SPF/DKIM problem and a DMARC gap, the advisor leads with SPF/DKIM — because DMARC depends on a working SPF/DKIM foundation.
What changed
The advisor now ranks SPF and DKIM problems above DMARC in its priority order. If a domain has, say, an over-budget SPF record and a DMARC setup prompt, the advisor leads with "Fix your SPF" — not the DMARC item. The same holds for a missing/invalid SPF record or an invalid/weak DKIM key.
When SPF and DKIM are healthy and DMARC is the only gap, DMARC still leads — this only changes the order when both have issues.
(The rare cases where a Managed DMARC delegation is actively broken — a DNS conflict or a CNAME pointing at the wrong place — still surface at the top, since those need resolving regardless.)
Why
DMARC works by checking whether SPF or DKIM align with the From domain. If your SPF is broken (missing, malformed, or over the 10-lookup limit so receivers drop it), DMARC has a weaker foundation to act on — so fixing SPF/DKIM first is the right order of operations. The advisor now reflects that dependency instead of leading with DMARC.
DMARC page: 'Available' instead of 'Pending activation', honest enforcement wording, and pct/p=reject explainers
Managed DMARC now reads as an available option rather than a started task, partial enforcement is no longer called full 'Enforcing', and we added plain-language depth explainers for how pct and p=reject actually behave.
What changed
A few wording and clarity fixes on the DMARC surfaces:
- "Available" replaces "Pending activation." A pre-built but not-yet-activated Managed DMARC capability now reads as an option you can take whenever you want — not a task with a clock running. On the domain hub it shows a calm "Available" with no management badge (matching how pre-built Managed SPF already behaves), and the focused page leads with "Want DMARC monitoring for this domain? We've pre-built it — activating is a single CNAME record, whenever you're ready."
- The staged-record label softened. "We'll publish (replaces your current record)" is now "Here's what we'd publish if you turn this on."
- Honest enforcement wording. When your policy is at
pct < 100, the advisor heading now says "Partial enforcement — monitoring for changes" instead of "Enforcing" — onlypct=100(orp=reject) reads as full "Enforcing." The exact percentage still shows just below. - Two new plain-language explainers (collapsible, so they don't crowd the page):
- How does pct work? — DMARCbis-aware receivers treat a
pctbelow 100 as testing mode (effectivelyp=none); move topct=100to actually enforce. - Does p=reject guarantee rejection? — receivers MAY honor
p=reject; large mailbox providers generally do.
- How does pct work? — DMARCbis-aware receivers treat a
Why
The old wording quietly pressured customers toward DMARC and overstated what their policy was doing. "Pending activation" implied a task you'd started and needed to finish, even on domains where you'd never asked for DMARC. "Enforcing" at pct=10 reads as full protection when only 10% of failing mail is actually being acted on — and DMARCbis-aware receivers treat anything under 100% as a test. Stating these precisely, with the spec details one click away, respects both the admin who just wants the gist and the expert who needs the citation.
DMARC explanations lead with the benefit, with the RFC detail one click away — and a plainer pricing headline
The DMARC tool-result card and wizard now explain Managed DMARC in plain language first, with alignment/policy/enforcement detail tucked into a 'How does Managed DMARC work?' disclosure. The pricing page headline now names what's on the page.
What changed
- DMARC result card + wizard lead benefit-first. When you check a domain with no DMARC record, the result card used to say Managed DMARC "watches alignment, and walks the policy from monitoring to enforcement" — three terms you'd need to already know. It now leads with what you get: "Managed DMARC sets this up for you, watches who's sending as your domain, and makes it harder for spammers to fake you — no DNS work on your side." The same rewrite applies to the Managed DMARC offer on the DMARC wizard.
- The precise terms moved into a depth layer. Both surfaces now carry a collapsible "How does Managed DMARC work?" explainer with the exact RFC vocabulary — SPF/DKIM alignment, advancing your policy from monitoring (
p=none) to enforcement (p=quarantine/p=reject) — and a link to RFC 7489. Available to anyone who wants it, out of the way for anyone who doesn't. - Plainer pricing headline. The
/pricingH1 changed from "Stop managing email authentication by hand." to "Pricing — Diagnose, Monitor, and Manage email authentication" — it now names what's on the page using the same Diagnose → Monitor → Manage vocabulary as the plans themselves.
Why
A first-time visitor checking their DMARC shouldn't have to decode "alignment," "policy," and "enforcement" before they understand what the product does — but an expert evaluating us shouldn't find the explanation dumbed-down either. Leading with the plain-language benefit and putting the spec-grounded detail one click away serves both. And a buyer who's already finished evaluating wants the pricing page to label itself, not pitch at them.
Adding a domain you already monitor is now rejected cleanly
Re-adding a domain that's already on your dashboard returns a clear 'domain already added' message instead of silently creating a duplicate.
What changed
Adding a domain you're already monitoring now returns a clear "domain already added" error (HTTP 409) instead of creating a second copy. The duplicate check runs at the application layer, so it holds regardless of database-level constraints.
Why
A database schema change had removed the unique constraint the create path quietly relied on to catch duplicates, so re-adding the same domain could create a duplicate entry. The check is now enforced explicitly in the domain-create handler.
Faster domain list and history views
The domain list now loads in well under a second even for accounts with many domains, and the per-domain timeline and stats views stay fast as monitoring history grows.
We made the dashboard noticeably faster for accounts with lots of domains and long monitoring histories.
What changed
- The domain list loads almost instantly. Previously, opening Domains could take many seconds for accounts with a large number of domains, because the page was computing a per-domain health summary it never actually displayed. We removed that wasted work — the list now paints in well under a second, and your per-domain advisor recommendations fill in right behind it.
- Timeline and stats stay fast as history accumulates. The per-domain history timeline and the health-percentage stats are now backed by a precomputed per-cycle summary instead of scanning every raw check result on each page load. The views look identical; they just don't slow down as months of monitoring history pile up.
Why
As an account grows — more domains, more months of continuous monitoring — the underlying check history grows with it. The old approach re-derived everything from the full raw history on every page view, which got slower over time. These views now read from a compact rollup that's maintained as checks run, so performance stays flat no matter how much history is behind it. No setting to change and nothing to migrate on your end.
Clearer domain status, login, and DNS-checks wording
A monitored domain now reads 'Monitoring' instead of 'Active', the DNS hygiene section is labeled more plainly, and the login bullets describe alerts in plain terms.
What changed
A few small wording fixes for clarity:
- A monitored domain now reads "Monitoring," not "Active." On the per-domain page, the status pill for a watched domain said "Active" — which collides with the "Active" state used by Managed SPF and Managed DMARC. It now says "Monitoring," with a tooltip: "We're watching this domain's email-auth records." "Active" is reserved for managed services that are actually publishing on your behalf.
- The "DNS health checks" section is labeled plainly. The collapsible substrate on the domain page was titled "Monitoring & DNS hygiene"; it's now "DNS health checks," and its empty state explains what runs there: "Delegation, expiry, and blacklist checks run here."
- Login page bullets are plainer. "Alerts the moment your SPF, DKIM, or DMARC breaks" → "Alerts the moment something breaks that could send your email to spam" (with the protocol detail in a tooltip). "A heads-up if your mail server hits a spam blacklist" → "A heads-up if the IP your email provider uses ends up on a spam blacklist."
Why
"Active" meant two different things depending on where you saw it — a domain being watched vs. a managed service publishing your records. Splitting those words removes the ambiguity. The login and section copy lead with the outcome a non-expert cares about (email landing in spam, the right IP getting blacklisted), with the technical specifics available but not in the way.
Record cards always show a broken record over a setup prompt — even on Free, even mid-activation
A malformed DMARC record now surfaces regardless of plan or Managed-DMARC state, and the card precedence is now structural so a setup/availability message can never hide a health problem.
What changed
A follow-up to the health-first card fixes — making "a real problem always shows over a setup prompt" a structural guarantee rather than a per-case patch:
- A malformed DMARC record now surfaces on every plan. Previously a Free-plan domain with a broken
_dmarcrecord showed "Locked — DMARC Reporting (paid)," hiding the broken record. Fixing a DMARC record is free, so the broken record now shows ("Malformed record") regardless of plan. - A stale or failed-to-provision domain shows that problem instead of "Managed active" / "Available."
- Under the hood, the DMARC card derivation and the SPF/MX card derivations now run through an explicit precedence — structural delegation errors, then health problems, then setup/availability — so a future managed-service card can't re-introduce a setup message that buries a health problem.
When everything's healthy, the calm "Available" / "Ready to activate" framing still leads, exactly as before.
Why
These cards exist primarily to tell you the health of each record. The fix generalizes the principle into the code's structure: a setup or availability message is always secondary to a real problem, in every card.
Domain record cards lead with health problems, not setup prompts
The per-domain SPF and DMARC cards now surface a real problem (over-budget SPF, malformed DMARC) as the primary message — a 'ready to activate' or 'available' setup affordance can no longer hide a broken record.
What changed
The SPF, DKIM, and DMARC cards on the per-domain page are health indicators first. A couple of cases where a setup/availability message was overriding a real health problem are fixed:
- SPF card: if your SPF record has a problem (over the 10-lookup limit, missing, invalid, or soft-fail) while Managed SPF is pre-built, the card now leads with that problem — e.g. "SPF lookup limit exceeded" — and offers Managed SPF as the fix, instead of showing only "Ready to activate."
- DMARC card: a malformed
_dmarcrecord now shows as "Malformed record" even when Managed DMARC has been pre-provisioned — the "Available" setup pill no longer hides a broken record.
When SPF/DMARC are healthy, the calm "Ready to activate" / "Available" framing still leads, as before — this only changes things when there's an actual problem to surface.
Why
Those cards exist primarily to tell you the health of each record. A pitch to activate a managed service shouldn't outrank "your record is broken right now." This also makes the cards agree with the advisor banner above them, which already leads with the real problem.
Clearer record-card labels: 'Self-managed' replaces 'Unmanaged', and 'No DMARC record' states the facts
Record cards now say 'Self-managed' (not 'Unmanaged') when you maintain a record, show no badge when there's no record at all, and the DMARC card states the DNS reality plainly instead of implying you forgot something.
What changed
The per-domain record cards (MX / SPF / DKIM / DMARC) now use a clearer, three-state management badge:
- Managed — mxio publishes and maintains this record for you.
- Self-managed — you maintain the record; mxio monitors it for changes. (This replaces the old "Unmanaged" label.)
- No badge at all — when there's no record in DNS, the card simply states that fact instead of attaching a label.
The DMARC card's no-record state was also reworded. Where it used to read "Not set up," it now reads "No DMARC record" with a neutral line: "No DMARC record found. A domain can run fine without one — add DMARC when you want to see who sends mail as you." And if you already have a DMARC record published but haven't turned on mxio's DMARC reporting, the card now says "Reporting off" and keeps the "Self-managed" badge — it no longer incorrectly claims you have no record.
Why
"Unmanaged" read like a broken or unfinished state — as if you'd forgotten something — when it actually just meant "you maintain this record yourself, and we watch it for you." That's a normal, healthy configuration, not a deficiency. "Self-managed" says what's true without the negative undertone, and dropping the badge entirely when there's no record keeps the label honest: it speaks to who manages a record, and only when one exists.
The DMARC wording follows the same principle — state the DNS reality plainly and offer DMARC as an option, never as a chore you're behind on.
Managed SPF reads as complete on its own — DMARC sender discovery is now framed as optional
The Senders and Managed SPF surfaces now lead with the SPF-only-complete path; the DMARC-report sender discovery is described as a conditional enhancement, not something Managed SPF depends on.
What changed
Two pieces of copy on the Managed SPF and Senders surfaces were re-worded so that Managed SPF reads as a complete product on its own, and DMARC-report sender discovery reads as an optional add-on rather than a dependency:
- Senders header. Was: "After activation, new senders must be added explicitly here or surfaced from your DMARC reports." Now: "After activation, add new senders explicitly here. If you use DMARC reporting, we'll also surface new senders we see in your reports."
- Managed SPF focused-page pitch. Was: "…folds in new senders as you authorize them from your DMARC reports." Now: "…folds in senders you add here. If you use DMARC reporting, it also surfaces new senders it sees in your reports."
Why
The old wording led the auto-sender-discovery value with "from your DMARC reports," which framed Managed SPF — a product a customer may have bought specifically to avoid DMARC — as working better only if they adopt DMARC. Leading with the explicit "add senders here" path and making the DMARC clause conditional keeps the discovery feature fully visible for customers who do use DMARC reporting, while removing the implication that an SPF-only setup is incomplete.
Managed SPF now activates for any SPF record, not just recognized providers
Managed SPF could not be activated for a domain whose SPF record contained only includes we didn't recognize by name — exactly the over-budget records the SPF flattening funnel attracts. Provisioning silently did nothing and the page showed a spinner that never resolved. It now builds and manages your flattened record from your whole SPF record, preserves your -all/~all disposition, and gives an honest state when a record uses something we don't auto-flatten yet.
What changed
1. Managed SPF activates for records built from any sender — recognized provider or not. Previously, auto-provisioning only kept the include: mechanisms it recognized from its provider catalog (SendGrid, Mailchimp, etc.) and discarded everything else. A domain whose SPF record was, say, a chain of custom include: mechanisms — the classic "too many DNS lookups" record the SPF flattening funnel exists to fix — ended up with zero recognized senders, so provisioning quietly no-op'd: no managed record was created, and there was no way to activate it from the UI. Managed SPF now builds your flattened record from your entire SPF record (every include, a, mx, ip4, ip6), using the catalog only to put friendly names on the senders it recognizes.
2. Your -all / ~all enforcement stays exactly as you set it. A separate bug meant the provisioning path didn't persist your record's all qualifier, so a strict -all record could be silently rebuilt as a softer ~all. Your disposition is now preserved verbatim.
3. Managed SPF is worth turning on even when you're under the lookup limit. Provisioning is no longer gated on being over the 10-lookup budget — Managed SPF maintains your record in concert with your sender list (including senders surfaced from DMARC reports), so it's useful as ongoing management, not just as a one-time flatten.
4. Honest states instead of a spinner that never finishes. When there's genuinely nothing to do yet, the SPF page now tells you why instead of showing an indefinite "setting up…":
- If your SPF record uses something we don't auto-flatten yet (an
exists:mechanism, aredirect=, a qualified mechanism, or a CIDRa/mx), you'll see a clear note saying so — and your record is left completely untouched. We never rewrite a record we can't flatten faithfully. - If there are no senders to build a record from yet, you'll get an "add your first sender" link to the Senders page.
5. The "Set up Managed SPF →" link now goes to the right place. It previously dropped you on the domains list with no setup surface. It now opens the domain's focused SPF page, where activation actually happens.
Why
The records that benefit most from SPF flattening are, almost by definition, the ones full of include: mechanisms — and many of those point at services outside any fixed provider catalog. Refusing to flatten what we don't recognize by name defeated the feature for exactly the customers it's built for. Flattening resolves an include to its IP addresses; it doesn't require us to know the sender's brand name.
Activity feed trim — less noise, real domain attribution, no more resolver flap
The cross-domain Activity page (/dashboard/activity) was carrying generic uptime-monitor framing (long-running 'Fail for N days' streak rollups, incidents, identical rows with no domain attribution) and was contaminated by false 'MX IPs changed / SPF record changed' events whenever an upstream DNS resolver blinked. We trimmed the feed to actions-and-changes only, fixed the domain prefix on every row, and stopped treating transient DNS lookup failures as record changes.
What changed
1. Cross-domain /dashboard/activity no longer shows long-running health streaks or incident events. Rows like "Fail for 6 days (1388 runs)" were dominating the feed — single events that kept re-jumping to the top as their streak continued. They're useful per-domain (the per-domain hub still shows them on the Monitor strip + Advisor), but in a cross-domain rollup they hide everything else. Incident events similarly: useful as backend triggers for the email-ack mute flow, but as in-app UI rows they were vestiges of the retired Incidents page.
2. Every record_change row now actually says which domain it's for. Previously, when MailRoute rotated IPs and five of your domains' MX records re-resolved at the same time, you'd see five identical "MX mail server IPs changed" rows with no attribution. They now read e.g. "terramar.net — MX mail server IPs changed", "mailroute.net — MX mail server IPs changed", etc. Root cause: the label lookup was filtering on a user-supplied display-name column that's usually NULL; fallback to the domain/host identifier was missing.
3. Transient DNS lookup failures stop being recorded as DNS configuration changes. When an upstream resolver returned empty data for a transient reason (timeout, recursive lookup glitch), the change detector compared the new empty result to the prior populated result and emitted "MX IPs changed: 199.89.1.120 → (empty)" — then the next cycle resolved fine and emitted "MX IPs changed: (empty) → 199.89.1.120" again. Forever flapping. The detector now suppresses these asymmetric empty↔populated transitions for MX, SPF, DKIM, and DMARC — real config changes (non-empty → different non-empty) still emit normally.
4. The "Health" tab on the cross-domain Activity page is gone (it would have been an always-empty bucket after #1). The per-domain Activity page keeps all four tabs unchanged.
Why
The Activity feed had become noise: long-running streak rollups crowded out fresh activity, identical rows with no domain attribution couldn't be acted on, and resolver flakiness in dev (and customer environments with intermittent NS lookups) was generating false "your records changed" notifications that customers had to ignore.
mxio's on-ladder vocabulary is Advisor (active issues) + Activity (history). The cross-domain Activity feed should be a portfolio-wide audit trail of real changes, user actions, and managed-service deployments — not a re-surface of per-domain check-run aggregates that already have better homes in the hub and Advisor.
What's deferred
- Persistent record-removal audit rows. With the change-detector fix, a customer who actually removes their SPF record gets the failure alarm from the status path, but the granular "SPF record changed from
v=spf1 …to(empty)" timeline row is suppressed. Status notifications still fire; the audit row will return when we add debouncing (N consecutive cycles of the new state confirm it's real, not transient). - Category dropdown ("show only DMARC events", "show only Managed SPF events"). Backend supports it; UI was descoped because the existing filter semantic doesn't include
spf_change_log/incident_eventsrows under their natural categories. Proper version needs per-category source mapping. - Resolver-layer retry on transient empty responses. Stacks with #3 above as a second line of defense. Reduces how often the change detector even sees a degraded result.
Domain health timeline now agrees with your score
Fixed a long-standing mismatch where a domain could score 100/100 yet show a solid-red 30-day health timeline. The timeline and the score now exclude the same informational checks (delegation, MTA-STS, DNSSEC, expiry). Also: when your DMARC record already points at us, the advisor stops telling you to 'add a DMARC record' — it now correctly says 'enable monitoring'.
Two related dashboard fixes surfaced while auditing a customer's per-domain page.
What changed
- The per-domain health timeline (and the small history pips on the domain list) now exclude informational checks —
delegation,MTA-STS,DNSSEC, anddomain expiry. Until today, those checks could flip a cycle's overall status to "fail" even though they're explicitly excluded from your domain's health score. The most visible symptom: a domain that scored 93 or 100 still showed a wall of solid-red bars on the 1h / 24h / 7d / 30d timeline, with no way to tell whether something was actually broken. The timeline now mirrors the score: green when your email auth is healthy, amber/red when something genuinely needs attention. - The "Set up DMARC" advisor no longer asks you to add a record you already have. If your
_dmarcrecord is already pointing at mxio's reporting address but the corresponding settings row went missing (a rare orphan state — usually post-deletion or manual re-publishing), the advisor now says "DMARC record found — enable monitoring to receive reports" instead of the misleading "No DMARC record — add one."
Why it mattered
The contradiction was real and confusing: the score said "you're fine," the badge on the "Delegation" hygiene chip said "fail," and the timeline said "you've been failing every check for a month." A customer reading that page had no path to a coherent story. Now all three surfaces are sourced from the same exclusion set (store.InformationalCheckTypes on the backend), and they can't drift apart.
Where to see it
Open any domain at Dashboard → Domains → [your domain] and expand "Monitoring & DNS hygiene." The 1h / 24h / 7d / 30d history bar should now show real cycle history, not a flat color.
Associated Hosts: removed the cap and the off-ladder 'View all hosts' link
The per-domain Associated Hosts panel now lists every monitor inline, no cap. The 'View all hosts →' link pointing at the removed Hosts page is gone.
What changed
The Associated Hosts panel on each per-domain page now renders every monitor inline — there's no 5-host cap and no "View all hosts →" link.
Why
The cap and the View-all link were both vestiges of when mxio surfaced generic host/uptime monitoring as a top-level feature. In the email-auth model, the per-domain host count is tight (typically 2-3 MX IPs plus a handful of SPF-derived IPs), so capping the inline list almost never helped. The "View all" link itself pointed at /dashboard/hosts — which we removed from the left nav as part of the off-ladder trim. Sending customers there was wrong on both counts.
What remains: each monitor row (IP + source badge + monitor type) still links to its own host detail page, and the "Discover Hosts" button still works for re-detecting MX/SPF IPs after a DNS change.
Activity replaces Incidents in the dashboard nav
The dashboard now has an Activity page — a cross-domain merged timeline of check changes, health transitions, sender authorizations, and managed-record deploys. It replaces the Incidents nav slot. Alerts still fire on the same schedule and respect the same suppression; the in-app surface is now framed as monitoring activity, which is what email-auth observation actually is.
What changed
The Incidents page is gone. In its place is Activity — a cross-domain merged timeline showing check changes, health-status transitions, sender authorizations, Managed SPF deploys, and DMARC enforcement moves. The nav item now reads "Activity" and points at /dashboard/activity. Filter by tier (actions / changes / health), days (7 / 30 / 90), and domain. The per-domain timeline you already have on each domain hub is unchanged.
Behind the scenes, nothing about alerts changed. The same checks fire on the same cadence, the same 24-hour and 7-day reminder cycle runs, the same noise-suppression rules apply. What moved is the in-app vocabulary: "Incidents" was uptime-vendor framing borrowed from generic monitoring, and it never fit email authentication — a ~all SPF record or a DMARC policy at p=none isn't an outage, it's a posture. Activity is what monitoring an email-auth surface actually produces: a history. If you want to mute a repeating reminder for a known-ongoing issue, the Acknowledge link in the reminder email still works the way it did — that's the canonical mute path now.
Why
mxio's Monitor rung is continuous email-authentication observation, not endpoint reachability. The Incidents framing was a vestige of the earlier generic-monitoring positioning; pulling it out lines the dashboard up with what the product is. Active issues already live on the Advisor (per-domain hub banner + portfolio domain list); history now lives on Activity. Two surfaces, two jobs.
Tool-result CTAs now route to Managed services first
Free-tool result pages — DMARC checker, SPF checker, header analyzer, domain health — now route Fail results to Managed SPF and Managed DMARC as the primary fix, instead of generic Monitor framing. One CTA per failure, in one place.
When you run a free email-auth check on mxio and the result is a Fail, the page now leads with a single Manage-rung fix — Fix with Managed SPF, Fix with Managed DMARC — instead of competing Monitor-flavored CTAs scattered across the result.
What changed
- DMARC checker: a "no DMARC record" result now points to Managed DMARC. The bottom action card carries the single CTA; the per-finding inline boxes and the top action bar coordinate so you never see three competing "Monitor this domain" buttons.
- SPF checker: failing SPF (over the 10-lookup limit, record too long) keeps routing to Managed SPF — unchanged.
- Header analyzer + domain health: DMARC-fail results now route to Managed DMARC instead of DMARC Reporting. The free-tool arrival's "fix this for me" intent is best served by the Manage rung.
- Per-finding inline upgrade boxes (the small "fix with…" panels inside each finding card) only appear for findings that have a Manage product available — SPF and DMARC. Findings for MX, DKIM, blacklist, and delegation no longer carry their own inline CTA, because there's no Manage product to recommend; the bottom action card handles those cases with a single Monitor CTA.
- Generic "Track this domain to catch changes and regressions" fallback is gone. The action bar at the top of a result no longer competes with the bottom card when a Manage product applies.
Why
We pivoted from an email-monitoring product to an email-authentication-management platform a while back, and the marketing surfaces ratified the new product order in May (the Diagnose → Monitor → Manage ladder in docs/reference/BRAND-VOICE.md §6.1). But the tool-result pages were still mostly Monitor-framed — three or four "Monitor this domain" buttons per result, no clear path to the Manage product that would actually fix the customer's problem.
A persona walkthrough as a small-business owner with a newsletter going to spam surfaced this clearly: the page told her what was wrong but every CTA asked her to "watch the problem continue" rather than "let us fix it." Wave 6 corrects that.
What's NOT in this change
- DMARC Reporting (the Monitor-rung product for DMARC) still exists and is still available — it just isn't the automatic CTA off a diagnostic failure anymore. Customers who specifically want a reports-only product can reach it via the marketing nav or
/services/dmarc-reportingdirectly. A small "or just want reports? →" subordinate affordance on the bottom card is a possible follow-up. - The DMARC Wizard (
/tools/dmarc-wizard) — the "build a DMARC record yourself" tool — is unchanged. A separate change will add a "Don't want to configure? Let us do it for you" Managed-DMARC entry point inside the wizard. - Logged-in dashboard surfaces — the per-domain hub, focused pages, and advisor are unchanged. Wave 6 is specifically about the free-tool result pages and the diagnostic-to-Manage handoff.
Per-check detail in the monitoring strip — chips finally explain themselves
Expanding the 'Monitoring & DNS hygiene' panel on a domain now shows a labeled row per hygiene check (DNSSEC, MTA-STS, Delegation, Domain expiry, Blacklist) with the analyzer's one-line verdict. Previously, the panel showed colored chips and offered nothing else — no tooltip, no click target, no context.
What changed
The expanded Monitoring & DNS hygiene panel on each domain (Dashboard → Domains → [domain] → "View detail" on the hygiene strip) now lists each check with status, label, and a plain-English verdict — sourced from the analyzer summary the backend already produces. Previously, that panel showed colored chips at the top and then jumped to uptime/incidents/hosts/config, skipping the one thing the chips were pointing at.
Each row covers one check:
- DNSSEC — pass/info/warn/fail with framing like "Active and validating" or "Not configured. Informational — not required for email."
- MTA-STS — same shape, with "Strengthens TLS for inbound mail" framing when absent.
- Delegation — when the customer hasn't delegated DNS to mxio, this now reads "NS records don't match parent delegation. Informational unless you're using mxio for DNS." instead of just a red chip with no explanation.
- Domain expiry — analyzer's expiry date and remaining days when healthy; "Renew at your registrar" when warn.
- Blacklist — listing details when applicable.
Why
Audit followup: customers were seeing a red "Delegation" chip with no way to learn what it meant or whether they needed to act. The chips alone gave no signal about severity context — delegation: fail is a real DNS observation but it's informational for the vast majority of customers (who haven't delegated DNS to mxio, and don't need to). The detail rows close the loop: chip is the glance, row is the explanation.
Where the analyzer summary comes from
The backend per-check summary field has always existed; it just wasn't on the wire for hygiene checks. The list and anchor endpoints now carry it on checks[].summary (optional — pre-existing rows that never wrote a summary serialize the field as absent). Frontend falls back to per-check informational copy when the summary is missing.
Monitoring panel cleanup — uptime block out, last-change line in, hosts inline
The per-domain 'Monitoring & DNS hygiene' panel was carrying generic uptime monitoring framing that didn't fit how email auth actually works (DMARC warn ≠ downtime). We replaced the uptime % and 30-day pip chart with a 'Last change' line that links to per-domain activity, and the Associated Hosts panel now lists monitors inline instead of forcing a click out.
What changed
Per-domain page → "Monitoring & DNS hygiene" (expanded view) is now three quieter, more useful blocks:
-
Removed the uptime % pills (1h/24h/7d/30d) and the 30-day pip history bar. They were applying a generic "endpoint uptime" model to email authentication, which never really fit — a DMARC record in
warnstatus isn't "downtime," your email is still flowing. Treating it as 0% uptime created the dashboard contradiction where a domain could score 100/100 but show a wall of orange bars. -
Added a "Last change" line. Replaces the pip chart with a single sentence: "Last change: MX mail servers changed (3 days ago). View activity →" — or "Steady for 30 days. No changes." when nothing has happened in the window. The "View activity →" link opens the cross-domain activity log pre-scoped to this domain.
-
Associated Hosts now lists monitors inline (for counts ≤ 5). Previously the panel said "2 monitors associated with this domain" and forced you out to a separate hosts page to actually see them. You now see each IP, its source (MX/SPF), monitor type, and a link to the host detail — right in the panel. For accounts with more than 5 monitors per domain, the count-summary + "View all hosts →" fallback still applies.
Why
mxio's "Monitor" rung is continuous email authentication observation — DMARC reports flowing, SPF not drifting, DKIM keys still valid. It's not "is this HTTPS endpoint reachable?" generic uptime monitoring. The dashboard had vestiges of the earlier generic-monitoring positioning; this trims them out so the surface matches the product.
Tool-result pages: one clear path to fix, DIY behind a disclosure
Free-tool result pages now lead with a single primary fix (the Managed CTA), with technical details and do-it-yourself DNS instructions tucked into an Or fix it yourself disclosure. AI Explain no longer shows an internal cost estimate.
Three small follow-ups to the Wave 6 tool-result CTA work earlier today.
What changed
- "Or fix it yourself" disclosure on every tool result page. Findings (the per-issue technical details) and DNS-host-aware fix instructions (the Cloudflare / Namecheap / etc. guidance panel) are now grouped under a single disclosure at the bottom of every tool result page. When a Managed service is available for the failure (Managed SPF or Managed DMARC), the disclosure is closed by default — the primary fix lives in the Managed CTA above and the DIY path is one click away for power users. When no Managed service applies to the failure (MX, DKIM weak key, blacklist, delegation), the disclosure is open by default because DIY is the only path.
- Disclosure features the matching wizard tool as the recommended DIY path. For the DMARC checker, the disclosure leads with "Use the DMARC Record Builder →" linking to
/tools/dmarc-wizard?domain=…. For the SPF checker, it leads with "Use the SPF Record Generator →" linking to/tools/spf-builder?domain=…. This makes the "this is how complicated it is" alternative explicit instead of dumping raw DNS instructions on the user. - DMARC checker: the "No DMARC record published" warn-tinted banner is folded into the action card. Previously the page showed two stacked panels saying overlapping versions of "no DMARC record": a warn-tinted banner ("anyone can spoof your domain") and an action card ("Managed DMARC publishes the record"). Now it's one warn-tinted card with both the consequence framing and the Managed DMARC CTA.
- DMARC Record Builder gets a Managed DMARC upsell at the top. A small "Don't want to configure all this yourself?" panel sits above the wizard form, pointing to
/services/managed-dmarc. Users who arrived at the wizard but realize they don't want to make 6+ configuration decisions can opt out without backing all the way up to the checker page. - AI Explain: the "≈$0.02" cost estimate is gone. That number was mxio's internal AI cost, not anything customers pay for. Showing it created the wrong impression. Removed from both the collapsed and expanded variants of the AI Explain affordance.
Why
These three came directly out of a persona walkthrough as a small-business owner who arrived at the DMARC checker frustrated about a newsletter going to spam. She read top-to-bottom and saw: "Managed DMARC will fix this for you" → "update your DNS records at Cloudflare" → "add a DMARC record at _dmarc.your-domain.com". Three mental models stacked vertically — "we do it for you," "go to Cloudflare yourself," and "here's the literal record to publish yourself." She couldn't tell which path the page actually wanted her to take.
The disclosure separates the choice cleanly: pick the Managed product (recommended), or expand the disclosure to see the DIY instructions. Diagnosis (the score, the failure summary) stays visible above so users always see what's wrong, regardless of which fix path they choose.
The cost estimate fix is even simpler — that label was just wrong. Customers don't pay for AI Explain. Showing them an internal cost estimate was a confusing artifact of an early experiment.
What's NOT in this change
- The Managed DMARC, Managed SPF, and DMARC Reporting marketing pages are unchanged.
- The dashboard (logged-in surfaces) is unchanged. This is a free-tool result-page polish, not a dashboard change.
- AI Explain itself still works the same way — same content, same quota, same model. Only the cost-estimate label was removed.
Clearer reporting state on the DMARC card
The DMARC record card on each domain hub now shows a second pill — Reports: Pending / Not Published / Stale / On — so you can tell at a glance whether aggregate DMARC reports are actually flowing without opening the focused DMARC page.
The DMARC record card on the per-domain hub now surfaces report flow as a distinct pill, separate from the Managed/Unmanaged badge.
What changed
-
New
Reports:pill on the DMARC card. Sits next to the existing Managed/Unmanaged badge and answers a different question: not "who publishes this record" but "are aggregate reports actually showing up?" Four states:- Reports: Pending — DMARC is enabled and our RUA address is in your record, but no reports have arrived yet (the first batch lands within ~24 hours of enable for most senders).
- Reports: Not Published — DMARC is enabled on our side, but
your published
_dmarcrecord does not include our RUA address. Reports are not flowing to us and won't until the record is updated. - Reports: Stale — reports were flowing but have stopped for 14+ days. Usually means a sender or rua tag changed and needs a look.
- Reports: On — recent reports observed within the freshness window. No action needed.
-
Visual harmonization. The Managed/Unmanaged badge and the new Reports pill now share the same shape, font size, and border treatment — they read as a pair of sibling pills rather than two different components stacked together.
-
Tighter subtitle copy on stale reports. When the DMARC card surfaces a stale-reports gap, the subtitle is shorter and more action-oriented so the next step is obvious.
Why it matters
DMARC reporting failure is silent by default — your record stays published, your policy stays enforced, but the visibility you signed up for quietly evaporates. The Reports pill puts that on the surface of the domain hub instead of buried two clicks deep.
What stays the same
- No DNS or policy changes — your published
_dmarcrecord, your enforcement state, and your RUA destinations are untouched. - The reporting axis is DMARC-only — MX, SPF, DKIM, and Senders cards don't render a Reports pill.
- The focused DMARC page is still the place to investigate why reports are stale or not published. The pill links you there.
Managed DMARC — delegate your _dmarc record to mxio
Pro and Business plans can now hand off _dmarc.<domain> to mxio via a single CNAME. We publish policy on your behalf and shepherd you from p=none through quarantine to reject. Rolling out to staff first.
Managed DMARC is live — for staff accounts first, then a staged rollout to customers. Here's what it does.
What it is
You point your _dmarc.<domain> record at mxio with a CNAME:
_dmarc.yourdomain.com. CNAME <label>.dmarc.mxdns.io.
From that point on, mxio controls what receivers see. We start you at
p=none (monitoring-only) and advance your policy on a schedule — tracking
your email volume, sender alignment, and report coverage at each step before
we move. The progression goes: none → quarantine → reject.
How the progression works
We enforce dwell times at each stage before advancing. On the standard cadence:
- None → quarantine: 14 days of reports, ≥ 50 authorized messages in the last 30 days, ≥ 98% pass rate, no anomalies.
- Quarantine → reject: 7 days at quarantine, same readiness gates. You explicitly approve the quarantine→reject step before we move.
You can also choose a cautious cadence (double the dwell at each stage) or a fast cadence (half the dwell) — or set fully custom dwell times.
Pre-existing DMARC records
If your domain already has a _dmarc record, we read it first. Policy tags
we recognize (p=, pct=, sp=, adkim=, aspf=) are preserved where
safe; your RUA destinations are migrated so you don't lose existing reports;
tags we don't manage are kept verbatim. Records with partial pct= values,
psd markers, or unknown tags are flagged for manual review — we won't
silently change a record we can't fully reason about.
What you keep control of
- You flip DNS, not us. We provision the managed sub-record, but the CNAME is your change to make.
- The quarantine→reject step requires your explicit approval — no automatic jump to the strictest policy.
- You can reset the cadence, change the pace, or disable Managed DMARC at any time. Disabling removes our record from Cloudflare; what you had before is yours to restore.
Current rollout status
Managed DMARC is live behind a feature flag. Staff accounts see it first; we'll open it to customers on Pro and Business plans once we've done a full staff walkthrough. The Pro plan minimum mirrors Managed SPF.
If you're a staff member and don't see the Managed DMARC option on your domain's DMARC page, ping the team to get your account added to the allowlist.
Managed DMARC: faster CNAME verification + safer first-touch onboarding
Verify CNAME now uses authoritative-direct DNS — works within seconds instead of waiting on stale cache. Customers with a pre-existing _dmarc CNAME to a third-party DMARC provider are flagged for review instead of having that provider's policy silently published into our zone.
Two issues caught in Phase U functional testing of Managed DMARC. Both ship together because they shared a code path.
What changed
-
Verify CNAME works within seconds, not 30 minutes. Previously the "Verify CNAME" button could keep saying "DNS not propagated yet" for up to 30 minutes after the customer had set the CNAME correctly. The probe was going through the OS recursive resolver, which negative-cached the pre-CNAME NXDOMAIN for the full SOA-min TTL — and the reconciler's background polling kept re-priming that cache. Verify now queries the customer's authoritative nameservers directly via miekg/dns, bypassing recursive caches entirely. Reconciler polling on
readyrows is also paused until the user has confirmed the CNAME, so it can't re-prime the cache during setup. -
Live cache countdown when DNS is still propagating. When the resolver does return a cached-negative response, the API now returns the live SOA TTL as
cache_ttl_seconds. The activation surface renders a countdown — "DNS cache clears in 0:42 — we'll re-check automatically when it does" — instead of the vague "give it a few minutes" copy. When the countdown hits zero we re-probe immediately. -
Third-party DMARC providers are no longer silently inherited. A customer whose
_dmarc.<domain>was a CNAME pointing at another DMARC provider (dmarcian, PowerDMARC, etc.) previously had that provider's full DMARC policy — including their RUA / RUF reporting endpoints — published into our zone. Customer DMARC reports would have flowed to a third party they may have no contract with. We now detect the wrong CNAME at provision time, refuse the import, and flag the domain for manual review with the observed target captured.
Why this matters
Both issues affected first-touch onboarding. The verify delay was a real-world blocker; the foreign-CNAME adoption was a data-exfiltration risk masquerading as a smooth "we found your existing DMARC policy" experience. Customers should now have a faster, safer first run-through of Managed DMARC activation.
Who it affects
Customers on Pro+ plans where Managed DMARC has been enabled. Existing
active customers are unaffected (the reconciler skip only applies to
ready rows that haven't yet been verified; once activated, drift
detection runs as before).
Cleaner DMARC + SPF status badges on per-domain pages
Domain hub and DMARC focused page now reflect Managed DMARC state correctly — no more stale 'Self-managed / Awaiting reports' on a freshly provisioned domain, and no more duplicate 'Setting up' cards stacking against the activation instructions.
A small round of cleanup on the per-domain pages, surfaced during Phase U functional testing.
What changed
- Hub DMARC card respects Managed DMARC state. Pro/Business customers on Managed DMARC now see "Pending activation" + "Set the CNAME at _dmarc to activate" on the hub the moment we provision, instead of the misleading "Self-managed / Awaiting reports" framing carried over from the legacy DMARC Reporting state machine.
- Hub SPF card no longer claims "Setting up" when nothing is in flight. When auto-provisioning Managed SPF no-ops because we couldn't catalog-match any senders (typical for a brand-new domain with no SPF record), the card now mirrors its MX/DKIM siblings with SPF-health framing — "Attention — No SPF record found" — instead of an alarming "Setting up" pill with nothing for the customer to do.
- DMARC focused page suppresses conflicting setup cards. When Managed DMARC is enrolled, the legacy "Publish this _dmarc TXT record at your DNS provider" card and the "Setting up — we're publishing your DMARC record" banner are hidden. The Managed DMARC block carries the authoritative next step (set the CNAME) without competing instructions that would have asked the customer to set both a TXT and a CNAME at the same DNS name (impossible per DNS rules).
Who it affects
Customers on Pro+ plans where Managed DMARC has been enabled. Non-eligible users are unaffected (the response was already correct for them).
Managed DMARC: clearer activation progress + activation-complete notification
The Managed DMARC focused page now shows a 4-step progress display during the 5–15 minute window between CNAME verification and full activation. When activation completes we send an in-app notification + a transactional email so you know your DMARC pipeline is live.
Two related improvements to the Managed DMARC activation experience.
What changed
-
Intermediate "Activating" state on the focused DMARC page. Verifying your CNAME with the inline check button tells you mxio detected the change — but full activation only flips on the reconciler's next 5-minute tick. Previously the page went straight from "Pending activation" to "Active" with no signal in between, which led to a reasonable "did I break something?" reaction when the page kept showing "Pending activation" five minutes after a successful verify. The focused page now renders a 4-step progress display during that window:
- CNAME verified
- Confirming with our reconciler
- DMARC reporting handshake
- Active
The page polls our status endpoint every 30 seconds and auto-advances as each step completes. You can leave the page; we keep working in the background.
-
In-app notification + email when Managed DMARC goes active. Once the reconciler confirms the delegation and flips your service to active, you now get a bell-dropdown notification and a transactional email — "Managed DMARC is active for
<your domain>" — so you can close the loop without checking the dashboard.
Why it matters
Activation is the moment you actually get the value of Managed DMARC — ongoing policy progression and aggregate reporting. The progress UI makes the 5–15 minute handoff window legible rather than mysterious, and the notification + email mean you find out the moment we're done.
What stays the same
- No DNS or policy changes — this is pure UX + notification.
- Manual review, wrong-CNAME, and DNS conflict surfaces still take priority over the activation progress display when they fire.
- N3 invariant preserved: customers not eligible for Managed DMARC see no UI change.
Compare pages refreshed: Manage-first across all 7 vendor comparisons
All comparison pages — autospf, mxtoolbox, dmarcian, easydmarc, powerdmarc, dmarcly, valimail — rewritten to position mxio as a Manage-rung platform. Managed DMARC now called out as live alongside Managed SPF.
The seven comparison pages on /compare/* used to position mxio as a Monitor
platform with extras stacked on top. They now position mxio as what it
actually is: a Manage-rung platform — we publish your SPF record (Managed
SPF), we publish your DMARC policy (Managed DMARC), and we monitor everything
around them.
What changed. Across all seven pages:
-
Endpoint-monitoring framing dropped. The HTTPS / Ping / TCP Port bullets that appeared on every page are gone. They were off-ladder for what mxio actually does — manage email authentication, not monitor arbitrary endpoints. MX SMTP reachability stays as on-ladder substrate (it's email-specific and runs on every tier including Free).
-
"Honest Caveat: Managed DMARC" sections retired. The PowerDMARC and DMARCLY pages used to carry sections conceding that Managed DMARC wasn't available. It is now. The pages flip to head-to-head: both vendors offer CNAME-delegated Managed DMARC; the differentiator is bundling and price tier.
-
MXToolbox page re-lede. Previously "built for continuous monitoring" — that framing concedes Monitor positioning to a vendor who already owns it. Now: "built to manage email authentication, not just report on it."
-
Valimail page rewritten as a Manage-rung peer. Both vendors operate the email-auth layer. The differentiators are the delegation model (selective record delegation vs full namespace handover), the audience (SMB vs enterprise), and the pricing model (published self-serve vs $5,000/yr sales-call entry).
-
autospf page sharpens the full-platform-vs-single-feature framing. AutoSPF is a SPF flattener; mxio is the email-auth platform that includes Managed SPF alongside Managed DMARC and DMARC Reporting.
No new features in this update. The product changes (Managed DMARC, the five-plan ladder) already shipped. This is the marketing site catching up to the product.
Cleaner pricing lineup + Managed DMARC arrives at Pro+
We retired the Monitoring Starter plan, surfaced Managed DMARC as a Pro+ peer to Managed SPF, and rewrote the pricing page around a single linear ladder. Existing customers see no change.
The old lineup had two $19 starter plans — Monitoring Starter and DMARC Starter — that worked the same except for which feature was included. Customers found the symmetric-starter UI confusing, and we never saw a customer pick Monitoring Starter when DMARC Starter was right there for the same price.
New lineup. One linear ladder, five tiers:
| Free | DMARC Starter | Core | Pro | Business | |
|---|---|---|---|---|---|
| $0 | $19/mo | $34/mo | $59/mo | $129/mo |
DMARC Starter is the $19 entry. Core ($34) is "DMARC Reporting at scale" — more domains, faster checks, more email alerts. Pro and Business are the managed-services tier: Managed SPF + Managed DMARC + the full ops platform.
Always-on monitoring on every tier. MX, SPF, DKIM, and DMARC records are monitored continuously on every plan, free tier included. The "Monitoring Starter" plan that used to sell monitoring as a standalone product is gone — because monitoring is now substrate, not a product.
Managed DMARC arrives at Pro+. Symmetric with Managed SPF. We auto-provision
your managed _dmarc record at domain-add time. You publish one CNAME at
_dmarc.<your-domain> — the same single-DNS-change pattern as Managed SPF.
We monitor reports, track enforcement readiness, and propose tightening from
p=none to quarantine to reject when your senders are reliably aligning.
You approve. We deploy.
The full Managed DMARC page is at /services/managed-dmarc.
Existing customers see no change. Owner verified zero monitoring_starter
subscribers at cleanup time — there was nothing to migrate. Anyone on Pro or
Business will see the new Managed DMARC surface alongside their existing
Managed SPF. No price change, no feature loss.
What else moved:
- Nav dropdown renamed "Services" → "Managed Services". Order: Managed SPF, Managed DMARC, DMARC Reporting.
- Homepage subhead "Diagnose. Monitor. Fix." → "Diagnose. Monitor. Manage." — three nouns that match the three product rungs in order.
/services/monitoringpage retired — 301 redirect to/pricing. Anyone with a bookmark goes straight to the new lineup.- Flatten packs eliminated. SPF flattening is now a hard plan benefit: Pro gets 10 flattened domains, Business gets 25. No add-on, no per-domain arithmetic.
Tool results now point at the right fix
Failing SPF results route to Managed SPF. p=none DMARC routes to DMARC Reporting. p=reject DMARC routes to Managed DMARC. The generic 'Want continuous monitoring?' CTA is gone.
Every free-tool result page used to end with the same suggestion: "Want continuous monitoring? Add this domain to your dashboard." Useful when the result was healthy. Less useful when it wasn't — a failing SPF check deserves a CTA that fixes the SPF, not a generic monitoring nudge.
What changed. The CTA below every tool result is now driven by the specific failure mode:
- SPF over the 10-lookup limit, near the limit, or failing → "Fix this with Managed SPF." Managed SPF flattens the include chain to IPs and stays under the limit automatically.
- DMARC missing or
p=none→ "Start with DMARC Reporting." Reporting classifies your senders so you can tighten the policy safely. - DMARC enforcing (
p=quarantineorp=reject) → "Keep it that way with Managed DMARC." Brand-new CTA surface — the enforcing-DMARC result used to fall through to the generic monitoring substrate, now it routes to the right service. - Weak DKIM key (1024-bit) → "Rotate to 2048-bit" with a link to the learn hub. We don't manage DKIM rotation yet — no fake CTA.
- Healthy results → still "Add this domain to your dashboard," because monitoring is the right move when nothing's broken.
What this fixes. The old "Want continuous monitoring?" CTA appeared
12 times across the tools surface and on the public /report/<domain> page.
Every appearance now picks the right destination per failure mode. A
logged-in customer viewing a tool result for a monitored domain gets a
deep-link straight to the relevant focused page (/dashboard/domains/N/spf,
/dashboard/domains/N/dmarc) — no more "go to dashboard, find the domain,
find the right tab."
No behavior change for anyone viewing healthy results, and no behavior change inside the dashboard itself — the dashboard already had per-domain focused pages.
Advisor now flags weak DKIM keys
The domain advisor now detects DKIM selectors using short RSA keys (under 2048-bit) and gives provider-specific guidance on how to rotate them.
The domain advisor now detects DKIM selectors using short RSA keys — typically 1024-bit keys that predate modern security guidance — and surfaces a "Weak DKIM key detected" advisory action.
What it checks: When a DKIM health check finds a selector using an RSA key between 513 and 2047 bits, the advisor flags it. Keys of 512 bits or fewer are already treated as invalid (broken, not just short); this new signal covers the in-between range that is technically valid but increasingly considered insecure.
Provider-aware guidance: The advisor identifies which email provider each affected selector belongs to (Google Workspace, Microsoft 365, and others in the provider catalog) and tailors the advisory body accordingly:
- Single known provider: "Your Google Workspace DKIM key uses a short RSA key (under 2048-bit). Rotate it to 2048-bit in the Google Workspace admin console."
- Multiple providers or mixed: Lists all affected providers and routes you to the DKIM focused page for a full selector review.
- Unknown selector: Shows the selector name and advises contacting your email provider.
The action appears at priority 2.92 in the advisor — after dkim_invalid (a broken key),
before DMARC setup steps — and routes to the DKIM focused page via "Review DKIM
selectors →".
Domain settings now live where you'd expect them
Monitoring check configuration moved into the Monitoring & DNS hygiene panel, and DKIM selector management is on the DKIM page. The catch-all Edit button on the domain page is gone.
The per-domain page (Domains → your domain) used to hide two unrelated settings behind a single Edit button: monitoring check configuration and DKIM selectors. Each now lives with the thing it controls.
- Monitoring check configuration — which checks run for a domain — is now inside the Monitoring & DNS hygiene panel on the domain page. Expand the panel, then open Check Configuration.
- DKIM selector management — discover, add, and remove selectors — is on the domain's DKIM page, alongside DKIM status and CNAME setup.
- The Edit button is gone. Nothing was removed — both surfaces simply moved next to what they configure, so you no longer dig through a settings dialog to find them.
Managed SPF auto-activates when you add a domain
Managed SPF no longer requires a multi-step wizard. Adding a domain on a Pro or Business plan now pre-builds the managed record from your existing apex SPF — activation is a single DNS change.
Managed SPF setup used to be a multi-step wizard — detect senders, configure the managed record, publish, wait, verify. If you started but didn't finish, the domain detail page would sit in a "resume to finish" limbo with no cancel path.
We've replaced that with auto-provisioning at domain-add time. When you add a domain on a Pro or Business plan, we read your existing apex SPF, identify the senders we can catalog-match, and pre-build the managed sub-record on Cloudflare. The domain detail page then shows a "Ready to activate" card with a copyable replacement record and a single "Check DNS" button.
Activation is one DNS change at your registrar:
v=spf1 include:<your-label>.spf.mxdns.io ~all
We preserve the all qualifier from your existing record — if you were running
-all (hard fail), the copyable record uses -all too. No silent downgrade.
Drift panel: the domain detail page compares the managed record against your current apex SPF. If you have senders in your apex that we haven't added yet (or vice versa), the panel tells you so before you flip DNS — no surprise coverage gaps.
For domains already in the wizard's pending state: an ops backfill
sweeps them safely. Domains that already have a working managed record
transition to active without a re-deploy; the rest get re-provisioned.
Plan upgrades: crossing into a Managed-SPF-eligible plan now retroactively provisions all your existing domains via the same path. No manual setup required.
Downgrades: if your plan loses Managed SPF entitlement while a domain is in
ready state, we check your apex DNS first. If you've already pointed at us,
we transition to active then paused (standard billing flow). If you
haven't, we delete the managed record cleanly. On DNS failure, we leave
everything intact — your configuration is never destroyed on ambiguous DNS.
Lookup answer shown first on every tool
Every DNS and email-authentication tool now shows the raw record - your MX hosts, SPF string, DMARC policy - as the first thing on the page, above the health score.
Tool results now lead with the answer. Run an MX lookup and the first thing you
see is the actual record, mail.mailroute.net, not a score or a paragraph about
it. The same applies across SPF, DKIM, DMARC, MTA-STS, blacklist, nameserver,
DNSSEC, expiry, and the DNS-record lookups: the raw value sits at the top,
copyable, with the health score and full breakdown right below it. The score you
rely on has not changed; it just no longer hides the lookup result.
The DMARC focused page now states your policy, and SPF soft-fail guidance is context-aware
The per-domain DMARC page reads your published record and policy, surfaces malformed records with a fix path, and never leaks internal error codes. SPF ~all guidance now depends on whether DMARC is enforcing.
A full walkthrough of the dashboard turned up a cluster of issues on the per-domain DMARC page and in how SPF soft-fail was framed. They're fixed.
The DMARC focused page reads your record. It used to show "p=unknown" and a
bare policy keyword where the published record should be. It now states your
actual policy — p=none, p=quarantine, or p=reject — and shows the full
_dmarc TXT record currently in DNS.
Malformed DMARC records are surfaced, not hidden. A _dmarc record that
exists but has a syntax error used to be mislabeled "DMARC not enabled." The
hub card now reads "Malformed record" and the focused page shows the broken
record with a clear fix path — receivers ignore a malformed record entirely, so
this matters.
No more internal error codes. A domain without DMARC enabled no longer renders raw backend codes or an empty "report evidence" section.
SPF soft-fail guidance is context-aware. An SPF record ending in ~all
(soft-fail) is no longer labeled "Recommended". Whether ~all is adequate
depends on your DMARC policy: with DMARC enforcing, ~all is fine and the page
says so; without DMARC enforcing, ~all is flagged as a real gap on the SPF
card, the domain list, and the advisor.
Clearer advisor and card copy. The advisor banner's eyebrow now reflects severity consistently. A DMARC enrollment stuck without reports for over a week reads "No reports yet" instead of a calm "Setting up". Managed SPF setup that's mid-flight is labeled "Setup in progress" on the domain hub.
The domain list now flags SPF budget, malformed DMARC, and missing reporting addresses
The advisor and the status chips now agree. Over-budget SPF, broken DMARC records, and DMARC records that omit your mxio reporting address are caught for every domain — not just managed ones.
A domain's status chips and its advisor verdict used to draw from different places — the chips from real DNS probes, the advisor from our internal records. They could disagree: a domain with a red SPF chip could still read "All clear." That's fixed. The advisor now reads the same observed-DNS signals the chips do.
Over-budget SPF is caught everywhere. An SPF record that exceeds the 10-lookup limit is now flagged on every domain, with the real count ("11/10 lookups"), not just on domains using Managed SPF.
Malformed DMARC is no longer mislabeled. A _dmarc record that exists but
has a syntax error used to be reported as "No DMARC record." It now gets its own
verdict — "Your DMARC record is malformed" — so you fix the record instead of
adding a second one.
Missing reporting address is flagged. If a domain is enrolled in mxio DMARC
reporting but its published _dmarc record doesn't actually include your mxio
rua= address, the advisor now tells you — instead of showing "All clear" while
no reports come in.
SPF soft-fail shows as a warning. An SPF record ending in ~all (soft-fail,
which doesn't enforce) now renders an amber SPF chip, matching the advisor's
existing soft-fail verdict.
Advisor now surfaces SPF/DKIM gaps and DMARC enforcement readiness
The domain list advisor gains seven new recommendations: missing or broken SPF records, missing or invalid DKIM selectors, and DMARC enforcement readiness signals. DMARC chips now show observed policy labels.
The domain list advisor now covers the full email-auth lifecycle — not just DMARC setup and SPF budgets. Seven new recommendations surface the missing pieces:
SPF gaps — Missing SPF records, syntax errors, and soft-fail (~all) policies
each get their own recommendation so you know exactly what's wrong and what to fix.
DKIM gaps — No selectors configured (so we can't monitor your DKIM signing) and invalid DKIM records both surface as actionable attention items.
DMARC enforcement readiness — When your DMARC policy is p=none and your alignment data looks healthy, the advisor surfaces "ready to start enforcing?" When you're at p=quarantine with strong alignment, it suggests moving to full rejection. Both fire only when the data supports it.
DMARC chip labels — The DMARC chip on each domain row now shows the observed policy: "DMARC: none" in amber (monitoring-only), "DMARC: qtn" (quarantine), or "DMARC: reject". You can see enforcement level at a glance without opening the domain.
Managed SPF drift — When Managed SPF is active but the domain's published record no longer includes the managed SPF record, the SPF chip turns amber immediately — no waiting for the staleness threshold.
Subdomain checks now climb to the registered domain
Domain-expiry checks on a subdomain now report the registered domain's renewal date, and DMARC checks recognize protection inherited from a parent domain's subdomain policy.
Two checks gave wrong answers when you pointed them at a subdomain rather than a registered domain. Both are fixed.
Domain expiry now works for subdomains. Registries only hold a renewal date
for the registered domain — example.com, never mail.example.com. The expiry
check used to query the subdomain directly, get nothing back, and report a
lookup failure. It now climbs to the registered domain, reports that renewal
date, and labels the result clearly so you know whose expiry you're looking at.
DMARC now recognizes inherited protection. Under the DMARC standard
(RFC 7489 §6.6.3), a subdomain with no _dmarc record of its own is still
protected if the parent domain publishes a subdomain policy (sp=). The check
used to ignore this and report "No DMARC record found" — a false alarm on a
subdomain that was actually protected. It now climbs to the organizational
domain and reports the real, inherited policy:
- Inherits
quarantineorreject→ the subdomain is protected. - Inherits
none→ the subdomain is covered only by monitoring, flagged as a warning. - The parent has no valid DMARC record either → still reported as missing, with guidance to fix it at the subdomain or the organizational domain.
DMARC Setup Guide report
A new Setup Guide tab on the Reports page groups every domain by its DMARC setup stage and shows the exact _dmarc TXT record to publish for each one — with a per-domain Verify now button that checks DNS on demand.
The Reports page has a new Setup Guide tab. It groups every domain by its
DMARC setup stage — not configured, ready to strengthen, collecting data — and
gives you the exact _dmarc TXT record to publish for each one. Domains that
still need their record published carry a Verify now button that checks DNS
on demand. Export the whole guide as CSV to work through a portfolio at once.
The domain list now shows every advisor issue, not just the top one
Hover any domain's verdict to see the full list of outstanding email-authentication issues, each with its own explanation and fix link. The status column no longer repeats text already in the verdict.
The domain list verdict has always shown your single most important next step — the right call for keeping a long list scannable. But a domain can have more than one thing wrong at once, and until now the others were invisible.
Every issue, on hover. The row still shows the one primary headline; hover it to see the complete, priority-ordered list of everything the advisor found — missing SPF, an unconfigured DKIM selector, no DMARC record, and so on. Each entry gets its full explanation and a direct link to the page where you fix it. The verdict is now a link, and the whole row is clickable — no separate "Open" control.
A status column that earns its space. The short status text to the right of the verdict used to echo the headline — "No DMARC record" next to "No DMARC record — add one…", "Monitoring" next to "All clear — monitoring." It now carries only information the headline doesn't: lookup counts, senders to review, the day-of-14 baseline counter, alignment percentages. When the headline already says it, the column stays empty.
Senders now appear on the domain hub
A new Senders card on the per-domain hub shows how many senders you've authorized and whether any DMARC-discovered senders need review — all in one place, no longer split between the SPF page and DMARC slide-over.
The domain hub (/dashboard/domains/[id]) now has a fifth card: Senders.
Authorized senders were previously accessible only through the SPF focused page or the DMARC slide-over — two separate entry points for one shared registry. The new card surfaces the registry at a glance and routes directly to the Senders page.
What the card shows:
- Authorized senders — the count of senders you've explicitly approved (source other
than DMARC discovery, status
authorized). - Review needed — if senders appeared in your DMARC reports but haven't been authorized or dismissed yet, the card turns amber and shows the count.
- Mode-aware copy — when Managed SPF is active, the card notes that your SPF record is built from the list automatically. When you manage SPF yourself, it reminds you to make sure authorized senders are included in your record.
A faster dashboard home and clearer per-domain cards
The dashboard now opens straight to your domain list, domain rows are proper links, record cards show whether mxio manages each record, and new domains stay calm on day one.
A round of dashboard improvements makes the everyday flow faster and the per-domain view easier to read.
- Straight to your domains. The dashboard now opens directly to your domain list — no separate loading hub in between. The platform status for Monitoring, DMARC, and Managed SPF sits right at the top of the list.
- Domain rows are real links. Open a domain in a new tab or middle-click it like any other link.
- Managed or Unmanaged, at a glance. Each record card — MX, SPF, DKIM, DMARC — now shows a Managed or Unmanaged badge, so you can see what mxio maintains for you versus what you maintain yourself.
- The SPF card leads with SPF health. The per-domain SPF card now opens with the state of your SPF record — like its MX, DKIM, and DMARC siblings — instead of only talking about Managed SPF.
- Calmer first day for new domains. When you add a domain, its DMARC page no longer shows the full enforcement roadmap before there's anything to act on. It stays calm until reports arrive and explains that DMARC monitoring is turned on automatically.
- Polish. Clearer billing copy, a "mark all read" action for notifications, and a tidier navigation sidebar.
Domains list grouped by severity, with a recommendation per domain
The domains list now groups domains by severity — Needs attention, Watching, Healthy — with a plain-English recommendation per domain. The 0–100 health score and the dense column table are retired.
The domains list now groups your domains by what needs you — Needs attention, Watching, Healthy — so the one that's broken is at the top, not buried in a sorted table. Each row shows SPF, DKIM, and DMARC at a glance plus a plain-English recommendation of the next move. The 0–100 health score and the dense column grid are gone — a number and eight columns never told you what to actually do.
"Include in SPF record" toggle when authorizing senders
When you authorize a DMARC-discovered sender, you can now choose whether to include it in your Managed SPF record — with an evidence-based default and a real lookup-cost preview.
When you authorize a sender from the DMARC Discoveries panel, a new "Include in SPF record" toggle appears on each row.
- Evidence-based default. The toggle defaults off when your DMARC reports show the sender is already DKIM-aligned — meaning it passes DMARC without an SPF entry. For senders without DKIM alignment, the toggle defaults on.
- Real lookup impact. When the toggle is on and you have Managed SPF active, the UI shows the exact lookup cost from your SPF engine — e.g. "+1 lookup -> 5/10" — not a local estimate.
- Always reversible. The toggle is a recommendation, not a verdict. Override it any time. Authorizing with the toggle off leaves your SPF record untouched.
SPF page now shows your record and sender coverage
The per-domain SPF page now shows your published SPF record, lookup budget, and a gap analysis of which authorized senders your record actually covers — not just Managed SPF.
The SPF page for a domain (Domains → your domain → SPF) used to be only about Managed SPF. Now it works whether you manage SPF yourself or let mxio do it.
- Your SPF record, in plain view. See the published record, a DNS-lookup budget meter (with a warning when you cross the 10-lookup limit), the default-policy explainer for
~all/-all, and any validation problems. - Sender coverage gap analysis. mxio compares the services you've authorized against what your SPF record actually contains. It flags authorized senders that aren't covered — with the exact
include:to add — and includes in your record that don't match any sender, so you can spot stale entries wasting lookups. - Managed SPF, still one click away. If you'd rather not maintain the record by hand, the Managed SPF panel is right there — it flattens and maintains the record for you. When Managed SPF is active, mxio handles coverage automatically and the page says so.
Domain page is now a single morphing section stack — no more tabs
The per-domain page collapses Health / Reports / Configure tabs into one surface. Eight sections, each adapting to what your domain needs right now: a conversational prompt when a decision is pending, a compact status card when it's done, a focused editor when you're fixing something. A persistent Advisor names the single next move.
The biggest change to the Domain page since we launched it. /dashboard/domains/<id> no longer has tabs at all. Everything you used to navigate between — uptime status, DMARC policy, Managed SPF, DKIM, senders, reports, infrastructure checks, recent activity — now lives on one page as eight sections in a single stack.
Why kill the tabs. Health / Reports / Configure was a useful first cut, but the tab labels were product-shaped, not customer-shaped. "Am I on the right tab?" is a question we asked you to answer that we should have answered for you. The new model: one URL per domain, sections morph based on what the domain needs right now. A fresh domain with three pending decisions looks different from a year-old domain in monitoring mode — but it's the same page, the same skeleton, the same scroll. No tab to land on.
Sections adapt to their state. Each of the eight sections — Mail Flow, Senders, SPF, DKIM, DMARC Policy, DMARC Reports, Infrastructure, Activity — can render in one of three modes:
- Conversational when a decision is pending. Accent left border, plain-English prose explaining what to do and why, the action button right there.
- Monitor when the section is settled. Compact one-line status, or a rich-monitor card with stats and a deep-link for forensic detail.
- Edit when you're actively configuring something. The section expands in place — the editor opens right where the status card was, and the sections above and below stay exactly where they are. No modal, no pop-up, no leaving the page. Click Save or Cancel and the section settles back to its monitor card. You can deep-link straight into an editor too (
?edit=senders,?edit=dmarc) — useful for "fix this" links in alert emails.
Persistent Advisor names the next move. A block above the section stack always tells you the one most important thing to do right now, and points you straight at the section that handles it — "Start with DMARC", "Start with Senders". It doesn't re-explain the problem; the section itself does that when you get there. When nothing's urgent and the domain has been healthy for two weeks, the Advisor goes quiet ("All clear — monitoring").
DMARC arrival framing. A new visual strip in the DMARC section shows where you landed when you first turned on mxio (p=none / p=quarantine / p=reject) — frozen at first observation, so the framing copy matches your actual journey. Customers who arrived at p=quarantine see different setup prose than customers who arrived at p=reject. We've watched too many people land on a generic "configure DMARC" screen that didn't match where they actually were.
Deep reports route to the cross-domain hub. The per-domain Reports tab is gone; "View full reports →" on the DMARC Reports section takes you to /dashboard/reports?domain=<your-domain>#senders — same data, but in the cross-domain UI where you can flip to comparing across all your domains mid-investigation. The URL contract is shareable: ?since=&until=&source= all preserved across navigations.
Old bookmarks still work. ?tab=health|reports|configure URLs automatically router.replace to the clean URL and smooth-scroll to the relevant section.
What this enables next. The section primitive (<DomainSection>) is the foundation for future managed services. Managed DMARC (Phase U) will add a configure section, not a new route. Pattern is locked.
This work shipped as Phase 6 of the Domain IA Redesign — the per-domain page rebuilt around a single morphing section stack. Local-only for now while we run visual regression and your final review before production deploy.
The DMARC enforcement journey is back inside the domain page
The step-by-step journey to enforcement — from monitoring through quarantine to reject — is now visible right under the DMARC Policy header in the Configure tab. Stage badges, blocker cards, anomaly cards, and AI Explain are all back.
If you've used the DMARC surfaces over the last few weeks and felt like something was missing from the Configure tab, you were right. The enforcement journey — the vertical stepper that walks you from p=none through p=quarantine to p=reject, with stage badges, blocker cards, anomaly cards, and the AI Explain button on each source — went quiet when we collapsed the per-domain DMARC surfaces into the Domain page back on 2026-05-16. The page only kept the status header (which state you're in right now); the path (where you are on the journey and what's blocking the next step) went missing.
It's back.
Where it lives. /dashboard/domains/<id>?tab=configure#section-1-dmarc-policy. The status header (DMARC Policy) sits at the top of Section 1; the journey panel sits right underneath, separated by a border. Same panel you've seen since 2026-04-14, mounted in its proper home.
What it shows. Same as before:
- Stage badge — Discovery, Configuration, Readiness, Enforcement, or Steady state.
- Three-phase stepper — Phase 1 Monitoring → Phase 2 Quarantine → Phase 3 Reject, with seven sub-steps highlighting the one you're currently working on.
- Blocker card — when something is holding you back from advancing (most commonly: unclassified senders that need an Authorize/Dismiss decision).
- Anomaly cards — new sender detected, alignment dropped, country cluster — each with an inline AI Explain button that gives you a plain-English read on what's happening.
- Authorize / Dismiss / Skip — per-source decisions wired straight into the sender registry, so a click here updates the same data the Senders surface uses.
Sources → When the journey panel says "Review N more sources" or "Review senders," that affordance now takes you to the Reports tab (?tab=reports), where the full Sources / Timeline / Geography / Reports detail lives since the three-tab refactor. Same destination as the "Full evidence →" button on the Health tab.
Nothing else changed. The journey UI hasn't been redesigned. The state machine hasn't moved. The backend hasn't changed shape. This is purely a re-mount of the existing component into the live IA — what shipped on 2026-04-14, in the place it should always have lived.
If you've been wondering "where do I see what's blocking my next policy advance?" — that answer is back in your Domain page.
Domain page is now three tabs: Health (default), Reports, Configure
The per-domain page splits Report into two — Health for the at-a-glance snapshot, Reports as a first-class evidence surface. The authentication-detail modal goes away; its contents are now a real tab. Old bookmarks redirect automatically.
A small but meaningful refinement to the Domain page. /dashboard/domains/<id> now opens with three tabs instead of two: Health (default), Reports, and Configure.
Why split Report into two. The old Report tab was doing two jobs — it was both the at-a-glance snapshot (uptime pills, history bar, service health cards, hosts, timeline, incidents) AND the entry point for the deeper Sources / Timeline / Geography / Reports evidence viewer (which was buried behind a "Full evidence →" button that opened a modal). Putting the snapshot on its own tab — Health — lets it breathe, and promoting evidence to its own top-level tab — Reports — makes the forensic detail a first-class destination instead of a modal hiding one click away.
Reports is no longer a modal. Sources / Timeline / Geography / Reports now render inline on the Reports tab. Same data, same sub-tabs, same DMARC report drill-down — just without the dialog shell, no focus trap, no "where did the page go." You can deep-link directly to it: /dashboard/domains/<id>?tab=reports.
Health is now the default. Land on a domain page and you see the snapshot view first. The Authentication Report card (7-day DMARC aggregate) lives at the top of Health, with "Full evidence →" right under it — clicking now navigates to the Reports tab instead of opening a modal.
Your old bookmarks still work. Two legacy URL shapes redirect automatically on mount:
/dashboard/domains/<id>?tab=report(singular, from the two-tab era) →?tab=health/dashboard/domains/<id>?dmarc=evidence(the old "open the evidence modal" intent) →?tab=reports
Both redirects happen in the URL bar — a refresh doesn't loop you back through the redirect.
Configure tab is unchanged. Sections 1–5 (DMARC Policy, DNS Pointing Status, Senders, External Reporting, Subdomains) all render exactly as they did last week. Deep links like ?tab=configure#section-3-senders still land at the right section.
Nothing about the underlying data, fetches, or service behavior changes — this is purely a layout and navigation refinement, building on Phases 1–4 of the Domain-Centric IA Redesign. With evidence now a real surface instead of a modal, you can leave it open, share the URL, refresh it without losing your place.
DMARC Policy block on the Domain page: better data density, clearer copy
Same-day polish pass on Phase 3's DMARC surface — the awaiting-DNS view now shows the record to publish, the active view shows your current configuration inline, and a handful of copy and dedup fixes across the Report tab.
After shipping the DMARC-into-Configure-tab move this morning, a targeted UX audit caught a handful of rough edges. Same-day fixes:
Awaiting-DNS now shows the record to publish. Earlier today the Configure tab's DMARC Policy block told you to "publish this _dmarc TXT record" without showing the record. Fixed — the expected TXT record name and value now render inline with copy buttons, sourced from your account's reporting destinations. No more clicking "Verify DNS →" hoping it reveals the record you're supposed to publish.
Active state shows your current configuration inline. Same screen, active state — was just "Policy: none — receiving aggregate reports." Added a "Current configuration" panel that shows your published _dmarc record, where reports are going (RUA destinations), when the last report arrived, and your sending status. You no longer have to click "Customize policy" just to see what's currently published.
p=none clarified. "none — receiving aggregate reports" misread as "no policy at all." Now reads "Policy: p=none (monitoring mode) — receiving aggregate reports for example.com."
Stale state no longer renders the badge label twice. Visible render bug — fixed.
DMARC and Managed SPF health cards on the Report tab no longer render two "View config" links side by side. The Slice 14 / Phase 2 "View configuration →" deep link is the one that goes to the canonical home; the legacy duplicate is removed.
Authentication Report empty-state copy differentiates "newly enabled — reports incoming" (under 48 hours since enable) from "no recent traffic — check your rua= destination" (enabled over 48 hours ago with zero messages).
Nothing about the backend changes. Same DMARC handlers, same anchor state machine, same authentication-summary endpoint. Just a closer-to-finished UX on the new DMARC home.
DMARC Reporting now lives on your Domain page, alongside SPF
Setup, configuration, status, override, and reports for DMARC have collapsed into the Configure tab on the Domain page — the same place Managed SPF moved to last week. The legacy URLs still work as redirects.
Phase 3 of the Domain-Centric IA Redesign ships today. Everything you used to do at /dashboard/services/dmarc/<your-domain>/{advisor,override,dns-records,setup,how-it-works} now lives on a single screen: /dashboard/domains/<id> → Configure tab → Section 1: DMARC Policy.
Why the move (again). If you're managing a domain, the natural place to check what mxio is publishing for it is on that domain's page — not buried under a per-service hub. Last week Managed SPF moved into Configure tab Section 2. Today DMARC Reporting takes Section 1. One Domain page, all the dials. The Configure tab is now your full DMARC + SPF + Senders + External Reporting workbench.
A new way to see "what's happening" on the Report tab. The Report tab on every Domain page now shows a new Authentication Report card up top: 7-day snapshot of message volume, aligned SPF pass-rate, aligned DKIM pass-rate, disposition breakdown (Allowed / Quarantined / Rejected), and a 5-bucket sender rollup (mostly passing / partially passing / mostly failing / unidentified / internal). The "Full evidence →" button opens a focused modal with the Sources / Timeline / Geography / Reports tabs you're used to, without losing your place on the Domain page.
Eleven states the DMARC Policy block can be in. Active (showing your published DMARC record + Customize policy + Refresh status). Awaiting DNS (you haven't published the _dmarc TXT yet — instructions + Verify DNS button). Awaiting reports (DNS is published, no aggregate reports yet — give it a day). Awaiting provision (we're publishing your record to our delegated zone — under a minute). Stale (reports stopped arriving for 14+ days — check your rua= mailto). Provisioning failed (publish failed; Retry button + Contact support after 3 retries). Not enabled (Enable DMARC CTA). Loading + plan-locked round out the set. Paused and Grace are billing-enforcement states: if you ever see them, it means your account is over your plan's domain limit and the least-recently-used DMARC services have been paused or are about to pause. Recovery is a click — Upgrade plan or Manage your domains — both linked directly from the card.
Direct-link URLs to specific actions. Want to send a customer straight to the enable flow for a domain? /dashboard/domains/<id>?tab=configure&dmarc=enable#section-1-dmarc-policy. Same pattern for &dmarc=override (opens the policy customization modal), &dmarc=evidence (opens the Sources/Timeline/Geography/Reports modal directly), &dmarc=verify-dns (kicks off the "we'll check your DNS now" flow). The intent param strips itself out of the URL after the modal opens, so a refresh doesn't loop you back in.
Your old bookmarks still work. Five legacy /dashboard/services/dmarc/<domain>/* URLs all redirect to the new home — your saved tabs, your email-link bookmarks, anything pointing at the old advisor / override / dns-records / setup pages lands at the right Configure section with the right modal pre-opened. The old how-it-works explainer becomes a polished "moved" note linking back to your domain list.
The Report tab on the Domain page now has a "View configuration →" link on the DMARC health card that jumps straight to Section 1 — handy when you spot an attention badge on the dashboard and want to dig in.
Phase U (Managed DMARC) is now unblocked. With both Managed SPF (Phase 2) and DMARC Reporting (Phase 3) collapsed into the Configure tab, the IA infrastructure can host the next managed service: mxio publishing your DMARC record on your behalf, with the same operational model as Managed SPF. Plan drafted; ship date when you greenlight.
Nothing about the actual DMARC report ingestion, aggregation, advisor logic, or enforcement journey changes. Same backend, same reports, same alerts. Just a much shorter path from "I want to check DMARC on example.com" to actually being on that screen.
Managed SPF now lives on your Domain page, not a separate route
Setup, configuration, status, and history for Managed SPF have collapsed into the Configure tab on the Domain page. The four legacy URLs still work — they redirect to the new home.
Phase 2 of the Domain-Centric IA Redesign ships today. Everything you used to do at /dashboard/services/spf/<your-domain>/{setup,config,status,history} now lives on a single screen: /dashboard/domains/<id> → Configure tab → Section 2: DNS Pointing Status.
Why the move. If you're managing a domain, the natural place to check what we're publishing for it is on the domain's own page — not buried four clicks deep under a per-service hub. The Configure tab is where every per-domain managed service ends up: Senders moved here in Phase 1, Managed SPF moves here today, DMARC Reporting and Managed DMARC follow in upcoming phases. One Domain page, all the dials.
Setup, edit, and history open as modals. Click Enable Managed SPF and the multi-step setup wizard opens inline — no route change, no losing your spot. Same for Edit SPF record (the mechanism builder with live preview and the diff-before-publish confirmation modal) and Version history (the forensics view of every published version with full content diffs). Close the modal and you're back on the same Section 2 view with the latest status refreshed.
Eight states the SPF block can be in. Active (showing your apex include hint + the current published managed record + lookup count + last deployed). Drift detected (the managed include is gone, extra mechanisms appeared, or your policy doesn't match — with the specific findings spelled out). Not configured (Enable CTA). Setting up (Resume button). Paused — important: if you ever see this, it means your account is over its plan's domain limit and the least-recently-used Managed SPF deployments have been paused for billing enforcement. The recovery is to upgrade your plan or remove some domains, both of which the page now links to directly. Error states surface the worker's error message and offer Refresh + Contact support. Loading + plan-locked states fill out the set.
Direct-link URLs to specific actions. Want to send a customer straight to the setup wizard for a domain? /dashboard/domains/<id>?tab=configure&setup=spf#section-2-dns-pointing. Same pattern for &edit=spf (opens the editor modal) and &history=spf (opens the history modal). The intent param strips itself out of the URL after the modal opens, so a refresh doesn't loop you back in.
Your old bookmarks still work. The five legacy /dashboard/services/spf/<domain>/* URLs all redirect to the new home — your saved tabs, your email-link bookmarks, anything pointing at the old routes lands at Section 2 with the right modal pre-opened. The redirect chain resolves in under a second.
The Report tab on the Domain page now has a "View configuration →" link on the Managed SPF health card that jumps straight to Section 2 — handy when you spot drift on the dashboard view and want to dig in.
Nothing about the actual SPF flattening, polling, or deployment behavior changes. Same backend, same Cloudflare-side record publishing, same DMARC report ingestion. Just a much shorter path from "I want to check my Managed SPF for example.com" to actually being on that screen.
Domain pages now have Report and Configure tabs
The domain detail page has two tabs: Report (health checks, all the existing content) and Configure (per-domain service settings, starting with Senders). Hosts and Incidents are now top-level nav items. A new Reports section links to the service hubs.
The domain detail page (/dashboard/domains/[id]) now has two tabs.
Report contains everything the page showed before — health checks, MX, SPF, DKIM, DMARC status, anchor cards. Nothing moved; the tab just makes it the explicit default.
Configure is a new structured layout for per-domain service config. Right now it contains the Senders surface (the same one that used to live at its own separate route). The remaining sections — DMARC Policy, DNS Pointing Status, External Reporting, and Subdomains — are placeholders that Managed SPF, DMARC Reporting, and other services will fill in over the next few phases. Deep links work: /dashboard/domains/[id]?tab=configure#section-3-senders goes straight to Senders on the right domain.
The old /dashboard/services/senders/[domain] URLs redirect automatically to the Configure tab, so any bookmarks or external links continue to work.
Nav changes: Hosts and Incidents are now top-level nav items alongside Dashboard and Domains — the "Monitoring" sub-group label is gone. The separate Senders nav item is also gone (Senders is now inside Domains). The discoveries count badge moved to the Domains item where it still shows when new senders need attention.
New Reports section: A top-level "Reports" nav item points at /dashboard/reports. For now it's a hub with links to the existing service-level reporting surfaces (Senders, Managed SPF, DMARC Reporting). A unified cross-domain reporting surface is planned for a later phase.
New: Email Authentication 101 reading guide and glossary
Two new pages on /learn — a curated reading path through SPF, DKIM, DMARC, BIMI, and MTA-STS, and a 25-term glossary with deep-linkable anchors for the working vocabulary.
The learn library had the full email-authentication surface covered — fifty-plus guides across SPF, DKIM, DMARC, MTA-STS, DNSSEC, RFC walkthroughs, error fixes, and per-provider setup. What it didn't have was a front door for someone arriving cold.
Two new pages fix that.
Email Authentication 101 is a curated reading path. It frames the material in order — Why → SPF → DKIM → DMARC → Adjacent protocols (BIMI, MTA-STS, TLS-RPT, ARC) → Operate and Maintain — and each section is a short orientation followed by links into the existing deeper guides. Read top-to-bottom on your first pass; come back to individual sections when you're working a specific problem.
Email Authentication Glossary defines the 25 terms that make up the working vocabulary — SPF mechanisms, the 10-lookup budget, DKIM selectors and key sizes, DMARC alignment and the p=/sp=/pct=/rua/ruf tags, ARC, BIMI, MTA-STS, TLS-RPT, DNSSEC, PermError vs TempError, and the forwarding break. Each term is short by design: definition, one line of "why it matters," and a link to the guide that covers it in depth. Every term gets a deterministic anchor ID so you can deep-link from chat, docs, or anywhere else.
Both pages are featured on /learn.
Managed SPF UX pass: drift detection, faster deploys, and a dozen rough edges
Status page now flags when your DNS doesn't match what we expect, adding a sender redeploys immediately instead of waiting 5 minutes, and a sweep of redundant displays + broken buttons across Config and Senders.
A pass over Managed SPF from a real customer's perspective surfaced more rough edges than we'd like. None individually catastrophic, but collectively the experience was confusing in ways that a careful test pilot would never tolerate.
Status page now tells you when your DNS is wrong. The "Active SPF Record" section was labeled as if it showed your DNS but actually showed our managed sub-record content — confusing because the two aren't the same thing. Now it leads with your apex DNS record at the top ("here's what's in your DNS") and "Resolves to" below ("here's what that expands to"). Above that, three new drift banners catch real failure modes: if your apex doesn't reference our managed include at all (broken — mail will fail SPF), if it has extra mechanisms alongside our include (defeats the lookup-budget benefit), or if your ~all/-all policy in DNS doesn't match what you've configured here.
Adding a sender now deploys immediately. Previously, authorizing Google Workspace from Discoveries or adding a custom IP range left your published SPF record stale until the next polling cycle (up to 5 minutes). The deploy worker now wakes on every sender mutation that changes what gets published — add a sender, toggle "IN SPF," delete a row, or repair an orphaned row, and the redeploy starts immediately.
Duplicate Google Workspace rows fixed. If you'd authorized a sender via DMARC discovery before its catalog mapping was enriched, then later tried to add it from the catalog picker, you'd end up with two rows for the same service — one with the DMARC traffic data and one with the catalog metadata. Adding from the catalog now detects the orphaned row and promotes it in place. New "Enable SPF" action button on orphaned rows resolves the catalog mapping server-side, in one click, without losing the DMARC linkage.
Config page cleanup. The "Senders in your SPF record" list and the "SPF Sources" sub-list were showing the same data twice — gone. Senders list now shows provider favicons. New + Add IP / hostname / include button surfaces custom mechanisms (ip4, ip6, a, mx, exists, include) without the previous three-clicks-and-a-buried-tab dance.
Save & Redeploy fixes. The button no longer claims a redeploy when nothing changed; it disables itself when the editor has no unsaved edits. If you click through anyway (or hit it from a fresh page open), the diff modal now says "Nothing to deploy" rather than rendering two identical record blocks side by side.
Change Log entries. History → Change Log was rendering blank pill badges with no text — a field-name mismatch between the backend and the frontend interface. Now displays human-readable event types ("Redeployed," "Drift repaired," "Initial deploy," "Rolled back," etc.) with relevant context from the deploy details.
Faster navigation. Jumping from Senders for {domain} to the Managed SPF surface for the same domain used to mean going back to the sidebar, opening Managed SPF, finding the domain in the picker. Direct cross-link in the Senders page header now.
If you've been bouncing off any of these — try again. They should all behave the way you'd expect.
Managed SPF setup now works end-to-end from a clean account
Fixed a hard deadlock where Managed SPF could never activate from a fresh account. Plus the wizard no longer tells you to change your DNS until our managed record actually exists, and several smaller new-user UX rough edges.
If you'd added a brand-new domain and tried to set up Managed SPF, you would have hit a wall: the final "Enable Managed SPF" step returned "could not compile flattened record; please retry," and retrying never worked. Behind the scenes, your sender was authorized but flagged "not in SPF" — and the toggle to flip it the other way was greyed out because Managed SPF wasn't active yet. Activation needed senders in SPF; senders in SPF needed activation. Nobody could escape it from a clean account state. Fixed: first-time activation now includes every authorized sender you've added through the wizard or Senders, regardless of the toggle state. The "IN SPF" toggle is now a post-activation refinement (after Managed SPF is live, you can still flip individual senders off to exclude them from the record).
We also closed a related correctness hole. The "Publish" step previously instructed you to point your domain's SPF at <label>.spf.mxdns.io — but in some paths, that managed sub-record hadn't actually been created in our DNS yet. If you'd followed the instructions before we'd written the record, your live SPF would have pointed at NXDOMAIN. Now the Publish step only renders once we have proof we created the record on our side.
A few smaller things you'll notice on the way through:
- The Senders empty state now has a clear "Add your first sender" call-to-action instead of a passive "No senders configured yet" message.
- When you open Senders from inside the Managed SPF setup wizard, the "Set up Managed SPF →" banner is suppressed — you're already in the middle of doing exactly that.
- The "IN SPF" column header explains what it means (a click on the info icon), and the disabled toggle explains why it's disabled rather than just sitting there greyed out (screen-reader accessible).
- Adding a domain that doesn't resolve yet no longer flashes an orange warning one frame before the page navigates.
If you hit any of these last week and bounced off — we owe you the next attempt working. It should.
Managed SPF preview now actually previews
The 'What will publish' panel on the Managed SPF wizard and Config sub-page no longer hangs at '(computing…)' indefinitely. A new diff modal also gates Save & Redeploy so you see exactly what's about to change before you publish it.
The "What will publish" preview on the Managed SPF wizard and the Config sub-page used to load fine the first time you typed something — but if you arrived on the page with an existing config, it just sat at "(computing…)" forever because nothing had triggered a preview fetch. Fixed: preview now fires on mount, retries on transient failure, and falls back to a stamped "as of HH:MM" view if the fetch fails after a successful load.
Same change adds a diff modal that opens when you click Save & Redeploy. You'll see a token-by-token diff of the managed record we publish behind your include host — current vs proposed — plus the lookup-count delta and any senders being added or removed. Your apex SPF (v=spf1 include:<your-managed-host> ~all) doesn't change; only what we publish behind it does, and the modal makes that explicit. Cancel still works; nothing publishes until you confirm.
Direct checkout from /dashboard/billing — no extra confirmation modal
Plan cards on /dashboard/billing now hand you straight to Stripe — no more 'Upgrade Plan → modal → Subscribe → Continue' chain. Anchor card 'Upgrade plan →' links also send DMARC-card users to DMARC Starter ($19) instead of Pro ($59) when DMARC Starter is enough.
The Upgrade flow used to make you click "Upgrade Plan", then a slide-over appeared with plan cards, then clicking a plan card opened ANOTHER modal asking you to confirm, and only then did Stripe Checkout load. Fixed: plan cards now live directly on /dashboard/billing. Click a plan card and you go straight to Stripe — no in-between confirmation. The active card shows "Opening checkout…" while we hand you off, and any error surfaces inline above the cards instead of silently failing.
Deep links into the billing page now work: clicking "Upgrade plan →" on the anchor DMARC card or Managed SPF card scrolls you to the right plan and highlights it before you click. Previously the URL params were dropped on render. The ?interval= param also pre-sets the annual/monthly toggle to match the link.
While we were in there, the DMARC card's "Upgrade plan" link used to point at Pro ($59/mo). For most users wanting DMARC, DMARC Starter ($19/mo) is the cheapest plan that does the job — so that's where the link goes now.
Paid users on /dashboard/billing keep the Change Plan slide-over (with its preview modals for downgrades and lateral switches) — those modals warn you about real consequences and stay.
Domain pages now reflect what you actually configured
The per-domain anchor used to silently downgrade DMARC and Managed SPF cards to "Not configured" when the domain had no MX record — a trust killer for sending-only subdomains. The downgrade is gone; cards derive from your service config, and a separate banner explains apex-doesn't-resolve cases without lying about your setup.
The per-domain anchor page used to silently downgrade DMARC and Managed SPF cards to "Not configured" when the domain had no MX record. For sending-only subdomains (transactional mail, marketing identity, ESP-fronted subdomains), this meant the page would tell you the service was unconfigured immediately after you'd configured it — a trust killer we heard about repeatedly.
The fix removes the downgrade entirely. Cards now derive their state from your actual service config, regardless of MX presence. If your domain has no DNS records at all (a brand-new registration before propagation), we render a separate banner explaining why checks fail — without lying about your service state.
Same change also wires the anchor to re-fetch automatically after you enable DMARC reporting, so you no longer need to refresh the page to see the new state.
DMARC Advisor: inline recommendations, in-app DKIM records, sharper status pills
After you authorize a discovered sender, the DMARC Advisor now renders the recommended next step inline — no hunt through external docs. DKIM CNAMEs for major providers show up in the dashboard with one click. The status pill distinguishes proposed from current policy, flags stale reports earlier, and explains the per-customer RUA hash.
Five fixes to the DMARC Advisor surface, all from the Managed SPF + DMARC new-user audit.
-
Recommended action inline after Authorize. The backend has been returning a structured
recommended_actionfromPOST /v1/domain-senders/<domain>for a couple of weeks; the slide-over treated authorize as fire-and-forget and dropped the payload. Now the just-authorized sender renders a dismissible card right under the Discoveries panel with the headline, body, and next-step buttons. Stops the "ok, what now?" cliff that hit immediately after the most important action on the surface. -
In-app DKIM CNAME records — no more hop to /providers. When the recommendation is "configure DKIM," click "View the exact CNAME records you need to publish" and see the records inline — name, target, and a Copy button per row. Templated for the major catalog providers we know algorithmically: Google Workspace, Microsoft 365, Mailroute, Mailgun, SendGrid, Amazon SES, Mailchimp, Postmark. The external
/providers/<x>guide stays as a secondary "Full guide →" link. -
"Proposed policy" vs "current policy" on the status pill. Before your first report arrives, the Advisor reads "proposed policy: p=none" — because mxio hasn't yet seen confirmation that your
_dmarcTXT is live at DNS. Once reports start flowing, it flips to "currently at p=…." Stops the ambiguity where a pre-DNS-verification surface looked the same as a verified-at-DNS surface. -
Stale-warning color escalation on reports flowing. At ≥7 days since the last report, the "reports flowing (last: Nd ago)" pill colors amber. At ≥10 days, red. Beyond 14 days the lifecycle has always flipped to "stale" with the "reports stopped" copy — this just gives you earlier eyes on a slowdown.
-
RUA hash tooltip in the setup surface. The
rua=mailto:<hash>@rua.mxdns.iovalue gets a ⓘ tooltip explaining the per-customer routing key. A curious admin Googling the hash and finding nothing is no longer a thing.
Closes audit findings M47, M48, M49, M52, M54.
Enable DMARC reporting from the domain anchor
Pre-upgrade domains can now enable DMARC reporting in two clicks from the domain anchor. No more dead-end portfolio empty state, no more 'we can't load your assessment' error on a domain that just hasn't been set up.
Customers who added domains before upgrading to a DMARC-eligible plan had no working path through the dashboard to enable DMARC reporting on those existing domains. The anchor's "Enable DMARC monitoring" link landed on an empty portfolio. The per-domain DMARC page rendered "we can't load your assessment" — a transient-error message for what's actually a "you haven't set this up yet" state. The only working path was the raw API.
This release closes that gap end to end:
- Anchor enable, inline. The DMARC card's "Enable DMARC monitoring →" button on
/dashboard/domains/<id>now opens a confirmation modal. Confirm, and we provision the RUA address and route you to the per-domain DMARC page — no extra hops. - Per-domain page knows the difference between 404 and 500. Visiting
/dashboard/services/dmarc/<fqdn>on a domain that isn't enabled now shows an "Enable DMARC for<fqdn>" empty state with an inline Enable button. Transient backend errors still show the existing degraded fallback. - Portfolio empty state surfaces your existing domains. If you have domains but none are DMARC-enabled, the portfolio now lists each one with its own Enable button — instead of suggesting you add another.
- Welcome card targets the right place. The "Set up DMARC reporting" card now links to your most-recently-added domain's anchor with
#dmarc-card(or to Add Domain when the account is empty), instead of redirecting to the empty portfolio. The anchor page watches the hash and scrolls to the DMARC card once its data resolves, so the deep-link works even though the page renders async.
No changes to billing, plans, or report ingestion.
DMARC reporting now turns on automatically when you upgrade
If you added a domain on Free and later upgrade to a plan with DMARC reporting, every existing domain is enabled retroactively — same one-step setup the next domain you add gets.
If you added a domain to mxio while on the Free plan and later upgrade to Pro, Business, Core, DMARC Starter, or add a DMARC tier, every existing domain you own now gets DMARC reporting enabled automatically — the same one-step setup our auto-enable hook fires when you add a new domain.
What you'll see right after upgrade:
- Each of your existing domains shows DMARC Setting up — awaiting first reports on the DMARC Advisor.
- A bell notification per domain telling you the
_dmarcTXT record to publish. - No more dead-end where the upgrade succeeded but the dashboard pretended DMARC wasn't part of the deal.
Previously this hook only fired the moment you added a domain. If you added domains first and upgraded later, DMARC stayed quietly disabled until you walked through the setup wizard per-domain. That dead-end is closed.
If you set this up the long way before today's release, you're already done — nothing changes for you.
Disable Managed SPF: typed-confirm modal and preserved original record
Disabling Managed SPF now opens a typed-confirmation modal — no more silent single-click destructive action. On success we show your original SPF record so you can re-publish it at your DNS host within the 24h grace window.
Disabling Managed SPF is one of the few customer-facing actions that can break mail flow if taken without a follow-up DNS edit. The previous flow guarded it with a single "Are you sure?" inline button — easy to misclick, no record of what you were giving up. This release replaces that with a typed-confirmation modal modeled after the same safety pattern we use for DMARC policy overrides.
What changed:
- Typed-confirm gate. Clicking "Disable Managed SPF" on the per-domain Status page now opens a modal that requires you to type the domain's FQDN before the destructive button enables. The body explains that your apex SPF record currently includes our managed entry and that you have 24h to re-publish your original record at your DNS host before new sender IPs start failing.
- Original SPF surfaced on success. On confirm, we fire a success toast that includes the exact original SPF record we stored when you enabled Managed SPF — so you can copy it back to your DNS host without digging through history. The toast text is locked:
Managed SPF disabled. Your original SPF record is preserved at <record> — re-publish it at your DNS to restore mail flow. - Portfolio redirect. After a successful disable we return you to the Managed SPF portfolio (
/dashboard/services/spf) instead of leaving you on a page describing a service you no longer have.
No changes to billing, polling, or Cloudflare cleanup — the underlying disable endpoint behavior is unchanged.
Managed SPF: inline add-sender on the wizard, Copy on the Status page, and the setup-time detection rule made explicit
The Managed SPF setup wizard now surfaces an explicit 'Add your first sender' affordance when a domain has no detectable SPF and no senders yet, opening the Senders slideover inline. The Status page gains a labeled Copy button next to the active record, and both the Senders page and the Status page now spell out that mxio only detects new senders during setup — after activation, new senders must be added explicitly or from DMARC reports.
Three Managed SPF surface polishes, one release.
Wizard step 1 — explicit "Add your first sender" CTA. When a customer starts the Managed SPF setup wizard on a domain with no detectable SPF record and no authorized senders yet, the wizard previously landed them on a blank editor with the helper text "use Senders" — a buried link, no path forward, no momentum. The wizard now renders an explicit empty-state panel: "No senders configured yet. Managed SPF publishes your record from your Senders list. Add the first sender that should be allowed to send mail as <your domain>." The "Add your first sender →" button opens the Senders slideover inline (modal-style) over the wizard, so the customer never leaves the setup flow. After adding a sender and closing the slideover, the wizard refetches the SPF configuration and the new sender appears as a configured source — ready to Save & Redeploy.
Status page — labeled Copy button on the active SPF record. The Copy affordance next to the active SPF record on the Status page was icon-only, easy to miss. It now reads "Copy" alongside the icon — mirroring the affordance on the wizard's Publish step.
Setup-time-only detection rule, made explicit. The Senders page header and the Status page caption now spell out: "We only detect new senders during setup. After activation, new senders must be added explicitly here or surfaced from your DMARC reports." This codifies a long-standing architectural property (Managed SPF polling is read-only against the senders registry) into user-facing copy so customers can plan around it.
Closes audit findings M28, M66, M67.
Managed SPF wizard: replace-not-add diff; anchor cards agree with the Advisor
The SPF setup wizard now shows a side-by-side current-vs-proposed diff with explicit 'replace, don't append' framing — closing a copy bug that could blow a customer past the 10-lookup limit. The domain anchor's DMARC and Managed SPF cards now read the same signals as the Advisor and Status page, so the headlines no longer disagree across surfaces.
Two clusters of surface fixes, one release.
Managed SPF wizard — replace-not-add diff. Step 2 of the Managed SPF setup wizard previously read "ADD THIS TO YOUR SPF RECORD" with an example that replaced the customer's existing includes. A literal-reading admin would have appended our managed include on top of their existing three — landing back over the 10-lookup limit, the exact failure mode Managed SPF is supposed to solve. The wizard now renders a single LEFT/RIGHT diff: the customer's current apex SPF on the left (with strike-through), the proposed replacement on the right, a single Copy button, and a clear caption: "Don't append — replace. We've already brought the senders behind our managed hostname." Step 1 gains the same always-visible diff panel so customers can see what they're replacing before they save. The Status page now explains the versioned-hostname indirection (<label>.spf.mxdns.io → CNAME → <label>-v1.spf.mxdns.io) so the hostname the customer published and the active record they observe match up. Marketing copy on /services/managed-spf updated to use the per-customer <label>.spf.mxdns.io pattern instead of the misleading bare spf.mxdns.io.
Domain anchor — agrees with the Advisor and Status page. The domain anchor's DMARC card previously said "Not configured" for domains whose DMARC Advisor correctly said "Setting up — awaiting first reports." The cards now read the same dmarc.Compose() assessment as the Advisor itself, so both surfaces always agree. The Managed SPF card subtitle now mirrors the Status page exactly: "Active · X/10 lookups · last deployed Nm/h/d ago" — instead of a bare metric line with no provenance.
Together these close audit findings M02, M27, M30, M56, M57, and M60.
Marketing CTA polish and a softer first-touch for new domains
Anonymous visitors to /pricing now get a per-tier 'Start with <plan>' CTA on every card, the header shows 'Sign in or sign up', and the 'Need help choosing' widget answers the combined Managed SPF + DMARC case. Brand-new domains no longer paint a wall of red — we show a 'freshly added — failures expected' banner and collapse the check details by default for the first 24 hours. Pro/Business users also see their eventual Managed SPF hostname before they enter the wizard so they can pre-prepare DNS.
A batch of polish across two adjacent surfaces — anonymous marketing pages and the per-domain anchor — closes eight audit findings from the Managed SPF + DMARC new-user walkthrough.
Anonymous marketing surfaces
- Per-tier CTAs on /pricing for anonymous visitors. Every paid tier card now has its own "Start with <plan name> →" button that routes through
/login?next=/pricing?plan=<slug>so the chosen plan survives signup. Previously every card said "Get Started" and the only differentiated CTA lived at the bottom of the page. - Header nav signals signup is welcome. The right-side auth control reads "Sign in or sign up" on both desktop and mobile — previously just "Login," which obscured the unified-auth flow for first-time evaluators.
- "Need help choosing?" answers the combined case. Added a fourth row: "Managed SPF + DMARC reports → Pro." Evaluators who want both no longer have to infer Pro from the comparison table.
- Beta banner copy softened. Replaced "Beta Preview — Accounts may be reset at launch" with "Active development — Existing paid plans bill in production. New trial signups run in test mode." Honest framing for paying customers; transparent framing for evaluators.
/loginbrowser tab now reads "Sign in — mxio." Previously fell back to the site-default title.- Authenticated-from-
/redirect: documented behavior, no change. Authenticated visitors still get pushed to/dashboard; the sidebar still uses?view=marketingas the marketing-content escape hatch.
Per-domain anchor empty-state
- Fresh-domain banner replaces the wall of red. A newly-added domain shows a single inline banner above the check table — "<domain> is freshly added. Failures are expected until you publish DNS records." — instead of six simultaneous failure rows. The banner derives from a backend
fresh_domainboolean (≤10 minutes old AND no positive record observation yet) so the frontend doesn't re-derive the boundary. - Failure rows default to collapsed for the first 24 hours. A "Check details" disclosure wraps the table; you can expand on demand. After 24 hours the disclosure auto-expands so an established domain's failures stay visible.
- Pro/Business users see their future Managed SPF hostname before they enter the wizard. The Managed SPF card on the anchor surfaces "Your future managed hostname:
<label>.spf.mxdns.io" when the service isn't configured yet —dns_labelis generated at domain creation and stable, so you can pre-prepare your DNS host's UI without re-opening the wizard later. Hidden for Free users (the card is plan-locked).
More specific Managed SPF failure notifications, plus DMARC alignment alerts
Notification settings now break the 'SPF flatten failed' group into four specific causes — Cloudflare API errors, pointer NXDOMAIN, upstream timeouts, and DNS publish-budget exceeded. Two new DMARC events fire when authorized-sender alignment drops below 90% and recovers above 95%.
Two improvements landed on /dashboard/notifications to close out the new-user UX audit:
-
Managed SPF failures now enumerate their cause. The "SPF flatten failed" notification group used to be a single bucket. The "What triggers alerts" reference now lists the four specific failure modes under it: Cloudflare API error, pointer record NXDOMAIN, upstream resolution timeout, and DNS publish-budget exceeded. Routing is unchanged — the parent toggle still controls all four — but the email body and bell-tray entry will now tell you which one fired, so you can stop guessing when a job 502s.
-
DMARC alignment drops and recoveries get their own notifications. Until now the Advisor surfaced "alignment is dropping" only in the dashboard mood — there was no email. Two new events join the DMARC Reporting group: "DMARC alignment dropped below 90%" (warning) and "DMARC alignment recovered above 95%" (info). Both fire at most once per domain per 24 hours; a recovery only fires if a drop was emitted first. The 90/95 hysteresis band keeps a domain that hovers at 92% from oscillating between the two events.
No action required. Existing notification preferences keep their current settings; the four flatten sub-bullets ride on top of your existing "SPF flatten failed" toggle, and the two alignment events default to enabled for the DMARC Reporting group.
Pricing, billing, and welcome surface fixes
Three Critical UX bugs from the Managed SPF + DMARC new-user audit are fixed. Annual billing now reads as annual everywhere, the savings calculator stays in sync with the pricing toggle, and the post-signup welcome surface no longer hides Managed SPF from Free users.
Three fixes shipped from the recent Managed SPF + DMARC new-user audit:
- Annual billing now reads as annual everywhere. The billing page renders "$49/mo billed annually ($590/yr)" for Pro annual customers — previously the surface showed "$59/mo" regardless of interval.
- Savings calculator stays in sync with the pricing toggle. Flipping the /pricing toggle between Monthly and Annual now moves the Pro number in the savings block alongside the tier table — no more $49 vs $59 contradiction on the same screen.
- Managed SPF is on the welcome surface for everyone. After signup, the welcome cards include "Fix your SPF lookup limit" — Pro/Business users get a direct "Set up Managed SPF" link, Free users get an "Available on Pro — Upgrade" CTA. Visitors arriving from the Managed SPF marketing page no longer wonder where the product went.
Also fixed a backend bug: the notifications unread-count endpoint returned HTTP 500 on every first dashboard load for brand-new accounts when the queue was empty. The bell badge silently dropped the count; now it returns 0 cleanly.
UX polish: 22 supporting copy + a11y + account menu fixes
Twenty-nine audit findings from the Managed SPF + DMARC new-user audit are cleaned up in one polish PR. Highlights: SPF wizard counter now distinguishes display chars from DNS-string truth, status page reframes the 848B/512B reading, Pricing hides the Get Started Free CTA when you're already signed in, modal Tab traversal is trapped to satisfy WCAG 2.1 AA, and Billing joins the avatar dropdown.
The polish batch from the Managed SPF + DMARC new-user audit landed. Twenty-nine small but trust-shifting items, plus two carry-overs from PR 2 R2 (focus trap on the DMARC enable modal + a regression test for the #dmarc-card deep-link scroll).
Marketing & pricing
/servicesnow redirects to the homepage services anchor instead of 404'ing./services/managed-spf"Get started on Pro" deep-links to/login?next=/pricing?plan=proto match its DMARC sibling./pricinghides "Get Started Free" for signed-in users and surfaces "Go to Dashboard" instead.- Homepage and service-page fade-in animations honor
prefers-reduced-motionand never trap content invisible if the IntersectionObserver fails to mount.
Dashboard anchor & welcome
- Upgrade-plan CTAs on locked anchor cards drive into
/dashboard/billing?plan=pro&interval=annualinstead of the public pricing page (one click to checkout, full context preserved). - The welcome card's faux example.com monitoring table is gone — Sam no longer reads a sample failure as a real one.
- Managed SPF portfolio auto-routes
?domain=<fqdn>to that domain's setup wizard.
Managed SPF status & wizard
- Status page "Size: 848B / 512B limit" is reframed as "Size: 848B · split into 2 DNS strings" with an RFC 1035 §3.3.14 hover.
- Wizard char counter reads "80 / 255 chars (display)" with a tooltip explaining DNS-string concatenation.
- "Original SPF Record" disclosure has an explicit Show/Hide label.
- Save & Redeploy now shows a success indicator after the network call completes.
- Step 2 "Include record detected" surfaces "Verified at DNS just now" plus the literal
include:value. - "Continue later" is captioned with the URL where progress resumes.
- "Reconfigure" button explains it doesn't take the published record offline.
DMARC advisor & sources
- "Showing last known assessment" preamble is suppressed when no snapshot exists (was misleading on first visits).
- "Clean streak" panel renamed to "Senders aligned" (label describes what's measured even when no streak number renders).
- "Why?" exclusion link gets proper aria-expanded / aria-controls semantics.
- "Rename" buttons on sources/advisor explain the use case in a tooltip.
Accessibility (TASK 12)
- Avatar trigger gets
aria-label="Account menu for <email>"plusaria-haspopup/aria-expanded. - Domain header "Pause" button explains what pausing does and doesn't pause.
- All wizard steps inherit the new
cancelHelpcaption from the sharedServiceSetupWizard. - New shared
useFocusTraphook constrains Tab/Shift+Tab inside modal dialogs (WCAG 2.1 AA). Applied to the DMARC enable modal; future modals get it for free.
Account menu (TASK 18)
- Billing joins the avatar dropdown alongside Profile and Security. Security stays in both the avatar and the sidebar — explicit duplication for a low-traffic but security-sensitive surface.
Add Domain hygiene
- Inline DNS resolution probe on blur. If the domain doesn't resolve, a non-blocking warning surfaces; you can still proceed (pre-DNS / split-horizon domains are valid).
Magic-link login
- The "Check your email" panel now has "Resend email" (client-side rate-limited to 5 per 15 min, server-side cap remains authoritative) and "Use a different email" — no more dead-end if Sam fat-fingered his address.
Backend changes
internal/platformapi/anchor_handlers.gobuildDmarcCTA/buildSpfCTAroute plan-locked CTAs into the in-app billing flow.
Tests
- New
useFocusTraphook + 5 unit tests. - New
#dmarc-carddeep-link regression test (carry-over from PR 2 R2): asserts the wrapper exists AND thatscrollIntoViewis called on it once the anchor settles.
Managed SPF setup pipeline overhaul
We swept ten interrelated bugs out of Managed SPF setup. No more 'awaiting first deploy' stuck state, no more NXDOMAIN window during wizard, senders added during setup just work, Config page now clearly separates the record you publish from the record we maintain, and re-enabling never clobbers your sender choices.
We swept through ten interrelated bugs in Managed SPF setup. The biggest user-visible wins:
- No more "awaiting first deploy" stuck state. Hitting Enable now publishes your record in the same request — no wait for the next polling cycle.
- No more NXDOMAIN window. The setup wizard now refuses to advance to step 2 if the include record didn't publish — so customers never get a hostname that returns NXDOMAIN.
- Senders you add during setup just work. Toggle is on by default, deploys on the next cycle automatically.
- The Config page now clearly separates the record you publish at your DNS host (publish once, never changes) from the record we maintain for you (we publish, updates as senders rotate).
- Re-enabling never clobbers your sender choices — your authorized senders survive any future enable/disable cycle.
If you set up Managed SPF before this release and noticed any of the above, your account is unaffected; the fixes apply forward.
Senders gets its own home
Authorized senders now live at /dashboard/services/senders — a dedicated registry that DMARC and Managed SPF both flow into, instead of two separate places to manage the same list. Managed SPF also moved off the slide-over architecture to its own per-domain pages.
Until now, your authorized senders lived in two places: the catalog picker on Managed SPF, and the Sources tab on DMARC Reporting. Both wrote to the same list, but they showed it differently and let you do different things from each. If you wanted to add Mailchimp via the catalog and then dismiss a spoofing source from DMARC, you were managing two lookalike inboxes.
Senders is now its own surface at /dashboard/services/senders. One registry, one set of actions, one place to add a custom sender (an ip4, ip6, include, or mx mechanism with a name you'll recognize later). DMARC's "Discoveries" inbox shows post-enrichment senders that aren't in your list yet — authorize or dismiss in one click. Managed SPF and DMARC Reporting both publish into the same registry; you don't have to think about which "list" you're editing.
What you'll notice in the dashboard:
- A new "Senders" item in the sidebar, above Managed SPF and DMARC Reporting. The number badge counts unaddressed discoveries.
- DMARC Reporting Sources tab — every actionable row now has one Manage button (instead of separate Authorize / Dismiss / Revoke buttons). Clicking it opens the Senders panel scoped to that source so you can authorize, classify, toggle the "in SPF record" switch, or remove — all in one place.
- Managed SPF Config page — moved off the slide-over. Each domain now has dedicated
Status,Config, andHistorytabs at/dashboard/services/spf/[domain]/.... The Config page shows a read-only summary of the senders currently in your SPF record, with a Manage senders → button that opens the same Senders panel. The raw record editor (policy~all/-all, lookup budget, source preview) is still inline. - The catalog picker is gone from Managed SPF. Adding senders happens on Senders. The SPF page is now record mechanics only — review what's in the record, edit policy, remove existing entries.
If you've been using the catalog picker to add senders, the same workflow now starts from Senders → "+ Add a sender" → catalog tab. Custom senders (named mechanisms) get their own tab next to the catalog.
Three small things that came along for the ride:
- The "Manage in Managed SPF →" link at the top of the DMARC Sources tab now reads Manage senders → and points at the Senders page for that domain — works for every plan tier, not just customers with Managed SPF active.
- Tab navigation between Status / Config / History is faster — we now resolve the domain ID once at the layout level and share it across tabs, instead of re-fetching the entire domain list on every tab click.
- The free SPF Builder tool at
/tools/spf-builderis unchanged — it still has the catalog picker. The dashboard's editor was the surface that needed the change.
No accounts to migrate, no settings to touch — your existing senders, deploy decisions, and SPF record are unchanged. The only difference is where you find and edit them.
Domain page now manages all your services
Your domain detail page now shows DMARC and Managed SPF status side by side. Brand-new domains get a setup-mode view instead of a wall-of-red diagnostic table. Domains also moved to the top of the sidebar — out from under Monitoring, where they didn't belong.
Your domain detail page now shows DMARC and Managed SPF status side by side. Brand-new domains get a setup-mode view ("no records detected yet") instead of the wall-of-red diagnostic table — the page knows when you're setting up versus running steady, and shows you the right thing at the right time.
We also moved Domains to the top of the sidebar, out from under Monitoring. Domains are platform-wide; they shouldn't have lived under a single service category. Same domains, same data — just easier to find.
If you've added a domain in the last few days and saw a page full of red diagnostics for records you hadn't published yet, that's the issue this release fixes.
DKIM setup links, manual SPF instructions, and quieter health alerts
Configure DKIM recommendations now link to per-provider setup guides. Domains without Managed SPF get a publish-yourself preview. Health monitoring stops alerting on changes that mxio itself made.
Update 2026-05-06: the Open DKIM setup guide button described above required a follow-up fix to surface in all cases — see the DMARC and Managed SPF integration fixes entry for the full story.
When the DMARC Advisor recommends DKIM for a sender, the Open DKIM setup guide button now points to that provider's setup page directly — Google Workspace, Microsoft 365, SendGrid, Mailgun, Klaviyo, and 13 others. Less hunting for the right doc.
For domains without Managed SPF active, the SPF preview modal now shows a publish-yourself flow: the exact record to publish at your DNS host, a one-click copy, a warning if you're getting close to the 10-lookup budget, and a link to the provider guide. The Apply button is hidden because there's nothing for us to apply on your behalf — you're publishing this one yourself. If you'd rather we managed it, Managed SPF is one switch away on the domain settings page.
And on the quieter front — when mxio's own apply flow updates your SPF record, the health monitor no longer pages you about the change. Your phone gets quieter when you take an action with us. False-positive "SPF record changed" alerts after every Managed SPF update are gone.
Each apply now also writes an audit-trail entry to your activity log with the provider name, the before-and-after record hashes, and the change ID — useful when reviewing what mxio published on your behalf.
DMARC overview redesigned around the Advisor
The multi-domain DMARC page now answers 'where does the Advisor need my attention?' in one glance — mood-grouped rows, calm domains quiet, paused isolated, bulk DNS export preserved.
The /dashboard/services/dmarc page is now a triage view rather than a reporting table. Domains are grouped by Advisor mood with the most-actionable sections first. Stable domains collapse below the fold once you have more than five. Paused domains live in their own section so they don't compete for attention.
The bulk DNS export affordance is now first-class — you can copy or download records for every domain that needs DNS setup in one place.
Per-row actions stay on the per-domain Advisor page — no inline approve/apply in the list.
DMARC Advisor — clearer reasons why your domain isn't ready yet
The Advisor's 'we're learning' panel now shows the four readiness gates with current values vs thresholds, instead of generic bullets. Readiness is also computed only from your authorized senders' traffic — forgeries from unknown senders no longer count against you.
We rebuilt the readiness signal that drives the "Ready to advance" recommendation — and the panel that explains why we're not recommending advancement yet.
Specific gates, not vague bullets. When the Advisor is still in the Learning mood, it used to say generic things like "we're watching for enough volume to make a confident recommendation." Now it shows the four gates by name, with your actual numbers and the thresholds: authorized senders configured, authorized aligned messages over 30 days (need ≥50), authorized pass rate over 30 days (need ≥98%), and no recent anomalies. Each row gets a check or an X so you can see at a glance which one is blocking you and what to do about it.
Only your authorized senders count. Readiness used to be sensitive to any failure on the domain, including forgeries from unknown senders showing up in your aggregate reports. That made low-volume SMB domains nearly impossible to clear — one forged spam blast from an unknown IP would reset the clock. The new model counts only traffic from senders you've explicitly marked as authorized in the Sources tab. Forgeries are still surfaced — they show up in the unknown-traffic chip — but they no longer hold up your rollout.
What this means for you. If you're a small business with a few hundred legitimate sends a month from Google Workspace and one transactional ESP, you can now reach Ready. You couldn't before — the bar was tuned for higher-volume domains and didn't separate "your mail" from "everyone forging your domain."
Backwards compatibility. Pre-recalibration assessment snapshots that don't carry the new diagnostic field render with the prior generic copy. You'll see the new per-gate panel as soon as your domain produces a fresh assessment (which happens automatically on every Advisor view).
DMARC Sources tab now recommends what to fix
Authorized senders in the DMARC Sources tab show a specific next action — configure DKIM, add to Managed SPF, or no action needed — so you know exactly what each sender still needs.
The DMARC Sources tab now knows what each authorized sender still needs. Instead of classifying a sender and leaving you to figure out the next step, the Advisor computes a specific recommendation for each one.
For senders missing DKIM configuration, you'll see an amber card pointing to the provider's setup guide. For senders not yet in your Managed SPF record, you'll see a blue card with a preview-and-apply flow — review the proposed record change, confirm it, and the update queues immediately. Senders that are fully configured (SPF and DKIM both in place) show no card.
SPF include: mechanisms are now matched automatically against the sender catalog in the background, so recognized providers start appearing in the Sources tab without requiring a manual add.
DMARC Advisor — sharper headlines, real record diffs, fewer contradictions
Eight UX fixes from our internal Advisor audit: clearer mid-journey advancement copy, a safety check that catches enforcement-with-low-alignment, the actual current vs proposed _dmarc record on every recommendation, and a visible grace-period deadline.
We ran our first end-to-end audit of the DMARC Advisor through a customer's eyes — IT lead, inherits the email auth setup, manages it as one of fifteen things — and shipped fixes for eight of the nine cross-cutting findings.
The headline read what's actually happening. When you're already at p=quarantine; pct=25 and ready to move to pct=100, the headline now says "advance from pct=25 to pct=100 on p=quarantine" — not "advance to p=quarantine," which you already are. The risk panel matches: "If pct=100 on p=quarantine takes effect" instead of pretending quarantine starts today. Same for r-partial → r;100 ramps.
Sharper safety on enforced domains. If a fully-enforced domain (p=reject; pct=100) drops below 95% authorized alignment, the Advisor now switches to "attention needed" with a direct read: "Authorized alignment for [domain] dropped below 95%." Until automatic anomaly detection ships, this catches the worst class of failure — a tool confidently saying "nothing to do" while real mail is leaking.
The actual record, not a placeholder. Every "Ready to advance" recommendation now shows the literal current _dmarc TXT record we read from your DNS, alongside the proposed record we're suggesting. No more "Phase 2 populates the diff" placeholder text. This is the trust surface for hosted DMARC — you see exactly what changes before you commit.
The grace deadline is on the card. When you pause a domain into grace, the Advisor now says "Grace expires 2026-05-17 (in 14 days)" right above the holding panel — answering the "am I losing data?" question with a date, not a hand-wave.
Header verbs match reality. A stale domain says "reports stopped (last: 21d ago)" instead of "reports flowing (last: 21d ago)." The chip no longer claims "100% alignment / 7d · clean" when the 7-day window has zero data — it says "no recent data" or hides itself entirely.
Sources tab pointer. On the Learning mood (when we're still figuring out your mail flow), there's a short hint card pointing at the Sources tab: "Tell us which senders are yours. Open Sources to mark senders as authorized — we use that to compute alignment."
Chip math reads coherently. "N of M senders aligned" is now numerator-≤-denominator by construction. Both numbers come from the same observed-traffic population — so no more 5/3 or 10/6 reads.
The audit and remediation plan are tracked in docs/audits/2026-05-03-dmarc-advisor.md and docs/audits/2026-05-03b-dmarc-advisor.md (the verification re-run). Two minor scaffolding bugs surfaced during the re-audit (an empty warning card on paused/grace, and a dmarc_not_enabled debug string in the Sources tab on those states) — they're queued as follow-ups.
Choose your own DMARC policy with full impact preview
DMARC customers can now apply any policy override directly from the per-domain advisor — with a projected per-sender impact breakdown before you commit.
DMARC customers can now apply any policy override directly from the per-domain advisor. Before you commit, we show exactly which senders would be affected, how many messages, and what would happen — projected from your last 30 days of report data. PCT fallback semantics are explained on every screen so you always know what happens to mail outside the percentage.
How it works. From the DMARC Advisor in the Ready mood, click "Apply this change" to open the override route. You pick from seven standard rungs: no policy, quarantine at 10%/25%/100%, or reject at 10%/25%/100%. We show you the projected impact per sending service, a before/after record diff, and the appropriate confirmation friction for the risk level. Submit, then publish the computed record at your DNS host. We check DNS every five minutes and update your status automatically when the record is live.
Confirmation friction scales with risk. Small incremental steps (recommended next hop) need only a single click. Larger jumps require checkboxes. Moving to reject at full volume requires typing your domain name to confirm you've thought about it.
"We can't model the impact" is honest, not a blocker. If you're on a freshly-enabled domain with no reports yet, we tell you we can't model the impact rather than refusing the override. You can still proceed — we ask for one extra confirmation step and show you what data would tell you once reports arrive.
Manual mode only. Records are published at your DNS host. Managed publishing — where mxio handles the DNS change on your behalf — is coming with Managed DMARC (Phase U).
April 2026
New DMARC lifecycle emails: DNS setup reminder and reports-stopped alert
Two new automated email campaigns help users complete their DMARC setup and catch DNS regressions. dmarc-awaiting-dns reminds users to publish their _dmarc record after auto-enable. dmarc-reports-stopped fires when report ingestion stops for 14+ days.
DMARC awaiting DNS (3 emails). When DMARC is auto-enabled on your account, a _dmarc TXT record needs to be published on your DNS provider before reports can flow in. If no reports arrive within 24 hours of auto-enable, a reminder email explains what's missing and links directly to your DMARC setup page with the exact record to publish. A follow-up arrives after one week, and a final nudge after one month — at which point it also mentions disabling DMARC reporting if you've decided not to use it.
DMARC reports stopped (1 email). If your domain was previously receiving DMARC reports and they stop for more than 14 days, a transactional alert fires. The most common cause is a DNS change that removed or broke the _dmarc TXT record — a provider migration, an accidental edit, or a record that got dropped during DNS import. The email links to your DMARC setup page to compare the expected record against what's currently published.
DMARC auto-enable: activity log + bell notification
When a domain is added on a DMARC-eligible plan, the activity log now records the auto-enable and an in-app bell notification appears with a direct link to the DNS record instructions.
When you add a domain on a DMARC-eligible plan, the platform silently enables DMARC reporting in the background. That was invisible until now.
Activity log entry. A DMARC Reporting set up for <domain> event appears in your activity log immediately after domain creation. No action required — it's informational, confirming the auto-enable ran successfully.
Bell notification. The notification bell adds an entry with a direct link to the DMARC DNS setup page, where you'll find the _dmarc TXT record to publish.
DMARC lifecycle emails: onboarding now fires on first report
The DMARC onboarding email series now triggers when your first aggregate report arrives — not when DMARC is enabled. The old enable-nudge campaign is retired. EDV provisioning failures now route an alert to the admin team.
Onboarding email on first report. The DMARC Reporting Onboarding email series now fires when your first aggregate report arrives, not when DMARC is enabled. Since DMARC is enabled automatically on eligible plans, the old "you just enabled DMARC" email didn't reflect anything you did — this one celebrates a real milestone you can act on.
Old enable-nudge campaign retired. The "Enable DMARC Reporting" nudge campaign that prompted eligible users to turn on DMARC is disabled. Auto-enable handles that now; the campaign returned near-zero candidates.
Admin alert on provisioning failure. If the EDV authorization record fails to publish to Cloudflare on two consecutive reconciler passes, an alert routes to the admin team for investigation. A 24-hour suppression key prevents repeat notifications for the same domain.
DMARC multi-domain onboarding: bulk DNS export, auto-enable, lifecycle states
Three changes that fix the multi-domain DMARC setup pain point. Bulk DNS-record export lets you copy or download every domain's _dmarc record at once. New domains on a DMARC-eligible plan are auto-enabled, no per-domain Enable click. The DMARC list now shows a real lifecycle state per domain — provisioning, awaiting your DNS, active, stale — instead of a binary Disabled/Active pill.
Three changes targeted at customers managing more than a handful of DMARC-monitored domains.
Bulk DNS-record export. Multi-select domains on the DMARC Reporting list, hit "Copy DNS records," and you land on a page that shows the _dmarc TXT record for each one — copy each, copy all, or download as markdown. There's also a per-row "Copy DNS record" entry in the row menu. This is the immediate fix for customers running 5+ domains who were copy-pasting records one at a time. The bulk endpoint preserves any advanced tags already on your existing _dmarc record (adkim, aspf, ruf, fo, ri, sp) — only the rua= reporting address is added or rewritten. The downloaded markdown includes a per-domain NOTE so a DNS admin reading the file knows whether the suggested record merges with an existing one, replaces an absent record, or is already in place.
Auto-enable on domain add. When you add a domain on a DMARC-eligible plan (Pro, Business, DMARC Starter, or any plan plus a DMARC tier add-on), DMARC reporting is now turned on automatically. No per-domain Enable click. Plans without DMARC entitlement skip silently — domain creation still succeeds either way. The Cloudflare-side EDV record is published asynchronously by the reconciler within ~5 minutes; you'll see the lifecycle state advance from provisioning to awaiting_dns once that completes.
Lifecycle status states on the DMARC list. The old binary "Disabled / Active" pill is replaced with eight derived states: provisioning, provisioning_failed, awaiting_dns, active, stale, grace, paused, and not_provisioned. Each comes with a state-aware row CTA so you know what action, if any, is on you — typically "publish your _dmarc TXT" during awaiting_dns, "check DNS" during stale, or "re-enable" during paused. State is computed from existing columns plus the most recent report timestamp; no schema change.
DMARC first-time-user fixes: setup checklist, pricing errors, mobile overflow
Three user-visible fixes from a fresh-eyes audit of the DMARC first-time-user flow. The DMARC domain detail page now shows the setup checklist on a new domain instead of a dead-end 'Domain not found' error. Pricing-page error handling no longer auto-fires a broken API call or leaks a raw internal error string. The domain detail tab bar now scrolls horizontally on 375px mobile viewports instead of pushing the page sideways.
Three user-visible fixes from a fresh-eyes audit of the DMARC first-time-user flow.
DMARC domain detail now shows the setup checklist on a brand-new domain. When a new DMARC Starter subscriber added their first domain and clicked through to its detail page, they previously saw "Domain not found. Back to overview." — a dead end. The detail page now recognizes the "new domain, no settings row yet" case and renders the setup checklist in place, so the user can click Enable monitoring and continue through the flow without backtracking.
Pricing page no longer leaks raw backend errors or auto-fires a broken plan change. When a logged-in user landed on /pricing?plan=X&interval=Y with the URL matching their current plan and interval, the page auto-fired a change-plan API call that could fail in certain Stripe-linkage edge cases, surfacing an internal error string ("no active Stripe subscription to downgrade") in a red banner. The auto-fire now skips same-plan same-interval (it's a no-op) while still firing for legitimate interval switches (monthly ↔ annual). If the underlying API call does fail, the backend returns a plain-language message and the URL params stay intact so the user can retry.
DMARC domain detail tab bar scrolls horizontally on narrow mobile viewports. At 375px, the five tabs (Journey, Sources, Timeline, Geography, Reports) pushed the page sideways by 72px. The tab bar now scrolls within its own container, keeping the rest of the page aligned to the viewport.
Three additional internal / dev-environment fixes shipped alongside but aren't user-visible: a CSP tweak so competitor favicons render on compare pages in dev (production was unaffected), a platform-api startup warm-up that reduces the cold-load spinner on /dashboard/services/dmarc after a deploy, and a verified-as-working closure on a speculative broken-anchor finding that turned out to be fine.
DMARC Reporting: clearer positioning, sharper SEO, 3 new guides
Post-launch amplification pass on DMARC Reporting. The service is now the first proof-point on the homepage, the pricing page has a clearer DMARC callout, the DMARC tool pages have stronger bodies and metadata, and we added a field-by-field aggregate report guide, an Office 365 setup guide, and a free-analyzers comparison.
DMARC Reporting launched 2026-04-14. This update amplifies its visibility across the marketing site.
DMARC Reporting is now the first proof-point on the homepage. The hook has been sharpened — "Ready for p=reject. Without the guesswork." replaces the previous headline, and the supporting copy emphasizes the data-driven enforcement story.
The /services/dmarc-reporting page links to the full setup guide. The product setup guide at /learn/product/dmarc-reporting-guide was orphaned; it's now linked under the setup steps and surfaced in the Learn More list.
DMARC tool pages have stronger bodies and metadata. /tools/dmarc-checker (the biggest-volume DMARC query at ~6,600/mo) gained detailed education content covering what DMARC checking validates, policy levels, what a record check cannot tell you, and when to use the checker vs the wizard. /tools/dmarc-report-viewer added a benefit-list body for crawlable SEO signal. /tools/dmarc-wizard got a tightened title and a short intro paragraph.
Pricing page now surfaces DMARC Reporting above the plan grid. A new callout explains what's included on paid plans and links to the service page.
spfflatten.net DMARC cross-sell now has dual CTAs. SPF flattening visitors get two clear paths: the free DMARC analyzer for one-off reports, and the paid DMARC Reporting service for ongoing coverage.
Three new long-tail guides:
- "DMARC Aggregate Report Explained" — field-by-field walkthrough of the XML, with a worked example, what the report tells you, and what it doesn't.
- "Setting Up DMARC on Office 365" — M365-specific deployment guide covering Exchange Online, hybrid deployments, relay connectors, tenant DKIM vs shared signing, and a safe path from p=none to p=reject.
- "Free DMARC Analyzers Compared" — honest comparison of what mxio, Postmark, Dmarcian, EasyDMARC, MxToolbox, and PowerDMARC offer for free. Competitor details verified 2026-04-23.
Cross-linking and hub updates. Six DMARC articles (error guides plus the RFC 7489 reference) now link the DMARC Reporting service page in-body. All five vendor comparison pages now link to the service page. The /learn/dmarc hub surfaces the product setup guide and the two new articles. Sitemap lastModified dates updated for all touched pages so search engines know to recrawl.
DMARC content fixes: broken links, missing service panel, social sharing
Three content fixes on the DMARC pages. Two broken article links on the DMARC Reporting service page now resolve correctly. The Gmail 550 5.7.26 error article now shows the DMARC Reporting service panel at the bottom. All five DMARC comparison pages now share properly on social with og:type article.
Three content fixes found in a post-launch audit of the DMARC pages.
Two broken article links fixed on the DMARC Reporting service page. The "Understanding DMARC Aggregate Reports" and "DMARC Policy Progression" links in the Learn More section of /services/dmarc-reporting pointed to articles that had been renamed during the content build. Both now resolve to the correct articles.
Gmail 550 5.7.26 error article now shows the DMARC Reporting service panel. The article on fixing Gmail's 550 5.7.26 rejection error was missing its service association in frontmatter, so the "Get started with DMARC Reporting" panel at the bottom of the page wasn't rendering. It does now.
DMARC comparison pages now share correctly on social. The five DMARC comparison pages (/compare/dmarcian, /compare/valimail, etc.) were missing og:type: article in their metadata — they were being shared as generic website links rather than articles. Fixed. The comparison pages also now appear in the sitemap.
Billing: fix plan/interval handling on Change Plan, Billing, and Pricing
Five billing UI fixes: Change Plan modal now defaults to your current billing interval, same-plan-different-interval cards show 'Switch to monthly/annual' instead of a disabled 'Current Plan', the plan-change success banner reads the actual backend message (no more 'scheduled' on immediate upgrades), tier upgrades that would flip interval now show a confirmation before the Stripe handoff, and the pricing page toggle state persists in the URL so back-nav from Stripe restores your choice.
Five improvements to how the billing UI handles plan and interval changes, addressing issues found in the 2026-04-16 UX re-audit.
Change Plan modal defaults to your current interval
When you open Change Plan from the billing page, the monthly/annual toggle now matches your active subscription instead of always defaulting to Annual. If you're on Pro monthly, the modal opens with Monthly selected.
"Switch to monthly/annual" CTA on same-plan cards
Previously, if you were on annual Pro and flipped the modal's toggle to Monthly, the Pro card showed a disabled "Current Plan" button — there was no way to request an interval switch from the UI. Now the Pro card shows an active "Switch to monthly" CTA wired to the existing backend endpoint. Works in both directions (annual→monthly and monthly→annual).
Plan-change banner reads the real backend message
The success banner after a plan change used to hard-code "Your plan change is scheduled. It will take effect at the end of your current billing period." regardless of what actually happened. It now renders the backend-supplied message — so an immediate upgrade says "Plan upgraded" and a scheduled downgrade says "Plan will change at the end of your current billing period" with the effective date.
Interval-switch warning before Stripe handoff
When a tier upgrade would also flip your billing interval (e.g., monthly Pro upgrading to Business with the pricing toggle on Annual), a confirmation modal now flags the interval change before redirecting to Stripe. Stripe still shows the exact prorated charge; the modal's job is to make sure the interval flip was intentional.
Pricing toggle persists in URL
Flipping the monthly/annual toggle on /pricing now updates the URL to ?interval=month or ?interval=year. If you back-nav from Stripe Checkout, your interval choice is restored instead of resetting to the default. Only the public pricing pages do this — the in-app Change Plan modal does not alter the dashboard URL.
Internal scope: five findings from the UX-P1.3 re-audit (PAY-10, PAY-11, PAY-12, PAY-13, PAY-15). Source: docs/audits/2026-04-16-p1.3-payment-upgrade.md. Implementation: docs/tasks/2026-04-17-ux-p1.3-followup-plan.md Batch 1.
Email: customer receipts, working unsubscribe, and working ack-from-email
Six email improvements: buyers now receive a welcome/receipt email after subscribing and a confirmation email when their plan changes. Alert emails carry List-Unsubscribe headers for one-click unsubscribe and Feedback-ID for Gmail deliverability tracking. The 'This was intentional' button in alert emails no longer 404s. Verification email gets a plain-text part so it renders correctly in every client.
Six improvements to mxio's transactional email. Customer-facing emails that were either missing or broken are now reliable, and deliverability headers are in place for Gmail and other major inboxes.
Welcome / receipt email after subscribing
When you subscribe or upgrade, you now get an email confirming the plan, billing interval, amount, and next billing date, with a link to the billing page. Previously, only admin got notified; the paying customer got no email.
Plan-change confirmation email
When your plan or billing interval changes — immediate upgrade, scheduled downgrade, monthly↔annual switch — you receive an email summarizing the old plan, new plan, and effective date. Scheduled changes show the effective date; immediate changes are marked effective now.
Ack-from-email button actually works
The "Acknowledge this incident" button (previously "This was intentional") in every alert email had been pointing at a URL that 404'd. Fixed. One click on the email now acknowledges the incident and takes you to the incident detail page.
List-Unsubscribe + Feedback-ID on alert emails
Alert emails now carry List-Unsubscribe and List-Unsubscribe-Post: One-Click headers (per RFC 8058) plus a Feedback-ID that identifies mxio, your account, the alert type, and the sender domain. This matches what the digest email already had, and lines up with Gmail's 2024 bulk-sender requirements for maintaining inbox placement.
Verification email sends a plain-text part too
Notification channel verification emails used to be HTML-only, which hurts deliverability and makes the email unreadable in plain-text clients. They now ship as multipart/alternative with both HTML and plain-text parts.
Internal scope: six findings from the UX-P1.3 re-audit (NOT-15, NOT-18, NOT-19, NOT-20, PAY-8, PAY-14). Source: docs/audits/2026-04-16-p1.3-notifications.md and docs/audits/2026-04-16-p1.3-payment-upgrade.md. Implementation: docs/tasks/2026-04-17-ux-p1.3-followup-plan.md Batch 3.
Deployment note for operators: production requires MXIO_PLATFORM_API_BASE_URL set to the platform-api public URL (e.g., https://api.mxio.io or equivalent) before deploy. Without it, ack URLs default to the frontend origin and will not resolve. See docs/reference/DEPLOYMENT.md.
Dashboard: bigger tap targets, tab-title per page, readable uptime bars
Five accessibility + mobile polish fixes on the dashboard. Icon buttons in the header (bell, theme toggle, avatar) are now 44×44 px — WCAG AAA-compliant tap targets. The mobile sub-nav gets a right-edge fade so you can see there's more tabs off-screen. Each dashboard page now has its own browser tab title ('Billing | mxio', 'Incidents | mxio', etc.) instead of every tab saying the same thing. Uptime history bars are grouped into chunkier 20px blocks on mobile so you can actually interact with them, with aggregate labels showing issue counts per time range.
Five accessibility and mobile polish fixes on the dashboard.
Header icon buttons are now 44×44. The bell, theme toggle, and avatar buttons in the dashboard header used to be ~24px tap targets — too small for reliable thumb use on a phone, and below WCAG's Target Size guideline. They're now 44×44 each, with icon sizes unchanged. Easier to hit, easier to scan.
The mobile sub-nav fades at the right edge when there's more. The dashboard's secondary navigation (the row of section tabs) scrolls horizontally on narrow screens, but there was no visual cue that content continued off-screen. A right-edge fade gradient now subtly suggests "keep scrolling" when there are more tabs.
Each dashboard page has its own browser tab title. Previously, every dashboard route shared the generic "mxio" tab title. You now get "Billing | mxio", "Incidents | mxio", "Activity | mxio", "DMARC Reporting | mxio", and so on — useful when you have several tabs open.
Uptime bars on mobile group into larger, readable chunks. Domain and host detail pages used to render uptime history as ~80 individual 3-pixel bars. Each was technically tappable but nowhere near the size needed for a phone. They're now grouped into 20px chunks of 5 buckets each, with the worst status across the group setting the color and an aggregate label like "Apr 17, 14:00–14:25, 3 issues" for screen readers. Clicking a group still navigates to the activity view filtered to that time range.
Notification bell already announces the unread count. The bell button's tooltip and screen-reader label now name the unread count ("12 unread notifications") — this one shipped earlier in Batch 6; listed here for completeness with the other a11y touches.
DMARC advisor: cost badge, clickable thresholds, clearer setup accessibility
Four fixes to the DMARC advisor and journey tabs. AI Explain shows an approximate cost badge up front and uses a better non-blocking loading state with rotating status text. The reject-gate threshold in the journey progression-blocker card is now a clickable popover that defines what the threshold means. The setup checklist adds aria-expanded and aria-controls so screen readers announce the details toggle correctly. The 'can take 24-48h' timing note on the Reports step moves from a parenthetical to a clear secondary line.
Four fixes to the DMARC advisor and journey surfaces — part of the UX-P1.3 polish pass.
AI Explain shows the cost up front. A small ≈$0.02 badge now sits next to the AI Explain button so you know the approximate cost before you click. The badge hides while the explanation is generating and when you're out of monthly AI quota.
AI Explain loading is no longer an 8-second silent wait. The previous spinner blocked interaction and told you nothing. The new loading state is non-blocking (the rest of the page stays readable), with status text that rotates every 2.5 seconds — "Reading your DNS records", "Analyzing configuration", "Drafting explanation" — so you know work is in progress and roughly where we are. No backend protocol change; the cycling is purely client-side feedback.
The reject-gate threshold is now explained. On the DMARC journey progression-blocker card, the "X% reject-gate threshold" text is now a click-to-open popover that explains what the threshold means: "Advancement to the next policy step is blocked while unclassified traffic exceeds {N}% of total volume." Keyboard users can Tab to it, Enter to open, Escape to close.
Setup checklist is announced correctly by screen readers. The Show/Hide details toggle now has aria-expanded and aria-controls attributes so assistive tech announces the state transition correctly.
"Can take 24-48h" is no longer a hidden parenthetical. On the Reports received step of the setup checklist, the timing disclaimer used to sit inside parentheses at the end of the detail line. It now lives as a clear secondary line below the step — visible at a glance, sets expectations on first read.
Per-subdomain alignment in the subdomain inventory is tracked as a follow-up — it requires a backend aggregation query that's out of scope for this polish batch.
DMARC dashboard: setup wizard on new domains, honest headline stats, one CTA per row
Five fixes on the DMARC dashboard: new domains open to a setup checklist instead of a raw error, the 'Recheck now' button now shows loading state and a toast, the headline stat no longer claims percent-aligned over domains that aren't reporting, duplicate rows for the same domain collapse into one, and each row has a single universal 'View' action with a phase badge instead of three rotating CTAs.
Five fixes to the DMARC dashboard surfaced in the UX-P1.3 re-audit.
New domains open to a setup checklist, not an error. Previously, clicking into a domain that hadn't finished DMARC setup showed a raw "domain not found or DMARC not enabled" error. The backend now distinguishes between truly-missing domains and domains that exist but haven't published a DMARC record yet; the latter case opens the same setup checklist customers see elsewhere in the flow, so the path from "I added this domain" to "I see what to do next" is continuous.
"Recheck now" confirms the recheck happened. The button used to silently re-query with no feedback. It now disables during the fetch, flips its label to "Checking…", and fires a toast when the result is in — success or failure. Errors no longer display both a red banner and a green toast at the same time.
Headline stats no longer overstate alignment. The dashboard headline used the total domain count as the denominator for alignment percentage, but the percentage was actually computed only over domains receiving reports. The label now foregrounds the active (receiving-reports) count alongside the percentage, and surfaces any awaiting/disabled domains separately — so "97% aligned" never gets credit for domains that aren't reporting at all.
Duplicate rows collapse to one. In rare cases (legacy data inconsistency, specifically across the monitor_targets UNIQUE KEY that was dropped in migration 052), the same domain could appear several times in the DMARC dashboard and in admin views. The store now dedupes these at the query boundary, keeping the most-recent row. This also protects the admin domain list and the DMARC setup endpoint.
One CTA per row, phase badge for context. Each DMARC domain row used to rotate between three different actions ("Set up reporting", "Continue DNS setup", "View status") depending on setup state, with no legend. Each row now has a single "View" action plus the existing phase badge that already labels the state (Disabled / Needs DNS setup / Awaiting reports / Receiving reports), so the row reads the same way regardless of state and the action is always predictable.
DMARC overview: grouped domain list, elevated Recheck button, add-domain validation
Five fixes to the DMARC overview. Domains split into Active / Awaiting setup / Disabled sections with counts. 'Awaiting reports' now carries an explanatory popover. 'Recheck now' becomes a real secondary button next to the status badge. Add-a-domain gains client-side format validation and a one-line preview of what we probe. A passive note below subdomain-source Authorize actions clarifies that it updates classification only, not the headline alignment metric.
Five fixes to the DMARC overview and setup surfaces — part of the UX-P1.3 polish pass.
Overview is now grouped by status. Domains on the DMARC overview list used to scroll as one flat list. They're now split into three sections with counts: Active (domains actively receiving reports), Awaiting setup (configured but no reports yet), Disabled (explicitly paused or off). Headers appear when there's more than one non-empty section, so small accounts don't see noise.
"Awaiting reports" explains itself. A click-to-open info popover next to the "Awaiting reports" badge now explains the two most common causes: reports dated today roll up overnight, and some domains only receive subdomain traffic. Users no longer have to guess whether something is broken.
"Recheck now" is a real button. Previously it was a small inline text link easy to miss on the setup checklist. It's now a secondary button sitting next to the status badge where users actually look.
Add-a-domain catches typos before the network call. The inline Add-a-domain form now validates the domain format client-side and shows an inline error for invalid input. Below the field, a one-line preview describes what we'll probe: MX · SPF · DKIM · DMARC · Delegation · Blacklist — and sets expectations that RUA reports arrive only after the TXT record is published.
Authorize on subdomain sources shows a passive scope note. A small sub-line below the Authorize action clarifies that authorizing a subdomain source updates classification, not the headline alignment metric (which reflects ESP-level traffic). The note is scoped to subdomain sources only — root/ESP sources don't see it.
DMARC tabs and filters: age-aware p=none badge, per-tab indicators, adaptive ticks
Four fixes to DMARC detail tabs and filters. The p=none policy badge is neutral gray for the first 14 days after DMARC setup (fresh configs deserve a grace period) and flips to amber afterward so long-term p=none gets surfaced. Tab headers now show small data indicators — Sources count, Geography countries count, Reports count, and a recency dot on Timeline — so users can tell at a glance which tabs have something to show. The Timeline chart x-axis thins ticks on narrow viewports. Remaining title-case CTAs in DMARC UI standardized to sentence case per brand voice.
Four fixes across the DMARC detail tab bar, filters, and policy badges — part of the UX-P1.3 polish pass.
p=none policy badge is age-aware. A brand-new DMARC setup with p=none is normal and expected — the policy should ramp to quarantine and reject over weeks, not minutes. The badge now renders neutral gray for the first 14 days after DMARC enable, then flips to amber. Long-term p=none (the dangerous state) is now visually distinct from brand-new p=none (the healthy state). Re-enabling a domain resets the grace window, which is the right behavior — a re-enabled domain is functionally a fresh setup.
Tab headers carry data indicators. The DMARC detail tab bar now shows inline counts and status dots: Sources count, Timeline green dot (if there's activity in the last 7 days) or gray dot (if empty), Geography countries count, Reports count. Users can tell at a glance which tabs have content before clicking. Dots and counts are marked aria-hidden since the tab label alone already conveys the destination.
Timeline x-axis ticks adapt to viewport. On narrow viewports (<640px) the x-axis now shows a tick every 5 days instead of every 3 days, so labels don't overlap.
DMARC CTA capitalization standardized. Grep of DMARC UI surfaced two remaining title-case CTAs ("Add Rule", "Setup Guide") — both now sentence case ("Add rule", "Setup guide") per brand voice. Proper nouns (DMARC, SPF, DKIM, DNS) remain capitalized.
Geography tab top-10 default + "Show all" toggle was already implemented in an earlier batch; spec verified and no changes needed.
Marketing mobile polish: login priority, tap targets, stable pricing toggle
Six fixes across marketing and auth surfaces. Provider logos no longer flash alt text on slow loads. The login form renders above the fold on mobile — form first in the DOM so screen readers and keyboard users also hit it first. Test-account buttons stop cramming at phone widths. Learn-hub article TOC links and bottom-of-article CTAs hit 44px tap targets. Tool pages now carry a consistent 'Free X Checker — mxio' title template so brand presence and SEO signal both survive. Pricing toggle chip no longer clips on re-render.
Six fixes across the marketing site, login page, learn hub, tool pages, and pricing page — part of the UX-P1.3 polish pass.
Provider logos no longer flash alt text. The FaviconImg component previously rendered the <img> immediately, so on slow connections the alt text (e.g., "Goo" for Google Workspace) was visible until the image arrived. The component now keeps the image hidden until onLoad fires.
Login form renders first on mobile. At <lg breakpoints, the marketing/value panel used to sit above the form, forcing returning users to scroll past the pitch every visit. The form is now first in the DOM and visually, with the value panel below — so screen readers, keyboard users, and scroll-reluctant users all land on the form. Desktop visual layout (value-panel-left, form-right) is preserved via lg:order-*.
Test-account buttons breathe on phones. The dev test-account grid used to cram plan label and slug on one line. Label now sits on its own line; slug hides below 640px.
Article TOC + bottom CTA hit 44px tap targets. Learn-hub article TOC links bumped from py-0.5 to py-2. The bottom-of-article "Browse all guides" affordance is now a full-width bordered block with min-h-[44px]. Inline prose citations stay dense — they're acceptable at reading density.
Tool page titles keep "Free" for SEO and add a brand suffix. Tool pages previously varied between "Free SPF Record Checker" (no brand) and inconsistent treatments. They now consistently render as "Free SPF Record Checker — mxio" via an explicit absolute title so the root template doesn't double. The "Free" keyword stays because it carries real CTR weight on high-intent queries like "free spf checker".
Pricing toggle chip stable across re-renders. The "Save 17%" chip used to conditionally render, causing layout shift when toggling Monthly/Annual. The chip is now always rendered; inactive state fades it with opacity-0 and aria-hidden.
Mobile: dashboard and pricing render correctly on phones again
Ten mobile rendering fixes: every dashboard page now fits a phone screen without horizontal overflow, incident and DMARC lists stack into readable cards on phone, the pricing feature-comparison table scrolls horizontally within its own container instead of blowing out the page, tool result content spans the full viewport width, domain headings wrap cleanly, and phone users can still dismiss or promote DMARC domains (no more desktop-only actions).
Ten mobile rendering fixes across the dashboard, pricing page, and free tools. Phone experience is now on par with desktop for the surfaces most buyers see first.
Dashboard no longer overflows horizontally on phone
A single missing CSS rule on the dashboard's main content area caused every dashboard page to overflow horizontally at phone width — incidents had 45px overflow, domain detail 107px, DMARC overview 326px. Adding min-w-0 to the flex container eliminates all four Critical overflow issues at once.
Incident list stacks into cards on phone
The incidents list rendered as a desktop table at phone width, clipping the "View" CTA on every row. It now stacks into readable cards on phone while preserving the full table layout on tablet and desktop. The Ack and View actions are always reachable.
DMARC overview stacks into cards on phone — and you can still take actions
The DMARC overview table similarly stacks into cards on phones and small tablets. Critically, the Action menu (Enable dedicated reporting, Copy RUA record, Disable, Remove, Dismiss) is preserved on the phone cards — you can manage your DMARC configuration from your phone, not just read it.
Pricing feature-comparison table scrolls within its own container
The full feature-comparison table at the bottom of /pricing used to push the entire page sideways on phone, hiding three of the five plan columns off-screen. The table now scrolls horizontally within its own container, keeping the rest of the page aligned to the viewport.
Tool result content now full-width on phone
Free tool result layouts (SPF checker, DMARC checker, headers, MTA-STS, IP geolocation, IMAP, ping, DMARC report viewer) stacked to full-width on phone instead of rendering in a narrow right-hand column. The SPF checker result narrative that was appearing in a ~136px-wide strip is now full-viewport.
Long domain names wrap cleanly in headings
Domain detail page headings like ops.dmarc-parent.test.mxdns-test.us were clipping mid-word at phone width. They now wrap across two lines.
Other fixes
- Home page DMARC section no longer clips body copy at phone width.
/services/dmarc-reportingplan summary table scrolls within its container on phone.- React duplicate-key warnings on the DMARC overview list are fixed by using a composite key that correctly disambiguates root and subdomain rows.
Internal scope: ten findings from the UX-P1.3 re-audit (MOB-1, MOB-2, MOB-3, MOB-11, MOB-13, MOB-14, MOB-15, MOB-16, MOB-17, MOB-22). Source: docs/audits/2026-04-16-p1.3-mobile-sweep.md. Implementation: docs/tasks/2026-04-17-ux-p1.3-followup-plan.md Batch 2.
Notification settings: sharper framing, keyboard-accessible tooltips, sensible defaults
Seven fixes to the notification settings page and history. The expanded channel-edit row now has a visible accent frame so you know where the edit starts and stops. The '?' help icons are now keyboard-accessible popovers, not hover-only title tooltips. Webhooks and SMS rows are hidden until those channels ship. 'What triggers alerts' defaults open the first time you land on the page. The notifications history page defaults to the last 7 days instead of an empty/unbounded view. New Business-tier subscribers get weekly digests by default (existing customized cadences are never overwritten). The digest tracking-pixel disclosure moved from inline copy into an info popover beside the digest label.
Seven fixes to the notifications settings page, the notifications history page, and the digest defaults — part of the UX-P1.3 polish pass.
The expanded edit row is now visually framed. When you expand a channel to edit which alert groups route to it, the expanded section used to sit flush against the row above it with no visual boundary. It now has an accent left-border frame and a small heading "Editing alert groups for [Channel]" so the scope of the edit is unambiguous.
Info tooltips are keyboard-accessible. The ? icons next to each alert group used to be browser-native title= hover tooltips — invisible to keyboard users and screen readers. They're now proper popovers: Tab lands on them, Enter or Space opens, Escape closes, click-outside closes. Hover still works for mouse users.
Webhooks and SMS rows are hidden until shipped. We were showing "Coming soon" rows for channels we didn't have a concrete ship date on. Hidden until they actually ship — less noise, fewer unmet expectations.
"What triggers alerts" opens itself on first visit. The disclosure that explains which events fire alerts used to always default closed. On a first visit it now opens so new users see what's in scope; subsequent visits remember your last state.
Notifications history defaults to the last 7 days. Previously the history page loaded with no filter — showing all time, paginated. Most people want to see "what happened recently," so we default to the last 7 days. The filter is still user-adjustable and your selection persists via URL.
New Business-tier subscribers get weekly digests. Daily digests are fine for smaller accounts but get noisy at Business scale. New Business subscribers now default to a weekly digest instead of the system default. Existing users who customized their digest cadence are never overwritten — we only set the weekly default when the current cadence is still the system default. Covers initial checkout and in-portal plan upgrades.
Digest tracking-pixel disclosure moved into an info popover. We always disclosed that digest emails include a tracking pixel for deliverability monitoring. The disclosure used to live as inline copy in the digest section; it now lives behind a ? popover beside the digest label, so the zone is less cluttered without losing the transparency.
Notifications: honest unread counts, destructive-action safeguards
Ten fixes to the notification system. The bell badge no longer climbs to 99+ and never comes down — we now cap the unread count at a 30-day window and surface an honest 'you have older notifications' banner in the dropdown. The dropdown itself separates read-state (left border) from severity (the colored dot), so skimming triage is faster. Destructive actions now have undo or confirm: channel toggle-off pops an Undo toast, mark-all-read asks before firing, DMARC Authorize confirms because there's no revoke-from-UI yet. The alert email's ack button now reads 'Acknowledge this incident' to match the dashboard.
Ten fixes to the notifications system — both in the bell dropdown and around destructive actions across notifications and DMARC.
The bell badge is honest again. Every notification you'd ever received counted toward the unread badge, so the badge climbed to 99+ and stayed there forever. The unread count now caps at a 30-day rolling window — anything older than that stops counting. When you have older notifications, the dropdown shows a small banner at the top ("N older notifications not shown here") with a link to the full history, so nothing is hidden, just moved off the nagging badge.
Unread-state and severity are now separate signals. The bell dropdown previously used row tint for read-state and colored dots for severity. Both used color — so a skim felt noisy. Unread now gets a single left-edge accent border on the row; severity stays on the dot. Two axes, two visual channels.
Bell dropdown has an Unread/All filter. Default is Unread. The Unread label shows the count inline. Your choice persists across sessions.
Bell button announces the unread count. Screen readers and hover tooltips now say "N unread notifications" when there are any, not just "Notifications".
Channel toggle-off gets an Undo toast. Flipping a verified channel off used to fire instantly with no way back except re-enabling through settings. Now disabling a verified channel shows an Undo toast for 5 seconds — click Undo to re-enable immediately.
"Mark all as read" confirms before firing. The mark-all action asks "Mark N notifications as read?" before it wipes your inbox unread state, since there's no way to bring it back.
Verified channels with no subscribed alert groups show a warning. If you verified a channel but haven't ticked any alert groups, the settings page now shows a warn badge on that row — "No alerts subscribed — this channel will receive nothing". Click the badge to jump straight to the editor.
Unverified channels can't be toggled on. The enable switch on a notification channel is now disabled until verification completes, with an explanatory aria-label. Previously you could flip it on before verification even started, creating a confusing partial state.
DMARC Authorize confirms before firing. There's currently no way to revoke an authorized sender from the UI (revoke needs support), so Authorize now asks you to confirm with a warning that the action can't be undone from the UI.
Alert email ack button matches the dashboard vocabulary. The "This was intentional" link on health-alert emails now reads "Acknowledge this incident" — the same word the dashboard uses.
Notification verification hardened, bell popover widened, history CSV export
Four fixes to the notification verification flow and history page. The bell popover is now 384px wide so long domain names (like survey-tracking.example.com) stop truncating. The email-channel verification page no longer auto-verifies on load — mail gateways (Mimecast, Proofpoint) that prefetch links won't accidentally confirm a channel. Users now click an explicit 'Verify this channel' button, which POSTs the confirmation. A regression test confirms the verification token is invalidated immediately after use. History page gains an Export CSV button for the current filtered view.
Four fixes across the notifications bell, the verify-channel landing page, and the history page — part of the UX-P1.3 polish pass.
Bell popover is wider. Long domain names (anything beyond ~30 chars) were truncating in the bell dropdown. The popover is now 384px instead of 320px, which comfortably fits survey-tracking.example.com and similar.
Verification no longer auto-fires on landing. Corporate mail gateways — Mimecast, Proofpoint, Barracuda, and similar — prefetch links in inbound email to scan them for malware. Our verify-channel link used to run the verification automatically on page load, which meant a gateway fetch would silently confirm the channel without the real user ever clicking. The verify page now shows an explicit "Verify this channel" button. Verification only happens after the button is clicked, which gateways don't do. The backend endpoint was already POST-only; the fix was entirely on the landing page.
Verification tokens are invalidated on use. This was already the case, but we added a regression test so a future refactor can't silently break it. Tokens now have a guaranteed single-use lifecycle: generate → email → confirm → token deleted from Redis.
Export CSV on notifications history. The history page has a new "Export CSV" button that downloads a CSV of the currently-displayed rows with event time, channel, domain, event title, summary, and status. RFC 4180 escaping handles commas, quotes, and newlines in data.
A full-range CSV export (beyond the current page) and a free-text search across all history are tracked as follow-ups.
Pricing page and first-paid dashboard: no more misleading copy
Six fixes across pricing, billing, the login heading, and the new-customer dashboard. Starter plans no longer advertise 'free to start' when they're $19/mo; annual customers see both the monthly-equivalent and the annual total on their billing page; the 'Billed yearly' subline on /pricing is now legible and shows the yearly total; the login heading welcomes new signups; the fresh-account dashboard shows a clearly-labelled Sample preview instead of example.com rows that looked like real monitoring; and doubled '| mxio' browser-tab suffixes are gone.
Six fixes in the payment, pricing, and first-paid-dashboard surfaces.
Starter plans no longer advertise "Free to start · no card required". The Monitoring Starter and DMARC Starter cards on /pricing are $19/mo — they're not free. That badge used to appear on both of them alongside the actual Free tier, which was dishonest. Now only the Free tier shows the no-card-required hint.
The fresh-account dashboard preview is obviously a sample. New paying customers used to land on a dashboard showing example.com and mail.example.com rows with red/amber status dots — some of them confused it for their own monitoring data coming back broken. The preview now has a "Sample" badge in the card header, the rows are desaturated with neutral gray dots, and the accessibility tree skips the table entirely. It reads as "this is what your dashboard will look like," not "your domains are failing."
Annual billing now shows the full pricing picture. If you're on an annual subscription, the billing page used to say "$59/mo billed annually," which left you guessing at the actual monthly rate and yearly total. It now shows $49/mo · billed annually · $590/yr — the monthly equivalent you're effectively paying, plus the yearly total you see on your invoice. No more mental math.
The "Billed yearly" subline on /pricing is readable. The small text under each plan card that noted the annual savings was rendering at ~12px, so small it was easy to miss. It's now at 14px with the full annual total ($590/yr on Pro, for example) shown prominently next to the "Billed yearly" label.
The login page welcomes new users. The heading used to say "Sign in to your account" — fine for returning users, unwelcoming to first-time visitors who might also land on /login. It now reads "Sign in or create your account," with a subline explaining that we'll email a magic link and create an account automatically if you're new.
Browser tab titles no longer double up the | mxio suffix. Several marketing pages had their own | mxio in the page-level title, and the site's root layout adds one automatically, which produced tab titles like "Monitoring — mxio | mxio". Fixed across the services, blacklists, and managed-SPF pages.
Signup keeps your plan choice; MFA skip remembers for 2 days
Four fixes on the signup → checkout → dashboard path. If you pick a plan before signing up, that choice now survives magic-link signup and auto-opens Stripe when you return. First-time paid subscriptions see a brief preview (plan, billing interval, amount) before being handed off to Stripe. DMARC report rows now deep-link — the expanded report is captured in the URL and survives copy-paste. Clicking 'Skip for now' on the MFA setup page is remembered for 2 days, so you're not bounced back to /setup every time you log in during that window.
Four fixes along the signup → checkout → dashboard path.
Your plan choice survives signup. If you hit "Get Pro / Monthly" on the pricing page before you had an account, you used to come back after magic-link signup and have to pick the plan and interval all over again. The choice is now preserved in the URL through the whole signup chain. When you land back on /pricing post-setup, Stripe Checkout opens automatically with the plan and interval you originally selected. If something goes wrong on the checkout side, the URL state stays intact so you can refresh and retry.
First-time paid subscriptions see a quick preview before Stripe. When an existing Free-tier account upgrades to a paid plan for the first time, a small modal now summarizes what's about to happen: plan name, annual or monthly, and a reminder that Stripe will show the exact amount on its side. Cancel dismisses, proceed hands you off to Stripe. (Upgrade-across-interval and downgrade previews were already in place — this fills the free → paid gap.)
DMARC report rows now deep-link. Expanding a report on the DMARC dashboard used to be per-tab state only — if you wanted to share the view with a teammate, you couldn't. The expanded row is now reflected in the URL as ?report=<id>, so copying and pasting the URL lands them on the same pre-expanded report. Clicking to collapse clears the query.
"Skip for now" on MFA setup remembers for 2 days. Clicking "Skip for now" on the /setup page used to do nothing persistent — next login, you'd get bounced right back to /setup. Now a skip is recorded and we respect it for 48 hours. After two days, we nag again. The skip also honors whatever destination you were trying to reach: if you came in via /pricing?plan=pro&interval=month, you land there after skipping, not on the dashboard.
DMARC: authorize and dismiss senders appearing in subdomain traffic
Subdomain sources in the DMARC Sources tab now show Authorize and Dismiss actions, matching the classification workflow available for root-domain senders. Discovered-domain pages remain read-only. Also fixes a crash when expanding the subdomain accordion and a 'No source data' false negative on subdomain-only domains.
The DMARC Sources tab now lets you classify senders that appear only in subdomain traffic, not just root-domain traffic.
Authorize and Dismiss actions on subdomain sources
- Senders listed under the Subdomain Traffic section now show Authorize and Dismiss buttons for sources that have a recognized ESP but haven't been classified yet — the same workflow available for root-domain senders.
- Authorized subdomain senders are split into passing (≥95% DMARC pass rate) and failing buckets, so sources that are authorized in name but misaligned in practice stand out rather than blending into the clean group.
- Discovered domains remain read-only. Pages for domains discovered automatically from your DMARC reports (rather than explicitly added) don't show action buttons, since you haven't claimed ownership of those domains.
Bug fixes
- Fixed a crash when expanding the subdomain accordion on domains where no subdomain source data had been collected yet.
- Fixed a "No source data" false negative on domains where all traffic arrives via subdomains and the root domain has no volume. The subdomain traffic card now surfaces first in these cases rather than showing a misleading empty state.
DMARC dashboard: hourly report aggregation
The job that turns raw DMARC aggregate reports into your dashboard breakdown now runs every hour instead of once a night. Reports covering previous UTC days appear in your dashboard within roughly an hour of arriving.
We shortened the gap between a DMARC report arriving and it showing up in the dashboard.
What changed
- Rollup runs hourly, not nightly. The background job that turns raw aggregate reports into the per-source breakdown now runs every hour instead of once a day. For reports covering previous UTC days (the overwhelming majority — Gmail, Yahoo, Microsoft, and other major reporters all send reports for the prior day), the delay between receipt and dashboard drops from up to a day to roughly an hour. Reports covering the current UTC day are still held until the next UTC midnight — unchanged from before — so that today's in-flight data isn't aggregated mid-collection.
- Automatic multi-datacenter coordination. The job is safe to schedule on all of our hosts simultaneously — a shared lock ensures only one host actually runs the aggregation per hour, with automatic failover if one host is unavailable.
Why
Previously, a customer who enabled DMARC reporting in the afternoon could see "Awaiting reports" on the dashboard for up to 24 hours even though the first report had already arrived — the aggregation that populates the dashboard only ran at 02:00 UTC each night. That was an uncomfortably long feedback loop for a feature where "is this working?" is the main question during setup.
Impact
No action required. If you just turned on DMARC reporting, your first sources breakdown should appear within an hour of the first report arriving — assuming that report covers a previous UTC day, which is how essentially every major reporter sends them. The badge will still read "Awaiting reports" during that window — honest labeling of the "report received, aggregation pending" state is tracked as a separate follow-up.
DMARC: redesigned domain detail with journey tracker and cleaner tabs
The DMARC domain detail page is reorganized into focused tabs — Journey, Sources, Timeline, Geography, Reports — with a new step-by-step enforcement tracker, reduced clutter, and a smarter overview that shows each domain's enforcement stage at a glance.
The DMARC domain detail page has been reorganized to make your enforcement journey easier to follow.
Tabbed layout and journey tracker
- Five focused tabs replace the single long-scroll page: Journey (default), Sources, Timeline, Geography, and Reports. The Journey tab opens first — it's where most of the actionable work happens.
- Vertical enforcement tracker runs down the Journey tab and shows your current step in the progression from monitoring to full enforcement (none → quarantine → reject). Each step shows what it requires and where you stand.
Less noise, better signal
- Redundant warning cards consolidated. Multiple overlapping "attention" cards that were firing at once have been replaced with a single contextual advisory, so you're not trying to prioritize three alarming messages at the same time.
- Subdomain Traffic surfaces first when it dominates. If the bulk of your DMARC reports is coming from subdomains rather than your root domain, that card now floats to the top of the page rather than appearing below less-relevant information.
- "Subdomains" card renamed to "Child DMARC records." Clearer label for what the card actually shows: whether your subdomains have their own DMARC policies or inherit yours.
Overview improvements
- Each domain now shows its journey stage inline on the DMARC overview list — no need to open each domain to see where it stands.
- "Skip for now" is explained. The skip action now includes a tooltip that describes what it does and when the item will resurface, so it's a deliberate choice rather than a mystery button.
- "Explain" renamed to "AI Explain." Makes it unambiguous that clicking it generates an AI-written explanation, not static documentation.
DMARC Domain Actions: Menu Now Available on Disabled Rows
Fixed a dashboard bug where disabled DMARC domains showed no actions menu at all — you couldn't re-enable from the menu, and you couldn't delete without enabling first.
On /dashboard/services/dmarc, disabled domain rows (including the placeholder rows for domains you haven't enrolled yet) were rendering an em-dash in the Actions column instead of the usual ⋯ menu. That left no way to re-enable a domain from the menu, and no way to delete a disabled domain without enabling it first.
What changed:
- Disabled rows now render the Actions menu with state-appropriate items: "Enable reporting" (opens the setup wizard) and "Remove domain" (when a stored settings row exists).
- Placeholder rows for active domain targets that haven't been enrolled in DMARC yet show only "Enable reporting" — there's nothing in the DMARC tables to remove, so "Remove domain" is intentionally omitted there. Those domain targets are managed from
/dashboard/domains. - Enabled rows are unchanged (View details, Configure DNS, Copy RUA address, Disable reporting, Remove domain).
The inline "Set up reporting ›" link on the row stays — the menu adds a second, more discoverable path to the same flow.
DMARC Re-Audit Response, Plan Consistency, and Overage Cap
Fixed a domain-detail empty-state crash, hardened the DMARC setup wizard against record replacement, corrected AutoSPF competitor pricing, gated the DMARC overage ladder on starter plans, and swept the website for plan-citation drift.
A second fresh-eyes audit of the DMARC launch readiness work surfaced 27 new findings; a follow-on plan-consistency sweep caught five more factual drifts between the website and the shipped plan configuration. Everything's fixed.
Critical fixes that would have hit real customers:
- DMARC domain detail no longer crashes on empty state. Any domain with zero reports (which every new DMARC customer has for the first 24–48 hours) was throwing a runtime TypeError in the sources rounding helper. Guarded the helper against empty and zero-sum input, added regression tests.
- Setup wizard now protects your existing DMARC policy. Step 2 previously handed everyone a naked
v=DMARC1; p=none; rua=...template. If you were migrating from another DMARC provider withp=rejectin place and followed the wizard verbatim, you would have downgraded your enforcement. The backend already merged correctly when it could read your current record; added an explicit "replace your current record" framing, plus a prominent warning on the no-record branch that catches transient DNS lookup failures. - AutoSPF competitor pricing corrected. The savings calculator and competitor matrix on
/pricingused a flat$37/domain/monthestimate for AutoSPF. Their actual pricing is tiered — a 10-domain customer's cheapest configuration is $127/mo (AutoSPF Plus + 9 add-ons), not the $370/mo we were claiming. New competitor-pricing module picks the cheapest fitting tier; matrix, calculator, cost-comparison, and compare/autospf.md all updated.
Dashboard and billing polish:
- Monitoring card renders as an upsell, not a red alarm, on plans without monitoring alerts. DMARC Starter users were seeing a red "1 failing" monitoring card for a capability their plan doesn't include. The card now renders as "Add monitoring" with a link to pricing when the plan excludes alerts.
- Grace-period banner stops telling top-tier users to upgrade. Customers on Business were seeing "Upgrade to restore DMARC reporting" banners for grace domains that Business could easily absorb. The banner now detects when the current plan has headroom and switches to "Re-enable in DMARC settings."
- Advisor sender counts stop contradicting themselves. The "X unrecognized senders" warning and the actual sender list now use the same 50-message threshold, so the numbers always agree.
- Subdomain summary matches the expanded row totals. The headline "X messages from Y subdomains" line and the detailed group rows now come from the same raw-record query; the ~4× discrepancy that appeared when daily aggregates drifted is gone.
- Billing meter label corrected from "DMARC reports this period" to "DMARC emails this period" — matches the value and the cap unit.
Competitor and pricing page accuracy:
- Added mxio Core as a third highlighted column in the
/pricingcompetitor matrix, plus a new DMARC aggregate reporting row. - valimail.md table now shows actual annual prices (applying the real 17%-off discount) instead of monthly × 12.
- dmarcian pricing consistency:
/pricingand service pages both use the $24/mo monthly rate now. - Five DMARC competitor compare pages (easydmarc, dmarcly, dmarcian, powerdmarc, valimail) are gated behind
NEXT_PUBLIC_DMARC_DISABLEDuntil launch — filtered out of the compare hub, sitemap, and Next.js static params. - Business plan's health check interval is 5-min, not 15-min (corrected on valimail.md, dmarcly.md, powerdmarc.md).
- Setup wizard acknowledged-sender copy now says "is rejecting these messages at receivers" on p=reject domains instead of the future-tense "will be subject to your DMARC policy when enforcement is active."
DMARC overage cap on starter plans:
DMARC Starter and Core are now capped at the 100k overage tier. If you need 500k or 2M emails per month, upgrade to Pro or Business. Reports continue processing regardless of cap state — we never drop aggregate reports; the cap just gates automatic billing upgrades and the Stripe tier change endpoint. /pricing overage disclosure labels 500k and 2M rows as "Pro or Business only" with an added explanation block.
Plan-consistency sweep:
- Fixed
dmarc-reporting-guide.mdclaiming Pro has 5 domains and Business has 20 — real values are 25 and 50. - Managed SPF availability now noted on
dmarc-deployment-guide.mdandspf-flattening-explained.mdso Free/Core readers aren't surprised at the paywall. - spfflatten.net pricing FAQ clarifies "25 domains total, up to 10 with SPF flattening" instead of bare "10 domains."
/pricingFAQ no longer implies Core is a starter plan.
Internal: new shared constant anomalyMessageThreshold = 50 keeps advisor warning counts consistent; new competitor-pricing.ts module centralizes AutoSPF tier math; DMARC setup wizard backend has regression tests for spliceRUA covering every tag combination; DmarcGraceInfo carries a new can_absorb field that backends compute from activeDomainCount + graceCount <= MaxDomains.
DMARC Setup Wizard: Stale Reports No Longer Skip the DNS Step
Fixed a setup-wizard bug where deleting and re-adding a DMARC domain skipped you past the DNS update screen because historical reports from the prior setup were mistaken for a working configuration.
If you deleted a DMARC reporting domain and then re-added it, the setup wizard would jump straight to the final "Reports Flowing" screen — past the DNS update step — and hide the new reporting address you needed to publish. Reports from the prior setup survive a delete (intentional, so history isn't lost), and the wizard was treating any non-zero report count as proof the current DNS was correct. It isn't — after a re-add, the reporting address changes but old reports remain.
What changed:
- Step 2 of the wizard now only auto-advances when a live DNS check confirms your current
_dmarc.<domain>record points at our reporting address. Historical report counts are no longer a trigger. - The initial step is determined by
enabledstate alone. If you're enrolled, you land on the DNS step; the async DNS check advances you to step 3 within a second when the record is correct. - Added a regression test that mocks the delete-and-re-add case (100 historical reports, live DNS shows a stale RUA address) and asserts the wizard stays on step 2.
The fix closes two related symptoms:
- The domain row showing "Awaiting reports" while the wizard simultaneously claimed "Reports Flowing" — two sources of truth disagreeing on the same screen.
- Your unique reporting address being hidden behind a skipped step, with no other path to find it.
If you're mid-migration and need to wipe old report data for a re-added domain, reach out — we can clear it server-side.
DMARC Advisor Improvements and Downgrade Flow
DMARC advisor now detects unclassified sender volume before recommending policy advancement. Downgrade and lateral plan changes show a confirmation preview with feature diff, domain impact, and DMARC grace period disclosure.
DMARC advisor now considers unclassified sender volume — the most critical safety fix in this release. Previously, the advisor could recommend advancing to p=reject while simultaneously showing unrecognized senders whose mail would be dropped by that policy. The advisor now gates advancement on the ratio of unclassified traffic:
- p=reject gates: advancement blocked until unclassified traffic is below 1% of total volume
- p=quarantine gates: blocked until below 5%
- p=none advisory: no hard block, but a warning appears when unclassified traffic exceeds 5% — advancing is still your choice
When the gate is active, the advisor shows a "Unclassified senders detected" card with a message count, sender count, and a "Review senders" link that jumps directly to the affected sources. Acknowledged senders (those you've already reviewed and dismissed) are excluded from the ratio — classifying a sender actually removes the block.
The enforcement journey stepper is now visible at every policy state, including p=none domains in discovery and configuration stages. Previously, domains early in the onboarding flow showed no progression context.
Plan changes now show a confirmation preview before committing. Downgrading or switching plan tiers opens a modal showing:
- Feature losses (what you'll give up)
- Domain impact (which domains will be paused and how many)
- DMARC grace period disclosure ("You'll keep DMARC reporting for 30 days")
- SPF flattening impact (if applicable)
- Effective date ("takes effect at end of your billing period — no credit issued")
The downgrade button is now amber rather than the same neutral style as an upgrade, matching the visual hierarchy: upgrade (teal) → lateral switch (neutral) → downgrade (amber) → cancel (red).
A persistent grace-period banner appears on the dashboard and billing page after a plan change is scheduled or DMARC grace is active. The banner shows the type of grace (domain limit or plan loss), affected domain count, expiry timeline, and a Restore CTA.
Competitor comparison pages have been corrected — several pages contained false feature-absence claims that we used as competitive arguments. EasyDMARC has SPF flattening (EasySPF). DMARCLY has SPF flattening (Safe SPF) and blacklist monitoring. MXToolbox's $129 plan is called Delivery Center, not Monitor, and includes additional monitoring capabilities. All prices updated to match current published rates.
The DMARC setup wizard now correctly waits for DNS proof before advancing to the verified state. Previously, the wizard could show "DNS verified · awaiting reports" as soon as we published the redirect TXT record — even if you hadn't yet added the DMARC record pointing to our RUA address. The wizard now stays on step 2 until either reports start flowing (proving your DNS is correctly configured) or a live DNS check confirms your _dmarc record contains our RUA address.
The DMARC domain overview now shows all your domains, including those awaiting first reports and disabled domains. Previously, domains with no report data were silently hidden — if you added a domain and didn't see it in the list, that was the reason. Disabled domains now show a "Disabled" badge; domains awaiting first reports show "Awaiting reports."
The billing dashboard now correctly shows the DMARC Reporting usage meter for DMARC Starter customers. It was previously hidden due to a plan-detection logic error that checked for endpoint monitoring access instead of DMARC reporting access.
The DMARC volume meter no longer shows the add-on tier price — it now shows only the tier name and billing reset date. The plan price belongs on the billing page, not the dashboard usage widget.
You can now remove a domain from DMARC reporting. The domain action menu includes a "Remove domain" option with an inline confirmation step.
The /pricing toggle now defaults to your current billing interval when you're signed in — annual if you're on annual billing, monthly if you're on monthly. Anonymous visitors still see annual pricing by default.
DMARC Lifecycle Emails
New email campaigns for DMARC Reporting onboarding, activation, and milestones. Existing campaigns updated with DMARC-aware content.
Four new DMARC lifecycle campaigns that guide users from activation through enforcement:
- Activation nudge — DMARC-entitled paid users who haven't enabled DMARC Reporting receive a 3-email sequence explaining the blind spot between monitoring and visibility.
- Onboarding — after enabling DMARC Reporting, a 4-email sequence covers what to expect, how to read sources, and when to move toward enforcement.
- First report milestone — a transactional notification when your first DMARC aggregate report arrives and data populates your dashboard.
- Enforcement milestone — celebrates when your DMARC policy advances to
p=quarantineorp=reject, with guidance on what comes next.
Six existing campaigns updated with DMARC-aware content — welcome emails, upgrade confirmations, educational drips, and win-back sequences now mention DMARC Reporting where relevant, gated by plan entitlement so users only see features they can access.
All milestone emails use event-specific metadata stored at enrollment time, so the domain and policy referenced in the email always match the event that triggered it — even on multi-domain accounts.
Rename and categorize DMARC sources for your account
Give DMARC sources your own names and categories in the Sources tab. Local labels are account-specific — they don't affect alignment math, authorization status, or other customers.
When a DMARC source shows up in your sources tab that doesn't match what you expect, you can now rename it and change its category for your account. Your labels don't affect other customers. They don't change alignment math or authorization status. They just make your dashboard read the way you think. Renamed sources show a small "Local label" badge so it's always clear what's your naming and what's verified by mxio.
A note on what's not yet renamable: if a source shows up as "Unknown senders" (no ESP match), we can't yet let you rename it individually — our daily report groups every unmatched sender on a domain into a single bucket, so naming one would relabel them all. We're widening that grouping in a follow-up so you can name unfamiliar senders too.
UX fixes — signup redirect, dead links, dashboard 404
Four polish fixes: /signup redirects to /login, the spf-permerror article link works again, tool CTAs carry the domain you checked into the add-domain flow, and bad /dashboard URLs show a proper in-dashboard 404.
What changed
Four small fixes that were causing unnecessary dead ends.
/signup redirects to /login. Old bookmarks and external links pointing at /signup no longer land on a 404 — they go straight to the login page.
/learn/errors/spf-permerror is fixed. The article link was broken after a URL change. It now resolves to the correct page.
Tool CTAs preserve your domain. The "Activate Managed SPF" button on free tool result pages now passes the domain you checked through the login flow. After authenticating, you land on the add-domain page with the domain pre-filled instead of an empty form.
Dashboard 404 stays in the dashboard. Navigating to an invalid /dashboard/... path used to drop you out to the marketing site. It now shows a proper not-found page within the dashboard chrome, with navigation intact.
UX fixes — reduced motion, health status display, SPF error messages
Five polish fixes: scroll animations now respect prefers-reduced-motion, informational checks (MTA-STS, DNSSEC) no longer show green pass, SPF failures show the actual error instead of a lookup count, info checks display in gray, and the DMARC panel now reads from live health data.
What changed
Five display fixes from our UX audit.
Scroll animations respect your OS reduced-motion setting. If you have "Reduce Motion" enabled in your system preferences, page animations no longer play — all content appears immediately. Previously, the CSS media query was the only guard; JavaScript-driven animations (scroll reveals, pricing table, feature matrix) could still fire.
MTA-STS and DNSSEC no longer show green "pass" when absent. If your domain doesn't have MTA-STS or DNSSEC configured, health checks for those features now show a neutral gray badge instead of a green pass. Not having these set up is informational — it's not something to celebrate, but it's also not a failure.
SPF failures show the actual error message. When an SPF check fails, the health summary now reads the first error message (e.g., "Included domain d1.mxdns.io has no SPF record") instead of reporting the lookup count ("8/10 lookups used"), which only makes sense when SPF is passing.
Info checks display as gray and group separately from passes. Informational check results on the domain health tool page now use a gray neutral style and appear in their own section alongside inconclusive results — not mixed in with green passing checks.
DMARC panel reads from live health data. The DMARC configuration panel in domain detail now uses the live health check result to determine whether a DMARC record is present, rather than a stale snapshot from the domain list.
Pricing consistency, inline fix CTAs, and tool count corrections
Prices are now consistent across every page. Error articles link directly to the service that fixes the problem. Tool counts corrected to 22 across the site.
What changed
A set of UX polish fixes targeting price consistency, inline fix paths, and accurate tool counts.
Prices are consistent site-wide. All plan prices now come from a single source so they can't drift out of sync between pages. Every CTA, pricing card, comparison page, and article shows the same number.
SPF checker CTAs include pricing. The "Activate Managed SPF" action bar on SPF lookup limit and SPF record too long results now shows "from $59/mo" so you know what you're clicking into.
Error articles link to the service that fixes the problem. Six error articles now include an inline CTA after the article body pointing to the relevant mxio service with the plan price: spf-too-many-lookups, multiple-spf-records, no-dmarc-record, dmarc-policy-none, dmarc-failing, and dmarc-alignment-failure.
Tool count corrected to 22. Outdated "18+" and "30+" claims have been replaced with the actual count across the site, including seven comparison pages.
spfflatten.net add-on copy removed. References to a $15/domain flatten pack that no longer exists have been replaced with current Pro/Business plan pricing.
Hero subhead updated. The homepage hero now reads "Diagnose. Monitor. Fix." — a tighter summary of what mxio does.
DMARC pricing stays marked coming soon before launch
Pricing pages now keep DMARC plans and feature copy labeled coming soon until the DMARC launch flag is enabled.
What changed
- Pricing pages now respect the DMARC launch flag on both mxio.io and spfflatten.net, so DMARC plan cards and feature rows stay labeled Coming soon while
NEXT_PUBLIC_DMARC_DISABLEDis still enabled - Pricing metadata is now consistent with the visible UI on mxio.io, so structured data no longer advertises live DMARC pricing before launch
Why it matters
- Visitors no longer see mixed signals where DMARC looks purchasable in one part of the pricing page but gated in another
- The pricing page source now matches the launch state shown in the product UI
DMARC Reporting dashboard
DMARC Reporting is now available. Connect your RUA address, get aggregate report data parsed and classified automatically, and track your path to p=reject.
What's new
DMARC Reporting — full aggregate report ingestion, source classification, and enforcement readiness analysis for your domains.
Aggregate report ingestion
Enable DMARC Reporting for a domain and mxio generates a unique RUA address (rua+<token>@rua.mxdns.io). Add it to your DMARC record's rua= tag. Reports from Gmail, Microsoft, Yahoo, and other major receivers start arriving within 24–48 hours. No XML parsing on your end.
Source classification
The Sources view groups every sending IP into one of five buckets:
- Authorized & Passing — senders you own, passing DMARC alignment
- Authorized & Failing — senders you own, misconfigured
- Forwarded — traffic from forwarders or mailing lists breaking SPF as expected
- Unknown — unrecognized sources that need review
- Misconfigured — recognized services without a working auth setup
Authorized Senders engine
mxio identifies sending infrastructure by reverse DNS, ASN, and known ESP patterns. When a source maps to a recognized provider — Mailchimp, SendGrid, Postmark, Google Workspace, Microsoft 365, and others — it shows the provider name and logo alongside the IP. Unrecognized sources are surfaced for manual classification.
Enforcement journey
The Enforcement advisor tracks your readiness to tighten policy. It shows your current alignment rate, flags any sending sources that would be blocked if you moved from p=none to p=quarantine or p=reject, and guides you through the progression step by step.
Geography tab
Sending infrastructure plotted on a map by data center location — useful for spotting unexpected sending regions.
Subdomain grouping
Subdomains discovered through reports can be organized with pattern-based grouping rules. Rules are matched top to bottom; first match wins.
AI explain on anomaly cards
Unusual traffic patterns surface as anomaly cards. Each card has an AI explain button that gives a plain-language analysis of what the anomaly likely represents and what to investigate.
New-sender notifications
When a high-volume unrecognized sender appears (1,000+ emails in a 7-day window), you get an email alert with the IP, hostname, message count, and first-seen date.
Availability
DMARC Reporting is included in:
- DMARC Starter — $19/mo, 2 domains, 100k records/mo
- Core — $34/mo, 5 domains, 100k records/mo
- Pro — $59/mo, 5 domains, 150k records/mo
- Business — $129/mo, 20 domains, 500k records/mo
For setup, see DMARC Reporting in mxio: Setup, First Data, and What To Do Next.
DMARC Reporting Notification Group + New Sender Alerts
New DMARC Reporting notification group with subdomain discovery, external reporting, and unrecognized sender alerts. Email alerts fire when a high-volume unrecognized sender is detected on your domain.
New DMARC Reporting notification group — a dedicated group in notification settings for DMARC-specific events. Available when your plan includes DMARC reporting. Covers three alert types: subdomain discovery, subdomains reporting outside mxio, and the new unrecognized sender detection.
Unrecognized sender detection — mxio now scans DMARC report data for high-volume sources that aren't in your authorized sender list and aren't known forwarders. When a source exceeds 1,000 emails in a 7-day window, you get an email alert with the IP address, hostname, email count, and first-seen date. Alerts are suppressed per domain for 7 days after each notification to avoid noise.
MTA-STS, DNSSEC, and Domain Expiry tools and monitoring
Three new free tools and three new domain monitoring check types: MTA-STS validation, DNSSEC chain-of-trust verification, and domain registration expiry tracking.
What changed
Three new free tools and three new domain monitoring check types ship together — each tool doubles as both a standalone lookup and an automated health check when you add a domain to monitoring.
MTA-STS Checker
Validates your _mta-sts TXT record and fetches your /.well-known/mta-sts.txt policy file. Checks mode, max_age, and whether your MX hosts are covered by the policy. If you have MTA-STS configured, monitoring now alerts you when the policy expires, MX coverage drifts, or the policy file becomes unreachable.
DNSSEC Validator
Walks the DNSSEC chain of trust from the root, verifying DS/DNSKEY agreement, RRSIG expiry, and algorithm strength at each level. Monitoring alerts you if signatures expire, the chain breaks, or a weak algorithm is detected.
Domain Expiry Checker
Queries RDAP (the modern replacement for WHOIS) to find your domain's registration expiry date, registrar, and renewal status. Monitoring checks this daily and alerts you before your domain expires — preventing the kind of outage that takes down everything at once.
SMTP banner verification
The existing SMTP check now compares the mail server's 220 greeting hostname against the expected hostname. A mismatch shows up as an informational finding — a common deliverability issue that's easy to miss.
Why it matters
MTA-STS, DNSSEC, and domain expiry are infrastructure concerns that sit underneath email authentication. A lapsed domain registration or a broken DNSSEC chain can take down email delivery regardless of how well your SPF and DMARC are configured. These checks close that blind spot.
Pending-state motion accessibility polish
Active waiting states across the dashboard now use a clearer pending treatment, with reduced-motion fallbacks that look intentional instead of frozen.
What changed
We updated the dashboard's in-flight waiting states so they communicate progress more clearly, especially when your system has Reduce Motion enabled.
Clearer active-waiting states
- Domain and host health checks now use a shared pending indicator instead of a generic pulsing dot
- Blacklist streaming rows now show a compact pending shimmer while providers resolve one by one
- DMARC setup and other long-lived waiting states now use the same pending treatment for a more consistent feel
Better reduced-motion behavior
- Pending scan bars now fall back to a static striped treatment when motion is reduced
- Pending dots now fall back to a visible resting ring instead of looking like a stuck animation frame
Why it matters
The previous behavior could look broken when animations were intentionally suppressed by the OS. These states now read as intentionally pending whether motion is enabled or reduced.
DMARC Starter Plan + DMARC Included in Pro and Business
New DMARC Starter plan at $19/mo for DMARC-first customers. DMARC reporting now included in Pro (150k/mo) and Business (500k/mo) plans.
New DMARC Starter plan — a dedicated entry point for customers who need DMARC reporting but not full monitoring. $24/mo, $240/yr. Includes 2 domains, 100,000 DMARC records/mo, full reporting dashboard, enforcement journey tracker, AI explanations (50/mo), and free-tier health visibility. No email alerts — add monitoring for $10/mo to upgrade to Basic+DMARC at $34/mo.
DMARC included in Pro and Business — DMARC reporting is now bundled into the Pro ($59/mo, 150k/mo) and Business ($129/mo, 500k/mo) plans. No separate add-on required. Volume overages continue to auto-bump on monthly plans.
Two paths to the same ladder — DMARC-first customers start at $24/mo, monitoring-first at $19/mo. Both converge at $34/mo (Basic + DMARC). From there the upgrade path to Pro ($59/mo) and Business ($129/mo) is the same for everyone.
DMARC walkthrough remediation
DMARC Reporting now gives clearer sender review actions, better DNS progress feedback, and copyable next-step policy guidance.
What changed
The DMARC dashboard now closes several first-use gaps that showed up in the March cognitive walkthrough.
Safer sender review
- Needs Review rows now have actions in place so you can authorize, dismiss, or skip a sender without bouncing between tabs
- Consequence copy is now visible before you decide, so it is clearer what authorize and dismiss actually mean
- Provider descriptions appear in review-needed rows to make recognition easier
- "Skip for now" leaves the sender in review instead of forcing a low-confidence decision
Better DNS and status feedback
- The setup wizard now stays open after enablement so DNS setup and verification steps remain reachable
- DNS polling now rechecks automatically and advances once your RUA is detected
- EDV status labels now match reality: needs setup, awaiting reports, receiving reports, and failure states are clearer
- Status badges open the setup flow directly instead of acting like passive labels
More concrete enforcement guidance
- Ready-to-advance guidance now includes a copyable DMARC record
- You can preview a merged version of the next record that keeps tags from your current DMARC record when available
- Advisor overflow links now jump to the Sources tab so review work stays connected
Why it matters
The old flow made a few important things harder than they should have been: deciding whether a sender was legitimate, knowing whether DNS changes had been seen yet, and figuring out the exact next DMARC record to publish. The updated walkthrough keeps those steps in one place and makes the next action much more explicit.
DKIM provider icon cleanup
The DKIM selector picker now shows clearer provider icons for Fastmail, MailRoute, and other transparent-brand marks in both light and dark mode.
What changed
The "Add by provider" section in the DKIM selector picker now uses a more reliable icon treatment.
Better provider logos
- Fastmail now has a real provider icon instead of a plain fallback initial
- MailRoute now uses a local icon override instead of the washed-out harvested favicon
- Transparent logos now sit inside a neutral icon chip so they stay legible in both light and dark mode
Where this shows up
This update applies to the DKIM selector flows in the dashboard, including the provider cards and the selector discovery rows.
Why it matters
The old approach treated harvested favicons like stable product icons. That worked for some providers, but it broke down for transparent or low-contrast assets. The new treatment keeps the picker readable and consistent without relying on brittle third-party favicon artwork.
Drawer accessibility and save-state cleanup
Dashboard and admin slide-over panels now behave more consistently, restore focus correctly, and stop warning about unsaved changes immediately after a successful save.
What changed
The dashboard and admin side panels now use a more consistent slide-over pattern, with a cleanup to saved-state handling in host and profile editors.
Save-state fixes
- Host editing no longer shows a discard warning immediately after a successful save
- Monitor editing now re-bases correctly after save before you navigate away
- Profile settings now treat the saved value as the new baseline right away
- Host and domain detail pages now reload their primary snapshot after an in-place save so the detail view stays in sync with the list view
Better slide-over behavior
- Focus now moves into the panel when it opens and returns to the trigger when it closes
- Keyboard navigation stays inside the panel while it is open
- Dialog semantics are now explicit for assistive technologies
- Mobile sizing is safer for narrower screens
More consistent admin panels
The admin drawers for DNS host providers, SPF catalog providers, Managed SPF service detail, and partners now share the same panel shell instead of each using a separate hand-rolled implementation.
Why it matters
The old behavior could tell you a save succeeded and still act as if the form was dirty, which is contradictory and undermines trust. The new behavior makes saves feel final, and the shared drawer implementation reduces UI drift across the product.
Platform hub overview
Your dashboard landing page is now a platform-level hub showing the health of all services at a glance — monitoring, DMARC reporting, and Managed SPF.
What changed
The dashboard landing page (/dashboard) is now a platform hub instead of a monitoring-only overview.
Service gauge cards
Each active service gets a compact card showing status, key metrics, and a link to its detail section:
- Monitoring — domain count, host count, open incidents
- DMARC Reporting — monitored domains, email volume, aggregate pass rate (visible when DMARC is enabled)
- Managed SPF — managed domain count, flatten limit (upgrade prompt if plan doesn't include it)
Cards show setup guidance when a service is available but not yet configured.
Monitoring overview
The full monitoring detail — attention table, open incidents, key numbers, activity feed — now lives at /dashboard/monitoring. Everything that was there before is still there, just at a dedicated address.
Updated navigation
The sidebar has a new top-level "Home" link for the hub. Monitoring gains its own "Overview" entry. All other links (domains, hosts, incidents, services, account) are unchanged.
March 2026
Free DMARC aggregate report viewer
Upload or paste a DMARC aggregate report XML file and see who's sending email as your domain. Client-side only — your data never leaves the browser.
What changed
A free DMARC aggregate report viewer is now available at /tools/dmarc-report-viewer. No account required.
How it works
Drag and drop (or paste) a DMARC aggregate report XML file. The viewer parses it entirely in your browser — the file never leaves your machine. Supports raw XML, gzip-compressed, and zip archives.
What you see
- Summary stats — reporting organization, date range, published policy, total message count
- Source table — every sending IP with volume, SPF result, DKIM result, and DMARC alignment. Sortable by any column.
- Auth detail rows — expand any source to see the specific SPF and DKIM authentication results with domain and selector detail
- Privacy banner — clear confirmation that parsing happens client-side only
Why it matters
DMARC aggregate reports are XML files that mailbox providers (Google, Microsoft, Yahoo) send to your RUA address. They tell you who's sending email as your domain and whether those senders pass authentication. Most people never read them because the raw XML is dense and hard to parse. This tool makes them readable in seconds.
Upgrade path
The free viewer handles one report at a time. For continuous monitoring across all your domains with source identification, alignment tracking, and enforcement guidance, enable DMARC Reporting in the dashboard.
Service onboarding and dashboard polish
Unified service setup wizards, shared plan gate, dashboard welcome previews, host detail enrichment, and hydration fixes.
What changed
Service setup consistency
- Managed SPF and DMARC Reporting now use the same setup wizard pattern: numbered stepper with clickable completed steps, consistent DNS verification flow, and shared cancel behavior
- Plan gates use a shared component across both services — Free-tier users see what the service does, which plan unlocks it, and the starting price
- Status badges follow a universal vocabulary (Active, Setting up, Awaiting, Paused, Error, Not configured) across all service pages
- Basic plan pricing now shows the $15/domain/month add-on cost upfront on the Managed SPF page
Dashboard improvements
- Welcome panel shows mini preview tables with status dots instead of text-only description cards, giving new users a visual preview of what monitoring looks like
- Host detail shows an "Awaiting first check" panel with sub-check badges when a host is newly added, instead of empty timeline tabs
- Hosts empty state explains what endpoint monitoring offers with check-type badges and a clear CTA
Bug fixes
- Fixed login page hydration mismatch caused by localStorage read during server-side rendering
- Fixed setup page hydration mismatch from evaluating WebAuthn support at render time
- Fixed DMARC setup table not refreshing after inline domain creation
Bulk actions on domains and hosts
Select multiple domains or monitored hosts and apply actions in bulk — pause, resume, delete, or check now.
What changed
The Domains and Monitored Hosts list pages now support multi-select with bulk operations.
Selection
- Checkbox column on every row
- Select-all checkbox in the table header (with indeterminate state for partial selection)
- Selection clears automatically after a successful bulk action
Bulk action toolbar
When one or more items are selected, a toolbar appears above the table with context-aware buttons:
- Pause — only visible when active items are selected
- Resume — only visible when paused items are selected
- Check Now — runs health checks on all selected items
- Delete — with confirmation dialog (domains note that child monitors will be kept as standalone monitors)
Partial failure handling
If some items in a batch fail (e.g., plan limit reached during bulk resume), the toolbar shows how many succeeded and keeps the failed items selected so you can see which ones need attention.
Backend
Two new batch endpoints (POST /v1/domains/batch and POST /v1/monitors/batch) handle pause, activate, and delete operations with per-item results. Plan limits are enforced — bulk resume won't exceed your plan's domain or monitor quota.
Dashboard convention polish
Consistent buttons, smoother interactions, and shared components across the entire dashboard — delete confirmations, page headers, action menus, and more.
What changed
A systematic sweep across every dashboard page to standardize conventions, adopt shared components, and eliminate inconsistencies.
Inline delete confirmations
Delete actions on domain and host list pages now show an inline confirmation row instead of a browser dialog. You see the warning in context with Cancel and Delete buttons — no more jarring popup.
Shared action menus
The three-dot action menus on domain and host lists are now powered by a shared ActionMenu component with smart positioning that flips above the button when near the bottom of the screen.
Consistent page headers
All dashboard list pages (Domains, Incidents, Billing, Settings, Notification History) now use a shared PageHeader component for consistent title, description, and action button layout.
Destructive button styling
Delete and disable buttons across detail pages and the Managed SPF panel now use the standard destructive button style — subtle red border with tinted background — instead of varied hand-rolled styles.
Additional improvements
- Managed SPF panel tabs use the shared
TabBarcomponent - Navigation arrows animate on hover in health cards
- Keyboard focus rings on interactive table rows
- Internal links use Next.js
<Link>for instant SPA navigation - Timestamps use consistent relative formatting ("5m ago", "3d ago")
Security hardening across all services
Comprehensive security hardening covering authentication, API protection, and infrastructure — 21 fixes across the OWASP Top 10 categories.
What changed
We completed a full OWASP Top 10 security audit and shipped fixes for every finding. These changes harden authentication flows, API endpoints, and infrastructure across both mxio.io and spfflatten.net.
Authentication hardening
- Magic link and passkey login flows now have brute force protection with automatic rate limiting
- Per-email rate limiting prevents magic link spam (3/min per address)
- Admin impersonation sessions are now read-only — diagnostic operations work, but billing changes and data mutations are blocked
API protection
- All outbound connections (favicon fetching, HTTPS probing, network diagnostics) now validate resolved IPs against private and reserved ranges, preventing server-side request forgery
- Email headers are sanitized against CRLF injection
- Global request body size limits prevent resource exhaustion
- Auth redirect URLs are validated against an origin allowlist on both backend and frontend
Infrastructure improvements
- Content Security Policy headers added to both frontend applications
- HSTS headers strengthened with
includeSubDomainsacross all services - Structured authentication event logging for all login methods
- Sensitive values removed from startup logs
Contextual actions on free tool results
Free tool results now surface relevant next steps right where you need them — fix structural problems with Managed SPF, or monitor operational issues to catch regressions.
What changed
Free tool results now bridge the gap between diagnosis and action. When a tool finds a problem, it tells you what to do about it — right in the diagnostic panel where you're already reading.
Action bar in diagnostic results
Every tool result with errors or warnings now shows an action bar below the diagnostic narrative. The action matches the problem type:
- Structural problems (SPF over the lookup limit, record too long) surface Managed SPF as a fix
- Approaching limits (8-9 lookups, record getting long) link to SPF flattening education
- Operational issues (blacklisted, weak DKIM key, DMARC p=none) suggest domain monitoring
The action bar picks the highest-priority issue and shows one clear next step — not a wall of buttons.
Domain health "Next Steps" card
Domain health results now include a Next Steps summary after the check rows. Service-lane items (Managed SPF) get prominent buttons. Monitoring covers all remaining issues in a single line. If you're already monitoring the domain, the monitoring line doesn't appear.
Smarter CTA de-duplication
When the action bar is already showing a monitoring pitch, the standalone monitoring card below the fold suppresses its anonymous rendering to avoid repeating the same message. Logged-in users still see their monitoring status. The SPF lookup budget bar hides its CTA button when the action bar already offers Managed SPF — the gauge and count remain, just not a duplicate button.
Upgrade hooks visible on grouped errors
Error-severity items in the findings list (3+ identical issues grouped together) now show their upgrade hook immediately, without expanding the group. You see the fix option right away instead of having to click "Show 3" first.
Smarter DKIM checks in domain health
Domain health no longer penalizes you when we can't guess your DKIM selector. Provide your own selector for a definitive check, or let us probe common ones — either way, your score reflects what we actually know.
What changed
Domain health checks probe 8 common DKIM selectors (google, selector1, k1, etc.). Previously, if none matched, DKIM scored as a hard fail — dragging your entire health score down to 20/100 even if SPF, DMARC, and MX were perfect.
Now, when no common selectors match, DKIM shows as inconclusive instead of failed. Your overall score is calculated from the checks we can actually verify.
Provide your own selector
The domain health form now includes a "DKIM Selector (optional)" field. If you know your selector (e.g., s1024, mail, or a provider-specific name), enter it for a definitive check.
Re-check from results
When DKIM comes back inconclusive, an inline prompt appears: "We couldn't find a common DKIM selector. Know yours?" Enter your selector and re-check without leaving the page.
Scoring improvements
- Inconclusive checks are excluded from the overall health score — we don't grade what we can't test
- Real DKIM problems (revoked keys, malformed records) still score as failures, even during the common-selector sweep
- Delegation checks no longer affect the overall score — they provide useful context but aren't email authentication checks
Change detection for free tools
Every free tool now remembers previous results. See at a glance whether your DNS configuration changed since the last check — no account required.
What changed
mxio's free tools now have memory. Every time you check a domain, we fingerprint the result and compare it to the last check. No account required.
Change detection badge
A subtle indicator appears in every tool result:
- First check — this is the first time we've seen this domain+tool combination
- Stable · N checks since [date] — configuration hasn't changed across multiple checks
- Changed since [date] — something is different from the previous check
What gets tracked
The system fingerprints meaningful DNS data (records, policies, key sizes) while ignoring volatile fields (response times, geo data, timestamps). A change means your actual configuration changed, not that a server responded 2ms slower.
Privacy
Snapshots are anonymous — no account, no cookies, no tracking. We store a fingerprint hash and key metrics per domain+tool combination. Results older than 12 months are automatically pruned.
Coming next
Field-level change details ("SPF lookup count went from 6 to 11") and integration with diagnostic narratives are planned follow-ups.
Diagnostic narratives for tool results
Every tool result now includes a plain-language diagnostic paragraph explaining what the data means, not just what the data is. Domain Health connects SPF, DKIM, and DMARC into one story.
What changed
Every free tool result now tells you what the data means, not just what the data is.
Diagnostic paragraphs
Each tool (SPF, DKIM, DMARC, MX, Delegation) generates a 2-4 sentence diagnostic paragraph that appears at the top of the result. It explains the findings in plain language — what's healthy, what's broken, and what to do about it.
For example, an SPF result might say: "This SPF record uses 9 of 10 DNS lookups, approaching the limit. Adding more services could push it over. The ~all (softfail) qualifier marks unauthorized senders but doesn't reject them. Consider -all for full enforcement."
Cross-protocol diagnostics
Domain Health now connects SPF, DKIM, and DMARC into a single diagnostic story. Instead of five separate traffic lights, you get one paragraph that explains the relationship: "Your SPF passes with 6 lookups and -all enforcement, and DKIM is active with a 2048-bit key. However, DMARC is set to p=none — receivers aren't enforcing authentication results."
This is the paragraph you screenshot for your boss.
Key metrics at a glance
Domain Health check rows now show key numbers inline — SPF lookup count and qualifier, DKIM key size, DMARC policy level, MX server count, and nameserver status. No drill-through needed for the basics.
Dynamic browser tab titles
Tool results update the browser tab to show the domain and score — useful when you have 12 tabs open checking different domains.
SPF Flattening add-on for Basic plans
Basic plan users can now purchase SPF Flattening packs ($15/domain/month) to enable Managed SPF on individual domains without upgrading to Pro.
Basic plan users can now add Managed SPF to individual domains without upgrading their plan.
Per-domain pricing — Each SPF Flattening pack covers one domain at $15/month. Add packs from the Billing page as you need them, up to your plan's domain limit. Remove packs anytime — enforcement automatically pauses flattening on excess domains.
Pro-equivalent polling — Domains with an active flattening pack get the same 30-minute polling interval as Pro plan users. Your flattened SPF record stays current with upstream provider changes.
Billing integration — Packs appear as line items on your existing Stripe subscription. Add or remove packs instantly from the Billing page — no plan change required.
Pro and Business plans include Managed SPF for all domains at no extra cost. The add-on is designed for Basic users who need flattening on one or two domains without the full Pro upgrade.
Smarter tool results
Free tool results now show proportional visualizations, contextual badges, and guided next steps — making DNS and email data easier to understand at a glance.
Every free tool result page has been redesigned to communicate data visually, not just textually.
DMARC Checker — A policy progression bar shows where you are on the none → quarantine → reject journey, with contextual guidance at each stage. Domains without DMARC now see a structured empty state with a direct link to the DMARC Record Generator.
MX Lookup — Response times render as proportional bars (like Ping results), making it easy to spot slow mail servers. Primary and backup MX hosts are visually distinguished by priority.
SMTP & IMAP Tests — A port comparison summary shows all tested ports at a glance with connection status, TLS version strength badges (color-coded by version), and certificate expiry indicators.
Delegation Health — Nameserver response times now display as proportional bars. SOA serial consistency gets a compact pass/fail indicator that only expands details when serials differ.
DNS Lookups — Record types are grouped with summary counts, and TTL values now display with human-readable labels (e.g., "TTL 5m - Short" instead of raw seconds).
Shared components — Three new reusable visualization components (ResponseTimeBar, CertExpiryBadge, TLSStrengthBadge) ensure consistent data presentation across all tools.
Notifications settings redesign
The notifications page has been rebuilt around channels and alert groups — simpler to configure, easier to understand what you'll be notified about.
The notification settings page has been redesigned from the ground up. Instead of a 50-event preference matrix, you now configure 4 alert groups per channel.
Alert groups — Errors & Outages, Warnings & Degradation, Recoveries, and Managed SPF. Toggle each group on or off per notification channel. The groups map to the right event types automatically.
Channel-centric layout — Each notification channel (email, in-app) gets its own section with clear enable/disable controls and per-group toggles.
Notification history — Extracted to its own dedicated page at /dashboard/notifications/history with improved display, keeping the settings page focused on configuration.
Activity pages and health history timeline
New activity pages for domains, hosts, and the dashboard overview — with filtering, pagination, and interactive health history bars.
Every monitored entity now has a dedicated activity page showing its full timeline — health status changes, configuration updates, re-checks, and incident events in a unified feed.
Three new pages:
/dashboard/activity— cross-entity activity feed for your entire account/dashboard/domains/{id}/activity— per-domain activity with tier and date range filters/dashboard/hosts/{id}/activity— per-host activity
Health history bar — Domain and host detail pages now show interactive health history as colored pips. Each pip represents a time bucket — click one to jump to the activity page at that point in time. Uptime pills above the bar let you select different time windows.
Timeline improvements — Flapping health checks are collapsed into single events. Streak events show human-readable durations. The timeline uses a compact table format instead of bordered cards.
Dashboard redesign — denser tables, richer health data
The dashboard overview, domains list, and detail pages have been redesigned with compact table layouts, inline health data, and a unified attention queue.
The dashboard has been redesigned for density and clarity across all major pages.
Overview page — Status headline telling you what needs attention, key numbers (domains, hosts, incidents, managed SPF), health breakdown bar, and a unified attention queue replacing the old sparse layout.
Domains list — Each row now shows health score, overall status, per-check status dots, and last checked time. No more clicking through to find out if a domain is healthy.
Domain detail — Stat cards (checks passing, 30-day health, open incidents, last checked), health section with sub-check pills, associated hosts discovery, and tabbed layout for Timeline and Incidents.
Host detail — Same stat card pattern, sub-check results with expandable detail, and tabbed navigation.
Monitors have been renamed to Hosts throughout the dashboard for clarity. The A/AAAA and IP Ping checks have been removed from domain health — they're infrastructure concerns, not email authentication.
Multi-IP health checking for endpoint monitors
Monitors now resolve all IPs for a hostname and check each one independently. Per-IP breakdowns show exactly which server is having issues.
When a hostname resolves to multiple IP addresses (load balancers, failover configurations, round-robin DNS), mxio now checks each IP independently — up to 4 per monitor.
Per-IP results appear in the monitor detail page, so you can see exactly which server is failing SMTP, which IP has a certificate issue, or which endpoint isn't responding to ping. IP set changes (new IPs appearing, old ones disappearing) are tracked and surfaced in the activity timeline.
Endpoint monitoring: per-monitor billing and 4 check types
Monitor SMTP, HTTPS, Ping, and TCP Port endpoints independently. Each monitor is one billable slot with its own check types — no more paying for checks you don't need.
Endpoint monitoring has been redesigned from the ground up. Instead of one monitor per hostname with all check types enabled, you now create typed monitors — SMTP, HTTPS, Ping, or Port — each as its own billable slot with only the relevant checks.
What's new:
- 4 monitor types — SMTP (port connectivity, STARTTLS, TLS certs), HTTPS (uptime, cert expiry), Ping (ICMP reachability), Port (TCP connectivity on any port)
- Per-monitor billing — one monitor = one slot against your plan limit. Only pay for what you monitor.
- TCP port checks — monitor any TCP port (database, custom services, mail submission)
- Type-picker creation — 4-across card selector when adding a new monitor, with type-specific inputs and sub-check toggles
- Redesigned detail page — denser layout, aggregated check history with cycle grouping, mini-history pips, incidents section
DNS host guidance on tool results
When a tool check finds issues, mxio now detects your DNS hosting provider and tells you exactly where to go to fix them — with a direct link to the provider's setup guide.
A common source of confusion: your SPF checker says "fix your SPF record," but where do you actually make that change? It's not your email provider — it's your DNS host, and they're usually different companies.
Now, every domain-based tool (SPF, DMARC, DKIM, MX, Domain Health, Delegation, DNS Lookup) shows a guidance card when issues are detected. If we recognize your DNS host, you get the provider name and a link to their setup guide. If we don't, you see your raw nameservers so you know who to contact.
Unrecognized DNS hosts are tracked internally so we can expand our provider directory over time.
Automatic DKIM selector discovery
When you add a domain, mxio now probes DNS for DKIM selectors from known providers — Google Workspace, Microsoft 365, MailRoute, SendGrid, and more. Selectors appear on your domain detail page without any manual setup.
Previously, adding a domain meant your first Domain Health check would show a DKIM warning because no selectors were configured yet. Now mxio automatically checks ~25 common DKIM selectors during domain creation and saves the ones that resolve.
New domains are also immediately scheduled for automated health checks — no more waiting for a manual trigger to enter the monitoring rotation.
Context-aware login page
The login page now adapts to where you're coming from. Visitors arriving from spfflatten.net, MailRoute, or ad campaigns see relevant value props alongside the login form. New users see 'Create your free account' instead of a generic sign-in prompt.
If you arrive at mxio.io from spfflatten.net, a MailRoute referral, or an ad campaign, the login page now shows value props relevant to your context instead of a blank form. Returning users see a streamlined "Welcome back" layout.
DMARC Record Generator
Build a valid DMARC record with guided deployment stages. Choose a rollout strategy — monitor, quarantine, or reject — configure aggregate and forensic reporting, alignment, and subdomain policy. Server-side validation catches mistakes before you publish.
New free tool at /tools/dmarc-wizard. Enter your domain to pre-fill from an existing DMARC record, or start from scratch.
Deployment stage selector — pick a rollout strategy and the wizard sets your policy and percentage automatically:
- Monitor first —
p=none(observe without affecting delivery) - Quarantine (gradual) —
p=quarantine; pct=25(test on a slice of traffic) - Quarantine (full) / Reject (gradual) / Reject (full) — step through enforcement at your own pace
- Custom — full manual control over every tag
Reporting — add multiple aggregate (rua) and forensic (ruf) addresses, comma-separated. The wizard validates each address and assembles the mailto: URIs for you.
Server-side validation — click Validate to run the same checks our DMARC Record Checker uses. Catches missing tags, invalid policies, and spec violations before you touch DNS.
The generated record includes full DNS setup instructions: hostname (_dmarc.yourdomain.com), record type (TXT), and a copy button for the value. Your configuration is assembled in-browser and never stored.
Monitor IPs directly from tool results
Running a blacklist or MX check? You can now add IPs to monitoring with one click, right from the results page. Notification preferences also show severity levels so you know which alerts need fast action.
When you run a blacklist check or MX lookup, each IP now shows a Monitor button inline. Click it to start tracking that IP — no need to navigate to the dashboard first.
Notification preferences now display severity badges (High, Medium, Info) alongside each event category, with recommended action timeframes so you can prioritize what matters.
RFC standards reference pages
Four annotated RFC reference pages covering SPF (RFC 7208), DKIM (RFC 6376), DMARC (RFC 7489), and MX/SMTP (RFC 5321). Every tool result now links to the governing RFC, and all existing content citations are properly hyperlinked.
DNS host setup guides
12 provider-specific guides for configuring SPF, DMARC, DKIM, and MTA-STS records at your DNS host. Domain Health and Delegation Health tools now detect your DNS provider and link directly to the right guide.
Guides cover GoDaddy, Cloudflare, Route 53, Namecheap, Network Solutions, Google Domains, Azure DNS, IONOS, Hover, DreamHost, DNS.com, and DNS Made Easy. Each guide includes exact field values, platform-specific conventions, and troubleshooting tips.
Improved monitor creation flow
A new type picker makes it easy to create the right monitor for each use case. Choose SMTP, HTTPS, Ping, or Port, configure sub-checks, and start monitoring in seconds.
The Add Monitor page now opens with a visual type picker — four cards showing SMTP, HTTPS, Ping, and Port with descriptions of what each monitors. After picking a type, the form adapts: hostname input for all types, a port field for Port monitors, and sub-check toggles for SMTP and HTTPS.
The monitor list is now a compact table with status dots, type badges, health summaries, and an actions menu. Failures sort to the top so problems are visible at a glance.
Partner embed system
Embeddable email health check widget for partners and integrators. Drop a single iframe into your product to show SPF, DKIM, DMARC, and MX status. Includes partner credentials, referral attribution, JSON API, and admin management.
Partners can now embed email authentication health checks directly in their products using a self-contained iframe widget or JSON API. The system includes partner credential management (embed tokens and API keys), per-partner rate limiting, HMAC-signed referral attribution with conversion tracking, and a full admin panel for partner review, credential rotation, and funnel analytics. Visit the integration guide to get started.
Security hardening for Managed SPF
Managed SPF DNS labels now use randomized identifiers instead of sequential numbering, preventing enumeration of customer domains through DNS queries.
Smarter AI explain caching
AI explanations for identical results no longer count against your monthly quota. Re-running a check you've already explained won't cost you an explain credit.
Previously, every "Explain this" request counted against your monthly quota — even if the results were identical to a previous check. Now, when your results match a previous explanation, we serve the cached response instantly without deducting from your quota.
Blacklist reference directory
19 dedicated blacklist pages covering Spamhaus, Barracuda, SORBS, SpamCop, and more. Each page explains what the blacklist checks, how to delist, and links directly to our blacklist checker.
Endpoint monitoring with monitor types
Monitor your infrastructure with four purpose-built types: SMTP for mail servers, HTTPS for web endpoints, Ping for reachability, and Port for TCP connectivity. Each monitor is one billable slot with sub-checks included.
Monitors are now organized by type instead of generic profiles:
- SMTP — mail server health: SMTP connectivity, PTR records, IP blacklists, ping
- HTTPS — web endpoint health: TLS certificate, IP blacklists, ping
- Ping — basic reachability checks
- Port — TCP port connectivity on any port (1–65535), plus ping
Each monitor uses one slot regardless of how many sub-checks it includes. Toggle individual sub-checks on or off without affecting your quota.
Monitor packs are available as add-ons for paid plans (+25 monitors for $5/mo).
February 2026
Privacy-first analytics
Replaced third-party analytics with self-hosted Plausible. No cookies, no cross-site tracking, no personal data collection. Your usage stays private.
Fresh visual design
New visual identity across both sites — cleaner typography, refined color palette, redesigned navigation, and a monochrome design language that puts your data front and center.
21 ESP provider setup guides
Dedicated setup pages for Google Workspace, Microsoft 365, SendGrid, Mailchimp, Amazon SES, and 16 more. Each guide covers SPF includes, DKIM selectors, and DMARC alignment for that provider.
Expanded learning center
13 new guides covering every diagnostic tool — from SPF record syntax to DKIM key rotation. Each guide links directly to the relevant tool so you can check your own domain as you read.
AI-powered check explanations
Every tool now has an 'Explain this' button that uses AI to interpret your results in plain English — what's wrong, why it matters, and how to fix it.
Available on all 20 diagnostic tools for signed-in users. Each explanation is tailored to your specific results, not generic advice. Usage is included with your plan — quota resets monthly.
DNS delegation health checks
SPF, DKIM, DMARC, and MX checks now detect split NS delegations — a common sign of incomplete DNS provider migrations that can silently break email authentication.
Performance and accessibility improvements
Faster page loads across both sites — reduced JavaScript bundles by over 100 kB per page, improved contrast ratios, larger touch targets on mobile, and faster font loading.
Platform launch
mxio.io is live. 20 free email diagnostic tools, domain health monitoring, incident tracking, Managed SPF service, and a full dashboard for managing your email authentication infrastructure.