Sendry Docs
Deliverability

DMARC Analyzer

Upload DMARC aggregate XML reports (or pipe them in via a DMARC mailbox) and see a pass/fail digest per source IP for the last 7-30 days.

DMARC Analyzer

Sendry ingests DMARC aggregate reports and renders a digest of which source IPs are passing DKIM / SPF alignment for each of your domains. Use this to spot misconfigured forwarders, third-party senders missing DKIM, or unauthorized senders pretending to be you.

Publishing a DMARC record

Before receivers will mail you reports, you need a DMARC record on your sending domain:

_dmarc.example.com  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
  • p=none — monitoring mode, no action taken on failing mail. Start here.
  • rua=mailto: — the address that should receive aggregate XML reports.

Once published, Google, Microsoft, Yahoo, and other large receivers will start mailing daily aggregate reports to the rua address. Forward them into Sendry via either of the two flows below.

Option 1 — Upload reports manually

  1. In the Sendry dashboard, go to Deliverability → DMARC.
  2. Click Upload report and pick the .xml or .xml.gz attachment from the receiver's email.
  3. The page refreshes with the new source-IP breakdown.

The dashboard upload uses POST /v1/dmarc/reports under the hood. You can call this directly from any script:

curl -X POST https://api.sendry.online/v1/dmarc/reports \
  -H "Authorization: Bearer $SENDRY_API_KEY" \
  -F "file=@google.com!example.com!1715731200!1715817600.xml.gz"

The response identifies the parsed report and indicates whether it was a duplicate of one already ingested (matched on reporter + report_id):

{
  "report_id": "dmarc_report_5n3Q…",
  "reporter": "google.com",
  "domain": "example.com",
  "date_begin": "2026-05-14T00:00:00.000Z",
  "date_end": "2026-05-15T00:00:00.000Z",
  "record_count": 12,
  "duplicate": false
}

Both raw XML and gzipped XML (.xml.gz) are accepted — Sendry detects the gzip magic header and decompresses transparently. The upload size limit is 10 MB.

Option 2 — Pipe reports from inbound email

If you've configured Sendry's inbound email routing, you can point the rua= address at a Sendry-managed mailbox and reports will be ingested automatically as they arrive. The dmarc-ingest BullMQ worker picks up each .xml.gz attachment, decompresses it, parses it, and inserts the records.

This path is asynchronous, so duplicates are still de-duplicated server-side on (org_id, reporter, report_id).

Endpoints

MethodPathDescription
POST/v1/dmarc/reportsMultipart upload — accepts .xml or .xml.gz (10 MB max).
GET/v1/dmarc/reportsList ingested reports (cursor-based, ?domain=&limit=).
GET/v1/dmarc/summaryPass/fail digest per source IP (?domain=&days= — default 7, max 90 days).

All three endpoints require full_access scope for the upload and read_only scope for the GETs.

What the summary shows

For each (source_ip, domain) bucket, Sendry returns:

  • Total — number of messages reported in the window.
  • Pass / Fail — counts where DKIM or SPF aligned, following the DMARC RFC's any-aligned semantics for treating a message as authenticated.
  • DKIM pass / SPF pass — per-mechanism pass counts.
  • Disposition — the receiver's chosen action (none, quarantine, reject).
  • Last seen — the most recent report's date range end.

The dashboard caps the displayed bucket list at the top 200 source IPs by message volume, so the page stays snappy even for very high-volume senders.

What it doesn't do

  • No automated remediation — DMARC findings are read-only. Use the data to harden DKIM / SPF, then re-run the analysis after a few days of fresh reports.
  • No forensic (RUF) report parsing yet — only RUA aggregate reports. Most receivers have deprecated RUF anyway.

On this page