Skip to main content

Who sends mail as your domains, and whether they should.

List sending sources

GET /sources

Sending IPs seen in reports, enriched with sender identification, reputation and DMARCguard's authorized-or-not verdict.

  • Permission analytics:read
  • Key scope readfull

Query parameters

Name Type Description
domain string Restrict to one monitored domain, matched exactly; a subdomain is a separate domain. Omit for the whole organization.
search string Substring match on IP, domain or sender name. Longer terms are truncated.
reputation string Keep only sources with this abuse status. An unrecognised value is ignored rather than rejected. One of "clean", "suspicious", "malicious", "unknown".
has_failures boolean true keeps only sources with SPF or DKIM failures.
sort_by string Sort column. Default "total_messages". One of "total_messages", "source_ip", "first_seen", "last_seen", "compliance", "auth_failures", "domains".
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.

Example request

curl bash
curl "https://api.dmarcguard.io/api/v1/sources?domain=example.com" \
  -H "Authorization: Bearer dg_your_key"

Response

Field Type Notes
sources object[] The requested page. Never null; an empty page is [].
total integer Sources 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
sources[].source_ip string The sending IP, exactly as the reports carry it.
sources[].total_messages integer Messages this IP sent as your domains.
sources[].pass_count integer Of those, how many passed DMARC.
sources[].fail_count integer Of those, how many failed DMARC.
sources[].spf_fail_count integer Messages whose SPF did not produce an aligned pass. A source can pass DMARC on DKIM alone, so this can be non-zero while fail_count is 0.
sources[].dkim_fail_count integer Messages whose DKIM did not produce an aligned pass. A source can pass DMARC on SPF alone, so this can be non-zero while fail_count is 0.
sources[].compliance_rate number Percentage from 0 to 100 of this source's messages that passed DMARC.
sources[].first_seen string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
sources[].last_seen string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
sources[].domains string The domains this IP sent as, comma-separated. The single-source endpoint returns the same list as an array.
sources[].service_name string optional The sending service the IP was identified as, when it is recognised.
sources[].service_icon string optional Icon slug for the identified service.
sources[].service_slug string optional Stable identifier of the identified service.
sources[].abuse_status string optional Abuse standing of the IP: clean, suspicious or malicious. Absent when the IP has no reputation record at all, and unknown when it has one but was never scored.
sources[].abuse_score integer optional Abuse confidence for the IP, 0 to 100; higher is worse. Negative when the IP has a reputation record but was never scored. Omitted when it is zero, which is a clean IP.
sources[].reputation_reason string optional A ready-to-show sentence explaining abuse_status.
sources[].blocklist_severity string Blocklist standing: unchecked, clean, degraded when the evidence was too thin to call it clean, advisory for non-mail lists, and warning or critical for a live deliverability problem. One of "unchecked", "clean", "degraded", "advisory", "warning", "critical".
sources[].blocklist_summary string optional A ready-to-show sentence stating the blocklist standing.
sources[].isp string optional Network operator the IP belongs to, when known.
sources[].country string optional Two-letter country code for the IP, when known.
sources[].hostname string optional Reverse-DNS name of the IP, when it has one.
sources[].classification string Whether this source's mail should worry you: authenticated when SPF or DKIM passed, likely_forwarded when a failure looks like ordinary relaying, suspicious when a failing source also carries reputation red flags, and needs_review when the signals decide neither.

Errors

Status When
400 The domain query parameter is not a valid domain name.
401 Missing, malformed, revoked, expired or not-entitled API key.
403 The key's scope or its owner's role does not allow this operation.
429 Hourly quota or an abuse limit exceeded; the body's code says which. Honour Retry-After.
500 Unexpected server error; retry with backoff.
503 A transient failure resolving the organization or reading storage; retry after a short pause.

Plus the errors every request can return.

Get one sending source

GET /sources/{ip}

Everything known about one sending IP: per-domain records, timeline, geo, blocklist verdict and classification.

  • Permission analytics:read
  • Key scope readfull

Path parameters

Name Type Description
ip string IPv4 or IPv6 address exactly as reported.

Example request

curl bash
curl "https://api.dmarcguard.io/api/v1/sources/203.0.113.10" \
  -H "Authorization: Bearer dg_your_key"

Response

Field Type Notes
source_ip string The sending IP, exactly as the reports carry it.
total_messages integer Messages this IP sent as your domains.
pass_count integer Of those, how many passed DMARC.
fail_count integer Of those, how many failed DMARC.
spf_fail_count integer Messages whose SPF did not produce an aligned pass. A source can pass DMARC on DKIM alone, so this can be non-zero while fail_count is 0.
dkim_fail_count integer Messages whose DKIM did not produce an aligned pass. A source can pass DMARC on SPF alone, so this can be non-zero while fail_count is 0.
compliance_rate number Percentage from 0 to 100 of this source's messages that passed DMARC.
first_seen string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
last_seen string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
domains string[] The domains this IP sent as. The list endpoint returns the same names as one comma-separated string.
records object[] The most recent report rows this IP appears in, one per reporting period and domain.
records_total integer All-time report rows for this IP; larger than the records array, which carries only the recent ones.
timeline object[] One bucket per calendar day, oldest first.
service_name string optional The sending service the IP was identified as, when it is recognised.
service_icon string optional Icon slug for the identified service.
service_slug string optional Stable identifier of the identified service.
hostname string optional Reverse-DNS name of the IP, when it has one.
geo object nullable optional Where the IP geolocates to; absent when it cannot be placed.
enrichment object nullable optional Everything the reputation lookup knows about the IP; absent until it has been looked up.
blocklist_verdict object The blocklist standing of this IP, already interpreted: severity, weighted score and a sentence you can show.
spam_signals object[] nullable optional Spam-filter signals observed for this IP, when any were recorded.
classification string Whether this source's mail should worry you: authenticated when SPF or DKIM passed, likely_forwarded when a failure looks like ordinary relaying, suspicious when a failing source also carries reputation red flags, and needs_review when the signals decide neither.
classification_description string optional A ready-to-show sentence explaining the classification. Absent for an authenticated source, which needs none.
Field Type Notes
records[].report_id string The report this row came from; fetch it to see the row in context.
records[].domain string The domain the mail claimed to be from.
records[].count integer Messages this row accounts for.
records[].disposition string What the receiver did with them: none, quarantine or reject.
records[].dkim_result string Whether DKIM produced an aligned pass for DMARC: pass or fail.
records[].spf_result string Whether SPF produced an aligned pass for DMARC: pass or fail.
records[].header_from string The From domain the recipient saw.
records[].org_name string The organization that sent the report this row came from.
records[].date_begin string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
records[].date_end string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
Field Type Notes
timeline[].total_messages integer Messages reported for the day.
timeline[].compliant_messages integer Of those, how many passed DMARC.
timeline[].compliance_rate number Percentage from 0 to 100 of the day's messages that passed DMARC.
timeline[].failed_messages integer Of the day's messages, how many failed DMARC.
timeline[].reports integer Reports covering the day.
timeline[].date string nullable Calendar day, YYYY-MM-DD (UTC); null when absent.
Field Type Notes
geo.country string Two-letter country code for the IP.
geo.city string City the IP geolocates to.
geo.latitude number Latitude of the geolocated IP.
geo.longitude number Longitude of the geolocated IP.
Field Type Notes
enrichment.ip string The IP this record is about.
enrichment.country string optional Two-letter country code the IP geolocates to.
enrichment.city string optional City the IP geolocates to.
enrichment.latitude number optional Latitude of the geolocated IP.
enrichment.longitude number optional Longitude of the geolocated IP.
enrichment.isp string optional Network operator the IP belongs to.
enrichment.usage_type string optional What the address range is used for, such as a data centre or a residential network.
enrichment.country_code string optional Two-letter country code as the reputation lookup reported it.
enrichment.abuse_score integer Abuse confidence for the IP, 0 to 100; higher is worse. Negative when the IP was never scored.
enrichment.abuse_reports integer How many abuse reports the IP has attracted.
enrichment.abuse_categories string[] nullable optional What the IP was reported for, such as port scanning or spam.
enrichment.abuse_status string Abuse standing of the IP: clean, suspicious or malicious, and unknown when this record exists but the IP was never scored. The enrichment block itself is absent for an IP with no record at all.
enrichment.sender_name string optional The sending service the IP was identified as, when it is recognised.
enrichment.sender_slug string optional Stable identifier of the identified service.
enrichment.sender_icon string optional Icon slug for the identified service.
enrichment.hostname string optional Reverse-DNS name of the IP, when it has one.
enrichment.blocklist_listed integer Lists holding the IP. Read blocklist_verdict instead; that is where the standing is interpreted.
enrichment.blocklist_total integer Lists consulted. Read blocklist_verdict instead; it separates the lists that answered from those that did not.
enrichment.blocklist_results object[] nullable optional One result per blocklist consulted, each with a delisting link when there is one.
enrichment.abuse_last_reported string nullable optional RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
enrichment.enriched_at string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
enrichment.updated_at string nullable RFC 3339 UTC instant with whole seconds, e.g. 2026-09-15T16:03:43Z; null when absent.
Field Type Notes
enrichment.blocklist_results[].name string The blocklist this result came from.
enrichment.blocklist_results[].listed boolean Whether the list holds the IP. Prefer status, which also distinguishes a list that could not be reached.
enrichment.blocklist_results[].status string optional What this list said: listed, clean, or error when it could not be reached.
enrichment.blocklist_results[].reason string optional Why the list holds the IP, in its own words.
enrichment.blocklist_results[].category string optional What kind of abuse the list tracks, such as spam or malware.
enrichment.blocklist_results[].details string optional The evidence behind the listing, such as the covering address range or the list's response code.
enrichment.blocklist_results[].tier integer optional How much this list counts, as a rank: 0 unrecognised, 1 advisory and not about mail, 2 an ordinary mail blocklist, 3 one mailbox providers widely enforce, 4 hijacked address space or malware infrastructure.
enrichment.blocklist_results[].delist_url string optional The list operator's self-service delisting page, present only when the list is holding the IP and publishes one.
Field Type Notes
blocklist_verdict.severity string Blocklist standing, listed best to worst: unchecked and clean need nothing, degraded means the evidence was too thin to call it clean, advisory covers non-mail lists, and warning or critical is a live deliverability problem. One of "unchecked", "clean", "degraded", "advisory", "warning", "critical".
blocklist_verdict.listed integer Blocklists that answered and reported the IP as listed.
blocklist_verdict.clean integer Blocklists that answered and did not list the IP.
blocklist_verdict.errored integer Blocklists that refused or failed to answer, so they prove nothing either way.
blocklist_verdict.checked integer Blocklists that actually answered, listed plus clean. This is the denominator to quote, not total.
blocklist_verdict.total integer Blocklists consulted, including any that did not answer.
blocklist_verdict.score integer Weighted seriousness of the listings, 0 to 100. A list mailbox providers enforce counts for far more than an advisory one.
blocklist_verdict.names string[] nullable optional The lists the IP is on, most consequential first.
blocklist_verdict.top_list string optional The most consequential list the IP is on.
blocklist_verdict.top_reason string optional Why that list holds the IP.
blocklist_verdict.top_tier integer optional How much that list counts, as a rank: 0 unrecognised, 1 advisory and not about mail, 2 an ordinary mail blocklist, 3 one mailbox providers widely enforce, 4 hijacked address space or malware infrastructure.
blocklist_verdict.top_errored string optional The most consequential list that did not answer. It names which evidence is missing when the standing is degraded.
blocklist_verdict.has_malware_c2 boolean True when a listing is for malware infrastructure rather than spam, which points at an active compromise.
blocklist_verdict.urgency string How soon to act: none, monitor, soon or now.
blocklist_verdict.summary string A ready-to-show sentence stating the blocklist standing.
blocklist_verdict.scope string optional Set to ingest when this verdict consulted the smaller set of lists checked as reports arrive, so its counts cover fewer lists. Absent for a full check.
Field Type Notes
spam_signals[].name string Identifier of the spam-filter rule that fired for this IP.
spam_signals[].score number How much the rule moved the spam score; a positive value counts against the sender.
spam_signals[].description string optional What the rule checks, in words.

Errors

Status When
400 The path segment is not a valid IP address.
401 Missing, malformed, revoked, expired or not-entitled API key.
403 The key's scope or its owner's role does not allow this operation.
404 No report in this organization mentions that IP.
429 Hourly quota or an abuse limit exceeded; the body's code says which. Honour Retry-After.
500 Unexpected server error; retry with backoff.
503 A transient failure resolving the organization or reading storage; retry after a short pause.

Plus the errors every request can return.

Search the guides, the API reference and the learn articles.