# DNS History API - Subdomains, WHOIS History, SSL, IP Search (`nabeelbaghoor/dns-history-subdomains-whois-api`) Actor

DNS history, subdomain finder, current and historical WHOIS, SSL certificates, associated domains, reverse domain search and IP search from the SecurityTrails API. One row per record, paged, deduplicated, pay per result. Bring your own key.

- **URL**: https://apify.com/nabeelbaghoor/dns-history-subdomains-whois-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Developer tools, SEO tools, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 domain or ip lookup returneds

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

## DNS History API - Subdomains, WHOIS History, SSL, IP Search

Pull DNS history, subdomains, current and historical WHOIS, SSL certificates, associated domains, reverse domain search and IP search from the SecurityTrails API with your own API key, as one clean dataset row per record.

SecurityTrails (part of Recorded Future) keeps one of the largest passive DNS and WHOIS archives on the internet. This actor wraps its official REST API v1 on api.securitytrails.com: give domains, IPs, a search filter or a DSL query, and get deduplicated rows you can download as JSON, CSV or Excel, schedule, or feed into attack surface monitoring, threat hunting, brand protection, M\&A due diligence, SIEM enrichment, Google Sheets and AI agents. Bring your own API key.

BYOK, not live-tested: every path, parameter and enum comes from the SecurityTrails API reference on docs.securitytrails.com, but the actor has not been run against a live SecurityTrails key, and the API gateway rejects unknown keys before routing, so the routes could not be confirmed with a test call.

### What it does

- **Current DNS**: one row per domain with its A, AAAA, MX, NS, SOA and TXT records, the date each set was first seen, and how many other domains share each IP, mail server and name server.
- **Subdomain finder**: every subdomain SecurityTrails knows for a domain, one row each, as full hostnames.
- **DNS history**: historical A, AAAA, MX, NS, SOA and TXT records with first seen and last seen dates and the hosting organizations, paged.
- **Current WHOIS and WHOIS history**: registrar, creation, update and expiry dates, name servers and contacts, now and across every recorded change.
- **SSL certificates**: valid, expired or all certificates for a domain (optionally its subdomains), with SAN names, issuer, validity and fingerprints.
- **Associated domains**: domains that share an owner with the one you give, with registrar, hosting and mail providers and company name.
- **Domain search**: query the whole database by IP or CIDR, name server, MX, CNAME, SOA email, keyword, TLD or WHOIS email, name, organization, phone or address (reverse WHOIS, reverse IP, reverse NS and reverse MX).
- **IP search and IP WHOIS**: find IPs by PTR pattern or open port with the SecurityTrails DSL, and read the owner of any IPv4 address.
- **Pay only for results**: refused and empty lookups are recorded as a free row that says why, never charged.

### How to get an API key

Sign up at securitytrails.com; a free account includes a small monthly allowance of API queries, and paid plans raise it and open more endpoints. Copy the key from the API Keys page of your account, paste it into the API key field, or set the DATA_API_KEY secret. The key is sent only to api.securitytrails.com in the APIKEY header, as the documentation recommends, and is removed from everything the actor logs.

### Input

| Field | Modes | Description |
| --- | --- | --- |
| `mode` | all | `domainDetails` (default), `subdomains`, `dnsHistory`, `whois`, `whoisHistory`, `sslCertificates`, `associatedDomains`, `domainSearch`, `ipSearch` or `ipWhois` |
| `domains` | domain modes | One hostname per line, such as `example.com` |
| `ips` | IP WHOIS | One IPv4 address per line |
| `dnsRecordTypes` | DNS history | Any of `a` (default), `aaaa`, `mx`, `ns`, `soa`, `txt` |
| `sslStatus` | SSL certificates | `valid` (default), `all` or `expired` |
| `sslIncludeSubdomains` | SSL certificates | Also list subdomain certificates (default false) |
| `domainSearchFilter` | domain search | JSON object of documented filter fields, such as `{"whois_email": "dns-admin@example.com"}` |
| `includeIps` | domain search | Resolve and return each hit's IPs (default false) |
| `ipSearchQuery` | IP search | DSL query, such as `ptr_part = 'amazon.com'` |
| `maxPages` | paged modes | Pages to read per lookup, default 10, at most 100 |
| `maxResults` | all | Row ceiling for the run (default 100) |
| `requestsPerMinute` | all | Pacing, default 60 |
| `apiKey` | all | Your SecurityTrails API key (or the DATA_API_KEY secret) |

Example: the A and MX record history of two domains.

```json
{
    "mode": "dnsHistory",
    "domains": ["example.com", "example.org"],
    "dnsRecordTypes": ["a", "mx"],
    "maxPages": 5
}
```

Example: every domain on a name server (reverse NS).

```json
{
    "mode": "domainSearch",
    "domainSearchFilter": { "ns": "ns1.example.net" },
    "includeIps": true
}
```

### Example output

An illustrative DNS history row, shaped like the documented response (values are an example, not real data). Every field the API returns is kept.

```json
{
    "mode": "dnsHistory",
    "modeLabel": "DNS history",
    "recordType": "dnsHistory",
    "target": "example.com A",
    "hostname": "example.com",
    "ip": null,
    "dnsType": "a",
    "values": ["93.184.215.14"],
    "firstSeen": "2024-01-15",
    "lastSeen": "2026-10-17",
    "registrar": null,
    "createdDate": null,
    "expiresDate": null,
    "organizations": ["Edgecast Inc."],
    "hostProviders": null,
    "mailProviders": null,
    "companyName": null,
    "alexaRank": null,
    "found": true,
    "historyType": "a/ipv4",
    "retrievedAt": "2026-10-18T12:00:00.000Z",
    "note": null
}
```

### FAQ

#### What is the SecurityTrails API?

SecurityTrails is a DNS, domain and IP intelligence service owned by Recorded Future. Its REST API on api.securitytrails.com returns current and historical DNS records, subdomains, WHOIS history, SSL certificates, associated domains and search across its passive DNS and WHOIS database, authenticated with an API key.

#### Do I need my own SecurityTrails API key?

Yes. This is a bring-your-own-key actor: it calls SecurityTrails with your key, under your plan and terms. A missing or rejected key, or a plan that is out of queries, ends the run cleanly with a status message that explains what to change, and nothing is charged.

#### How do I find all subdomains of a domain?

Choose the Subdomains mode and add the domain. SecurityTrails returns every subdomain label it has observed, and the actor writes each one as a full hostname such as api.example.com. For certificates issued to subdomains, use SSL certificates with Include subdomain certificates on.

#### How far back does the DNS history go?

As far as the SecurityTrails archive goes for that domain and record type; the API pages through everything it holds. Each history row carries first seen and last seen dates for one set of values, so you can see when a domain moved hosting, changed mail provider or swapped name servers.

#### Can I do a reverse WHOIS, reverse IP or reverse NS lookup?

Yes, with Domain search. A filter of whois_email, whois_name or whois_organization is a reverse WHOIS, ipv4 (with an optional CIDR mask) is a reverse IP, ns is a reverse name server and mx a reverse mail server lookup. Fields are combined with AND.

#### Why does an endpoint answer that it is not on my plan?

SecurityTrails answers 403 when the key is valid but the endpoint is outside your plan. Free plans cover fewer endpoints and a small monthly allowance; history, search and associated domains need a paid plan on many accounts. Pick another mode or upgrade the plan.

#### How many API queries does a run use?

One per domain, IP or search, and one per page in the paged modes (DNS history per record type, WHOIS history, associated domains, domain search and IP search). Maximum pages per lookup caps the pages, and the run log reports the exact request count.

#### What do I pay?

Pay per result: 0.01 USD per current DNS, current WHOIS or IP WHOIS row and 0.005 USD per subdomain, history record, certificate or search hit. Refused and empty lookups are never charged. Your SecurityTrails plan is billed separately by SecurityTrails.

### Pricing

| Event | Price | Charged for |
| --- | --- | --- |
| `domain-or-ip-lookup` | 0.01 USD | Each current DNS, current WHOIS or IP WHOIS row |
| `list-record` | 0.005 USD | Each subdomain, DNS or WHOIS history record, certificate, associated domain or search hit |

### Keyword map

SecurityTrails API, DNS history API, historical DNS records, passive DNS, subdomain finder, subdomain enumeration, WHOIS history API, WHOIS lookup, reverse WHOIS, reverse IP lookup, reverse NS lookup, reverse MX lookup, associated domains, SSL certificate lookup, certificate transparency, IP WHOIS, attack surface discovery, domain intelligence, threat intelligence, Recorded Future.

### Terms and data use

Use of the SecurityTrails API is governed by the Recorded Future Terms of Use (version 7.0, which section 9.13 applies to all SecurityTrails services) and by your plan's order form or API agreement. Section 1(A) limits use of the service and its output to your own internal security purposes, and free versions to internal, non-commercial security purposes. Section 3 forbids reselling, distributing or disclosing the data to third parties, and states that redistribution, transfer, resale, licence or copies of any data obtained through the service are not allowed unless your agreement with Recorded Future permits it. The terms set no cache or retention time limit on data you retrieve. Run this actor with your own key, keep the results for your own internal security work, and do not publish or resell them without written permission from Recorded Future. This actor is not affiliated with or endorsed by SecurityTrails or Recorded Future.

# Actor input Schema

## `mode` (type: `string`):

Current DNS gives one row per domain with its A, AAAA, MX, NS, SOA and TXT records. Subdomains gives one row per known subdomain. DNS history gives one row per historical record period for each record type. Current WHOIS and WHOIS history give the registration record now and over time. SSL certificates lists the certificates seen for a domain. Associated domains finds domains sharing its owner. Domain search and IP search query the whole SecurityTrails database. IP WHOIS reads the owner of an IPv4 address. Some endpoints are not on every SecurityTrails plan.

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

One hostname per line, such as example.com or mail.example.com. A URL or an email address is reduced to its hostname. Used by every domain mode. Each domain is one request, or one per page for the paged modes.

## `ips` (type: `array`):

IP WHOIS only. One IPv4 address per line; the endpoint is documented for IPv4 only.

## `dnsRecordTypes` (type: `array`):

DNS history only. Each record type is one lookup per domain.

## `sslStatus` (type: `string`):

SSL certificates only. Which certificates to list.

## `sslIncludeSubdomains` (type: `boolean`):

SSL certificates only. Also list certificates issued for subdomains of the domain.

## `domainSearchFilter` (type: `object`):

Domain search only. A JSON object of documented filter fields, combined with AND: ipv4 (may include a CIDR mask), ipv6, apex_domain, keyword, mx, ns, cname, subdomain, soa_email, tld, whois_email, whois_name, whois_organization, whois_telephone, whois_fax, whois_city, whois_postalCode and whois_street1 to whois_street4. For example {"ns": "ns1.example.net"} finds domains on that name server, {"whois_email": "dns-admin@example.com"} is a reverse WHOIS.

## `includeIps` (type: `boolean`):

Domain search only. Resolve each hit's A records and return the IP addresses.

## `ipSearchQuery` (type: `string`):

IP search only. A SecurityTrails DSL query against the IP database, for example ptr_part = 'amazon.com' or ports = 443.

## `maxPages` (type: `integer`):

Paged modes only (DNS history, WHOIS history, associated domains, domain search, IP search). Every page is one request against your plan's monthly allowance.

## `maxResults` (type: `integer`):

The most rows this run returns and charges for.

## `requestsPerMinute` (type: `integer`):

Pacing. A rate limit answer is waited out and retried.

## `apiKey` (type: `string`):

Your own SecurityTrails API key. Stored as a secret and sent only to api.securitytrails.com in the APIKEY header; it is never logged or put in a URL. You can instead set the DATA_API_KEY environment secret.

## Actor input object example

```json
{
  "mode": "domainDetails",
  "domains": [
    "example.com"
  ],
  "dnsRecordTypes": [
    "a"
  ],
  "sslStatus": "valid",
  "sslIncludeSubdomains": false,
  "domainSearchFilter": {
    "apex_domain": "example.com"
  },
  "includeIps": false,
  "maxPages": 10,
  "maxResults": 100,
  "requestsPerMinute": 60
}
```

# Actor output Schema

## `records` (type: `string`):

One row per record.

# 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": [
        "example.com"
    ],
    "domainSearchFilter": {
        "apex_domain": "example.com"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/dns-history-subdomains-whois-api").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": ["example.com"],
    "domainSearchFilter": { "apex_domain": "example.com" },
}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/dns-history-subdomains-whois-api").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": [
    "example.com"
  ],
  "domainSearchFilter": {
    "apex_domain": "example.com"
  }
}' |
apify call nabeelbaghoor/dns-history-subdomains-whois-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/dns-history-subdomains-whois-api"
        }
    }
}
```

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/nWfXdP3h8HlNAVkve/builds/jsXU31Lp0WrXRwOI7/openapi.json
