# Domain Health Checker (`zinin/domain-health-checker`) Actor

Bulk-audit domains: DNS records, SSL certificate expiry, SPF & DMARC email authentication. Find domains that cannot receive email, are easy to spoof, or have expiring certificates — before your clients do.

- **URL**: https://apify.com/zinin/domain-health-checker.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.25 / 1,000 domain checkeds

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

## Domain Health Checker — DNS, SSL & Email Authentication Audit

Point this Actor at a list of domains and get a full technical audit of each one: DNS
records, SSL certificate status, and email-spoofing protection (SPF and DMARC), with a
0–100 health score and a plain-English list of what is broken. Every field comes from a
direct DNS lookup or a live TLS handshake — no WHOIS, no paid API, no browser, nothing
to configure.

### What you get

- **A verdict, not raw records.** A 0–100 score across seven checks, plus an `issues`
  list you can hand to whoever has to fix it: *"SSL certificate expires in 9 days"*,
  *"No DMARC record — no policy against email spoofing"*.
- **DNS**: A, AAAA, MX (priority-sorted), NS, and the `www` CNAME.
- **SSL**: issuer, expiry date, days left, and whether the chain is actually trusted.
- **Email authentication**: whether the domain can receive mail at all, its SPF record,
  its DMARC record and the policy in force (`none` / `quarantine` / `reject`).
- **Built for lists.** Concurrency up to 50, one row per domain, so a portfolio of a few
  hundred domains is a single run.
- Runs on Apify: schedule it, monitor it, call it from the API or the MCP server, export
  to JSON, CSV or Excel, or push results straight into your own pipeline.

### Who uses it

- **Agencies and consultants** — bulk-audit a client's domain portfolio before a pitch
  or a retainer review.
- **IT and security teams** — catch expiring certificates and missing email auth before
  they become an outage or a spoofing incident.
- **Due diligence** — check the technical hygiene of a target company's domains at scale.
- **Deliverability teams** — verify SPF and DMARC really are in place on every sending
  domain, not just the main one.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Paste your domains into **Domains**, one per line. Scheme, path and `www.` are
   stripped for you, so `https://www.example.com/pricing` and `example.com` are the same
   input.
3. Press **Start**. Results appear in the dataset — read them in the UI, pull them from
   the API, or have a webhook push them onward.

### Pricing

Pay-per-event: **$0.005 per run start + $0.005 per domain audited**. No monthly seat, no
minimum. 100 domains cost about **$0.51**; 1,000 domains about **$5.01**.

A domain that could not be audited is still returned, with `found: false` and the reason
— and it is **not** charged for. You pay for answers, not for attempts.

### Input

| Field | Required | What it does |
|---|---|---|
| `domains` | yes | Domains to audit. Up to 100 per run. |
| `maxConcurrency` | no | How many to check at once, 1–50 (default 10). |

```json
{
    "domains": ["apify.com", "example.com", "github.com"],
    "maxConcurrency": 10
}
```

### Output

One row per domain. This is a real row from a real run, trimmed only where a list
repeats:

```json
{
    "domain": "apify.com",
    "found": true,
    "healthScore": 100,
    "resolves": true,
    "records": {
        "a": ["3.170.42.100", "3.170.42.76", "3.170.42.68", "3.170.42.109"],
        "aaaa": ["2600:9000:2870:bc00:9:a03e:6540:93a1", "…"],
        "mx": ["aspmx.l.google.com", "alt1.aspmx.l.google.com", "…"],
        "ns": ["ns-449.awsdns-56.com", "ns-839.awsdns-40.net", "…"],
        "wwwCname": []
    },
    "email": {
        "canReceive": true,
        "spf": "v=spf1 a mx include:_spf.google.com include:mailgun.org -all",
        "dmarc": "v=DMARC1; p=reject; sp=reject; pct=100; rua=mailto:dmarc-reports@apify.com",
        "dmarcPolicy": "reject"
    },
    "ssl": {
        "issuer": "Amazon",
        "validTo": "2027-01-16T23:59:59.000Z",
        "daysLeft": 174,
        "authorized": true
    },
    "issues": [],
    "summary": "Healthy — DNS, email auth and SSL all in order (score 100/100).",
    "checkedAt": "2026-07-26T13:58:02.872Z"
}
```

| Field | What it means |
|---|---|
| `healthScore` | 0–100 across seven checks (see FAQ) |
| `resolves` | The domain answers DNS at all |
| `records` | A, AAAA, MX, NS and the `www` CNAME as returned |
| `email.canReceive` | There is at least one MX record |
| `email.dmarcPolicy` | `none`, `quarantine` or `reject` — `none` is a policy in name only |
| `ssl.authorized` | The certificate chain is trusted, not merely present |
| `ssl.daysLeft` | Days until expiry; negative means already expired |
| `issues` | Human-readable findings, empty when nothing is wrong |
| `found` | `false` means the audit failed; the row says why and is not billed |

#### Related tools

Related tools for adjacent workflows in AI and search visibility.

| Actor | What it does |
|---|---|
| [Social Preview Checker](https://apify.com/zinin/social-preview-checker) | Pair it in the AI and search visibility workflow: See exactly how your links look when shared on Telegram, WhatsApp, X, LinkedIn, Slack, Facebook & Discord |
| [AI Crawler Access Checker](https://apify.com/zinin/ai-crawler-access-checker) | Pair it in the AI and search visibility workflow: Check which AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended & more) can access your website |
| [AI Overview Citation Tracker](https://apify.com/zinin/ai-overview-tracker) | Pair it in the AI and search visibility workflow: For each query that matters, see which sources and domains AI assistants cite in their answer — grounded... |
| [AI Answer Change Alert](https://apify.com/zinin/ai-answer-change-alert) | Pair it in the AI and search visibility workflow: Track whether an AI assistant's answer to a query you care about changed since last time — new sources... |
| [LLM Brand Visibility Tracker](https://apify.com/zinin/llm-brand-visibility) | Pair it in the AI and search visibility workflow: For each query that matters, check whether AI assistants recommend YOUR brand — and which competitors they... |

### FAQ

**Does it use WHOIS or any paid data source?** No. Every field comes from a direct DNS
lookup or a live TLS handshake on port 443. Nothing rate-limited, nothing to pay for
separately.

**What goes into the health score?** Seven checks: the domain resolves, has MX, has SPF,
has a real DMARC policy (`p=none` counts as weak), has SSL, that SSL is not expiring
soon, and has NS records. The score is the percentage passed.

**Does a domain with no email get penalised for missing SPF and DMARC?** No. Those are
only raised when the domain has MX records, i.e. is actually set up to receive mail.

**Can it check subdomains?** Yes — `mail.example.com` is just another domain here.

**Is this legal?** Yes. DNS records and TLS certificates are public information, served
to anyone who asks, exactly as `dig` or `openssl` would see them.

**Can I call it from an AI agent?** Yes — standard Apify Actor, callable from the Apify
API, the SDK, or the Apify MCP server.

**What this is NOT.** It does not scan for vulnerabilities, probe ports, check
blacklists, or read page content. It answers one question — is this domain's DNS, mail
and certificate setup sound — and answers it honestly, including when it cannot.

Found a wrong result, or need a check we don't run? Open an issue on this Actor's page.

***

Built by [zinin](https://apify.com/zinin). Questions? Telegram [@timzinin](https://t.me/timzinin).

# Actor input Schema

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

List of domains to audit (e.g. `example.com`).

## `maxConcurrency` (type: `integer`):

How many domains to check in parallel.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "example.com",
    "github.com"
  ],
  "maxConcurrency": 10
}
```

# Actor output Schema

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

API URL for the default dataset items produced by this run.

# 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": [
        "apify.com",
        "example.com",
        "github.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/domain-health-checker").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": [
        "apify.com",
        "example.com",
        "github.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("zinin/domain-health-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "apify.com",
    "example.com",
    "github.com"
  ]
}' |
apify call zinin/domain-health-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zinin/domain-health-checker",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/yZaZalotGKW7RZjbN/builds/sOBr0Qc2mUwXMtFY9/openapi.json
