Check SSL Certificate Expiry With a Free API

2026-04-25 | Tags: ["ssl", "certificates", "monitoring", "api", "security"]

Check SSL Certificate Expiry With a Free API

An expired SSL certificate is one of the most preventable causes of downtime. Your site goes from "secure" to "Your connection is not private" overnight, and users bounce immediately.

Most teams find out when a customer reports it. Here's how to find out before they do.

Quick Check: One Command

curl -s "https://hermesforge.dev/api/ssl?domain=example.com" | python3 -m json.tool

Response:

{
  "domain": "example.com",
  "valid": true,
  "issuer": "DigiCert Inc",
  "subject": "*.example.com",
  "not_before": "2025-01-15T00:00:00Z",
  "not_after": "2026-02-15T23:59:59Z",
  "days_until_expiry": 337,
  "serial_number": "0A:1B:2C:...",
  "san": ["example.com", "*.example.com"]
}

You get the issuer, validity dates, days until expiry, subject alternative names, and whether the cert is currently valid. No API key needed.

Monitor Multiple Domains

#!/bin/bash
# ssl-check.sh — Check SSL expiry for all your domains
DOMAINS=("myapp.com" "api.myapp.com" "docs.myapp.com" "staging.myapp.com")
WARN_DAYS=30

for DOMAIN in "${DOMAINS[@]}"; do
  RESULT=$(curl -s "https://hermesforge.dev/api/ssl?domain=${DOMAIN}")
  DAYS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('days_until_expiry', -1))")
  VALID=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('valid', False))")

  if [ "$VALID" = "False" ]; then
    echo "CRITICAL: $DOMAIN certificate is INVALID"
  elif [ "$DAYS" -lt "$WARN_DAYS" ]; then
    echo "WARNING: $DOMAIN expires in $DAYS days"
  else
    echo "OK: $DOMAIN ($DAYS days remaining)"
  fi
done

Run it daily via cron:

0 9 * * * /home/user/ssl-check.sh >> /var/log/ssl-check.log

Common Scenarios

Let's Encrypt Auto-Renewal Failures

Let's Encrypt certificates expire every 90 days. Certbot usually handles renewal, but it can silently fail:

A daily SSL check catches these before your users do.

Wildcard Certificates Covering Multiple Services

If you use *.myapp.com, checking just one subdomain isn't enough. The cert might be valid but misconfigured on a specific service:

# Check that all services actually serve the right cert
for SUB in www api docs admin; do
  curl -s "https://hermesforge.dev/api/ssl?domain=${SUB}.myapp.com" | \
    python3 -c "import sys,json; d=json.load(sys.stdin); print(f'{d[\"domain\"]}: {d[\"days_until_expiry\"]}d, issuer={d[\"issuer\"]}')"
done

Certificate Chain Issues

Sometimes the leaf certificate is valid but intermediate certificates are missing or expired. The API checks the full chain as presented by the server.

Integrating With Other Checks

Combine SSL monitoring with uptime and dead link checks for a complete site health dashboard:

#!/bin/bash
SITE="myapp.com"
URL="https://${SITE}"
BASE="https://hermesforge.dev"

echo "=== Site Health Report: $SITE ==="
echo "Generated: $(date -u)"
echo ""

# SSL Check
SSL=$(curl -s "${BASE}/api/ssl?domain=${SITE}")
DAYS=$(echo "$SSL" | python3 -c "import sys,json; print(json.load(sys.stdin).get('days_until_expiry', '?'))")
echo "SSL: ${DAYS} days until expiry"

# Uptime Check
STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$URL")
echo "HTTP: ${STATUS}"

# Dead Links
BROKEN=$(curl -s "${BASE}/api/deadlinks?url=${URL}" | \
  python3 -c "import sys,json; print(len(json.load(sys.stdin).get('broken_links',[])))")
echo "Broken links: ${BROKEN}"

# Tech Stack
TECH=$(curl -s "${BASE}/api/techstack?url=${URL}" | \
  python3 -c "import sys,json; d=json.load(sys.stdin); techs=d.get('technologies',[]); print(', '.join([t['name'] for t in techs[:5]]))")
echo "Stack: ${TECH}"

Why Use an API Instead of OpenSSL?

The classic way to check SSL expiry:

echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

This works, but:

API OpenSSL
Output format Structured JSON Raw text (needs parsing)
Days until expiry Calculated for you Manual date math
SAN list Included Extra command needed
Chain validation Automatic Manual flags
Works in CI/CD Yes (just curl) Needs openssl installed
Scriptable JSON + jq sed/awk/grep

For quick one-off checks, OpenSSL is fine. For automated monitoring scripts, structured JSON saves time.

Rate Limits

The SSL API is free with no signup: 5 requests per minute without an API key, 20 per minute with a free key. For monitoring a dozen domains daily, no key needed.


Try it now: curl -s "https://hermesforge.dev/api/ssl?domain=google.com" | python3 -m json.tool