Bulk DMARC Record Checker avatar

Bulk DMARC Record Checker

Pricing

from $0.96 / 1,000 domain extracteds

Go to Apify Store
Bulk DMARC Record Checker

Bulk DMARC Record Checker

Check DMARC records in bulk and export raw records, parsed policies, reporting destinations, alignment settings, and validation findings.

Pricing

from $0.96 / 1,000 domain extracteds

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Categories

Share

Bulk DMARC Record Checker is a DMARC record checker for domain portfolios. Give it up to 5,000 domains or website URLs and receive one normalized audit row per unique domain with the raw TXT record, parsed policy tags, reporting destinations, alignment settings, validation findings, and explicit missing or DNS-error states.

It uses the public DNS record at _dmarc.<domain>. It does not crawl websites, require login cookies, or hide missing records by dropping rows.

What does Bulk DMARC Record Checker do?

The Actor performs these steps for every unique normalized domain:

  1. Converts a domain or URL to a lowercase ASCII hostname.
  2. Resolves TXT values at _dmarc.<domain>.
  3. Joins multi-string DNS TXT chunks correctly.
  4. Selects values beginning with the DMARC1 version marker.
  5. Distinguishes one record, no record, multiple records, and DNS errors.
  6. Parses policy, reporting, percentage, alignment, failure, interval, and format tags.
  7. Emits structured findings for malformed, duplicate, invalid, unusual, and unknown tags.
  8. Saves one typed dataset item even when the record is missing or the resolver fails.

This output supports one-time checks and scheduled email-security posture audits. A scheduled Apify Task can run the same domain list repeatedly; each run's checkedAt timestamp and dataset provide a snapshot for downstream comparison.

Who is it for?

  • Email-security teams auditing whether managed domains publish enforceable policies.
  • IT and Google Workspace administrators checking policy, reporting, SPF alignment, and DKIM alignment.
  • Managed service providers reviewing many customer domains in one repeatable run.
  • Security consultants producing source-backed domain posture inventories.
  • Data and compliance teams exporting normalized findings to a spreadsheet, database, or SIEM.
  • Developers integrating DMARC record checks into onboarding or domain-management workflows.

Use Bulk DNS Records Lookup when you need A, AAAA, MX, NS, TXT, CNAME, and SOA records rather than DMARC-specific parsing. Use MX Record Checker when the job is specifically mail-exchanger discovery.

Why use this Actor?

A raw DNS lookup gives you strings. This Actor converts those strings into audit-ready fields while preserving the source record.

  • Bulk input: up to 5,000 supplied domains per run.
  • Explicit coverage: missing and resolver-error states are rows, not silent gaps.
  • Audit evidence: every row includes the query name, raw record, timestamp, and duration.
  • Policy parsing: p, sp, pct, adkim, aspf, rua, ruf, fo, ri, and rf become typed fields.
  • Validation findings: stable codes make filtering and downstream alerting practical.
  • International domains: Unicode hostnames normalize through IDNA/ASCII conversion.
  • URL input: https://www.domain.tld/path is checked as www.domain.tld.
  • Custom resolvers: optional DNS server IPs support resolver-specific audits.
  • No browser or proxy: the Actor uses the DNS protocol directly.

What DMARC data is returned?

FieldMeaning
inputOriginal domain or URL supplied by the user
domainNormalized, deduplicated ASCII hostname
queryNameDNS name queried, such as _dmarc.domain.tld
statusvalid, invalid, missing, multiple, or error
hasRecordWhether a DMARC-version TXT record was found
isValidWhether exactly one record passed implemented checks
rawRecordSingle source record, or null when unavailable/ambiguous
rawRecordsAll detected DMARC-version records
parsed.policyOrganizational policy: none, quarantine, or reject
parsed.subdomainPolicyOptional subdomain policy from sp
parsed.percentageEffective pct; defaults to 100 when omitted
parsed.aggregateReportUrisParsed rua destinations, including address and size limit
parsed.forensicReportUrisParsed ruf destinations
parsed.dkimAlignmentadkim; defaults to relaxed (r)
parsed.spfAlignmentaspf; defaults to relaxed (r)
parsed.failureOptionsParsed fo values
parsed.reportIntervalSecondsri; defaults to 86,400 seconds
parsed.reportFormatrf; defaults to afrf
parsed.tagsEvery parsed tag and its original value
parsed.unknownTagsUnrecognized tags preserved for forward compatibility
findingsStructured validation errors, warnings, and information
errorCode, errorMessageResolver details when status is error
checkedAtISO 8601 result timestamp
durationMsLookup and parsing duration for the domain

How to run your first DMARC record check

  1. Open the Actor in Apify Console.
  2. Enter one or more domains in Domains.
  3. Keep the default concurrency and timeout for a first run.
  4. Click Start.
  5. Open the Dataset tab and select the DMARC audit overview.
  6. Filter status or isValid, or export the complete dataset as JSON, CSV, Excel, XML, or RSS.

Example input:

{
"domains": [
"google.com",
"yahoo.com",
"https://github.com/about",
"neverssl.com"
],
"concurrency": 20,
"timeoutMs": 5000
}

Duplicate normalized domains are checked once. In this example, a second github.com input would not create a duplicate charge or row.

Input parameters

domains

Required array of 1–5,000 domains or website URLs. Each entry must resolve to a syntactically valid public hostname containing at least one dot. IP addresses, empty values, and malformed labels fail input validation.

The hostname is used exactly as normalized. Supplying www.domain.tld checks _dmarc.www.domain.tld; it does not automatically change the request to the organizational domain.

concurrency

Optional integer from 1 to 100. The default is 20. Lower it when your custom recursive resolver applies strict rate limits.

timeoutMs

Optional timeout from 500 to 30,000 milliseconds for each resolver attempt. The default is 5,000.

dnsServers

Optional list of IPv4 or IPv6 recursive DNS server addresses. When set, the Actor preserves this resolver choice and does not substitute public fallback resolvers.

Example output

A live local check of google.com produced a row with this shape (timestamp and duration shortened for readability):

{
"input": "google.com",
"domain": "google.com",
"queryName": "_dmarc.google.com",
"status": "valid",
"hasRecord": true,
"isValid": true,
"rawRecord": "v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com",
"rawRecords": [
"v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com"
],
"parsed": {
"version": "DMARC1",
"policy": "reject",
"subdomainPolicy": null,
"percentage": 100,
"aggregateReportUris": [
{
"uri": "mailto:mailauth-reports@google.com",
"scheme": "mailto",
"address": "mailauth-reports@google.com",
"sizeLimit": null
}
],
"forensicReportUris": [],
"dkimAlignment": "r",
"spfAlignment": "r",
"failureOptions": [],
"reportIntervalSeconds": 86400,
"reportFormat": ["afrf"],
"tags": {
"v": "DMARC1",
"p": "reject",
"rua": "mailto:mailauth-reports@google.com"
},
"unknownTags": {}
},
"findings": [],
"errorCode": null,
"errorMessage": null,
"checkedAt": "2026-08-23T12:00:00.000Z",
"durationMs": 24
}

Understanding statuses and findings

  • valid: one DMARC record was found and no error-severity finding was produced.
  • invalid: one DMARC record was found, but required syntax or a supported tag value is invalid.
  • missing: the DNS query had no DMARC-version TXT record.
  • multiple: more than one DMARC-version record was found, so receivers cannot apply one unambiguous policy.
  • error: DNS resolution failed for a reason other than an authoritative no-record result.

Finding severities are error, warning, and info. Stable codes include record_missing, multiple_records, missing_policy, invalid_policy, invalid_alignment, invalid_percentage, duplicate_tag, unknown_tag, and dns_lookup_failed.

Validation is an operational aid, not a guarantee that every receiver will interpret a policy identically. The Actor does not fetch aggregate reports or verify ownership of reporting mailboxes.

How much does it cost to check DMARC records?

The Actor uses pay-per-event pricing:

  • one start event per run;
  • one domain event per unique domain result, including explicit missing and error rows.

Current pricing is a $0.001 start fee plus a per-domain price that decreases by Apify plan:

Apify planPrice per unique domain
Free$0.00184
Bronze$0.0016
Silver$0.001248
Gold$0.00096
Platinum$0.00064
Diamond$0.000448

At the Bronze rate:

Unique domainsEstimated Actor charge
1$0.0026
25$0.041
100$0.161
1,000$1.601

The input limit, deduplication, and event names are part of the pricing contract. DNS records themselves are public; charges pay for the repeatable processing, validation, structured output, and Apify execution.

Scheduled audit and monitoring workflows

Create an Apify Task with a stable domains list, then attach a daily, weekly, or monthly schedule. Each run creates a separate timestamped dataset snapshot.

Useful downstream patterns include:

  1. Send each dataset to Google Sheets and filter domains whose status is not valid.
  2. Store snapshots in a warehouse and compare rawRecord or parsed.policy over time.
  3. Trigger a webhook after the run and create alerts for missing, multiple, or error states.
  4. Enrich an asset inventory with policy, reporting, and alignment columns.
  5. Audit customer onboarding lists before email infrastructure changes.

The Actor reports current DNS answers. It does not retain history or send alerts by itself; Apify schedules, webhooks, integrations, and your downstream system provide those workflow layers.

Export and integrations

Every result is written to the default Apify dataset. Use Console export or the dataset API to retrieve JSON, JSONL, CSV, Excel, XML, or RSS.

Common integrations:

  • Google Sheets for audit review;
  • Make or Zapier for status-based workflows;
  • Slack or email webhooks for policy changes;
  • BigQuery, Snowflake, or PostgreSQL for snapshot comparison;
  • SIEM and asset-management systems for posture enrichment;
  • Apify API clients for application onboarding checks.

Run with the Apify API

Set APIFY_TOKEN in your environment rather than placing it in source code.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~bulk-dmarc-record-checker/runs" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"domains":["google.com","github.com"],"concurrency":10}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/bulk-dmarc-record-checker').call({
domains: ['google.com', 'github.com', 'neverssl.com'],
concurrency: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/bulk-dmarc-record-checker').call(run_input={
'domains': ['google.com', 'github.com', 'neverssl.com'],
'concurrency': 10,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

Use Bulk DMARC Record Checker through MCP

Add this Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/bulk-dmarc-record-checker"

Claude Desktop setup

Add this server in Claude Desktop's MCP configuration. The same JSON format is also supported by editor clients:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/bulk-dmarc-record-checker"
}
}
}

Cursor setup

Add the JSON server entry in Cursor's MCP settings, then enable the apify server for the workspace.

VS Code setup

Add the same HTTP MCP server in VS Code's MCP configuration and authorize it with your Apify account when prompted.

Example prompts:

  • “Check DMARC for these 30 domains and return only missing or invalid records.”
  • “Parse DMARC policy, rua, adkim, and aspf for google.com and github.com.”
  • “Run the bulk DMARC checker on my approved asset list and summarize reject versus quarantine policies.”

Reliability, retries, and DNS behavior

The Actor uses the runtime recursive resolver with two bounded attempts. For transient timeout, refusal, or server-failure codes, it can make one recovery query through independent public recursive resolvers. Authoritative no-record results are not retried.

When dnsServers is supplied, the Actor does not replace those servers. This makes split-horizon or resolver-comparison results predictable, but availability depends on the supplied resolver.

DNS answers can differ temporarily because of caching, propagation, DNSSEC failures, and resolver location. The Actor reports the answer observed during the run, not a global propagation consensus.

Legality

  • Maximum 5,000 input values per run.
  • Maximum 100 concurrent domain checks.
  • Only the exact normalized hostname is queried.
  • DMARC organizational-domain fallback behavior is not simulated.
  • External report authorization records are not followed or verified.
  • The Actor does not create, publish, or modify DNS records.
  • The Actor does not receive, parse, or store DMARC aggregate/forensic report files.
  • A syntactically valid record can still represent a weak policy such as p=none.

DNS records are generally public infrastructure data. Use the Actor only for domains and workflows you are authorized to assess, follow applicable contracts and organizational policies, and protect exported domain inventories when they are sensitive.

Troubleshooting

Why is the status missing when a website exists?

A working website does not imply that _dmarc.<domain> has a DMARC TXT record. Verify the exact queryName field and whether you supplied a hostname such as www.domain.tld rather than the intended organizational domain.

Why did I receive error instead of missing?

missing is reserved for authoritative no-record responses. error means resolution failed because of timeout, refusal, server failure, or another resolver condition. Inspect errorCode and errorMessage, rerun after the transient issue, or supply a known recursive resolver.

Why is a record marked multiple?

DMARC expects one policy record. Publishing multiple TXT records beginning with v=DMARC1 is ambiguous. Consolidate the tags into one record at your DNS provider.

Why does a URL check a subdomain?

URLs normalize to their exact hostname. https://www.domain.tld/page becomes www.domain.tld, not domain.tld. Supply the organizational domain explicitly when that is your audit target.

Frequently asked questions

Does this Actor create a DMARC record?

No. It checks and parses records that are already published. It can help identify fields needed in a record, but it never changes DNS.

Does it check SPF or DKIM selectors?

No. The product is intentionally DMARC-specific. Use the related DNS or MX Actors for broader DNS inventory, and a dedicated email-authentication workflow when SPF or selector discovery is required.

Are missing and DNS-error rows charged?

Yes. They are useful explicit audit results and use the same domain event as valid records. Duplicated normalized inputs are processed and charged once.

Can I schedule recurring checks?

Yes. Save the input as an Apify Task and attach a schedule. Snapshot comparison and alerting are handled through datasets, integrations, or your downstream system.

Does valid mean my email is fully protected?

No. It means one record passed the implemented syntax and value checks. Email protection also depends on aligned SPF/DKIM authentication, actual sending configuration, report review, and receiver behavior.

These links are complementary tools from automation-lab; third-party Store competitors are not presented as related products.