GET /reports
Aggregate (RUA) reports received for the organization, newest first by default. Set format=csv or format=json to download the current page as an attachment instead of the paged envelope.
- Permission
report:read - Key scope
readfull
Query parameters
| Name | Type | Description |
domain | string | Keep only reports whose domain contains this text; a substring match, unlike the exact match elsewhere. |
org | string | Reporting organization name as printed in the report; a substring match, e.g. google.com. |
result | string | pass keeps reports in which every message passed DMARC; fail keeps reports in which at least one message failed. A report with no messages is in neither. One of "pass", "fail". |
source_ip | string | Keep only reports that contain exactly this sending IP. |
from | string | Earliest date to include, YYYY-MM-DD (UTC). A report is kept when its reporting window starts on or after this day. |
to | string | Latest date to include, YYYY-MM-DD (UTC), inclusive. A report is kept when its reporting window ends on or before this day, so a window that straddles the boundary needs a range covering both days. |
search | string | Fuzzy match against reporter names, domains and report IDs. Longer terms are truncated. |
sort_by | string | Sort column. An unknown value falls back to the default. Default "date_end". One of "date_end", "received", "org_name", "domain", "total_messages", "report_id", "compliance". |
sort_dir | string | Sort direction. Default "desc". One of "asc", "desc". |
limit | integer | Page size. Values above the maximum are clamped; zero, negative or non-numeric values are ignored and the default applies. Default 50. |
offset | integer | Number of rows to skip; combine with limit to page. A negative or non-numeric value is treated as 0. Default 0. |
format | string | Download the current page (up to the page limit) as an attachment instead of the JSON envelope. The CSV is a subset of the JSON row: it omits received_at and prints the reporting window as YYYY-MM-DD. One of "csv", "json". |
Example request
Response
| Field | Type | Notes |
reports | object[] | The requested page, newest first by default. Never null; an empty page is []. |
total | integer | Reports matching the filter, before paging. |
limit | integer | The page size actually applied. |
offset | integer | The offset actually applied. |
has_any | boolean | True when the organization holds any report at all, ignoring filters; use it for empty states. |
| Field | Type | Notes |
reports[].id | string | Identifier, Crockford Base32. Opaque; never parse it as a number. |
reports[].report_id | string | The reporter's own identifier for the report, as printed inside it. Not the id you fetch the report by. |
reports[].org_name | string | The organization that sent the report. |
reports[].domain | string | The domain the report is about. |
reports[].total_messages | integer | Messages the report accounts for. |
reports[].compliant_messages | integer | Of those, how many passed DMARC. |
reports[].compliance_rate | number | Percentage from 0 to 100 of this report's messages that passed DMARC. |
reports[].policy_p | string | The DMARC policy the reporter saw published: none, quarantine or reject. |
reports[].date_begin | string nullable | RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent. |
reports[].date_end | string nullable | RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent. |
reports[].received_at | string nullable | RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent. |
Errors
Plus the errors every request can return.
GET /reports/date-range
The earliest and latest report dates the organization holds, for building date pickers and backfill loops.
- Permission
report:read - Key scope
readfull
Example request
Response
| Field | Type | Notes |
earliest | string nullable | Calendar day, YYYY-MM-DD (UTC); null when absent. |
latest | string nullable | Calendar day, YYYY-MM-DD (UTC); null when absent. |
Errors
Plus the errors every request can return.
GET /reports/{id}
The parsed report as the reporter sent it, plus DMARCguard's per-record classification and identifier-alignment verdicts. Field names inside the report object are the report's own elements, re-cased (ReportMetadata, PolicyPublished, Records); take the names from the table below rather than transforming the XML yourself. Its date range is the reporter's epoch seconds.
- Permission
report:read - Key scope
readfull
Path parameters
| Name | Type | Description |
id | string | Report ID as returned by List aggregate reports (Crockford Base32). |
Example request
Response
| Field | Type | Notes |
Version | string | Report format version, 1.0 for every conformant report. |
ReportMetadata | object | Who sent the report, when, and how to reach them. |
PolicyPublished | object | The DMARC policy the reporter read from your DNS while it handled this mail. |
Records | object[] nullable | One entry per sending IP and authentication outcome. A report always carries at least one. |
parse_warnings | string[] nullable optional | Ways this report departs from the standard. DMARCguard keeps such a report and flags it rather than dropping it; not part of the report itself. |
record_classifications | string[] | DMARCguard's verdict on each record, in the same order as Records: authenticated, likely_forwarded, suspicious or needs_review. |
record_alignment | object[] | Which of each record's raw SPF and DKIM results aligned with the From domain, in the same order as Records. |
failure_summary | object | How the report's records split by which mechanism failed. |
| Field | Type | Notes |
ReportMetadata.OrgName | string | Name of the organization that generated the report. |
ReportMetadata.Email | string | Address to contact that organization about the report. |
ReportMetadata.ExtraContactInfo | string | Further contact details the reporter chose to include. |
ReportMetadata.ReportID | string | The reporter's unique identifier for this report. A resent report reuses it. |
ReportMetadata.DateRange | object | The reporting period this report covers, typically one UTC day. |
ReportMetadata.Errors | string[] nullable | Problems the reporter hit while reading your DMARC record. Worth reading when a report looks wrong. |
ReportMetadata.Generator | string | Name and version of the software that produced the report. |
| Field | Type | Notes |
ReportMetadata.DateRange.Begin | integer | Start of the reporting period, in seconds since the Unix epoch (UTC). This object is the reporter's own data, so it keeps the encoding the standard mandates. |
ReportMetadata.DateRange.End | integer | End of the reporting period, in seconds since the Unix epoch (UTC). |
| Field | Type | Notes |
PolicyPublished.Domain | string | The domain whose DMARC record the reporter applied. |
PolicyPublished.ADKIM | string | DKIM alignment mode published by the domain: r (relaxed) or s (strict). |
PolicyPublished.ASPF | string | SPF alignment mode published by the domain: r (relaxed) or s (strict). |
PolicyPublished.P | string | Policy the domain asked receivers to apply: none, quarantine or reject. |
PolicyPublished.SP | string | Policy published for subdomains, when the domain publishes one separately. |
PolicyPublished.NP | string | Policy published for subdomains that do not exist, when the domain publishes one. |
PolicyPublished.PCT | integer | Sampling percentage from the older DMARC specification, 0 to 100. Current reports omit it; the tag was removed from the standard. |
PolicyPublished.FO | string | Failure-reporting options the domain published, deciding when a receiver sends a failure report. |
PolicyPublished.T | string | Testing flag the domain published, y or n: y asks receivers to report without enforcing the policy. |
PolicyPublished.PSD | string | Flag, y or n, marking the record as published by a public suffix domain rather than an ordinary one. Only reporters that send the element supply it. |
PolicyPublished.DiscoveryMethod | string | How the reporter found the record: treewalk for the current algorithm, psl for the older public-suffix-list one. Diagnostic only. |
| Field | Type | Notes |
Records[].Row | object | The sending IP, how many messages it sent, and what the receiver did with them. |
Records[].Identifiers | object | The domains the policy was matched against. |
Records[].AuthResults | object | The raw SPF and DKIM results, before DMARC alignment was applied to them. |
| Field | Type | Notes |
Records[].Row.SourceIP | string | IP address the messages were delivered from. |
Records[].Row.Count | integer | Messages this entry accounts for. |
Records[].Row.PolicyEvaluated | object | What DMARC concluded for these messages. |
| Field | Type | Notes |
Records[].Row.PolicyEvaluated.Disposition | string | What the receiver actually did with the messages: none, quarantine or reject. |
Records[].Row.PolicyEvaluated.DKIM | string | Whether DKIM produced an aligned pass for DMARC: pass or fail. Not the raw DKIM result. |
Records[].Row.PolicyEvaluated.SPF | string | Whether SPF produced an aligned pass for DMARC: pass or fail. Not the raw SPF result. |
Records[].Row.PolicyEvaluated.Reason | object[] nullable | Why the disposition differs from the published policy, when it does. |
| Field | Type | Notes |
Records[].Row.PolicyEvaluated.Reason[].Type | string | Why the receiver departed from your policy: local_policy, mailing_list, trusted_forwarder, policy_test_mode, or other. |
Records[].Row.PolicyEvaluated.Reason[].Comment | string | Free text the receiver added about the override. |
| Field | Type | Notes |
Records[].Identifiers.EnvelopeTo | string | Recipient domain the messages were addressed to. |
Records[].Identifiers.EnvelopeFrom | string | Domain of the envelope sender SPF checked. May be present but empty when the message had no return path. |
Records[].Identifiers.HeaderFrom | string | The From domain the recipient saw. DMARC aligns everything against this one. |
| Field | Type | Notes |
Records[].AuthResults.DKIM | object[] nullable | One entry per DKIM signature the receiver verified. |
Records[].AuthResults.SPF | object[] nullable | The SPF check the receiver ran. |
| Field | Type | Notes |
Records[].AuthResults.DKIM[].Domain | string | Signing domain from the signature's d= tag. |
Records[].AuthResults.DKIM[].Selector | string | Selector from the signature's s= tag, naming the key in DNS. |
Records[].AuthResults.DKIM[].Result | string | Raw DKIM verification result: none, pass, fail, policy, neutral, temperror or permerror. Alignment is decided separately. |
Records[].AuthResults.DKIM[].HumanResult | string | The reporter's own explanation of a verification failure. |
| Field | Type | Notes |
Records[].AuthResults.SPF[].Domain | string | Domain the SPF check was run against. |
Records[].AuthResults.SPF[].Scope | string | Which identity was checked: mfrom, the envelope sender, is the only one DMARC uses; older reporters also send helo. |
Records[].AuthResults.SPF[].Result | string | Raw SPF verification result: none, neutral, pass, fail, softfail, temperror or permerror. Alignment is decided separately. |
Records[].AuthResults.SPF[].HumanResult | string | The reporter's own explanation of a verification failure. |
| Field | Type | Notes |
record_alignment[].spf | boolean[] nullable | One flag per SPF result on the record, in order, saying whether it aligned with the From domain under the published alignment mode. |
record_alignment[].dkim | boolean[] nullable | One flag per DKIM result on the record, in order, saying whether it aligned with the From domain under the published alignment mode. |
| Field | Type | Notes |
failure_summary.spf_only | integer | Records where only SPF failed to produce an aligned pass. |
failure_summary.dkim_only | integer | Records where only DKIM failed to produce an aligned pass. |
failure_summary.both | integer | Records where both failed, which is what makes a record fail DMARC. The three buckets are mutually exclusive. |
failure_summary.total | integer | Records in the report, failing or not. |
Errors
Plus the errors every request can return.