What's New

Recent features, improvements, and fixes.

April 2026

ImprovedApr 28, 2026

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.

FixedApr 23, 2026

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.

ImprovedApr 23, 2026

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.

FixedApr 22, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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-reporting plan 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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 17, 2026

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.

ImprovedApr 15, 2026

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.
ImprovedApr 14, 2026

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.

ImprovedApr 14, 2026

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.
FixedApr 13, 2026

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.

ImprovedApr 13, 2026

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 with p=reject in 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 /pricing used a flat $37/domain/month estimate 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 /pricing competitor 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: /pricing and 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_DISABLED until 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.md claiming Pro has 5 domains and Business has 20 — real values are 25 and 50.
  • Managed SPF availability now noted on dmarc-deployment-guide.md and spf-flattening-explained.md so 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."
  • /pricing FAQ 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.

FixedApr 13, 2026

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 enabled state 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:

  1. The domain row showing "Awaiting reports" while the wizard simultaneously claimed "Reports Flowing" — two sources of truth disagreeing on the same screen.
  2. 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.

ImprovedApr 12, 2026

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.

NewApr 11, 2026

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=quarantine or p=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.

NewApr 10, 2026

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.

FixedApr 10, 2026

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.

FixedApr 10, 2026

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.

ImprovedApr 10, 2026

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.

ImprovedApr 9, 2026

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_DISABLED is 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
NewApr 9, 2026

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.

NewApr 8, 2026

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.

NewApr 8, 2026

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.

ImprovedApr 8, 2026

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.

NewApr 5, 2026

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.

ImprovedApr 5, 2026

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.

ImprovedApr 4, 2026

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.

ImprovedApr 4, 2026

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.

NewApr 2, 2026

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

NewMar 26, 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.

ImprovedMar 25, 2026

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
NewMar 18, 2026

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.

ImprovedMar 17, 2026

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 TabBar component
  • 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")
ImprovedMar 17, 2026

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 includeSubDomains across all services
  • Structured authentication event logging for all login methods
  • Sensitive values removed from startup logs
ImprovedMar 16, 2026

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.

ImprovedMar 15, 2026

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
NewMar 14, 2026

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.

ImprovedMar 14, 2026

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.

NewMar 13, 2026

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.

ImprovedMar 11, 2026

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.

ImprovedMar 10, 2026

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.

NewMar 9, 2026

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.

ImprovedMar 8, 2026

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.

NewMar 7, 2026

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.

NewMar 6, 2026

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
NewMar 5, 2026

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.

NewMar 4, 2026

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.

ImprovedMar 4, 2026

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.

NewMar 4, 2026

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 firstp=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.

NewMar 3, 2026

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.

NewMar 3, 2026

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.

NewMar 2, 2026

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.

ImprovedMar 2, 2026

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.

NewMar 2, 2026

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.

ImprovedMar 2, 2026

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.

ImprovedMar 2, 2026

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.

NewMar 1, 2026

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.

NewMar 1, 2026

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

ImprovedFeb 28, 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.

ImprovedFeb 28, 2026

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.

NewFeb 27, 2026

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.

NewFeb 26, 2026

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.

NewFeb 25, 2026

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.

NewFeb 25, 2026

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.

ImprovedFeb 25, 2026

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.

NewFeb 25, 2026

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.