<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Łukasz Gogolin</title>
    <description>The latest articles on DEV Community by Łukasz Gogolin (@lgogolin).</description>
    <link>https://dev.to/lgogolin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3921331%2F862a3972-8ff8-4601-83f7-f5d3ce9fde5c.png</url>
      <title>DEV Community: Łukasz Gogolin</title>
      <link>https://dev.to/lgogolin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lgogolin"/>
    <language>en</language>
    <item>
      <title>One API Call to Audit Any Domain's Email Security</title>
      <dc:creator>Łukasz Gogolin</dc:creator>
      <pubDate>Sat, 09 May 2026 09:45:46 +0000</pubDate>
      <link>https://dev.to/lgogolin/one-api-call-to-audit-any-domains-email-security-2b6k</link>
      <guid>https://dev.to/lgogolin/one-api-call-to-audit-any-domains-email-security-2b6k</guid>
      <description>&lt;p&gt;You know the drill. A customer complains their transactional emails land in spam. Or a B2B trial signup uses a throwaway address. Or someone asks "do we have DMARC set up correctly?" and you open ten browser tabs to find out.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://api.market/fivetag-systems/mailsec" rel="noopener noreferrer"&gt;MailSec&lt;/a&gt; to replace that entire workflow with one API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Email infrastructure is deceptively complex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPF&lt;/strong&gt; has a hard 10-lookup limit that silently breaks when you add one too many &lt;code&gt;include:&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DMARC&lt;/strong&gt; with &lt;code&gt;p=none&lt;/code&gt; does literally nothing — but most teams ship it and assume they're protected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DKIM&lt;/strong&gt; selectors vary by provider (&lt;code&gt;google&lt;/code&gt;, &lt;code&gt;selector1&lt;/code&gt;, &lt;code&gt;k1&lt;/code&gt;, &lt;code&gt;s1&lt;/code&gt;) and you need to guess which one to check&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spamhaus&lt;/strong&gt; listings can tank your deliverability for days before anyone notices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNSSEC&lt;/strong&gt; is either there or it isn't, and most tools make you check separately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The information is all in DNS, but it's scattered across different record types, different query tools, and different mental models. You end up juggling &lt;code&gt;dig&lt;/code&gt;, MXToolbox, Spamhaus lookup, and a DMARC analyzer — just to answer "is this domain's email OK?"&lt;/p&gt;

&lt;h2&gt;
  
  
  One request, full picture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://prod.api.market/api/v1/fivetag-systems/mailsec/v1/audit/cloudflare.com &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-market-key: YOUR_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cloudflare.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"spf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"present"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"valid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"record"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v=spf1 ip4:199.15.212.0/22 ip4:173.245.48.0/20 include:_spf.google.com include:spf1.mcsv.net include:spf.mandrillapp.com include:mail.zendesk.com include:stspg-customer.com include:_spf.salesforce.com -all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lookupCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dmarc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"present"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"valid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"record"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v=DMARC1; p=reject; pct=100; rua=mailto:...@dmarc-reports.cloudflare.net,mailto:rua@cloudflare.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"subdomainPolicy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rua"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"mailto:...@dmarc-reports.cloudflare.net"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"mailto:rua@cloudflare.com"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dkim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"present"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"selector"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"k1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"valid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dnssec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"valid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"present"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"redundant"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"records"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mxa-canary.global.inbound.cf-emailsecurity.net."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mxb-canary.global.inbound.cf-emailsecurity.net."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mxa.global.inbound.cf-emailsecurity.net."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mxb.global.inbound.cf-emailsecurity.net."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"grade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"blacklists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"dblListed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"zenListed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verdict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"READY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mtaSts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"present"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"mta-sts: no DNS record found"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tlsRpt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"present"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"tlsrpt: no record found"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cloudflare scores 100/A. SPF with 7 lookups (under the limit of 10), DMARC at &lt;code&gt;reject&lt;/code&gt; with full reporting, DKIM present, DNSSEC valid, redundant MX, clean blacklists. Verdict: &lt;strong&gt;READY&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now try a domain that doesn't have its act together and you'll see the score drop, issues appear, and the verdict shift to &lt;code&gt;CAUTION&lt;/code&gt; or &lt;code&gt;BLOCKED&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's behind the score
&lt;/h2&gt;

&lt;p&gt;The audit scores five components out of 100:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Max points&lt;/th&gt;
&lt;th&gt;What it measures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SPF&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Valid record, &lt;code&gt;all&lt;/code&gt; mechanism present, lookup count under 10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DMARC&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;Present, enforced (&lt;code&gt;quarantine&lt;/code&gt;/&lt;code&gt;reject&lt;/code&gt;), reporting configured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DKIM&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Key found at a known selector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNSSEC&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;DS record present, chain of trust valid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;MX records exist, redundant hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Grades: A (90+), B (70+), C (50+), D (30+), F (&amp;lt;30).&lt;/p&gt;

&lt;p&gt;DMARC is weighted heaviest because it's the single biggest factor in whether spoofed mail gets through. A domain with &lt;code&gt;p=none&lt;/code&gt; is essentially unprotected — MailSec won't call that "ready."&lt;/p&gt;

&lt;p&gt;MTA-STS, TLS-RPT, and BIMI are included in the audit response for visibility but are &lt;strong&gt;informational only&lt;/strong&gt; — they don't affect the score. Adoption is still too low to penalize domains without them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the full audit
&lt;/h2&gt;

&lt;p&gt;You don't always need everything. Each check has its own endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Just SPF&lt;/span&gt;
GET /v1/spf/&lt;span class="o"&gt;{&lt;/span&gt;domain&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Just DMARC policy&lt;/span&gt;
GET /v1/dmarc/&lt;span class="o"&gt;{&lt;/span&gt;domain&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# DKIM — auto-probes common selectors, or pass ?selector=google&lt;/span&gt;
GET /v1/dkim/&lt;span class="o"&gt;{&lt;/span&gt;domain&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# MTA-STS — DNS record + HTTPS policy file (RFC 8461)&lt;/span&gt;
GET /v1/mta-sts/&lt;span class="o"&gt;{&lt;/span&gt;domain&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# TLS-RPT — reporting URIs for TLS failures (RFC 8460)&lt;/span&gt;
GET /v1/tlsrpt/&lt;span class="o"&gt;{&lt;/span&gt;domain&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Is this a throwaway email domain?&lt;/span&gt;
GET /v1/email/disposable/&lt;span class="o"&gt;{&lt;/span&gt;domain&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Full email validation: syntax + DNS + disposable check&lt;/span&gt;
GET /v1/email/validate?email&lt;span class="o"&gt;=&lt;/span&gt;user@example.com

&lt;span class="c"&gt;# Deliverability verdict without DNSSEC (focused on inbox placement)&lt;/span&gt;
GET /v1/deliverability/&lt;span class="o"&gt;{&lt;/span&gt;domain&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real use cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Validate B2B signups
&lt;/h3&gt;

&lt;p&gt;Before provisioning a trial, check if the domain is real, has working email, and isn't disposable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl .../v1/email/validate?email&lt;span class="o"&gt;=&lt;/span&gt;cto@acme-corp.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cto@acme-corp.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"syntaxValid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"domainExists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mxPresent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"disposable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deliverable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Block &lt;code&gt;mailinator.com&lt;/code&gt;, &lt;code&gt;guerrillamail.com&lt;/code&gt;, and 100k+ other throwaway domains automatically. The disposable check does suffix-walking, so &lt;code&gt;anything.mailinator.com&lt;/code&gt; is caught too.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Pre-flight transactional sends
&lt;/h3&gt;

&lt;p&gt;About to send a welcome email, invoice, or password reset? Check the recipient's domain first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl .../v1/deliverability/their-domain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;verdict&lt;/code&gt; is &lt;code&gt;BLOCKED&lt;/code&gt;, that domain is in Spamhaus — your email probably won't arrive. If &lt;code&gt;CAUTION&lt;/code&gt;, their SPF/DMARC is misconfigured and replies/bounces may behave unexpectedly. Only send with confidence when &lt;code&gt;verdict&lt;/code&gt; is &lt;code&gt;READY&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Customer onboarding — "Check my domain" button
&lt;/h3&gt;

&lt;p&gt;Building a SaaS that sends email on behalf of customers? Give them a one-click domain health check in your onboarding flow. Hit &lt;code&gt;/v1/audit/{domain}&lt;/code&gt; and render the results:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Your DMARC policy is set to &lt;code&gt;none&lt;/code&gt; — this means spoofed emails from your domain won't be blocked. Change it to &lt;code&gt;quarantine&lt;/code&gt; or &lt;code&gt;reject&lt;/code&gt; to protect your brand."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. Monitor your own domains
&lt;/h3&gt;

&lt;p&gt;Run a daily cron against &lt;code&gt;/v1/audit/bulk&lt;/code&gt; with your company's domains. Alert when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Score drops below a threshold&lt;/li&gt;
&lt;li&gt;DMARC policy changes from &lt;code&gt;reject&lt;/code&gt; to &lt;code&gt;none&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A new Spamhaus listing appears&lt;/li&gt;
&lt;li&gt;SPF lookup count crosses 8 (getting close to the limit of 10)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Audit third-party vendors
&lt;/h3&gt;

&lt;p&gt;Before integrating with a partner who'll send email on your behalf, check their domain. A vendor with &lt;code&gt;p=none&lt;/code&gt; DMARC and no DKIM is a phishing risk to your customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Live DNS lookups on every request (no stale scrapes)&lt;/li&gt;
&lt;li&gt;In-process cache respects each record's TTL — repeat queries are &amp;lt;50ms&lt;/li&gt;
&lt;li&gt;Full audit fans out all checks in parallel — cold lookups typically 200-800ms&lt;/li&gt;
&lt;li&gt;Bulk endpoint audits up to 10 domains in a single request&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;MailSec is available on &lt;a href="https://api.market/fivetag-systems/mailsec" rel="noopener noreferrer"&gt;api.market&lt;/a&gt;. Sign up, grab your API key, and start auditing domains in minutes.&lt;/p&gt;

&lt;p&gt;Try it now — pick any domain you're curious about and see what comes back. You might be surprised by your own.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>api</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
