# Subdomain Finder — Certificate Transparency, DNS, Live Check (`chorelet/subdomain-finder`) Actor

Every subdomain a company has ever certified, from Certificate Transparency logs: hostname, certificate count, first and last seen, issuer and expiry — plus DNS resolution and an optional HTTP check that says which ones are actually live. No API key.

- **URL**: https://apify.com/chorelet/subdomain-finder.md
- **Developed by:** [Chorelet](https://apify.com/chorelet) (community)
- **Categories:** Developer tools, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 hostnames

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/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

## Subdomain Finder — Certificate Transparency, DNS, Live Check

Every subdomain a company has ever put a certificate on, from the public **Certificate Transparency logs**, with the certificate history folded into one row per hostname: how many certificates, when the name first and last appeared, who issued the newest one and when it expires. Then, for each name, **DNS resolution** and an optional **HTTPS check** that tells you which of them actually answer today — with status code, final URL, page title and server header.

No API key, no account, no proxy. The source is SSLMate's certspotter API, which answered in **0.5 seconds where crt.sh took 13** in testing — and returned 60 hostnames for `apify.com` where crt.sh's usual query returned 25.

### Why this Actor

- **25x faster than the crt.sh Actors.** The same domain took 0.5 seconds against certspotter and 13 seconds against crt.sh in testing — and returned 60 hostnames where crt.sh's usual query returned 25.
- **Names in logs are not hosts.** Every hostname is resolved, so you see which of them point somewhere today, and an HTTPS check adds the status code, the page title and the server header for the ones that answer.
- **Certificate history per name.** How many certificates, first and last seen, every issuer, the newest expiry and a revoked flag — the difference between an active host and a name certified once in 2019.
- **Wildcards handled honestly.** `*.example.com` is marked as a certificate name and never counted as a live host, instead of padding the list.

### Sample output

One item of the dataset (long values shortened):

```json
{
  "hostname": "blog.apify.com",
  "resolves": true,
  "ips": [
    "151.101.3.7",
    "151.101.67.7",
    "151.101.131.7",
    "…"
  ],
  "cname": "apify.ghost.io",
  "httpStatus": 200,
  "httpTitle": "Apify Blog: Guides to the largest marketplace of tools for AI",
  "lastSeen": "2026-09-26T09:27:42Z",
  "lastIssuer": "Certainly",
  "certExpiresAt": "2026-10-26T09:27:41Z"
}
```

### What you get

- **The full name list**: subdomains, the apex itself and wildcard entries (flagged, never resolved — a wildcard is a certificate name, not a host)
- **Certificate history per hostname**: count, first seen, last seen, every issuer, the newest expiry, and a revoked flag
- **Which names are real**: A, AAAA and CNAME records, an `ipCount`, and a `resolves` column — with a filter that drops names pointing nowhere
- **What answers over HTTPS**: status code, final URL after redirects, page title and server header — the quick way to spot a forgotten staging box or a parked host
- **Sorted newest first**, so a run capped at 200 names returns the 200 most recently certified ones
- JSON, CSV, Excel or the API

Use it on domains you own or are authorised to assess. The Actor only reads public logs, public DNS and the home page of each host — it does not scan ports or probe paths.

### Input example

```json
{
  "domains": [
    "apify.com"
  ],
  "resolveDns": true,
  "httpCheck": false,
  "onlyResolving": false,
  "includeWildcards": true,
  "maxHostsPerDomain": 200,
  "concurrency": 8,
  "requestTimeoutSecs": 15
}
```

### How much does it cost?

Pay per hostname — no subscription, no minimum, no charge for platform usage.

| Volume | Price |
|---|---|
| 1,000 hostnames | $0.50 (+ $1.00 with `check`) |
| 10,000 hostnames | $5.00 (+ $10.00 with `check`) |
| 100,000 hostnames | $50.00 (+ $100.00 with `check`) |

The Apify **free plan includes $5 of usage every month** — about 10,000 hostnames with this Actor, no card needed. Nothing else is charged: platform usage is included in the price, and Apify Bronze, Silver and Gold subscribers get 10%, 20% and 30% off these prices.

### Use it from code, n8n, Make, Zapier or an AI agent

Run the Actor and download the dataset in one call (JSON by default; add `&format=csv` or `xlsx`):

```bash
curl -X POST "https://api.apify.com/v2/acts/chorelet~subdomain-finder/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["apify.com"], "resolveDns": true, "httpCheck": false, "onlyResolving": false, "includeWildcards": true, "maxHostsPerDomain": 200, "concurrency": 8, "requestTimeoutSecs": 15}'
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("chorelet/subdomain-finder").call(run_input={"domains": ["apify.com"], "resolveDns": true, "httpCheck": false, "onlyResolving": false, "includeWildcards": true, "maxHostsPerDomain": 200, "concurrency": 8, "requestTimeoutSecs": 15})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

- **n8n, Make, Zapier** — use the Apify node/module: run the Actor, then "get dataset items".
- **Google Sheets, Slack, webhooks** — add an integration on the run's *Integrations* tab.
- **AI agents** — the Actor is available as a tool through the Apify MCP server; the dataset schema describes every field for the model.
- **Schedules** — run it hourly, daily or weekly from the *Schedules* tab.

### FAQ

**Where does the data come from?**

SSLMate's certspotter API over the public Certificate Transparency logs, plus Cloudflare's DNS-over-HTTPS for resolution. No key or account is needed for either.

**Why is this faster than a crt.sh Actor?**

crt.sh answers a wildcard query in about 13 seconds per domain and is often queued; certspotter answered the same domain in half a second in testing and pages cleanly, so a list of 50 domains is a minute rather than a quarter of an hour.

**Does it find subdomains that have no certificate?**

No — Certificate Transparency only knows names someone certified. In practice that is almost everything public since browsers require certificates, but an internal host on plain HTTP will not appear.

**What does `resolves: false` mean?**

The name is in a certificate but DNS returns nothing for it today: a decommissioned service, a name certified before launch, or a typo in the certificate. Turn on *Only hostnames that resolve* to drop them.

**Is this legal to run on someone else's domain?**

Reading public Certificate Transparency logs and public DNS is passive and lawful. The optional HTTPS check fetches each host's home page once, like a browser would — use it on domains you own or are authorised to assess.

**Can I monitor a domain for new subdomains?**

Yes: schedule a daily run and compare `lastSeen` — a name that appears for the first time is a service that just got a certificate.

### Support

Questions, missing fields or a source that changed? Open an issue on the *Issues* tab or write to support@chorelet.app — problems are usually fixed within a day, and the Actor is checked every morning by an automated test run. If the Actor saved you time, a short review on its Store page helps other people find it.

# Actor input Schema

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

Apex domains (`apify.com`) or URLs. Subdomains of each are found automatically.

## `resolveDns` (type: `boolean`):

Look up A, AAAA and CNAME records for every hostname — the difference between a name in a certificate and a host that exists.

## `httpCheck` (type: `boolean`):

Fetch each resolving hostname and record the status code, final URL, page title and server header. One request per host.

## `onlyResolving` (type: `boolean`):

Drops names that appear in certificates but no longer point anywhere.

## `includeWildcards` (type: `boolean`):

`*.example.com` entries are certificate names, not hosts: they are marked and never resolved.

## `maxHostsPerDomain` (type: `integer`):

The most recently certified names come first.

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

How many hostnames to resolve and fetch at once.

## `requestTimeoutSecs` (type: `integer`):

Per hostname, when the HTTPS check is on.

## Actor input object example

```json
{
  "domains": [
    "apify.com"
  ],
  "resolveDns": true,
  "httpCheck": false,
  "onlyResolving": false,
  "includeWildcards": true,
  "maxHostsPerDomain": 200,
  "concurrency": 8,
  "requestTimeoutSecs": 15
}
```

# Actor output Schema

## `hostnames` (type: `string`):

Everything found — items of the default dataset. Use ?format=csv or xlsx on this URL for spreadsheets.

## `summary` (type: `string`):

Hostnames per domain, how many resolve, and errors.

# 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"
    ],
    "resolveDns": true,
    "httpCheck": false,
    "onlyResolving": false,
    "includeWildcards": true,
    "maxHostsPerDomain": 200,
    "concurrency": 8,
    "requestTimeoutSecs": 15
};

// Run the Actor and wait for it to finish
const run = await client.actor("chorelet/subdomain-finder").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"],
    "resolveDns": True,
    "httpCheck": False,
    "onlyResolving": False,
    "includeWildcards": True,
    "maxHostsPerDomain": 200,
    "concurrency": 8,
    "requestTimeoutSecs": 15,
}

# Run the Actor and wait for it to finish
run = client.actor("chorelet/subdomain-finder").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"
  ],
  "resolveDns": true,
  "httpCheck": false,
  "onlyResolving": false,
  "includeWildcards": true,
  "maxHostsPerDomain": 200,
  "concurrency": 8,
  "requestTimeoutSecs": 15
}' |
apify call chorelet/subdomain-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chorelet/subdomain-finder"
        }
    }
}
```

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/3xZCzgC0oSPmca1vs/builds/h5oil6AKj0RqphwQg/openapi.json
