CertGuard API

← checker

GET /api/v1/check

curl 'https://certguard.mike-tusa.workers.dev/api/v1/check?host=example.com'
curl 'https://certguard.mike-tusa.workers.dev/api/v1/check?host=mail.example.com&port=993'

Parameters: host (hostname, IP, or https:// URL — required), port (443 default; allowed: 443, 8443, 465, 993, 995).

POST /api/v1/check

curl -X POST 'https://certguard.mike-tusa.workers.dev/api/v1/check' -H 'content-type: application/json' -d '{"host":"example.com","port":443}'

JSON body, max 16 KB (larger → 413).

Response (abridged)

{
  "ok": true, "status": "checked", "host": "example.com", "port": 443,
  "revocation_checked": false,
  "source": { "method": "live_tls_handshake" | "certificate_transparency", "live": true, ... },
  "grade": "A", "summary": "...",
  "expiry": { "notBefore", "notAfter", "daysRemaining", "status": "ok|warning|critical|expired|not_yet_valid" },
  "certificate": { "subject", "issuer", "sans", "key": {"type","bits","curve"}, "signatureAlgorithm", "sha256Fingerprint", ... },
  "hostname": { "matches": true, "matchedName": "*.example.com" },
  "tls": { "version": "TLS 1.3", "cipherSuite", "keyExchangeGroup", "alpn", "ocspStapled" },
  "chain": { "complete": true, "trusted": true, "trustAnchor", "certificates": [ ... ] },
  "issues": [ { "severity", "code", "message" } ],
  "notChecked": [ "revocation (OCSP/CRL status)", ... ],
  "cache": { "hit": false, "ttlSeconds": 600 }
}

// failed live check (HTTP 502) — never graded, never cached
{ "ok": false, "status": "check_failed", "grade": null, "revocation_checked": false,
  "error": { "code": "check_failed", "reason": "connect_timeout", "message": "..." },
  "source": { "attempts": [ { "offered": "TLS 1.3+1.2", "result": "connect_timeout", ... } ] } }

Status thresholds: warning < 30 days, critical < 7 days. Grades: A (good), B (expires <30d or no TLS 1.3), C (expires <7d, weak key, TLS <1.2), F (expired or not yet valid, wrong host, untrusted/self-signed, incomplete chain, expired or SHA-1/MD5-signed intermediate, issuer_not_ca — an issuing certificate that isn't a CA or lacks keyCertSign, path_len_exceeded — a CA pathLen constraint violated). No grade (null) for check_failed and live_unavailable.

Every result carries "revocation_checked": false. Grades and summaries describe expiry, chain and hostname only.

Failed checks get no grade. If the live handshake can't complete (port closed/filtered, timeout, server rejects every cipher we offer, oversized certificate message, not TLS…), the API returns 502 with "status": "check_failed", "grade": null and the attempts made. These are never cached.

Cloudflare-hosted sites. Cloudflare Workers cannot open TCP sockets to Cloudflare's own IP ranges. For those hosts — and only those — the API returns "status": "live_unavailable", "grade": null (HTTP 422, or 503 if temporary). When a Certificate Transparency fallback is enabled on the deployment (it is not, currently), for hosts on Cloudflare's published IP list it instead returns the newest certificate logged in public CT logs with source.method = "certificate_transparency", source.live = false and gradeEstimated: true: inferred, not observed. If the Workers runtime refuses the socket to an address that is not on Cloudflare's published IP list, the reason is socket_blocked (platform restriction or transient runtime error); that answer gets no grade, never uses CT and is never cached, so a retry re-checks.

What we don't check: sites hosted behind Cloudflare (a large share of the web) can't be checked live; certificate revocation (OCSP/CRL) — a revoked certificate can still get a passing grade here; whether the server also accepts old TLS 1.0/1.1; and full cipher-suite enumeration.

Limits & free API keys

Anonymous: 10 checks/minute per IP. With a free key (X-API-Key header): 60/minute and 1000/day.

curl -X POST 'https://certguard.mike-tusa.workers.dev/api/v1/keys' -H 'content-type: application/json' -d '{"email":"you@example.com"}'
curl -H 'X-API-Key: cg_...' 'https://certguard.mike-tusa.workers.dev/api/v1/check?host=example.com'
curl -H 'X-API-Key: cg_...' 'https://certguard.mike-tusa.workers.dev/api/v1/usage'

Anonymous use is also capped at 200 checks/day per IP (IPv6: per /64, and 600/day per /48). All keys issued to the same IP (or IPv6 /64) share a combined 1000 checks/day. email is optional contact info and is not verified; keys are limited per IP per day. “Live check unavailable” (422) answers are cached per host for 10 minutes and blocked-target (403) answers for 5 minutes; failed checks (502) are never cached.

Errors: 400 invalid input, 401 bad key, 403 blocked target (private/internal), 405 wrong method, 413 body too large, 415 keys endpoint needs JSON, 422 not resolvable / live check unavailable, 429 rate limit or daily cap, 502 check failed (no grade), 503 temporarily unavailable.

MCP server for AI agents

POST https://certguard.mike-tusa.workers.dev/mcp — remote MCP (Streamable HTTP, stateless, JSON responses). One read-only tool, check_certificate (host, optional port and include_raw). Same keys, limits and cache as /api/v1/check; each tools/call is one check. Keys may be sent as X-API-Key or Authorization: Bearer (on the JSON API too). Machine-readable: /llms.txt, /openapi.json.

Other

GET /health — service status. /sitemap.xml, /robots.txt.