# SSL Certificate Checker: Bulk Expiry & Domain Expiry Monitor (`datawright-labs/ssl-certificate-checker`) Actor

SSL certificate expiry check for any list of domains: days until expiry, issuer, trust and hostname errors, TLS version, plus domain expiry via RDAP. Flags expired, expiring and invalid certificates. Callable by AI agents via MCP. $1 per 1,000 hosts; unreachable hosts free.

- **URL**: https://apify.com/datawright-labs/ssl-certificate-checker.md
- **Developed by:** [Datawright Labs](https://apify.com/datawright-labs) (community)
- **Categories:** Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 host checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

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

**For AI agents:** Use when asked to check SSL certificates, find certs expiring soon, debug a certificate error, or check when domains expire. Call with `domains` (domains or URLs; required), optional `warnDays` (default 30), `checkDomainExpiry` (RDAP, default on), `onlyProblems: true` to return only hosts that need attention, `port`. Returns one row per host: `host`, `status`, `daysUntilExpiry`, `validTo`, `issuer`, `domainDaysUntilExpiry`, `registrar`, `tlsVersion`, `problems` (expired, expiring, untrusted, hostname mismatch). Cost: $0.001 per host checked ($1 per 1,000); unreachable hosts free.

**For people:** Ask your agent "check the SSL certificates on these 20 domains and tell me which expire in the next 30 days" and it checks them all here and replies with just the ones to renew, plus any domain registrations about to lapse. 1,000 hosts cost $1.

**Check SSL certificates for hundreds or thousands of domains in one run.** Paste a list of domains or URLs and this SSL certificate checker connects to each one, reads the TLS certificate and tells you **how many days are left until it expires**, who issued it, which hostnames it covers, whether the chain is **trusted**, whether the **hostname matches**, and which **TLS version and cipher** the server negotiates. It also looks up the **domain registration expiry date and registrar** (via RDAP, the official successor to WHOIS), so one scheduled run catches both an expiring certificate and an expiring domain.

No agents to install, no monitoring subscription: it runs in the cloud, exports to **CSV, Excel, JSON or Google Sheets**, and can run on a **daily or weekly schedule** with an email, Slack or webhook alert when anything turns red.

### What does this SSL checker do?

- 🔐 **Certificate details** for every host: subject, issuer and issuer organization, valid-from / valid-to dates, **days until expiry**, serial number, SHA-256 fingerprint, key type and size (RSA/EC), all DNS **SANs** and wildcard detection.
- 🚦 **Status per host**: `ok`, `expiring` (within your warning window, default 30 days), `expired`, `invalid` (untrusted chain, self-signed, or hostname not covered) or `error` (unreachable / no TLS).
- 🧾 **Plain-English problems list**, e.g. "Certificate expires in 12 days", "Hostname not covered by certificate", "Not trusted: UNABLE_TO_VERIFY_LEAF_SIGNATURE", "Outdated protocol TLSv1.1".
- 🌐 **Domain expiry check** (RDAP): registration expiry date, days left, registration date and registrar of the registrable domain.
- 🔗 **Chain and protocol**: certificate chain, negotiated TLS version, cipher, ALPN (HTTP/2 support) and handshake time.
- 🧹 **Bulk-friendly**: accepts bare domains, URLs and custom ports (`host:8443`), removes duplicates, checks 10-50 hosts in parallel.
- 📊 A **SUMMARY** record with counts by status, ideal for dashboards and alerts.

### Use cases

- **SSL expiry monitoring** for all your company's domains and subdomains, without a paid uptime tool.
- **Agencies and MSPs**: one weekly job over every client site, exported to Google Sheets.
- **Domain portfolio management**: spot domains about to lapse and certificates about to expire in the same report.
- **Security and compliance audits**: find self-signed, untrusted, mismatched or TLS 1.0/1.1 endpoints.
- **Competitor and vendor research**: see which CA and certificate type a list of sites uses.

### How to use it

1. Paste domains or URLs into **Domains or URLs**, one per line.
2. Optionally change **Warn when expiring within (days)** and turn **Only output problems** on for alert-style runs.
3. Click **Start**, then open the **Overview** table or export it. For monitoring, add a **Schedule** (e.g. daily) and an integration (email, Slack, webhook) in Apify Console.

#### Input example

```json
{
  "domains": ["example.com", "shop.example.com", "https://api.example.org:8443"],
  "warnDays": 30,
  "checkDomainExpiry": true,
  "onlyProblems": false
}
```

### Output example

```json
{
  "host": "github.com",
  "port": 443,
  "url": "https://github.com",
  "status": "ok",
  "problems": [],
  "daysUntilExpiry": 39,
  "validFrom": "2026-03-06T00:00:00.000Z",
  "validTo": "2026-11-29T23:59:59.000Z",
  "issuer": "Sectigo Public Server Authentication CA DV E36",
  "issuerOrganization": "Sectigo Limited",
  "subject": "github.com",
  "trusted": true,
  "hostnameMatch": true,
  "sans": ["github.com", "www.github.com"],
  "wildcard": false,
  "chainLength": 2,
  "keyType": "EC",
  "tlsVersion": "TLSv1.3",
  "cipher": "TLS_AES_128_GCM_SHA256",
  "alpn": "h2",
  "registrableDomain": "github.com",
  "domainExpiry": "2028-10-09T18:20:50Z",
  "domainDaysUntilExpiry": 718,
  "registrar": "MarkMonitor Inc.",
  "checkedAt": "2026-10-21T22:30:00.000Z"
}
```

### How much does it cost to check SSL certificates?

You pay **$0.001 per host checked** ($1 per 1,000), including the domain expiry lookup. Hosts that can't be reached are **free**, and with **Only output problems** on, healthy hosts are skipped and **free** too. No start fee.

| Job | Hosts | Cost |
|---|---|---|
| Your 20 domains, checked daily | ~600/month | **~$0.60/month** |
| 500 client sites, weekly | ~2,000/month | **~$2/month** |
| One-off audit of 10,000 domains | 10,000 | **$10** |

- Apify's **free plan includes $5 of monthly credit**, enough for about **5,000 checks a month**.
- Paid Apify plans get automatic discounts: **Silver -10%**, **Gold and above -20%**.
- Set **Maximum cost per run** to cap spend; the Actor stops cleanly at the limit.

### SSL checker vs. the alternatives

| | This Actor | Free online SSL checkers | Uptime / SSL monitoring SaaS |
|---|---|---|---|
| Bulk lists (thousands of hosts) | ✅ | ❌ one at a time | by plan |
| Certificate + domain expiry in one report | ✅ | ❌ | sometimes |
| API, schedules, webhooks, Google Sheets | ✅ | ❌ | partial |
| Cost model | $1 per 1,000 checks, no subscription | free, manual | monthly subscription per monitor |

### Use it as an API (Python, JavaScript, cURL)

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("datawright-labs/ssl-certificate-checker").call(run_input={"domains": ["example.com", "example.org"], "warnDays": 30})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["host"], item["status"], item.get("daysUntilExpiry"), item.get("domainDaysUntilExpiry"))
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/datawright-labs~ssl-certificate-checker/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" -d '{"domains":["example.com"],"onlyProblems":true}'
```

### Use it from your AI agent (MCP)

Your AI assistant or agent can run this Actor as a tool through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp), so it can run SSL certificate and domain expiry checks on its own while you chat. Add this server to any MCP client that supports remote (Streamable HTTP) servers:

```json
{
  "mcpServers": {
    "datawright-ssl-certificate-checker": {
      "url": "https://mcp.apify.com?tools=datawright-labs/ssl-certificate-checker"
    }
  }
}
```

On first use your browser opens to sign in to Apify (OAuth). If your client can't do OAuth, add `"headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }` instead. The tool shows up as `datawright-labs--ssl-certificate-checker`, with the same input fields as above, and the agent reads the results with `get-dataset-items`. Then just ask, for example:

> Check the SSL certificates on these 20 domains and tell me which expire in the next 30 days.

Want several Datawright tools at once? Comma-separate them: `https://mcp.apify.com?tools=datawright-labs/ssl-certificate-checker,datawright-labs/pagespeed-auditor`. Runs are billed per result, exactly like normal runs.

### FAQ

#### How do I check when an SSL certificate expires?

Add the domain and run the Actor: `validTo` is the exact expiry time and `daysUntilExpiry` the days left. Anything within `warnDays` gets status `expiring`.

#### Can I monitor SSL certificate expiry for many domains automatically?

Yes. Create a Schedule in Apify Console (daily is typical), turn on **Only output problems**, and connect an email, Slack or webhook integration so you're only notified when something needs attention.

#### Does it check domain expiry (WHOIS) too?

Yes, via RDAP, the structured replacement for WHOIS run by the registries. A few country-code TLDs don't publish RDAP yet; those rows include `domainError` and still get the full certificate check.

#### Why is a certificate "invalid" when my browser shows it fine?

Usually the server doesn't send its intermediate certificate (browsers sometimes fetch it themselves, many API clients don't), or the hostname isn't in the SANs. `trustError` gives the exact reason.

#### Does it support custom ports and subdomains?

Yes: enter `host:port` or a full URL like `https://mail.example.com:8443`. Each subdomain is checked separately; domain expiry is looked up once per registrable domain.

### More tools from Datawright Labs

- [Sitemap URL Extractor](https://apify.com/datawright-labs/sitemap-url-extractor): get every URL of a site from its sitemaps.
- [Bulk PageSpeed & Core Web Vitals Checker](https://apify.com/datawright-labs/pagespeed-auditor): audit PageSpeed / Lighthouse scores for many URLs.
- [Website Screenshot API](https://apify.com/datawright-labs/website-screenshot): bulk full-page screenshots and PDFs.
- [Google Autocomplete Keyword Scraper](https://apify.com/datawright-labs/autocomplete-keyword-scraper): long-tail keyword ideas from Google, YouTube and Bing.
- [Greenhouse, Lever & Ashby Jobs Scraper](https://apify.com/datawright-labs/ats-jobs-scraper): normalized job feeds from 5 ATS platforms.
- [App Store Top Charts & Rank Tracker](https://apify.com/datawright-labs/app-store-top-charts): daily top free/paid/grossing app rankings with rank changes.
- [Broken Link Checker](https://apify.com/datawright-labs/broken-link-checker): find 404s and dead links on any website, by source page.
- [SPF, DMARC & DKIM Checker](https://apify.com/datawright-labs/email-domain-dns-checker): bulk email domain audit of SPF (10-lookup limit), DMARC, DKIM, MX provider, BIMI and MTA-STS.

Made by **Datawright Labs**: reliable, fairly priced web data tools. Questions or a missing feature? Open an issue on the Issues tab; we usually reply within a day.

# Actor input Schema

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

Hostnames or URLs to check, one per line (e.g. example.com, https://shop.example.com:8443). Duplicates are removed.

## `warnDays` (type: `integer`):

Certificates (and domains) that expire within this many days get status "expiring".

## `checkDomainExpiry` (type: `boolean`):

Look up the registrable domain's expiry date and registrar via the public RDAP system. Some ccTLDs don't publish RDAP; those rows get domainError.

## `onlyProblems` (type: `boolean`):

Save only hosts that are expired, expiring, invalid or unreachable. Healthy hosts are skipped and not charged.

## `port` (type: `integer`):

Port used when an entry has no explicit port.

## `timeoutSecs` (type: `integer`):

TLS handshake and RDAP timeout.

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

How many hosts to check at the same time.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "github.com",
    "expired.badssl.com"
  ],
  "warnDays": 30,
  "checkDomainExpiry": true,
  "onlyProblems": false,
  "port": 443,
  "timeoutSecs": 15,
  "concurrency": 10
}
```

# Actor output Schema

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

Per-host certificate and domain expiry results.

## `summary` (type: `string`):

SUMMARY record: hosts checked and counts by status.

# 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",
        "github.com",
        "expired.badssl.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datawright-labs/ssl-certificate-checker").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",
        "github.com",
        "expired.badssl.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("datawright-labs/ssl-certificate-checker").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",
    "github.com",
    "expired.badssl.com"
  ]
}' |
apify call datawright-labs/ssl-certificate-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datawright-labs/ssl-certificate-checker"
        }
    }
}
```

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/srfLepnzJc3Bxob8x/builds/D8gK8yha0kstgBV32/openapi.json
