# DNS & Domain Intelligence Scraper (SPF, DMARC, DKIM, DNSSEC) (`scrapers_lat/dns-domain-intelligence-scraper`) Actor

Resolve full DNS records for any domain via DNS-over-HTTPS: A, AAAA, MX, NS, TXT, SOA, CAA, plus parsed SPF, DMARC, DKIM, DNSSEC and mail-provider intelligence. Ideal for OSINT, attack-surface mapping, email-security audits and KYB. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/scrapers\_lat/dns-domain-intelligence-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.32 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

[![DNS & Domain Intelligence Scraper (SPF, DMARC, DKIM, DNSSEC)](https://scrapers.lat/banners/dns-domain-intelligence-scraper.png)](https://apify.com/scrapers_lat/dns-domain-intelligence-scraper)

## DNS & Domain Intelligence Scraper (SPF, DMARC, DKIM, DNSSEC)

Here is one real result, with every field the actor returns:

```json
{
  "domain": "github.com",
  "registrableDomain": "github.com",
  "resolvedIps": ["140.82.114.3"],
  "aRecords": ["140.82.114.3"],
  "aaaaRecords": [],
  "nameservers": [
    "dns1.p08.nsone.net",
    "dns2.p08.nsone.net",
    "ns-1283.awsdns-32.org",
    "ns-1707.awsdns-21.co.uk"
  ],
  "mxRecords": [
    { "host": "github-com.mail.protection.outlook.com", "priority": 0 }
  ],
  "mailProvider": "Microsoft 365",
  "cnames": [],
  "txtRecords": [
    "MS=ms44452932",
    "v=spf1 ip4:192.30.252.0/22 include:spf.protection.outlook.com ... ~all",
    "google-site-verification=UTM-3akMgubp6tQtgEuAkYNYLyYAvpTnnSrDMWoDR3o",
    "facebook-domain-verification=39xu4jzl7roi7x0n93ldkxjiaarx50",
    "apple-domain-verification=RyQhdzTl6Z6x8ZP4"
  ],
  "spfRecord": "v=spf1 ip4:192.30.252.0/22 include:spf.protection.outlook.com ... ~all",
  "hasSpf": true,
  "spfPolicy": "softfail (~all)",
  "dmarcRecord": "v=DMARC1; p=quarantine; sp=reject; pct=100; rua=mailto:dmarc@github.com; ruf=mailto:dmarc@github.com; fo=1",
  "hasDmarc": true,
  "dmarcPolicy": "quarantine",
  "dmarcSubdomainPolicy": "reject",
  "dmarcPct": 100,
  "dmarcRua": "mailto:dmarc@github.com",
  "dkimSelectorsFound": ["google", "selector1", "k1", "s1"],
  "caaRecords": [
    { "flag": 0, "tag": "issue", "value": "letsencrypt.org" },
    { "flag": 0, "tag": "issuewild", "value": "sectigo.com" }
  ],
  "hasCaa": true,
  "caaIssuers": ["letsencrypt.org", "digicert.com", "sectigo.com", "globalsign.com"],
  "soa": {
    "mname": "dns1.p08.nsone.net",
    "rname": "hostmaster.nsone.net",
    "serial": 1656468023,
    "refresh": 43200,
    "retry": 7200,
    "expire": 1209600,
    "minimumTtl": 3600
  },
  "dnssecEnabled": false,
  "txtVerifications": {
    "ms": "ms44452932",
    "google-site-verification": "UTM-3akMgubp6tQtgEuAkYNYLyYAvpTnnSrDMWoDR3o",
    "facebook-domain-verification": "39xu4jzl7roi7x0n93ldkxjiaarx50",
    "apple-domain-verification": "RyQhdzTl6Z6x8ZP4",
    "atlassian-domain-verification": "jjgw98AKv2aeoYFxiL/VFaoyPkn3undEssTRuMg6C/3Fp/iqhkV4HVV7WjYlVeF8"
  },
  "ttlByType": { "NS": 249, "A": 60, "MX": 98, "SOA": 2701, "TXT": 45, "CAA": 3600 },
  "resolverUsed": "google",
  "mailIpListed": false,
  "dnsblListedOn": [],
  "dnsblListedCount": 0,
  "aiRiskLevel": "low",
  "aiRiskVerdict": "GitHub enforces a strong email-authentication posture: SPF is published, DMARC is set to quarantine with a reject policy on subdomains, and multiple valid DKIM selectors resolve, so the domain is hard to spoof. No sending IP appears on the checked mail blocklists, indicating healthy deliverability. Enabling DNSSEC would further harden the zone against tampering.",
  "queriedAt": "2026-08-16T05:22:45.186Z",
  "error": null
}
```

> `mailIpListed`, `dnsblListedOn`, `dnsblListedCount`, `aiRiskLevel` and `aiRiskVerdict` are populated only when the optional paid add-ons are enabled (see [Billing and limits](#billing-and-limits)).

The most complete DNS lookup on Apify. Where other DNS actors hand you a flat list of raw records, this one resolves every record type over encrypted DNS-over-HTTPS and then parses the results into ready-to-use intelligence: your email-security posture (SPF, DMARC, DKIM, DNSSEC), the mail provider behind the MX, the certificate authorities allowed by CAA, and a clean map of every domain-ownership verification token hiding in TXT. One rich row per domain, or one row per record if you prefer.

**📥 [Input](https://apify.com/scrapers_lat/dns-domain-intelligence-scraper/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/dns-domain-intelligence-scraper/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/dns-domain-intelligence-scraper/pricing) · ▶️ [Examples](https://apify.com/scrapers_lat/dns-domain-intelligence-scraper/examples)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Source](https://img.shields.io/badge/Source-DNS%20over%20HTTPS-blue)
![Output](https://img.shields.io/badge/Output-JSON%20%7C%20CSV%20%7C%20Excel-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20result-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [Use cases](#use-cases)
- [Why it beats a plain DNS lookup](#why-it-beats-a-plain-dns-lookup)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

Give the actor one or more domains. For each domain it queries A, AAAA, MX, NS, TXT, SOA, CNAME and CAA records over DNS-over-HTTPS, plus the DMARC record at `_dmarc.<domain>` and a set of common DKIM selectors. It then derives:

- **Resolved IPs** from A and AAAA records.
- **Mail provider** inferred from the MX hosts (Google Workspace, Microsoft 365, Proofpoint, Mimecast, Zoho, Proton, Amazon, self-hosted and more).
- **Email-security posture**: `spfRecord` with a parsed `spfPolicy`, `dmarcRecord` with `dmarcPolicy`, `dmarcPct` and `dmarcRua`, and the DKIM selectors that actually resolve.
- **Certificate authority policy** from CAA, with a clean `caaIssuers` list.
- **DNSSEC status** from the resolver's authenticated-data flag.
- **Ownership verification tokens** (Google, Microsoft, Facebook, Apple, Atlassian, Stripe and dozens more) pulled out of TXT into a `txtVerifications` map.
- **SOA** authority details and a `ttlByType` map.

It pairs naturally with the [Certificate Transparency & Subdomain Discovery Scraper](https://apify.com/scrapers_lat/certificate-transparency-scraper) as an OSINT, attack-surface and KYB suite.

### Use cases

- **Email deliverability and DNS audit**: bulk-check SPF, DMARC, DKIM and DNSSEC across a domain portfolio to find spoofable domains and misconfigured mail security before attackers do.
- **Email spoofing and phishing risk assessment**: score how easily each domain can be impersonated, with an optional AI verdict that explains the risk in plain English for non-technical stakeholders.
- **Mail-server reputation and blocklist monitoring**: check whether a domain's sending IPs are listed on Spamhaus, SpamCop, Barracuda or SORBS blocklists that hurt inbox placement.
- **Attack-surface and OSINT recon**: map name servers, mail providers, resolved IPs and CAA certificate-authority policy for a target domain during security research.
- **KYB and vendor due diligence**: enrich a company domain with DNS hygiene, mail provider and ownership-verification signals for onboarding and compliance checks.
- **Lead enrichment for cold email and sales**: detect the email provider (Google Workspace, Microsoft 365, Proofpoint and more) and domain configuration behind a prospect list.
- **Cloud and SaaS inventory**: extract Google, Microsoft, Facebook, Apple, Atlassian and Stripe domain-ownership verification tokens from TXT to see which platforms a domain is wired into.
- **Migration and monitoring**: snapshot DNS records, TTLs and SOA serials before and after a DNS or email migration to confirm nothing broke.

### Why it beats a plain DNS lookup

A typical DNS actor returns raw record strings and stops there. This actor:

- Parses **email security** (SPF policy, DMARC policy and percentage, DKIM selectors present) instead of leaving you to read raw TXT.
- Identifies the **mail provider** and **allowed certificate authorities** for you.
- Reports **DNSSEC validation**, not just records.
- Extracts every **domain-ownership verification token** into a structured map.
- Uses **encrypted DNS-over-HTTPS** with Google primary and Cloudflare fallback, so lookups are reliable and never blocked.

### Quickstart

Open the actor, paste this into the input, and press Run.

```json
{
  "domains": ["stripe.com", "github.com", "cloudflare.com"]
}
```

You get one rich intelligence row per domain. Set `perRecordRows` to `true` to get one row per individual DNS record instead.

### Input reference

| Field | Type | Description |
|-------|------|-------------|
| `domains` | array | One or more domains to look up (registered domain only, no http or path). |
| `domain` | string | Alternative single domain, or several separated by commas, spaces or new lines. |
| `recordTypes` | array | Which record types to query. Defaults to A, AAAA, MX, NS, TXT, SOA, CNAME, CAA. DMARC and DKIM are always attempted. |
| `resolver` | string | `auto` (Google primary, Cloudflare fallback), `google`, or `cloudflare`. Default `auto`. |
| `perRecordRows` | boolean | When `true`, emit one row per DNS record instead of one rich row per domain. Default `false`. |
| `withDnsblCheck` | boolean | Opt-in paid add-on. Check each domain's resolved IPv4 against public mail blocklists (Spamhaus, SpamCop, Barracuda, SORBS) and return `mailIpListed`, `dnsblListedOn` and `dnsblListedCount`. Default `false`. Disabled for free accounts. |
| `withAiRisk` | boolean | Opt-in AI add-on. Turn the SPF, DMARC, DKIM, DNSSEC and blocklist findings into a plain-English `aiRiskLevel` and `aiRiskVerdict` on spoofability and deliverability risk. Default `false`. Disabled for free accounts. |
| `maxDomains` | integer | Maximum number of domains to process. Free accounts are capped at 10 per run. |
| `proxyConfiguration` | object | Optional proxy. DNS-over-HTTPS works without one; only needed for very large batches. |

### Output reference

One row per domain (default mode):

| Field | Description |
|-------|-------------|
| `domain` | Domain that was queried. |
| `registrableDomain` | Registrable (apex) domain. |
| `resolvedIps` / `aRecords` / `aaaaRecords` | Resolved IPv4 and IPv6 addresses. |
| `nameservers` | Authoritative name servers. |
| `mxRecords` | Mail exchangers with `host` and `priority`. |
| `mailProvider` | Email provider derived from MX. |
| `cnames` | CNAME targets. |
| `txtRecords` | All TXT records. |
| `spfRecord` / `hasSpf` / `spfPolicy` | SPF record and parsed all-mechanism policy. |
| `dmarcRecord` / `hasDmarc` / `dmarcPolicy` / `dmarcSubdomainPolicy` / `dmarcPct` / `dmarcRua` | Parsed DMARC posture. |
| `dkimSelectorsFound` | DKIM selectors detected among common names. |
| `caaRecords` / `hasCaa` / `caaIssuers` | CAA records and allowed certificate authorities. |
| `soa` | Start of authority (mname, rname, serial, timers). |
| `dnssecEnabled` | Whether the resolver reported DNSSEC validation. |
| `txtVerifications` | Map of extracted domain-ownership verification tokens. |
| `ttlByType` | Minimum TTL observed per record type. |
| `resolverUsed` | Which resolver answered (`google` or `cloudflare`). |
| `mailIpListed` / `dnsblListedOn` / `dnsblListedCount` | Mail-IP blocklist status (only with the `withDnsblCheck` add-on). |
| `aiRiskLevel` / `aiRiskVerdict` | AI spoofability and deliverability risk verdict (only with the `withAiRisk` add-on). |
| `queriedAt` | When the lookup was performed. |
| `error` | Error message, if any. |

In per-record mode each row has `domain`, `recordType`, `name`, `value`, `ttl`, optional `selector`, `queriedAt` and `error`.

### Run via API and CLI

```bash
apify call scrapers_lat/dns-domain-intelligence-scraper --input='{"domains":["stripe.com","github.com"]}'
```

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~dns-domain-intelligence-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains":["stripe.com","github.com"]}'
```

### Fetch results

```bash
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_TOKEN&format=json"
```

Swap `format=json` for `csv` or `xlsx` to export a spreadsheet.

### Billing and limits

This actor is billed pay per result: you are charged for each domain intelligence record returned (or each DNS record in per-record mode). Domains that cannot be resolved return an error row and are **not** charged. Free Apify accounts are capped at 10 domains per run; upgrade for more.

Two optional paid add-ons are available, both default off and both disabled for free accounts:

- **Mail-IP blocklist check** (`withDnsblCheck`, $0.012 per domain): checks the domain's resolved IPv4 against public mail blocklists and returns the listing status. Charged once per domain only when the checks complete (a clean result still counts).
- **AI email-security risk verdict** (`withAiRisk`, $0.012 per domain): produces a plain-English risk level and verdict on spoofability and deliverability. Charged only when a usable AI verdict is produced; if the AI service is unavailable, the field is left empty and you are not charged.

### FAQ and troubleshooting

**Is this blocked by bots or rate limits?** No. It uses public DNS-over-HTTPS endpoints from Google and Cloudflare, which are designed for programmatic use. There is no browser and no bot wall.

**Why is DNSSEC false for a big domain?** DNSSEC reflects whether the domain's zone is signed and validated. Many large domains still do not sign their zones, so `false` is the correct, real answer.

**Why are some DKIM selectors missing?** DKIM selectors are private to each sender and not discoverable from DNS alone. The actor checks a set of common selector names on a best-effort basis and reports the ones that resolve. A domain can use DKIM with a custom selector that is not in the common list.

**Can I get raw records instead of the parsed summary?** Yes, set `perRecordRows` to `true` for one row per individual DNS record.

**What does the mail provider field detect?** It infers the provider from MX hostnames, covering the major platforms. Domains with custom or uncommon MX hosts are reported as self-hosted or other.

# Actor input Schema

## `domains` (type: `array`):

One or more domains to look up, for example stripe.com. Enter the registered domain only (no http, no path).

## `domain` (type: `string`):

Alternative to Domains: a single domain, or several separated by commas, spaces or new lines.

## `recordTypes` (type: `array`):

Which DNS record types to query. Defaults to all. DMARC and DKIM are always attempted on a best-effort basis in addition to these.

## `resolver` (type: `string`):

Which DNS-over-HTTPS resolver to use. Auto uses Google as primary and Cloudflare as fallback.

## `perRecordRows` (type: `boolean`):

When off (default), the actor returns one rich intelligence row per domain. When on, it emits one row per individual DNS record instead.

## `withDnsblCheck` (type: `boolean`):

Opt-in paid add-on ($0.012/domain). Checks each domain's resolved IPv4 against public DNS blocklists (Spamhaus ZEN, SpamCop, Barracuda, SORBS) and returns mailIpListed, listedOn and listedCount for mail-reputation and deliverability screening. Billed once per domain only when the checks complete. Disabled for free Apify accounts.

## `withAiRisk` (type: `boolean`):

Opt-in AI add-on ($0.012/domain). Uses AI to turn the SPF, DMARC, DKIM, DNSSEC and blocklist findings into a concise plain-English verdict on spoofability and deliverability risk (riskLevel + verdict). Billed only when a usable verdict is produced. Disabled for free Apify accounts.

## `maxDomains` (type: `integer`):

Maximum number of domains to process. Free Apify accounts are capped at 10 domains per run.

## `proxyConfiguration` (type: `object`):

Optional proxy settings. DNS-over-HTTPS works without a proxy; a proxy is only needed for very large batches.

## Actor input object example

```json
{
  "domains": [
    "stripe.com",
    "github.com",
    "cloudflare.com"
  ],
  "recordTypes": [
    "A",
    "AAAA",
    "MX",
    "NS",
    "TXT",
    "SOA",
    "CNAME",
    "CAA"
  ],
  "resolver": "auto",
  "perRecordRows": false,
  "withDnsblCheck": false,
  "withAiRisk": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "domains": [
        "stripe.com",
        "github.com",
        "cloudflare.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/dns-domain-intelligence-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "domains": [
        "stripe.com",
        "github.com",
        "cloudflare.com",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/dns-domain-intelligence-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "domains": [
    "stripe.com",
    "github.com",
    "cloudflare.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call scrapers_lat/dns-domain-intelligence-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers_lat/dns-domain-intelligence-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5dG0DLYBEcHtJ5TKh/builds/IXETyRG6ND8bnaYxi/openapi.json
