DMARC Report Change Monitor
Pricing
from $10.00 / 1,000 domain period evaluateds
DMARC Report Change Monitor
Compare baseline and current DMARC aggregate-report periods for one or more domains. Find new sending IPs and SPF/DKIM alignment regressions with deterministic offline evidence for deliverability review.
Pricing
from $10.00 / 1,000 domain period evaluateds
Rating
0.0
(0)
Developer
Cedric Günther
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a month ago
Last modified
Categories
Security
Limited permissionsShare
Compares supplied baseline and current DMARC aggregate XML periods and emits deterministic new-source and identifier-alignment regression evidence. It is built for email-security teams, DMARC operations analysts, domain and deliverability engineers. The main result is structured, deterministic evidence that can be consumed from the default dataset or an Apify automation.
When to use this Actor
- Detect a source IP newly present in current aggregate reports.
- Identify SPF or DKIM identifier-alignment regressions between controlled periods.
- Generate stable comparison evidence for a scheduled DMARC monitoring workflow.
How it works
- Validate bounded inline DMARC aggregate XML for one explicit domain and two report periods.
- Normalize raw authentication separately from DMARC identifier alignment and aggregate evidence by source.
- Emit one comparison summary plus deterministic findings and complete REPORTS output before charging.
The Actor validates only the declared product contract. It does not infer facts outside the supplied data or claim outcomes that the source material cannot prove.
Quick start
- Open the Actor's Input tab or create a Task from one of the public examples.
- Paste or adapt this bounded example.
- Click Start and inspect the default dataset plus the output links shown on the run page.
{"comparisons": [{"id": "weekly-example","domain": "example.invalid","baselineReports": [{"id": "baseline","format": "XML","xml": "<feedback><report_metadata><org_name>Receiver</org_name><email>reports@example.invalid</email><report_id>b1</report_id><date_range><begin>1789516800</begin><end>1789603199</end></date_range></report_metadata><policy_published><domain>example.invalid</domain><p>none</p></policy_published></feedback>"}],"currentReports": [{"id": "current","format": "XML","xml": "<feedback><report_metadata><org_name>Receiver</org_name><email>reports@example.invalid</email><report_id>c1</report_id><date_range><begin>1789603200</begin><end>1789689599</end></date_range></report_metadata><policy_published><domain>example.invalid</domain><p>none</p></policy_published></feedback>"}]}],"maxXmlBytes": 1000000,"maxReportsPerPeriod": 100,"maxRecordsPerReport": 20000,"maxTotalRecordsPerComparison": 50000,"maxFindingsPerComparison": 1000}
Expected result: a successful comparison summary with zero findings for the two empty synthetic periods.
Input
The quick-start example is intentionally small. These are the material controls; the Input tab remains authoritative for the complete current schema.
| Field | Purpose and format | Default | Important bounds or interaction |
|---|---|---|---|
comparisons | Independent domain-period comparisons containing explicit baseline and current DMARC aggregate-report sources. | No implicit default | minimum items 1; maximum items 50 |
maxXmlBytes | Maximum decoded XML bytes accepted for each report before parsing. | 1000000 | minimum 1024; maximum 2000000 |
maxReportsPerPeriod | Caps report files in each baseline or current period for one domain comparison. | 100 | minimum 1; maximum 200 |
maxRecordsPerReport | Caps DMARC record elements parsed from any single aggregate report. | 20000 | minimum 1; maximum 50000 |
maxTotalRecordsPerComparison | Caps combined baseline and current record volume for one domain-period comparison. | 50000 | minimum 1; maximum 100000 |
maxFindingsPerComparison | Caps detailed change findings after deterministic ordering while preserving the comparison summary. | 1000 | minimum 1; maximum 5000 |
Unknown top-level fields and invalid field combinations fail validation rather than being guessed.
Output
The default dataset contains typed records. The run's Output tab links the dataset and any key-value-store reports declared by the current output schema.
| Field | Meaning |
|---|---|
recordType | Identifies comparison-summary, finding, or error evidence. |
comparisonId | Current dataset field. |
domain | Current dataset field. |
status | Current dataset field. |
baselineSourceCount | Current dataset field. |
currentSourceCount | Current dataset field. |
baselineMessageCount | Current dataset field. |
currentMessageCount | Current dataset field. |
findingCount | Current dataset field. |
totalFindingCount | Current dataset field. |
findingsTruncated | Current dataset field. |
findingType | NEW_SOURCE or ALIGNMENT_REGRESSION under the current public contract. |
sourceIp | Current dataset field. |
count | Current dataset field. |
previousState | Current dataset field. |
currentState | Current dataset field. |
summary | Current dataset field. |
fingerprint | Current dataset field. |
comparisonFingerprint | Stable identity for the normalized comparison. |
errorCode | Current dataset field. |
errorMessage | Current dataset field. |
engineVersion | Current dataset field. |
Representative current-schema dataset item:
{"recordType": "comparison-summary","comparisonId": "weekly-example","domain": "example.invalid","status": "PASS","baselineSourceCount": 0,"currentSourceCount": 0,"baselineMessageCount": 0,"currentMessageCount": 0,"findingCount": 0,"totalFindingCount": 0,"findingsTruncated": false,"comparisonFingerprint": "example-comparison-hash","engineVersion": "1.0.0"}
Comparable valid periods with no new source or alignment regression succeed with a zero-finding comparison summary.
Pricing and billing
This Actor uses PAY_PER_EVENT; platform usage is included in event prices. A charge is eligible only after the billable unit described below is durably completed. Validation failures and the non-billable failure classes in the product contract do not emit the custom completion event. The current live policy uses the same event price at every Store tier; no tier discount is active. The Apify Pricing tab is authoritative if a later approved pricing change takes effect.
| Event | What triggers it | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
|---|---|---|---|---|---|---|---|
domain-period-evaluated | One explicit baseline-versus-current comparison for one domain reaches a durable CHANGE or NO_CHANGE result. | $0.01000000 | $0.01000000 | $0.01000000 | $0.01000000 | $0.01000000 | $0.01000000 |
apify-actor-start | Platform-managed Actor start event. | $0.00005000 | $0.00005000 | $0.00005000 | $0.00005000 | $0.00005000 | $0.00005000 |
The Actor does not have Task-specific prices: public Tasks use this same live Actor pricing. Third-party costs are not implied; see the data and security section for external services actually contacted.
Limits and bounds
- The current public build accepts inline DMARC aggregate XML only; private HTTPS/gzip candidate behavior is not claimed.
- XML bytes, reports per period, records per report, total records, and findings are bounded by the Input schema.
- Mailbox ingestion, ZIP/MIME containers, DNS policy lookup, IP enrichment, vendor attribution, and message-content scanning are unsupported.
These are product-facing limits, not targets. Use smaller inputs when you need faster feedback or simpler evidence.
Failure and edge-case behavior
- Invalid top-level configuration, unsafe XML, wrong domain/period evidence, malformed reports, and bound breaches fail closed.
- A valid comparison with no drift succeeds with a summary and zero findings.
- Finding truncation is explicit; totalFindingCount remains truthful.
Operationally:
- Supply comparable baseline/current periods and stable comparisonId values.
- Treat new source/alignment evidence as an investigation trigger, not attribution or proof of abuse.
Use with Tasks and automation
Public Tasks provide reusable saved inputs for distinct supported workflows. Start with the closest Example Task, review its visible fields and scope caveat, then save your own Task for schedules or repeated runs. Do not treat an Example Task as evidence that unsupported behavior exists.
- Detect a new unaligned sender across two DMARC periods: Compare two synthetic daily DMARC periods and surface a newly observed source IP whose DMARC SPF and DKIM alignment both fail.
- Detect alignment regression for a known DMARC sender: Compare two synthetic daily DMARC periods and surface an existing source IP whose DMARC alignment changes from aligned to unaligned.
- Triage a multi-domain DMARC comparison batch: Evaluate synthetic domain-period pairs independently and review a change, a stable comparison, and an isolated malformed-report error in one batch.
Integration and API usage
Every saved Task can be started manually, through the Apify API, or from an Apify schedule. Run-completion webhooks can notify a downstream system after output is durable. Actor-to-Actor calls should consume the typed dataset/output links instead of scraping the Store page.
- Schedule a Task after upstream report aggregation and route findingType/fingerprint into alerting.
- Use comparisonFingerprint to reconcile repeated period comparisons.
No third-party integration is claimed unless it is named above and supported by the current product contract.
Data, privacy, and security
- Submitted aggregate XML and normalized evidence remain in Apify run storage under account retention settings.
- The current public build performs offline processing and contacts no external service.
Set Apify storage retention and access according to the sensitivity of your inputs and outputs. This documentation does not create legal, privacy, compliance, or security certification.
Support and known limitations
- The public build does not fetch remote reports or ingest a mailbox.
- The Actor does not query published DMARC policy, enrich IP ownership, or inspect individual messages.
For support, use the Actor Issues page. Include the run ID, a minimal reproducible input with sensitive values removed, the failing record or error code, and what you expected. Do not post credentials, private source files, customer data, or full confidential payloads.