DMARC Report Reader API

Turn DMARC aggregate reports (XML, .zip, .gz from Google, Microsoft, Yahoo) into JSON: senders by IP, SPF / DKIM alignment, pass rates and advice.

POSThttps://apibox.io.vn/v1/dmarc-report
Network & Validation▶ Try it online

Mailbox providers send DMARC aggregate (RUA) reports as XML files, usually zipped or gzipped. Upload one or more (file, file2…, up to 50 files or 200 reports, ZIPs may contain several) or paste the XML. The API reads both the RFC 7489 format and the newer DMARCbis aggregate format (namespace dmarc-2.0, with np, testing and discovery_method) and returns the reporter, report id, date range, the published policy and every record: source IP, message count, disposition, the DKIM and SPF results as evaluated by the receiver, override reasons, header / envelope from and the raw DKIM / SPF results with our own alignment check.

All reports are then aggregated: total messages, DMARC pass / fail and pass rates, aligned DKIM and SPF rates, dispositions, totals per From domain, and a list of sending sources sorted by volume with their pass rate, DKIM domains and selectors and SPF domains. failing_sources shows the IPs whose mail failed, and advice gives plain next steps (authorise a legitimate sender, add DKIM because SPF breaks on forwarding, move from p=none to quarantine when more than 98% passes).

With enrich=true the top 50 sources also get their reverse DNS (PTR) and, where available, ASN / network owner. Set include_records=false for a compact answer. Reports are parsed in memory and not stored.

Parameters

NameInTypeRequiredDefault
filebodyfilenoReport file: .xml, .xml.gz, .gz or .zip (also file2… for more files).
xmlbodystringnoThe report XML as text (or send a raw XML body).
enrichbodybooleannofalseLook up PTR and ASN for the top 50 source IPs.
include_recordsbodybooleannotrueInclude every record of each report.

Example

curl -X POST "https://apibox.io.vn/v1/dmarc-report" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/xml" \
  --data-binary '<feedback>…<policy_published><domain>example.vn</domain><p>none</p>…</policy_published><record>…</record></feedback>'

Response

{
  "reports_count": 1,
  "summary": {
    "messages": 123,
    "dmarc_pass": 120,
    "dmarc_fail": 3,
    "pass_rate": 97.56,
    "dkim_aligned_pass_rate": 97.56,
    "spf_aligned_pass_rate": 97.56,
    "dispositions": {
      "none": 123
    },
    "source_ips": 2,
    "policies": [
      "none"
    ],
    "domains": {
      "example.vn": {
        "messages": 123,
        "pass": 120,
        "fail": 3
      }
    },
    "date_range": {
      "begin": "2024-11-06T00:00:00.000Z",
      "end": "2024-11-06T23:59:59.000Z"
    },
    "reporters": [
      "google.com"
    ]
  },
  "advice": [
    "Policy is p=none: before enforcing, authorise (SPF) or sign (DKIM, aligned with the From domain) every legitimate source listed in failing_sources.",
    "1 source IP(s) sent mail that failed DMARC; check which are your own services (add them to SPF / set up DKIM) and which are spoofing."
  ],
  "sources": [
    {
      "source_ip": "209.85.220.41",
      "count": 120,
      "pass": 120,
      "fail": 0,
      "dkim_aligned_pass": 120,
      "spf_aligned_pass": 120,
      "header_from": [
        "example.vn"
      ],
      "dkim_domains": [
        "example.vn (google): pass"
      ],
      "spf_domains": [
        "example.vn: pass"
      ],
      "dispositions": {
        "none": 120
      },
      "pass_rate": 100
    },
    {
      "source_ip": "198.51.100.7",
      "count": 3,
      "pass": 0,
      "fail": 3,
      "dkim_aligned_pass": 0,
      "spf_aligned_pass": 0,
      "header_from": [
        "example.vn"
      ],
      "dkim_domains": [],
      "spf_domains": [
        "spammer.test: softfail"
      ],
      "dispositions": {
        "none": 3
      },
      "pass_rate": 0
    }
  ],
  "failing_sources": [
    {
      "source_ip": "198.51.100.7",
      "messages": 3,
      "header_from": [
        "example.vn"
      ]
    }
  ],
  "reports": [
    {
      "file": null,
      "format": "rfc7489",
      "reporter": {
        "org_name": "google.com",
        "email": "noreply-dmarc-support@google.com",
        "report_id": "1234567890"
      },
      "policy_published": {
        "domain": "example.vn",
        "p": "none",
        "sp": "none",
        "adkim": "r",
        "aspf": "r",
        "pct": 100
      },
      "records": [
        "…"
      ]
    }
  ]
}

Use cases

  • Read the daily DMARC reports of a domain without a paid dashboard
  • Find which services still send mail that fails SPF or DKIM before enforcing DMARC
  • Spot spoofing sources sending as your domain
  • Merge a month of reports from several providers into one summary

FAQ

Which files can I upload?

The XML report as sent by the provider, gzip (.xml.gz, .gz) or .zip archives, several at once. Forensic (RUF) reports and whole e-mails (.eml) are not parsed: extract the attachment first, for example with our e-mail parser.

What does dmarc: pass mean here?

A record passes DMARC when the receiver evaluated DKIM or SPF as pass and aligned with the From domain (policy_evaluated). The raw auth results and our alignment check are shown next to it.

When should I move to p=quarantine?

When all your legitimate senders pass, typically more than 98% of the volume over a few weeks. The advice field says so when the reports show it.

Related APIs

Start with 1,000 free requests every month. Get free API key →