# TLSX - TLS Data Gathering and Analysis (`rl1987/pd-tlsx`) Actor

Apify Actor wrapper for ProjectDiscovery's tlsx, a fast and configurable TLS grabber for TLS-based data collection and analysis.

- **URL**: https://apify.com/rl1987/pd-tlsx.md
- **Developed by:** [R.L.](https://apify.com/rl1987) (community)
- **Categories:** Developer tools
- **Features:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 96.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

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

## TLSX — TLS Recon & Subdomain Discovery from X.509 Certificates

Cloud-hosted wrapper around ProjectDiscovery's [tlsx](https://github.com/projectdiscovery/tlsx). Point it at hosts, IP ranges, or ASNs and pull back structured TLS/certificate data — no local Go toolchain, no binary to install.

### Why use this

TLS certificates leak infrastructure. The **Subject Alternative Name (SAN)** and **Common Name (CN)** fields on a cert routinely list every hostname it covers — internal tools, staging environments, forgotten subdomains — even ones that never show up in DNS brute-force wordlists or search-engine indexes. This actor grabs that data at scale and hands it back as clean JSON rows, ready to feed into a dataset, a spreadsheet, or the next stage of a recon pipeline.

Typical use cases:

- **Subdomain discovery for bug bounty / pentest recon** — scan a target's IP ranges (CIDR) or ASN and collect every hostname referenced in certs served on those IPs. Great for finding hosts that DNS enumeration misses.
- **Attack surface mapping** — enumerate TLS/cipher support, flag expired, self-signed, mismatched, revoked, or untrusted certificates across a fleet of hosts.
- **Fingerprinting** — grab JARM/JA3 TLS fingerprints to cluster or identify backend infrastructure (e.g. shared C2, CDN, or hosting provider) across otherwise unrelated hostnames.
- **Cert monitoring** — check expiry dates and issuer chains across your own domains before something breaks in production.
- **Certificate Transparency (CT) log streaming** — tap the live CT log firehose for near-real-time discovery of newly issued certs matching infrastructure you care about.

Only scan targets you're authorized to test.

### Input

Give it targets and (optionally) which data to pull. Targets accept IP, CIDR, ASN, hostname, hostname:port, or full URL:

```json
{
  "host": ["example.com", "173.0.84.0/24", "AS1449"]
}
```

For subdomain discovery from certs, the default settings already return SAN/CN data in every result — no extra flags needed. Just feed it hosts or IP ranges and read `subject_an` / `subject_cn` from the output.

The full input schema (`.actor/actor.json`) mirrors nearly every `tlsx` CLI flag, grouped by purpose:

- **Targets & scan mode** — hosts/CIDR/ASN, ports, IP version, `ctls`/`ztls`/`openssl`/`auto` connection mode, pre-handshake early termination
- **Probes** — fingerprint hashes, JARM, JA3, wildcard cert detection, TLS version / cipher enumeration, certificate serial
- **Misconfiguration checks** — expired, self-signed, mismatched, revoked, untrusted certificates
- **Connection config** — custom resolvers, SNI, min/max TLS version, custom ciphers, SOCKS5 proxy, cert verification
- **Optimizations** — concurrency, per-target timeout, retries, delay
- **CT log streaming** — live firehose mode, bounded by `maxRuntimeSecs` since it otherwise never terminates
- **PDCP dashboard upload** — push results to ProjectDiscovery's Cloud Platform

An `extraFlags` field is included as an escape hatch for anything not explicitly modeled.

Notes:

- The JSON output always includes SAN/CN/cipher/TLS-version/probe-status regardless of the remaining display-only probe flags (`-tv`, `-cipher`, ...) — those only affect plain-text CLI output, which this actor doesn't use. `-san`/`-cn` aren't exposed as inputs at all: `tlsx` hard-rejects combining them with any other display probe, and the JSON output includes that data unconditionally anyway.
- `cacert` expects inline PEM content (pasted in), not a filesystem path.

### Output

One dataset row per scanned host/port, in `tlsx`'s native JSON shape:

```json
{
  "host": "example.com",
  "ip": "93.184.216.34",
  "port": "443",
  "probe_status": true,
  "tls_version": "tls13",
  "cipher": "TLS_AES_256_GCM_SHA384",
  "subject_cn": "www.example.org",
  "subject_an": ["www.example.org", "example.net", "example.com", "..."],
  "issuer_cn": "DigiCert TLS RSA SHA256 2020 CA1",
  "not_before": "2022-03-14T00:00:00Z",
  "not_after": "2023-03-14T23:59:59Z"
}
```

`subject_an` is the field to pull for subdomain discovery — export it, dedupe, and feed into DNS resolution or an HTTP prober for the next recon step. The raw newline-delimited JSON is also saved to the key-value store under `RAW_OUTPUT`.

### Cyber recon toolkit

Part of the **Cyber recon toolkit** — OSINT, attack-surface recon, and vulnerability-intel data collection for security research:

- [Bugcrowd Scraper](https://apify.com/rl1987/bugcrowd-scraper) — Scrapes public Bugcrowd data: disclosed submissions, program directory, leaderboard.
- [HackerOne Scraper](https://apify.com/rl1987/hackerone-scraper) — Scrapes public HackerOne data: Hacktivity disclosed reports, program directory, researcher leaderboard.
- [Intigriti Scraper](https://apify.com/rl1987/intigriti-scraper) — Scrapes public Intigriti data: bug bounty/VDP program directory, researcher leaderboard and profiles.
- [CVE Scraper](https://apify.com/rl1987/cve-scraper) — CVE.org vulnerability info scraper.
- [BGP.HE.NET Recon Scraper](https://apify.com/rl1987/bgphenet-scraper) — Scrapes ASN, prefix, IP, and DNS recon data from bgp.he.net.
- [gau - Get All URLs](https://apify.com/rl1987/gau-wrapper) — Fetch known URLs from Wayback Machine, Common Crawl, AlienVault OTX, and URLScan.
- [Git Email Extractor](https://apify.com/rl1987/git-email-extractor) — Shallow-clones git repos and extracts contributor emails from commit history.
- [Wappalyzer Technology Lookup](https://apify.com/rl1987/wappalyzer-tech-lookup) — Detect the technology stack behind any website using Wappalyzer.
- [Meta Tags Scraper](https://apify.com/rl1987/meta-tags-scraper) — Web page metadata scraper (meta tags, Open Graph, Twitter Card).
- [Universal Contact Extractor](https://apify.com/rl1987/universal-contact-extractor) — Extract phone numbers, emails and social media URLs from web pages.
- [Web Text Extractor](https://apify.com/rl1987/web-text-extractor) — Extract clean text or Markdown content from web pages.

### Did you find this useful?

Rate this actor on Apify! Your feedback helps other users find it and helps us keep improving it.

# Actor input Schema

## `host` (type: `array`):

Target host(s) to scan. Accepts IP, CIDR, ASN, DNS name, DNS name with port, or URL (-u/-host).

## `port` (type: `array`):

Target port(s) to connect to (-p/-port). Default 443.

## `scanMode` (type: `string`):

TLS connection mode to use (-sm/-scan-mode).

## `preHandshake` (type: `boolean`):

Enable pre-handshake TLS connection using ztls (-ps/-pre-handshake).

## `scanAllIps` (type: `boolean`):

Scan all resolved IPs for a host (-sa/-scan-all-ips).

## `ipVersion` (type: `array`):

IP version(s) to use (-iv/-ip-version). Values: 4, 6.

## `so` (type: `boolean`):

-so

## `tlsVersion` (type: `boolean`):

-tv/-tls-version

## `cipher` (type: `boolean`):

-cipher

## `hash` (type: `array`):

-hash. Values: md5, sha1, sha256.

## `jarm` (type: `boolean`):

-jarm

## `ja3` (type: `boolean`):

-ja3

## `wildcardCert` (type: `boolean`):

-wc/-wildcard-cert

## `probeStatus` (type: `boolean`):

-tps/-probe-status

## `versionEnum` (type: `boolean`):

-ve/-version-enum

## `cipherEnum` (type: `boolean`):

-ce/-cipher-enum

## `cipherType` (type: `array`):

-ct/-cipher-type. Values: all, secure, insecure, weak.

## `clientHello` (type: `boolean`):

-ch/-client-hello

## `serverHello` (type: `boolean`):

-sh/-server-hello

## `serial` (type: `boolean`):

-se/-serial

## `expired` (type: `boolean`):

-ex/-expired

## `selfSigned` (type: `boolean`):

-ss/-self-signed

## `mismatched` (type: `boolean`):

-mm/-mismatched

## `revoked` (type: `boolean`):

-re/-revoked

## `untrusted` (type: `boolean`):

-un/-untrusted

## `resolvers` (type: `array`):

-r/-resolvers

## `cacert` (type: `string`):

-cc/-cacert (path or inline PEM content, written to a temp file).

## `cipherInput` (type: `array`):

-ci/-cipher-input

## `sni` (type: `array`):

-sni

## `randomSni` (type: `boolean`):

-rs/-random-sni

## `revPtrSni` (type: `boolean`):

-rps/-rev-ptr-sni

## `minVersion` (type: `string`):

-min-version

## `maxVersion` (type: `string`):

-max-version

## `certificate` (type: `boolean`):

-cert/-certificate

## `tlsChain` (type: `boolean`):

-tc/-tls-chain

## `verifyCert` (type: `boolean`):

-vc/-verify-cert

## `hardfail` (type: `string`):

-hf/-hardfail

## `proxy` (type: `string`):

-proxy

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

-c/-concurrency

## `cipherConcurrency` (type: `integer`):

-cec/-cipher-concurrency

## `timeout` (type: `integer`):

-timeout

## `retry` (type: `integer`):

-retry

## `delay` (type: `string`):

-delay (e.g. 200ms, 1s)

## `ctl` (type: `boolean`):

-ctl. Streams newly issued certs. Bounded by maxRuntimeSecs since this mode never terminates on its own.

## `ctlBeginning` (type: `boolean`):

-cb/-ctl-beginning

## `ctlIndex` (type: `array`):

-cti/-ctl-index. Format logURL=index, repeatable.

## `maxRuntimeSecs` (type: `integer`):

Actor-level guard applied via `timeout` when CT log streaming is enabled, since -ctl runs indefinitely.

## `dashboard` (type: `boolean`):

-pd/-dashboard

## `auth` (type: `string`):

-auth

## `teamId` (type: `string`):

-tid/-team-id

## `assetId` (type: `string`):

-aid/-asset-id

## `assetName` (type: `string`):

-aname/-asset-name

## `extraFlags` (type: `string`):

Escape hatch: any additional tlsx flags appended verbatim to the command line.

## Actor input object example

```json
{
  "host": [
    "example.com"
  ],
  "scanMode": "auto",
  "preHandshake": false,
  "scanAllIps": false,
  "so": false,
  "tlsVersion": false,
  "cipher": false,
  "jarm": false,
  "ja3": false,
  "wildcardCert": false,
  "probeStatus": false,
  "versionEnum": false,
  "cipherEnum": false,
  "clientHello": false,
  "serverHello": false,
  "serial": false,
  "expired": false,
  "selfSigned": false,
  "mismatched": false,
  "revoked": false,
  "untrusted": false,
  "randomSni": false,
  "revPtrSni": false,
  "minVersion": "",
  "maxVersion": "",
  "certificate": false,
  "tlsChain": false,
  "verifyCert": false,
  "concurrency": 300,
  "cipherConcurrency": 10,
  "timeout": 5,
  "retry": 3,
  "ctl": false,
  "ctlBeginning": false,
  "maxRuntimeSecs": 60,
  "dashboard": false
}
```

# Actor output Schema

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

Rows produced by the run.

## `rawOutput` (type: `string`):

The tool's unmodified NDJSON output, one JSON object per probed target.

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

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

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

```

## MCP server setup

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

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/ulsO8osUgUToqSfdC/builds/3nAMgKgZGX5Q01gqx/openapi.json
