DMARC Aggregate Report Analyzer
Pricing
from $8.16 / 1,000 item extracteds
DMARC Aggregate Report Analyzer
Parse DMARC aggregate XML into normalized sender, authentication, disposition, policy, and failure records for recurring email-security monitoring.
Pricing
from $8.16 / 1,000 item extracteds
Rating
0.0
(0)
Developer
Automation Lab
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Turn DMARC aggregate XML reports into normalized source-IP, message-volume, policy, disposition, DKIM, SPF, and failure records. This DMARC aggregate report analyzer accepts pasted XML, downloadable report files, and base64 attachments, making recurring email-authentication evidence ready for Apify Datasets, spreadsheets, alerts, and security pipelines.
The Actor analyzes aggregate (rua) feedback. It does not collect mailbox
messages, change DNS records, or parse forensic (ruf) reports.
What does this Actor do?
DMARC receivers such as Google, Yahoo, and Microsoft send machine-readable XML. Each file may contain many source rows and nested authentication results. The Actor:
- loads XML from input, an HTTP(S) URL, or base64;
- decompresses GZIP and ZIP attachments when necessary;
- validates the XML and required DMARC feedback sections;
- emits one stable dataset row per reported source record;
- derives a DMARC pass flag and concise failure signals;
- optionally combines matching source-IP rows across recurring reports.
The original message count is preserved. One output item can represent many
emails, so messageCount is the metric to sum for volume analysis.
Who is it for
- Email administrators investigating unauthorized or misconfigured senders.
- Security teams tracking reject, quarantine, and authentication-failure volume.
- Deliverability teams comparing SPF and DKIM alignment over time.
- Managed service providers processing daily reports for multiple domains.
- Data engineers feeding normalized DMARC evidence into a warehouse or SIEM.
- Developers who need a repeatable parser without maintaining XML edge cases.
Use Bulk DMARC Record Checker when you need to inspect the current DNS policy for domains. Use this Actor when you already have aggregate report files and need to understand observed traffic.
What is a DMARC aggregate report?
A DMARC aggregate report is XML feedback from a receiving mail provider. It summarizes messages claiming to be from a domain during a reporting period. Rows contain a sender IP, message count, receiver disposition, aligned DKIM/SPF results, identifiers, and detailed authentication evidence.
Reports do not contain message bodies. They can still reveal infrastructure, domains, addresses, and operational patterns, so store and share them according to your organization's security policy.
How to read a DMARC aggregate report
Start with these fields:
| Question | Output field |
|---|---|
| Which domain was evaluated? | domain, headerFrom |
| Which host sent the mail? | sourceIp |
| How much traffic did it send? | messageCount |
| What action did the receiver apply? | disposition |
| Did aligned DKIM pass? | dkimEvaluation |
| Did aligned SPF pass? | spfEvaluation |
| Did DMARC pass through either mechanism? | dmarcPass |
| Why should this row be reviewed? | failureReasons |
| Which policy was published? | policyDisposition, policyPercentage |
A DMARC pass requires aligned DKIM or aligned SPF. A detailed SPF result may
say pass while spfEvaluation says fail if the authenticated envelope domain
does not align with the visible From domain.
Input
reports is required and accepts 1–100 objects. Each object requires a name
and exactly one source:
xml: the complete XML string;url: an HTTP(S) URL returning XML, GZIP, or ZIP;base64: base64-encoded XML, GZIP, or ZIP bytes.
| Parameter | Type | Default | Purpose |
|---|---|---|---|
reports | array | required | Named report sources to analyze |
aggregateBySourceIp | boolean | false | Combine matching source/authentication rows |
failOnInvalid | boolean | true | Fail closed, or skip bad files in a mixed batch |
maxItems | integer | 10000 | Limit normalized output rows to 1–100,000 |
A URL is fetched once with redirects, a 30-second timeout, status validation, and a 10 MB compressed/download limit. Unpacked content is also limited to 10 MB. The Actor does not use a proxy and cannot access private intranet URLs unless they are reachable from the Apify run.
Example input: pasted XML
{"reports": [{"name": "Google daily report","xml": "<feedback>...</feedback>"}],"aggregateBySourceIp": false,"failOnInvalid": true,"maxItems": 10000}
For automation, base64 avoids JSON escaping issues. Keep the source label stable so downstream users can identify the originating file.
Example output
{"reportName": "Google report for sendgrid.net","reporter": "google.com","reportId": "2026-09-01-google-sendgrid","reportIds": ["2026-09-01-google-sendgrid"],"reportsCount": 1,"periodBegin": "2026-09-01T00:00:00.000Z","periodEnd": "2026-09-01T23:59:59.000Z","domain": "sendgrid.net","policyDisposition": "reject","policyDkimAlignment": "r","policySpfAlignment": "r","policyPercentage": 100,"policySubdomainDisposition": "reject","sourceIp": "209.85.220.41","messageCount": 24,"disposition": "none","dkimEvaluation": "pass","spfEvaluation": "pass","dmarcPass": true,"headerFrom": "sendgrid.net","envelopeFrom": "sendgrid.net","envelopeTo": null,"dkimResults": [{"domain":"sendgrid.net","result":"pass","selector":"s1"}],"spfResults": [{"domain":"sendgrid.net","result":"pass","scope":"mfrom"}],"policyOverrideReasons": [],"failureReasons": [],"analyzedAt": "2026-09-02T00:05:00.000Z"}
Provider-optional values are nullable. Arrays remain arrays even when the XML contains one result, which keeps warehouse and TypeScript contracts stable.
Aggregating recurring reports
Set aggregateBySourceIp to true when scheduled runs ingest multiple report
periods. Rows combine only when source IP, header-from domain, disposition, DKIM
evaluation, and SPF evaluation all match. This avoids hiding a change from pass
to fail or from none to reject.
Aggregated rows sum messageCount, list unique reportIds, expand the reporting
period, and set reportId to null. reportsCount records how many original rows
contributed. Schedule one run after new files land, or call the Actor from an
email-ingestion or object-storage workflow.
Failure and disposition analysis
failureReasons is designed for filters and alerts:
dkim:failordkim:missingindicates no aligned DKIM pass;spf:failorspf:missingindicates no aligned SPF pass;disposition:quarantineordisposition:rejectrecords enforcement;override:<type>preserves a receiver policy override.
Do not classify every listed reason as malicious activity. Forwarding, mailing lists, third-party senders, and temporary configuration changes can produce legitimate failures. Correlate source IP ownership and approved sender inventory before blocking traffic.
How much does it cost to analyze DMARC report source rows?
Pay-per-event billing has a $0.005 Actor start plus one item event for each
saved normalized or aggregated source row. The provisional market-led BRONZE
item price is $0.0136 per row; higher Apify tiers receive lower item prices.
The final live price shown in Apify Console is authoritative.
Example BRONZE costs at the provisional curve:
| Saved rows | Estimated charge |
|---|---|
| 1 | $0.0186 |
| 10 | $0.1410 |
| 25 | $0.3450 |
| 100 | $1.3650 |
Invalid reports, skipped files, and XML records beyond maxItems do not produce
item events. One item can summarize many messages; billing is not per email.
Getting started
- Open the Actor input page.
- Add a report name and paste XML, a URL, or base64 content.
- Keep Fail on an invalid report enabled for strict pipelines.
- Enable source-IP aggregation only when combining periods is desired.
- Set a practical
maxItemssafety limit. - Run the Actor and open the DMARC source results dataset view.
- Filter
dmarcPass = falseor non-emptyfailureReasonsfor investigation. - Export CSV, JSON, Excel, or connect the dataset to another service.
API usage with cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~dmarc-aggregate-report-analyzer/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"reports": [{"name":"daily-report","url":"https://your-authorized-host/reports/dmarc.xml.gz"}],"aggregateBySourceIp": false,"maxItems": 10000}'
Poll the returned run or use run-sync-get-dataset-items for small synchronous
jobs. Do not put tokens or confidential XML into logs or public Task inputs.
JavaScript API client
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/dmarc-aggregate-report-analyzer').call({reports: [{ name: 'daily-report', base64: process.env.DMARC_REPORT_BASE64 }],aggregateBySourceIp: true,maxItems: 10000,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.filter((row) => !row.dmarcPass));
Python API client
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/dmarc-aggregate-report-analyzer').call(run_input={'reports': [{'name': 'daily-report', 'url': 'https://your-authorized-host/reports/dmarc.xml'}],'failOnInvalid': True,'maxItems': 10000,})rows = client.dataset(run['defaultDatasetId']).list_items().itemsfailures = [row for row in rows if not row['dmarcPass']]print(failures)
MCP
Expose this Actor as a tool in Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/dmarc-aggregate-report-analyzer"
For Claude Desktop, Cursor, and VS Code, add this MCP JSON block to the client's MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/dmarc-aggregate-report-analyzer"}}}
Example prompts:
- “Analyze this base64 DMARC aggregate report and list failing source IPs.”
- “Combine these three authorized report URLs and rank senders by message count.”
- “Return rejected rows where neither aligned DKIM nor aligned SPF passed.”
Integrations and monitoring patterns
- Google Sheets or Excel: export source rows for a weekly deliverability review.
- Make or Zapier: launch a run when an attachment reaches object storage.
- Webhooks: notify a security workflow after a successful scheduled run.
- SIEM: ingest rows and alert on new IPs or rising reject counts.
- Data warehouse: partition by
periodEnd,domain, andsourceIp. - Apify schedules: rerun after daily aggregate-report collection completes.
The Actor analyzes supplied reports; it does not monitor an inbox or remember prior runs. Retain datasets or compare them downstream for change detection.
Limits and data handling
- Aggregate DMARC XML is supported; forensic message reports are not.
- One run accepts at most 100 report inputs.
- Each downloaded and unpacked report is limited to 10 MB.
- ZIP archives must contain at least one
.xmlmember; the first is parsed. - XML external entities are not resolved or fetched.
- Unknown provider extension fields are ignored.
- Results stop at
maxItems; reports are parsed in input order. - The Actor performs no reverse-DNS, ASN, geolocation, or reputation lookup.
- URL availability and authorization remain the user's responsibility.
Troubleshooting
“XML is not a DMARC aggregate feedback report” means the root does not
contain both report_metadata and policy_published. Confirm that the file is
an aggregate XML report rather than an email body or forensic report.
“Provide exactly one of xml, url, or base64” means a report object has no
source or several source fields. Keep one source and preserve the required
name.
A ZIP archive fails when it contains no .xml member. Extract or rebuild the
archive, or submit the XML member as base64.
Some reports succeed and one fails. Keep failOnInvalid: true for atomic
processing. Set it to false only when skipped-file warnings are acceptable.
SPF details pass while spfEvaluation fails. The detailed domain likely did
not align with headerFrom; this is valid DMARC behavior.
Legality and responsible use
Process only reports you are authorized to access. Treat report URLs as secrets when they contain signed query parameters. DMARC data can reveal internal or third-party email infrastructure, sender IPs, domains, and operational volume. Apply suitable access controls, retention limits, and regional privacy rules.
This tool provides technical normalization, not a legal conclusion, abuse verdict, or guarantee that a sender is authorized. Validate findings against business and infrastructure ownership records before enforcement.
Related Automation Lab Actors
- Bulk DMARC Record Checker — inspect published DMARC DNS records.
- Bulk SPF Record Checker — validate SPF DNS policy across domains.
- Bulk DKIM Record Checker — inspect known DKIM selectors.
- Bulk MX Record Checker — inventory mail exchangers when available.
FAQ
Does the Actor send or receive email?
No. It only processes report content supplied in Actor input.
Can it parse .xml.gz and .zip attachments?
Yes. Submit the bytes as base64 or provide an accessible HTTP(S) URL. ZIP
processing selects the first .xml member.
Does messageCount equal the number of dataset rows?
No. A dataset row represents one DMARC source record. messageCount is the
number of messages summarized by that record.
Can it identify unauthorized senders automatically?
It identifies authentication and disposition signals. Authorization depends on your sender inventory, forwarding rules, vendors, and business context.
Why is reportId null in an aggregated row?
An aggregate can include several reports. Use reportIds and reportsCount to
trace the contributing evidence.
Can I schedule recurring analysis?
Yes. Use Apify schedules after your report-collection workflow makes new XML or compressed files available. Store prior datasets if you need trend comparison.