# Domain WHOIS DNS SSL Lookup - OSINT Security Audit (`invincible_brookbed/domain-intel-suite`) Actor

Bulk domain OSINT in one run: WHOIS/RDAP, DNS records, SSL expiry, CT subdomains, SPF/DMARC/DKIM, security headers score, tech stack, IP/ASN and reputation. Built for security, SEO and sales enrichment. Pay per analyzed domain. MCP-ready.

- **URL**: https://apify.com/invincible_brookbed/domain-intel-suite.md
- **Developed by:** [Виталий Белогуров](https://apify.com/invincible_brookbed) (community)
- **Categories:** Developer tools, SEO tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 domains

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Domain WHOIS DNS SSL Lookup — OSINT & Security Audit

**Bulk domain WHOIS lookup, DNS, SSL and security audit API.** Paste domains or URLs and get WHOIS/RDAP, DNS records, SSL certificates, CT subdomains, security headers score, SPF/DMARC/DKIM, tech stack, IP/ASN and a reputation score — one clean JSON record per domain (~**$3 per 1,000 domains**).

Most WHOIS scrapers return registrar and expiry date, then stop. This Actor replaces five or six separate tools with one bulk-friendly run, billed per successfully analyzed domain.

### What you get for every domain

| Module | Data returned |
|---|---|
| **WHOIS / RDAP** | Registrar, IANA ID, creation / update / expiry dates, `ageDays`, `daysUntilExpiry`, name servers, EPP status, DNSSEC flag |
| **DNS** | A, AAAA, MX, TXT, NS, CNAME and SOA records |
| **SSL / TLS** | Issuer, subject, `validFrom`, `validTo`, `daysRemaining`, trust status, protocol, SAN list |
| **Subdomains** | Deduplicated subdomains from public Certificate Transparency logs (crt.sh), capped at your limit |
| **Security headers** | HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, plus a 0–100 `securityScore` and letter grade |
| **Email authentication** | SPF policy, DMARC policy/reporting, DKIM detection on 37 common selectors, email provider (Google Workspace, Microsoft 365, Zoho, Proton, Fastmail, Mimecast and more) |
| **Tech stack** | Web server, CDN/WAF, CMS, frameworks, analytics and more from headers, cookies and HTML hints |
| **IP & ASN** | Primary IPv4/IPv6, ASN, organization, BGP prefix, country |
| **Reputation** | 0–100 heuristic score, risk level, explainable signals, DNSBL `blacklisted` flag |

### Who uses it

- **Security & threat-intel teams** — triage suspicious or newly registered domains, spot missing email auth, expired certificates and weak headers.
- **Sales & lead-gen teams** — enrich a prospect list with tech stack, email provider and domain age before outreach.
- **SEO & agencies** — audit client and competitor domains: expiry risk, CMS, CDN, security posture.
- **Domain investors & brand protection** — monitor expiry dates, registrars and name-server changes.
- **IT / compliance** — verify SPF, DMARC, HSTS and certificate validity across a whole portfolio.

### Why it beats WHOIS-only tools

- **RDAP, not fragile WHOIS parsing.** Structured JSON straight from registries via RDAP, with automatic fallback to the IANA bootstrap.
- **Eleven signals in one record.** No stitching together separate DNS, SSL, header and email tools.
- **Built for bulk.** Concurrency control, per-module timeouts and domain deduplication.
- **Never fails the whole run.** One slow or blocked source adds an entry to that domain's `errors` array; everything else is still delivered.
- **Validated output.** Every record is checked against a strict schema before it is saved, so your downstream code gets a stable format.
- **Pay only for results.** You are charged per successfully analyzed domain, not for invalid input or domains that don't exist.

### Input

```json
{
  "domains": ["apify.com", "https://www.github.com/apify", "example.org"],
  "includeWhois": true,
  "includeDns": true,
  "includeSsl": true,
  "includeSubdomains": true,
  "includeSecurityHeaders": true,
  "includeEmailAuth": true,
  "includeTechDetect": true,
  "includeReputation": true,
  "concurrency": 5,
  "timeoutSecs": 30
}
```

- **domains** *(required)* — domains or full URLs. Entries are normalized to the registrable domain (`https://www.Shop.Example.co.uk/path` → `example.co.uk`), IDNs are converted to punycode, and duplicates are removed. IP addresses and invalid entries are skipped and reported in the log.
- **include\*** — switch modules on or off. Turn off what you don't need to speed up large runs (subdomain lookup is the slowest).
- **includeNetwork** — IP and ASN lookup (on by default).
- **maxSubdomains** — cap per domain (default 100).
- **concurrency** — domains analyzed in parallel (default 5, max 50).
- **timeoutSecs** — timeout applied to each network module (default 30).

### Output example

```json
{
  "domain": "apify.com",
  "status": "ok",
  "analyzedAt": "2026-10-11T08:30:12.481Z",
  "summary": {
    "registrar": "Amazon Registrar, Inc.",
    "ageDays": 6339,
    "daysUntilExpiry": 3156,
    "ip": "18.66.102.102",
    "asn": "AS16509",
    "asnOrg": "AMAZON-02 - Amazon.com, Inc., US",
    "sslDaysRemaining": 98,
    "securityScore": 75,
    "reputationScore": 95,
    "blacklisted": false,
    "emailProvider": "Google Workspace",
    "subdomainCount": 35,
    "technologies": ["Amazon CloudFront", "Next.js", "Google Tag Manager"]
  },
  "whois": { "...": "..." },
  "dns": { "...": "..." },
  "ssl": { "...": "..." },
  "subdomains": { "...": "..." },
  "securityHeaders": { "...": "..." },
  "tech": { "...": "..." },
  "emailAuth": { "...": "..." },
  "network": { "...": "..." },
  "reputation": { "...": "..." },
  "errors": []
}
```

Each record has a `status`: `ok` (everything requested succeeded), `partial` (some modules reported errors) or `failed` (no evidence the domain exists or every module failed). The `errors` array lists `{ module, code, message }` for anything that went wrong.

At the end of each run a `RUN_STATS` record is saved to the key-value store: domains analyzed, ok/partial/failed counts, charged events, duration and error counts per module.

### Pricing

**Pay-per-event** pricing:

| Event | Price | When it is charged |
|---|---|---|
| `domain-analyzed` | **$0.003** (about **$3 per 1,000 domains**) | One domain successfully analyzed |

Domains that fail entirely (for example unregistered domains) are returned with `status: "failed"` and are **not** charged. The Actor respects your maximum run cost and stops cleanly when the limit is reached.

### Good to know

- **Reputation score is a heuristic.** It combines domain age, certificate health, email authentication, header posture, registry status and blocklists. It is a triage aid, not a verdict. It is most accurate when WHOIS, DNS, SSL, security headers and email modules are all enabled.
- **DNSBL checks can soft-fail.** Spamhaus blocks queries from some public resolvers; when that happens the list is marked `inconclusive` and `blacklisted` stays `false`. Check `reputation.blacklistCheck` (`clean`, `listed`, `inconclusive`).
- **DKIM is best-effort.** DKIM selectors can't be enumerated, so 37 common ones are probed. "Not found" does not prove DKIM is missing.
- **RDAP coverage varies.** Some country-code TLDs don't publish RDAP; those domains get a `whois` error but still receive every other module.
- **Subdomains come from Certificate Transparency.** Great coverage for HTTPS hosts, but it won't list internal names that never received a public certificate. crt.sh is a free community service and can be slow or return errors under load; the Actor retries once and then records an error.
- **Passive and polite.** The Actor performs normal DNS queries, a TLS handshake and a single homepage request per domain. No port scanning or intrusive probing.

### Use with AI agents (MCP)

Works with the [Apify MCP server](https://mcp.apify.com/):

```json
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com/?tools=fetch-actor-details,call-actor,invincible_brookbed/domain-intel-suite"
    }
  }
}
```

Authenticate via OAuth or an Apify API token. Agents can inspect the schema and call this Actor for domain due diligence.

### FAQ

**Can I analyze subdomains directly?** Entries are reduced to their registrable domain. Subdomains are discovered through the subdomain module.

**Can I run it via API or on a schedule?** Yes. Use the Apify API, schedules, webhooks or integrations (Make, Zapier, n8n) to monitor domains continuously.

**How fast is it?** Without subdomain lookup, a domain typically takes a few seconds. Raise `concurrency` for large lists.

Questions or feature requests? Open an issue on the Actor page.

# Actor input Schema

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

Domains or URLs to analyze (e.g. `example.com`, `https://www.example.com/path`). Entries are normalized to their registrable domain and deduplicated.

## `includeWhois` (type: `boolean`):

Registrar, creation/expiry dates, domain age, name servers and status via RDAP.

## `includeDns` (type: `boolean`):

A, AAAA, MX, TXT, NS, CNAME and SOA records.

## `includeSsl` (type: `boolean`):

Issuer, validity dates and days remaining of the TLS certificate on port 443.

## `includeSubdomains` (type: `boolean`):

Discover subdomains from public Certificate Transparency logs (crt.sh). Can be slow when crt.sh is busy.

## `includeSecurityHeaders` (type: `boolean`):

Audit HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy and compute a 0-100 security score.

## `includeEmailAuth` (type: `boolean`):

SPF, DMARC and DKIM (common selectors) detection plus email provider detection from MX records.

## `includeTechDetect` (type: `boolean`):

Detect web server, CDN, CMS and frameworks from HTTP headers, cookies and HTML hints.

## `includeReputation` (type: `boolean`):

Heuristic reputation score and DNSBL checks (Spamhaus ZEN/DBL, SpamCop). Blacklist checks soft-fail when the resolver is blocked.

## `includeNetwork` (type: `boolean`):

Resolve the primary IP and look up its ASN and organization (Team Cymru DNS, ip-api.com fallback).

## `maxSubdomains` (type: `integer`):

Maximum number of subdomains returned per domain.

## `concurrency` (type: `integer`):

How many domains are analyzed in parallel.

## `timeoutSecs` (type: `integer`):

Timeout applied to each network module (RDAP, SSL, HTTP, CT, ...). One slow module never fails the whole domain.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "example.org"
  ],
  "includeWhois": true,
  "includeDns": true,
  "includeSsl": true,
  "includeSubdomains": true,
  "includeSecurityHeaders": true,
  "includeEmailAuth": true,
  "includeTechDetect": true,
  "includeReputation": true,
  "includeNetwork": true,
  "maxSubdomains": 100,
  "concurrency": 5,
  "timeoutSecs": 30
}
```

# Actor output Schema

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

One full OSINT record per domain (WHOIS, DNS, SSL, subdomains, security, email auth, tech, reputation).

## `overview` (type: `string`):

Summary columns: registrar, age, SSL days left, security score, reputation, email provider.

## `runStats` (type: `string`):

ok/partial/failed counts, charged domains, duration, and per-module error totals.

# 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.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("invincible_brookbed/domain-intel-suite").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.org",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("invincible_brookbed/domain-intel-suite").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": [
    "apify.com",
    "example.org"
  ]
}' |
apify call invincible_brookbed/domain-intel-suite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,invincible_brookbed/domain-intel-suite"
        }
    }
}
```

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/CmqTNAWahcXtd3Wxf/builds/lzBhlOLawzQyS98Jm/openapi.json
