Subdomain Finder via CT Logs: DNS, Takeover Hints & Alerts
Pricing
from $0.70 / 1,000 subdomains
Subdomain Finder via CT Logs: DNS, Takeover Hints & Alerts
Passive CT-log subdomain discovery with source-linked certificate dates, optional DNS and dangling-CNAME hints, and only-new monitoring. crt.sh by default; Cert Spotter requires explicit opt-in. Transparent per-host billing and strict run-budget guards.
Pricing
from $0.70 / 1,000 subdomains
Rating
0.0
(0)
Developer
Dano Desk
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 hours ago
Last modified
Categories
Security
Limited permissionsShare
Find subdomains observed in public TLS certificates, with dates and source evidence—not a claim of exhaustive DNS coverage. The data comes from Certificate Transparency (CT) logs, the public, append-only record of issued certificates. It's passive: the Actor never scans or brute-forces the target. It reads public CT search services and, if you ask, makes ordinary DNS lookups.
Why this one
- It doesn't die when crt.sh does. crt.sh is free and often overloaded (HTTP 502 or timeouts), and that's why single-source CT Actors fail so often. This Actor asks crt.sh for the small deduplicated result first. If that fails, it tries crt.sh's plain query once. SSLMate Cert Spotter is opt-in, disabled by default, and is never queried merely because an API key exists. Every domain gets a clear status and error code.
- Clean results. You get one row per host, with wildcard names merged or kept separate as you choose. Precertificates and their final certificates are counted once. Names from other domains on the same cert, plus emails and junk, are dropped.
- Useful fields.
firstSeen/lastSeen(certificate notBefore),latestExpiry,activeCert,certCount,latestIssuer,issuers,sourcesand a crt.sh link. - Optional DNS. A / AAAA / CNAME, plus
dnsStatus(RESOLVED, CNAME_NO_TARGET, NO_RECORDS, NXDOMAIN, TIMEOUT). There's also a dangling-CNAME hint that names the service (GitHub Pages, S3, Azure, Heroku, Netlify…) and a DNS-wildcard check per domain. - Monitor mode. It remembers which hosts it has already seen in a named key-value store. Schedule it daily and you get only new subdomains.
- Bulk: up to 100 domains per run. No API key needed.
Quick start
- Demo: run with
{}for three labelled archived real CT rows from 2026-10-29. No current DNS assertion, external requests or custom event charges. Supplydomainsfor a live query. - Bulk:
{ "domains": ["example.com", "https://www.example.org/page", "ops@example.net"] }
- Live hosts only, full history:
{ "domains": ["example.com"], "includeExpired": true, "onlyResolving": true }
- Daily new-subdomain alert (schedule it, then connect a webhook, Slack or email integration to the dataset):
{ "domains": ["example.com", "example.org"], "monitor": true, "monitorKey": "my-brands", "resolveDns": true }
Input
| Field | Default | Notes |
|---|---|---|
domains | demo | Root domains, max 100. URLs, emails, *.x and www. are cleaned. Invalid entries get an INVALID_DOMAIN error row and don't stop the run. |
sources | crtsh | auto can fall back only when enableCertSpotter=true. both/certspotter require that same explicit terms opt-in. |
enableCertSpotter | false | Separate consent even if a key is provided. Review SSLMate plan/use terms; a key alone does not establish permitted use. |
includeExpired | false | Also returns hosts that appear only in expired certificates. Cert Spotter has unexpired certificates only. |
wildcardMode | merge | merge: *.dev.x.com becomes dev.x.com with hasWildcardCert=true. separate: it gets its own row. drop: it's ignored. |
includeRootDomain | true | Includes a row for the domain itself. |
maxSubdomainsPerDomain | 5000 | Keeps the most recently seen hosts and logs a warning. |
resolveDns / onlyResolving | off | DNS lookups only, never ports or HTTP. |
takeoverHints | on | A dangling CNAME is a hint to check by hand, not a confirmed vulnerability. |
dnsServers, dnsConcurrency | platform, 10 | |
monitor, onlyNew, monitorKey, stateStoreName | off, on, default, subdomain-finder-ct-state | One memory record per (monitorKey, domain). The first run is the baseline: everything counts as new. |
certspotterApiKey | none | Optional, secret. Raises Cert Spotter limits. |
certspotterMaxPages | 5 (50 with key) | One request per page. |
crtshTimeoutSecs, maxResponseMb | 60, 40 | Answers over the size cap fail clearly; opt-in auto mode can try Cert Spotter. For very large domains, raise these together with run memory. |
Output
The dataset has one row per host (recordType: "subdomain") and one row per failed or invalid domain (recordType: "error", errorCode, message). There are four views: Subdomains, DNS & takeover hints, Monitor, and Errors.
Example row (from a real run, shortened):
{ "domain": "apify.com", "subdomain": "mail.apify.com", "level": 1, "firstSeen": "2026-01-26T00:00:00.000Z", "lastSeen": "2026-01-26T00:00:00.000Z","latestExpiry": "2027-02-24T23:59:59.000Z", "activeCert": true, "certCount": 1, "latestIssuer": "Amazon Trust Services","sources": ["certspotter"], "dnsStatus": "RESOLVED", "resolves": true, "a": ["…"], "cname": null, "takeoverHint": null, "crtshUrl": "https://crt.sh/?q=mail.apify.com" }
firstSeen and lastSeen are the earliest and latest certificate notBefore dates that name the host, so they reflect certificate dates, not DNS history. firstDetectedAt (monitor) is the time this Actor first saw the host.
The OUTPUT record in the key-value store has a per-domain status (ok / partial / failed / invalid), the status of each source (certificates, pages, notes), counts, warnings and request stats.
Error codes
- Per domain:
INVALID_DOMAIN,CRTSH_<code>orCERTSPOTTER_<code>(when only that source was tried),ALL_SOURCES_FAILED,SOME_SOURCES_FAILED(status partial, results kept). - Source codes:
TIMEOUT,UNAVAILABLE(5xx),RATE_LIMITED(429),TOO_LARGE,BAD_RESPONSE,NETWORK_ERROR,BAD_CREDENTIALS,FORBIDDEN,BAD_REQUEST. - Run level:
INVALID_INPUT(nothing usable in the input) andALL_DOMAINS_FAILED. The run fails only if every domain failed.
Fair use of the sources
- crt.sh (operated by Sectigo) is a free community service. The Actor sends one request at a time, at least 3 s apart. It asks for the small deduplicated result, honours
Retry-After, and has a limited retry budget (at most 3 crt.sh requests per domain) before reporting failure or trying the separately enabled Cert Spotter fallback. - Cert Spotter (SSLMate) allows a limited number of unauthenticated queries per hour for personal or evaluation use. Requests are at least 1 s apart and
Retry-Afteris honoured. For permitted regular/commercial use, select a suitable SSLMate plan and your own key; enabling this option does not grant a licence. - DNS lookups go through normal resolvers. The Actor does no port scanning, HTTP probing or brute-forcing.
Use this for domains you own or are authorised to assess, and for brand monitoring and research. CT data is public by design.
Limits and next steps
- Hosts that never had a public certificate (internal-only names, or names covered only by a wildcard cert) can't be found through CT.
- There's no HTTP probing (status or title) and no lookalike/typosquat permutations yet. Both are planned as opt-in modes.
- Cert Spotter without a key returns a few pages per domain. Very large domains need crt.sh, or a key.
Pricing
subdomain: $0.0007 per delivered host row. 1,000 hosts cost $0.70; 50 hosts cost $0.035, before any standard start fee/platform usage. Empty results, errors, filtered/seen hosts and archived demo rows have no custom event fee.
The former domain-scanned fee is retired/included, not stacked on top: the leading per-host peer charges $0.0008/row, and adding an arbitrary domain fee would make the stated undercut misleading. Configure only the named subdomain event—not a second priced default dataset-item event. The automatic apify-actor-start event costs $0.00005 per started GB (minimum one), including empty runs. Worked result examples exclude this start fee and any applicable platform usage, storage, integrations or taxes. No default dataset-row event is priced.
Set Apify run option maxTotalChargeUsd plus a sensible maxSubdomainsPerDomain. Exact active prices and the remaining budget are checked before each row, so the SDK never has to overrun a depleted cap. Hosts not delivered due to a billing cap are removed from the new seen-state commit and remain eligible next run. Never run concurrent writers against one monitor key.
Opt-in fallback example
{"domains":["example.com"],"sources":"auto","enableCertSpotter":true,"certspotterMaxPages":2}
Use this only where SSLMate permits the intended use. Commercial users should supply their own suitable-plan secret key; do not treat the anonymous evaluation tier as a commercial backend.
FAQ
Is this a vulnerability scanner? No. DNS dangling-CNAME indicators are manual-review hints, not confirmed takeovers. No port scan, HTTP probing or exploitation occurs.
Does a certificate prove a hostname is live? No. A certificate may be expired, historical or wildcard-only. Optional DNS status and wildcard-zone detection explain those limits.
What happens when crt.sh is down? The default reports a clear source error. Only explicit opt-in enables Cert Spotter; it is not an undeclared dependency.
Are firstSeen/lastSeen discovery dates? They are certificate notBefore dates. firstDetectedAt is this monitor's observation time, not proof of historic DNS use.
Troubleshooting
INVALID_INPUT: supply valid domains;both/certspotterrequireenableCertSpotter=true.CRTSH_UNAVAILABLE,TIMEOUT,TOO_LARGE: the service may be overloaded; retry later or reduce scope. The client paces requests and retries transient failures within a bounded budget, honoring Retry-After.CERTSPOTTER_BAD_CREDENTIALS/RATE_LIMITED: check your permitted plan/key and lower page caps; partial results stay labelled.BILLING_CAP_REACHED: increase the run cap or reduce expected rows. Unsent hosts are not silently marked delivered.- No output: CT coverage and filters can legitimately yield zero hosts. The Actor never manufactures records to fill a result cap.