# Domain Risk Report: SSL, Subdomains & Tech (`m_ctim/domain-website-risk-report`) Actor

One report per domain: registration/expiration status, SSL certificate health, subdomains discovered via Certificate Transparency logs, and the live site's tech stack, with a computed list of risk flags. Built for security, IT, and vendor-risk teams.

- **URL**: https://apify.com/m\_ctim/domain-website-risk-report.md
- **Developed by:** [Timothy Kelvin](https://apify.com/m_ctim) (community)
- **Categories:** Other
- **Stats:** 1 total users, 0 monthly users, 0.0% 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

## Domain & Website Risk Report: Expiration, SSL, Subdomains & Tech Stack

Give it a domain. Get back one combined report, covering registration and
expiration status, SSL certificate health, subdomains discovered via
Certificate Transparency logs, the live site's detected tech stack, and a
short list of computed risk flags: everything you'd otherwise check across
four separate tools, in one call.

### Who this is for

- **Security and IT teams** doing a quick external risk pass on a domain: their own, or before onboarding a vendor.
- **M\&A and vendor-risk due diligence** checking a target company's web presence health without four separate lookups.
- **Agencies and consultants** auditing a client's or prospect's domain before a pitch.

### Input

| Field | Type | Description |
|---|---|---|
| `domains` | array | Bare domains, e.g. `["example.com"]`: not full URLs. |
| `includeTechStack` | boolean (default `true`) | Fetch the homepage and detect CMS, ecommerce, JS framework, analytics, CDN, payment, and live-chat signatures. |
| `includeSubdomains` | boolean (default `true`) | Search Certificate Transparency logs for subdomains. |
| `maxSubdomains` | integer (default `20`) | Cap on discovered subdomains returned. |
| `ctDaysBack` | integer (default `365`) | How far back to search Certificate Transparency logs. |

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

### Output

One record per domain:

```json
{
  "domain": "example.com",
  "registration": {
    "registered": true,
    "registrar": "Example Registrar, Inc.",
    "creationDate": "1995-08-14T04:00:00Z",
    "expirationDate": "2027-08-13T04:00:00Z",
    "daysUntilExpiration": 328,
    "nameservers": ["a.iana-servers.net", "b.iana-servers.net"]
  },
  "ssl": {
    "reachable": true,
    "subjectCN": "example.com",
    "issuerCN": "DigiCert Global G2 TLS RSA SHA256 2020 CA1",
    "validTo": "2027-01-15T23:59:59.000Z",
    "daysUntilExpiration": 118,
    "isExpired": false,
    "isSelfSigned": false,
    "trustedByNode": true
  },
  "subdomains": {
    "discovered": ["www.example.com", "mail.example.com"],
    "totalCertificatesFound": 14
  },
  "techStack": {
    "reachable": true,
    "detected": { "cdnHosting": ["Cloudflare"], "analytics": [], "cms": [] },
    "server": "cloudflare"
  },
  "riskFlags": [],
  "checkedAt": "2026-09-19T12:00:00.000Z"
}
```

`riskFlags` is a short list of plain-text flags computed from the other
sections: e.g. `ssl-certificate-expires-within-30-days`,
`domain-registration-expired`, `ssl-certificate-self-signed`,
`https-unreachable`. An empty array means nothing flagged.

### How it works

Four independent, direct checks per domain, no scraping beyond the site's
own homepage and no proxy:

1. **RDAP** (the modern WHOIS replacement) for registration/expiration.
2. **A direct TLS handshake** against port 443 for certificate health and trust chain validation.
3. **crt.sh** (public Certificate Transparency log search) for subdomain discovery.
4. **One fetch of the domain's own homepage** for tech-stack signature detection: same signature set as [Website Tech Stack Detector](https://github.com/timmKal01/website-tech-stack-detector).

Each check runs independently and reports its own failure without failing
the others: e.g. a domain with no live website still gets a full
registration and SSL report, with `techStack.reachable: false`.

### Pricing note

Billed per **domain**, not per individual check performed. One charge covers the full report for that domain, registration and expiration, SSL certificate health, subdomain discovery via Certificate Transparency logs, and tech stack detection, rather than four separate charges for what would otherwise be four separate lookups.

### Related products

- [Domain Expiration Tracker](https://github.com/timmKal01/domain-expiration-tracker): registration/expiration only, for bulk monitoring across many domains
- [SSL Certificate Expiry Checker](https://github.com/timmKal01/ssl-certificate-expiry-checker): certificate health only, any host:port
- [Certificate Transparency Monitor](https://github.com/timmKal01/certificate-transparency-monitor): raw CT log search with more filtering options
- [Website Tech Stack Detector](https://github.com/timmKal01/website-tech-stack-detector): tech-stack detection across multiple URLs/pages, not scoped to one domain's risk profile

# Actor input Schema

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

Domains to build a risk report for, e.g. "example.com". A bare domain, not a full URL.

## `includeTechStack` (type: `boolean`):

Fetch the site's homepage and detect CMS, ecommerce platform, JS framework, analytics, CDN, payment, and live-chat signatures.

## `includeSubdomains` (type: `boolean`):

Search Certificate Transparency logs (crt.sh) for subdomains that have had a certificate issued.

## `maxSubdomains` (type: `integer`):

Cap on discovered subdomains listed per domain.

## `ctDaysBack` (type: `integer`):

How far back to search Certificate Transparency logs for subdomain discovery.

## Actor input object example

```json
{
  "domains": [
    "apify.com"
  ],
  "includeTechStack": true,
  "includeSubdomains": true,
  "maxSubdomains": 20,
  "ctDaysBack": 365
}
```

# Actor output Schema

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

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("m_ctim/domain-website-risk-report").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"] }

# Run the Actor and wait for it to finish
run = client.actor("m_ctim/domain-website-risk-report").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"
  ]
}' |
apify call m_ctim/domain-website-risk-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,m_ctim/domain-website-risk-report"
        }
    }
}
```

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/Yq6EtDrdHdeaXvLan/builds/mbIz0h78at3EhDK4w/openapi.json
