# Subdomain Enumeration via Certificate Transparency (`perryay/subdomain-enumeration-ct-logs`) Actor

Discover subdomains from Certificate Transparency logs using crt.sh and CertSpotter. Supports multi-source aggregation, deduplication, diff reporting, continuous monitoring, wildcard detection, and batch scanning — ideal for penetration testing, attack surface mapping, and security monitoring.

- **URL**: https://apify.com/perryay/subdomain-enumeration-ct-logs.md
- **Developed by:** [Perry AY](https://apify.com/perryay) (community)
- **Categories:** Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / actor start

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 Enumeration via Certificate Transparency

### Subdomain Enumeration via Certificate Transparency

Discover every subdomain for any domain by querying Certificate Transparency (CT) logs. Aggregate results from **crt.sh** and **CertSpotter**, with automatic deduplication, sorting, change tracking, and continuous monitoring — all in a single Apify actor.

---

### What does it do?

Discover every subdomain for any domain by querying Certificate Transparency (CT) logs. Aggregate results from **crt.sh** and **CertSpotter**, with automatic deduplication, sorting, change tracking, and continuous monitoring — all in a single Apify actor.

---

### Features

1. **Multi-Source Aggregation** — Queries **crt.sh** (primary) and **CertSpotter** (secondary) for maximum CT log coverage.
2. **Automatic Deduplication** — Merges results from all sources, removing exact duplicates while preserving source and certificate metadata.
3. **Wildcard Detection** — Identifies and counts wildcard certificate entries (`*.example.com`) separately.
4. **Diff Reporting** — Compares the current scan against the previous scan of the same domain. Produces lists of **new**, **removed**, and **unchanged** subdomains with counts.
5. **Continuous Monitoring** — Persistent state file tracks all subdomains ever discovered for a domain. Each run records a change event showing what's new since the last check.
6. **Batch Mode** — Scan multiple domains in a single run. Provide an array of domain objects via the `batchData` field.
7. **Exponential-Backoff Retry** — Transient HTTP errors (timeouts, 429, 503) are retried with exponential backoff for resilience.
8. **Concurrency Control** — Source-level and domain-level semaphores prevent overwhelming upstream APIs.
9. **Sorted Output** — Subdomains are sorted alphabetically with wildcard entries grouped at the end.
10. **Detailed Metadata** — Each entry includes the source, certificate ID, validity dates, and common name where available.

---

### Why use this?

- **Two CT sources in one tool** — crt.sh and CertSpotter together cover more certificate data than either alone. No need to run separate tools and merge results manually.
- **Stateful change tracking** — The diff and monitor modes remember what you found last time, so you can run this on a schedule (e.g., daily cron) and get a clean before-and-after report every time.
- **Enterprise-ready error handling** — Retry logic, rate limiting, graceful degradation, and informative error messages mean this actor works reliably in automated pipelines.
- **Wildcard awareness** — Wildcard certificates (`*.example.com`) are counted and flagged separately, giving you a clearer picture of the domain's certificate posture.

---

### Who is it for?

| Persona | What they use it for |
|---|---|
| Penetration Tester | Mapping the full attack surface of a target domain before an engagement |
| Security Team | Monitoring for unauthorised subdomain creation or certificate issuance |
| DevOps / SRE | Tracking infrastructure drift — new staging environments, removed services |
| Bug Bounty Hunter | Discovering hidden or forgotten subdomains for vulnerability research |
| Incident Responder | Quickly enumerating all publicly exposed subdomains of a compromised domain |
| IT Asset Manager | Maintaining an inventory of all domain-linked services and subdomains |

---

### Input Parameters

| Field | Type | Default | Description |
|---|---|---|---|
| `domain` | `string` | `example.com` | Target domain to enumerate. Protocol prefixes and URL paths are automatically stripped. |
| `fullScan` | `boolean` | `false` | When `true`, queries both crt.sh and CertSpotter for maximum coverage. When `false`, queries crt.sh only (faster, cheaper). |
| `diffReport` | `boolean` | `false` | When `true`, compares results against the previous scan snapshot and emits new/removed subdomain lists. Requires a prior scan to exist. |
| `monitorMode` | `boolean` | `false` | When `true`, maintains a persistent history of all ever-discovered subdomains and records change deltas. Ideal for scheduled/periodic runs. |
| `batchMode` | `boolean` | `false` | When `true`, scans multiple domains from the `batchData` array. The single `domain` field is ignored. |
| `batchData` | `array` | `[]` | Array of domain objects for batch mode. Each object must have a `domain` field: `[{"domain": "example.com"}, {"domain": "google.com"}]` |

#### Example Input JSON

```json
{
  "domain": "example.com",
  "fullScan": true,
  "diffReport": false,
  "monitorMode": false,
  "batchMode": false
}
````

Batch mode example:

```json
{
  "batchMode": true,
  "fullScan": true,
  "batchData": [
    { "domain": "example.com" },
    { "domain": "google.com" },
    { "domain": "github.com" }
  ]
}
```

***

### Output Format

The actor pushes one dataset item per domain scanned. Each item contains the full enumeration report.

#### Output Fields

| Field | Type | Description |
|---|---|---|
| `domain` | `string` | The target domain that was scanned |
| `subdomains` | `array` | Deduplicated, sorted list of discovered subdomains with metadata |
| `total_found` | `number` | Raw count of entries returned before deduplication |
| `unique_domains` | `number` | Count of unique subdomains after deduplication |
| `wildcard_count` | `number` | Number of wildcard certificate entries (starting with `*.`) |
| `sources_used` | `array` | List of CT log sources that were successfully queried |
| `scan_mode` | `string` | Operation mode used: `single-scan`, `full-scan`, `diff-report`, or `monitor` |
| `scan_date` | `string` | ISO-8601 timestamp of the scan |
| `elapsed_ms` | `number` | Wall-clock duration of the enumeration in milliseconds |
| `diff` | `object` | *(present only when `diffReport=true`)* Diff report with new/removed/unchanged counts |
| `monitor_delta` | `object` | *(present only when `monitorMode=true`)* Changes since the last monitor run |
| `error` | `string` | Error message if the scan failed for this domain |

#### Subdomain Entry Fields

| Field | Type | Description |
|---|---|---|
| `domain` | `string` | Fully-qualified subdomain (e.g., `api.example.com`). May start with `*.` for wildcards. |
| `source` | `string` | Source identifier: `crt.sh` or `certspotter` |
| `certificate_id` | `number` | Certificate identifier from the source |
| `not_before` | `string` | Certificate validity start date |
| `not_after` | `string` | Certificate validity end date |
| `common_name` | `string` | Certificate Common Name (available from crt.sh) |

#### Example Output JSON

```json
{
  "domain": "example.com",
  "subdomains": [
    {
      "domain": "admin.example.com",
      "source": "crt.sh",
      "certificate_id": 12345678,
      "not_before": "2026-01-01T00:00:00",
      "not_after": "2027-01-01T00:00:00",
      "common_name": "admin.example.com"
    },
    {
      "domain": "api.example.com",
      "source": "certspotter",
      "certificate_id": 87654321,
      "not_before": "2026-03-15T00:00:00",
      "not_after": "2027-03-15T00:00:00"
    },
    {
      "domain": "*.example.com",
      "source": "crt.sh",
      "certificate_id": 11223344,
      "not_before": "2026-06-01T00:00:00",
      "not_after": "2027-06-01T00:00:00"
    }
  ],
  "total_found": 184,
  "unique_domains": 147,
  "wildcard_count": 3,
  "sources_used": ["crt.sh", "certspotter"],
  "scan_mode": "full-scan",
  "scan_date": "2026-07-20T10:00:00.000000+00:00",
  "elapsed_ms": 3842.1,
  "diff": {
    "new_domains": ["new-admin.example.com"],
    "removed_domains": ["old-api.example.com"],
    "new_count": 1,
    "removed_count": 1,
    "unchanged_count": 145,
    "baseline_scan_date": "2026-07-19T10:00:00.000000+00:00",
    "current_scan_date": "2026-07-20T10:00:00.000000+00:00"
  }
}
```

***

### API Usage

#### cURL

```bash
## Single domain, full scan
curl -X POST "https://api.apify.com/v2/acts/perryay~subdomain-enumeration-ct-logs/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "fullScan": true
  }'

## Diff report
curl -X POST "https://api.apify.com/v2/acts/perryay~subdomain-enumeration-ct-logs/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "diffReport": true
  }'

## Batch mode
curl -X POST "https://api.apify.com/v2/acts/perryay~subdomain-enumeration-ct-logs/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "batchMode": true,
    "fullScan": true,
    "batchData": [
      { "domain": "example.com" },
      { "domain": "google.com" }
    ]
  }'

## Fetch results
curl "https://api.apify.com/v2/datasets/YOUR_DATASET_ID/items?token=YOUR_API_TOKEN&format=json"
```

#### Python (Apify SDK)

```python
import asyncio
from apify_client import ApifyClient

## Synchronous client
client = ApifyClient("YOUR_API_TOKEN")

## Run the actor and wait for results
run = client.actor("perryay/subdomain-enumeration-ct-logs").call(
    run_input={
        "domain": "example.com",
        "fullScan": True,
        "diffReport": False,
    },
)

## Fetch dataset
dataset_id = run["defaultDatasetId"]
items = client.dataset(dataset_id).list_items().items

for item in items:
    print(f"{item['domain']}: {item['unique_domains']} unique subdomains")
    if item.get("diff"):
        d = item["diff"]
        print(f"  +{d['new_count']} new, -{d['removed_count']} removed")
```

***

### Use Cases

1. **Penetration Testing Reconnaissance** — Before any security assessment, enumerate all subdomains to map the full attack surface. Wildcard entries highlight potential domain takeover vectors.
2. **Continuous Security Monitoring** — Schedule the actor to run daily with `monitorMode=true`. Each run produces a delta of new subdomains, alerting you to unapproved infrastructure.
3. **M\&A Due Diligence** — When evaluating a target company, enumerate their primary domains to discover shadow IT, forgotten services, and exposed management interfaces.
4. **Bug Bounty Automation** — Integrate into your recon pipeline. Run against a target, pipe the subdomain list to a port scanner or web crawler for deeper analysis.
5. **DevOps Infrastructure Audit** — Track which subdomains have valid certificates and which have expired (`not_after` dates). Identify certs that need renewal before they break TLS.
6. **Cloud Migration Tracking** — After moving services to a new cloud provider, monitor for old subdomains that should have been decommissioned (detected as `removed_domains` in diff mode).
7. **Subdomain Takeover Prevention** — Set up weekly scans for your own domains. If a subdomain disappears from CT logs but still resolves in DNS, it might be vulnerable to takeover.
8. **CDN / WAF Onboarding** — Before migrating traffic through a CDN, enumerate all subdomains so the onboarding team doesn't miss any origin.

***

### FAQ

**Q1: How does this actor find subdomains?**
A: It queries Certificate Transparency (CT) logs — public, append-only ledgers of every X.509 certificate issued by trusted Certificate Authorities. Every time a CA issues a certificate for your domain or one of its subdomains, that certificate (with its Subject Alternative Names) is recorded in a CT log. The actor queries two CT log aggregators: **crt.sh** (run by Sectigo / the community) and **CertSpotter** (run by SSLMate). Between them, they cover the vast majority of publicly trusted CAs.

**Q2: Is this a live DNS scanner? Does it perform DNS lookups?**
A: No. This actor **does not** perform any DNS queries, port scans, or active network probes. It is purely passive — it inspects certificate log data. This makes it safe to run against any domain without alerting the target's monitoring systems.

**Q3: Why scan two sources? Isn't one enough?**
A: Each CT log aggregator has a different coverage window, update latency, and backend. crt.sh has the broadest historical data but may lag a few hours on recent issuances. CertSpotter updates faster but has a smaller historical window. Using both maximises both coverage and freshness.

**Q4: How many subdomains can I expect to find?**
A: It varies enormously by domain. A small blog might have 3–5 subdomains; a large tech company like Google or Microsoft can have tens of thousands. The actor includes a 10,000-entry safety limit per source to prevent runaway memory usage.

**Q5: What's the difference between "diff report" and "monitor mode"?**
A: **Diff report** compares the current scan against exactly one previous snapshot (the last scan). **Monitor mode** maintains a full history of all subdomains ever seen across all scans of that domain, accumulating change events. Use diff for simple before/after comparisons; use monitor for long-running scheduled tracking.

**Q6: Does this actor support IDN / internationalised domain names?**
A: Yes. The ct log sources return Punycode-encoded domains (xn--...) which the actor passes through as-is. You can provide both plain ASCII and Punycode input.

**Q7: Will I get rate-limited by crt.sh or CertSpotter?**
A: The actor includes rate-limiting safeguards (concurrent request semaphores, exponential-backoff retries, per-source timeouts). However, for very large runs or high-frequency schedules, the upstream APIs may still rate-limit you. The actor logs HTTP 429 responses and retries with backoff.

**Q8: What happens to the state files when I stop using the actor?**
A: State files are stored in the actor's persistent storage on the Apify platform. They persist between runs for the same actor instance so that diff and monitor modes can track changes over time. If you stop monitoring a domain, the state files remain but do not affect new runs with a different domain.

**Q9: Can I use this actor for 10,000 domains in one run?**
A: The actor was designed for up to a few hundred domains per run. For massive lists, split into batches of 50–100 and run them sequentially or use the actor's batch mode with a reasonable array size. The 3-domain concurrency cap prevents overwhelming upstream APIs.

**Q10: Does this actor support wildcard subdomain enumeration (like `*.example.com`)?**
A: Yes — it detects wildcard entries present in certificates (e.g., `*.example.com`) and reports them separately in the `wildcard_count` field. However, it does not *generate* every possible subdomain from a wildcard; it only reports what's actually in the certificate logs.

**Q11: How fresh is the data from crt.sh and CertSpotter?**
A: crt.sh typically reflects certificate issuances within a few hours. CertSpotter is generally faster, often reflecting issuances within 30–60 minutes. Neither is real-time (CT log submission + processing delay).

**Q12: Is there a limit on the number of subdomains returned?**
A: Each source has a 10,000-entry safety limit per domain. Combined, you could receive up to 20,000 raw entries, which are then deduplicated. This is sufficient for the vast majority of domains.

***

### Usage & Billing

This actor uses Apify's **PAY\_PER\_EVENT** pricing model. You are charged only for successful runs based on the events your usage triggers.

#### Charge Events

| Event | Trigger |
|-------|--------|
| `apify-actor-start` | Every run (base) |
| `full-scan` | `fullScan: true` (queries both CT sources) |
| `diff-report` | `diffReport: true` |
| `monitor` | `monitorMode: true` |

Platform costs (Apify's infrastructure fee) are passed through to the customer.

***

### MCP Integration

This actor can be used through the [Apify MCP server](https://docs.apify.com/integrations/mcp). Once connected, your MCP client (Claude Desktop, Cursor, etc.) can discover and run this actor from the Apify Store.

#### Quick Start

1. **Install the Apify connector** in your MCP client:
   - **Claude Desktop**: Search for "Apify" in the connector directory, or use the remote server at `https://mcp.apify.com`
   - **Other clients**: See the [Apify MCP server docs](https://docs.apify.com/integrations/mcp) for setup instructions

2. **Ask your AI assistant** to enumerate subdomains using natural language. For example:
   > "Enumerate all subdomains for example.com using CT logs"
   > "Run a full scan on github.com and show me the wildcard subdomains"

#### Claude Desktop Configuration

Add the following to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com"
    }
  }
}
```

On first connection, your browser opens to sign in to Apify and authorize access.

> **Bearer token alternative:** For headless environments, CI/CD pipelines, or clients without browser-based OAuth, you can authenticate directly with your Apify API token:
>
> ```json
> {
>   "mcpServers": {
>     "apify": {
>       "url": "https://mcp.apify.com",
>       "headers": {
>         "Authorization": "Bearer YOUR_APIFY_TOKEN"
>       }
>     }
>   }
> }
> ```
>
> Get your API token from [Apify Console](https://console.apify.com) → **API & Integrations** section.

***

### Related Tools

- **[SSL Certificate Checker](https://apify.com/perryay/ssl-certificate-checker)** — Check SSL/TLS certificate expiry dates and issuer details for a domain. Complements subdomain enumeration by verifying certificate health.
- **[Domain Intel](https://apify.com/perryay/domain-intel)** — Domain registration and WHOIS intelligence gathering.
- **[JSON Studio](https://apify.com/perryay/json-studio)** — Format, validate, and transform JSON data for post-processing subdomain lists.

***

# Actor input Schema

## `domain` (type: `string`):

The domain to enumerate subdomains for (without https://).

## `fullScan` (type: `boolean`):

Enable to query multiple CT log sources (crt.sh + CertSpotter) for maximum coverage.

## `diffReport` (type: `boolean`):

Compare against previous scan results to show new and removed subdomains.

## `monitorMode` (type: `boolean`):

Enable persistent subdomain monitoring with state tracking.

## `batchMode` (type: `boolean`):

Scan multiple domains in a single run.

## `batchData` (type: `array`):

Array of domain objects for batch mode.

## Actor input object example

```json
{
  "domain": "example.com",
  "fullScan": false,
  "diffReport": false,
  "monitorMode": false,
  "batchMode": false,
  "batchData": [
    {
      "domain": "example.com"
    },
    {
      "domain": "google.com"
    }
  ]
}
```

# Actor output Schema

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

Subdomain enumeration results in the default dataset — one item per domain scanned

# 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 = {
    "domain": "example.com",
    "batchData": [
        {
            "domain": "example.com"
        },
        {
            "domain": "google.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("perryay/subdomain-enumeration-ct-logs").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 = {
    "domain": "example.com",
    "batchData": [
        { "domain": "example.com" },
        { "domain": "google.com" },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("perryay/subdomain-enumeration-ct-logs").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 '{
  "domain": "example.com",
  "batchData": [
    {
      "domain": "example.com"
    },
    {
      "domain": "google.com"
    }
  ]
}' |
apify call perryay/subdomain-enumeration-ct-logs --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=perryay/subdomain-enumeration-ct-logs",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Subdomain Enumeration via Certificate Transparency",
        "description": "Discover subdomains from Certificate Transparency logs using crt.sh and CertSpotter. Supports multi-source aggregation, deduplication, diff reporting, continuous monitoring, wildcard detection, and batch scanning — ideal for penetration testing, attack surface mapping, and security monitoring.",
        "version": "1.0",
        "x-build-id": "THy4Xsp9RrKYmMjGy"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/perryay~subdomain-enumeration-ct-logs/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-perryay-subdomain-enumeration-ct-logs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/perryay~subdomain-enumeration-ct-logs/runs": {
            "post": {
                "operationId": "runs-sync-perryay-subdomain-enumeration-ct-logs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/perryay~subdomain-enumeration-ct-logs/run-sync": {
            "post": {
                "operationId": "run-sync-perryay-subdomain-enumeration-ct-logs",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "domain": {
                        "title": "Target Domain",
                        "type": "string",
                        "description": "The domain to enumerate subdomains for (without https://)."
                    },
                    "fullScan": {
                        "title": "Full Scan (All Sources)",
                        "type": "boolean",
                        "description": "Enable to query multiple CT log sources (crt.sh + CertSpotter) for maximum coverage.",
                        "default": false
                    },
                    "diffReport": {
                        "title": "Diff Report",
                        "type": "boolean",
                        "description": "Compare against previous scan results to show new and removed subdomains.",
                        "default": false
                    },
                    "monitorMode": {
                        "title": "Continuous Monitor",
                        "type": "boolean",
                        "description": "Enable persistent subdomain monitoring with state tracking.",
                        "default": false
                    },
                    "batchMode": {
                        "title": "Batch Mode",
                        "type": "boolean",
                        "description": "Scan multiple domains in a single run.",
                        "default": false
                    },
                    "batchData": {
                        "title": "Batch Domain List",
                        "type": "array",
                        "description": "Array of domain objects for batch mode."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
