# 🔍 Subdomain Finder & CT Log Scraper (`taroyamada/subdomain-finder`) Actor

Map website architectures by extracting subdomains from public Certificate Transparency logs to find unlinked staging sites.

- **URL**: https://apify.com/taroyamada/subdomain-finder.md
- **Developed by:** [naoki anzai](https://apify.com/taroyamada) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 12 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 certificate subdomain rows

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?

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

## 🔍 Subdomain Finder

Uncover the full technical footprint of any website by extracting subdomains directly from public Certificate Transparency (CT) logs. This automated scraper queries the crt.sh database to map out complex website architectures, revealing hidden development environments, forgotten staging servers, and unlinked corporate web pages. Technical SEO specialists, system administrators, and digital marketers use this subdomain finder to build a comprehensive inventory of a domain network without needing internal server access, proprietary API credentials, or active crawling.

Running this subdomain scraper on a weekly schedule helps organizations maintain tight control over their web presence and eliminate duplicate content. By scraping certificate issuances and validity dates, you can easily identify unauthorized deployments or shadow IT that might be exposing vulnerable endpoints or diluting your crawl budget. It provides a purely passive reconnaissance method, ensuring that your data collection is both stealthy and exhaustive.

Whether you are conducting a rigorous technical SEO audit, tracking competitor brand expansions, or mapping digital assets across multiple websites, mining CT logs gives you an unfiltered view of a company's architecture. The extracted data includes exact subdomain URLs, certificate issuer records, creation timestamps, and expiration dates, giving you the exact details needed to secure and optimize your complete web infrastructure.

### Store Quickstart

Start with the **Quickstart** template (single domain). For large asset inventories, use **Enterprise Audit** with up to 50 domains.

### Key Features

- 🔍 **Certificate Transparency logs** — Uses crt.sh — the authoritative CT log database
- 📊 **Full subdomain history** — Active AND expired certificates both discoverable
- 🏷️ **Issuer tracking** — See which CA issued each certificate
- 📅 **Validity dates** — validFrom / validTo per certificate
- 🎯 **Deduplication** — Unique subdomains only, no duplicates
- 🔑 **No API key needed** — Free public CT log database

### Use Cases

| Who | Why |
|-----|-----|
| **Penetration testers** | Discover forgotten subdomains as attack surface |
| **Asset inventory teams** | Full catalog of company-wide subdomains |
| **Bug bounty hunters** | Find in-scope targets via CT logs |
| **M\&A due diligence** | Audit acquired company's public infrastructure |
| **DNS auditors** | Cross-reference CT logs with DNS records to find orphaned subdomains |

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| domains | string\[] | (required) | Domains to scan (max 50) |
| includeExpired | boolean | false | Include expired certificates |
| dedup | boolean | true | Deduplicate subdomain names |

#### Input Example

```json
{
  "domains": ["example.com", "target.org"],
  "includeExpired": false,
  "dedup": true
}
```

### Input Examples

#### Example: Single domain enumeration

```json
{
  "domains": [
    "example.com"
  ]
}
```

#### Example: Multi-domain audit

```json
{
  "domains": [
    "example.com",
    "example.org"
  ],
  "expandWildcards": true
}
```

#### Example: Recently-issued only

```json
{
  "domains": [
    "example.com"
  ],
  "sinceDays": 90,
  "includeIssuer": true
}
```

### Output

| Field | Type | Description |
|-------|------|-------------|
| `subdomain` | string | Discovered subdomain |
| `domain` | string | Root domain queried |
| `source` | string | Where it was found (crtsh, hackertarget, etc.) |
| `ip` | string | Resolved IP address (if resolveIPs enabled) |
| `firstSeen` | string | ISO date when first observed (if available) |

#### Output Example

```json
{
  "domain": "example.com",
  "subdomains": [
    {"name": "api.example.com", "issuer": "Let's Encrypt", "validFrom": "2026-01-01", "validTo": "2026-04-01"},
    {"name": "mail.example.com", "issuer": "DigiCert", "validFrom": "2025-06-01", "validTo": "2026-06-01"}
  ],
  "totalFound": 42
}
```

### API Usage

Run this actor programmatically using the Apify API. Replace `YOUR_API_TOKEN` with your token from [Apify Console → Settings → Integrations](https://console.apify.com/account/integrations).

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/taroyamada~subdomain-finder/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "domains": ["example.com", "target.org"], "includeExpired": false, "dedup": true }'
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("taroyamada/subdomain-finder").call(run_input={
  "domains": ["example.com", "target.org"],
  "includeExpired": false,
  "dedup": true
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### JavaScript / Node.js

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('taroyamada/subdomain-finder').call({
  "domains": ["example.com", "target.org"],
  "includeExpired": false,
  "dedup": true
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Tips & Limitations

- Use `crtsh` source for the most comprehensive results — it queries Certificate Transparency logs.
- Enable `resolveIPs: true` to identify shared infrastructure across subdomains.
- Run monthly to catch new subdomains your team may have spun up without security review.
- Combine with DNS Propagation Checker to verify which subdomains are still live.

### See also (Link analysis cluster)

- [Short URL Resolver & Scraper](https://apify.com/taroyamada/url-shortener-resolver) — Resolve obfuscated short URLs that surface during subdomain / CT log enumeration.

### FAQ

**Will I find ALL subdomains?**

Only those with valid HTTPS certificates. HTTP-only subdomains and those using wildcard certs are missed.

**What about wildcard certificates?**

Wildcard certs (\*.example.com) appear as a single entry. Individual subdomains under them may not be listed.

**Is crt.sh reliable?**

Yes — it aggregates all public CT logs required by browser vendors. Very comprehensive.

**Can I scan a competitor's domain?**

Publicly — yes, CT logs are public by design. Always comply with your jurisdiction's laws.

**Is this passive or active enumeration?**

Passive only — it queries public OSINT sources (CT logs, DNS aggregators). No port scanning or brute-forcing.

**Will it find subdomains behind WAFs?**

Yes, as long as the subdomain has been issued an SSL cert (which CT logs index).

### Related Actors

DevOps & Tech Intel cluster — explore related Apify tools:

- [🌐 DNS Propagation Checker](https://apify.com/taroyamada/dns-propagation-checker) — Check DNS propagation across 8 global resolvers (Google, Cloudflare, Quad9, OpenDNS).
- [🧹 CSV Data Cleaner](https://apify.com/taroyamada/csv-data-cleaner) — Clean CSV data: trim whitespace, remove empty rows, deduplicate by columns, sort.
- [📦 NPM Package Analyzer](https://apify.com/taroyamada/npm-package-intelligence) — Analyze npm packages: download stats, dependencies, licenses, deprecation status.
- [💬 Reddit Scraper](https://apify.com/taroyamada/reddit-data-scraper) — Scrape Reddit posts and comments from any subreddit via official JSON API.
- [GitHub Release & Changelog Monitor API](https://apify.com/taroyamada/github-release-monitor) — Track GitHub releases, tags, release notes, and changelog drift over time with one summary-first repository row per repo.
- [Docs & Changelog Drift Monitor API](https://apify.com/taroyamada/docs-changelog-drift-monitor) — Monitor release notes, changelog pages, migration guides, and key docs pages with one summary-first target row per monitored repo, SDK, or product.
- [Tech Events Calendar API | Conferences + CFP](https://apify.com/taroyamada/tech-events-intelligence) — Aggregate tech conferences and CFPs across multiple sources into a deduplicated event calendar for DevRel and recruiting workflows.
- [🔒 OSS Vulnerability Monitor](https://apify.com/taroyamada/oss-vulnerability-monitor) — Monitor open-source packages for known security vulnerabilities using OSV and GitHub Security Advisories.

### Cost

**Pay Per Event**:

- `actor-start`: $0.01 (flat fee per run)
- `dataset-item`: $0.003 per output item

**Example**: 1,000 items = $0.01 + (1,000 × $0.003) = **$3.01**

No subscription required — you only pay for what you use.

### ⭐ Was this helpful?

If this actor saved you time, please [**leave a ★ rating**](https://apify.com/taroyamada/subdomain-finder/reviews) on Apify Store. It takes 10 seconds, helps other developers discover it, and keeps updates free.

Bug report or feature request? Open an issue on the [Issues tab](https://apify.com/taroyamada/subdomain-finder/issues) of this actor.

# Actor input Schema

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

Root domains to find subdomains for (max 50).

## `includeExpired` (type: `boolean`):

Include expired entries

## `delivery` (type: `string`):

Where to send results: dataset or webhook

## `webhookUrl` (type: `string`):

Webhook URL to POST results to (if delivery=webhook)

## `dryRun` (type: `boolean`):

Run without saving results (for testing)

## Actor input object example

```json
{
  "domains": [
    "example.com"
  ],
  "includeExpired": false,
  "delivery": "dataset",
  "dryRun": false
}
```

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

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/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": ["example.com"] }

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/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": [
    "example.com"
  ]
}' |
apify call taroyamada/subdomain-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,taroyamada/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/3gs6vUEt6DFiCqUbf/builds/hBQ7333ltEP2AuTo6/openapi.json
