API 레퍼런스

인프라 모니터링에 대한 프로그래밍 방식 제어

Certack REST API는 SSL/TLS 인증서, DNS 레코드, 도메인 만료, 알림, 통합에 대한 프로그래밍 방식의 제어를 제공합니다. 모든 엔드포인트는 JSON을 사용하며 https://app.certack.com/api에서 액세스할 수 있습니다.

기본 URL
https://app.certack.com
인증
Bearer sp_...
형식
application/json
버전
v1

시작하기

Welcome to the Certack API. This guide walks you from zero to your first monitored site in a few minutes — no prior setup required. You'll learn how to create an account, generate an API key, run your first SSL check, wire up alert channels, receive webhooks, and even plug AI assistants into your monitoring workflow via MCP.

The Certack REST API lets you programmatically monitor SSL/TLS certificates, DNS records, and domain expiry — all from your own scripts, CI/CD pipelines, or internal tools.

1

Create an account

Sign up for a free account at /auth/signup. The Free plan includes 2 monitored sites and 100 API calls per month — no credit card required.

2

Generate an API key

Once logged in, create an API key via the dashboard or the API itself. API keys start with sp_ and are shown only once — store them securely.

Create an API key

bash
curl -X POST https://app.certack.com/api/api-keys \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{"name": "Production Monitoring"}'

Response (201 Created)

json
{
  "key": "sp_a1b2c3d4e5f6g7h8i9j0...",
  "name": "Production Monitoring",
  "created_at": "2026-06-23T10:00:00Z"
}

Important: The full key is returned only once. Save it immediately — you won't be able to see it again.

3

Make your first API call

Add a site to monitor, then run a check. Pick your language — switch tabs to see the same call in cURL, Python, Go, or TypeScript.

# Add a site to monitor
curl -X POST https://app.certack.com/api/sites \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com", "check_types": ["ssl", "dns", "domain"]}'

Now run an SSL check on the site you just added:

# Check SSL/TLS certificate
curl -X POST https://app.certack.com/api/check-ssl \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'

Response (200 OK)

json
{
  "valid": true,
  "domain": "example.com",
  "issuer": "Let's Encrypt R3",
  "issuer_org": "Let's Encrypt",
  "valid_from": "2026-06-01T00:00:00Z",
  "valid_to": "2026-09-01T00:00:00Z",
  "days_remaining": 70,
  "san": ["example.com", "www.example.com"],
  "error": null
}
4

Receive alerts in Slack, Discord, or Teams

Certack pushes alerts to your chat channels the moment an issue is detected — no polling required. Configure your webhook URLs via the Notifications API or the dashboard at Dashboard → Settings → Notifications.

Slack

Create an incoming webhook at api.slack.com/messaging/webhooks, then set slack_webhook_url. Available on Team plan and above.

curl -X PATCH https://app.certack.com/api/settings/notifications \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slack_webhook_url": "https://hooks.slack.com/services/T.../B.../..."}'

Microsoft Teams

In Teams, go to a channel → Connectors → Incoming Webhook, copy the URL, then set teams_webhook. Available on Team plan and above.

curl -X PATCH https://app.certack.com/api/settings/notifications \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"teams_webhook": "https://outlook.office.com/webhook/..."}'

Discord

In Discord, go to a channel → Edit Channel → Integrations → Webhooks → New Webhook, copy the URL, then set discord_webhook_url. Available on Team plan and above.

curl -X PATCH https://app.certack.com/api/settings/notifications \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"discord_webhook_url": "https://discord.com/api/webhooks/.../..."}'

Email

Enable email alerts with a single flag. Available on Pro plan and above.

curl -X PATCH https://app.certack.com/api/settings/notifications \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": true}'

Send a test notification to verify your channels are configured correctly:

curl -X POST https://app.certack.com/api/settings/notifications \
  -H "Authorization: Bearer sp_YOUR_KEY"
5

Receive alerts via webhook

For custom integrations (incident management, automation, dashboards), set a custom_webhook_url and Certack will POST event payloads to your endpoint in real time. See the Webhooks section for the full payload schema and event types.

curl -X PATCH https://app.certack.com/api/settings/notifications \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"custom_webhook_url": "https://your-app.com/webhook/certack"}'

Here's a minimal webhook receiver in Node.js / Express that acknowledges receipt and routes by event type:

webhook-receiver.js

ts
import express from "express";

const app = express();
app.use(express.json());

app.post("/webhook/certack", (req, res) => {
  const { source, timestamp, alerts } = req.body;

  // Verify the source
  ifsource !== "Certack") {
    return res.status(400).send("Invalid source");
  }

  // Process each alert
  forconst alert of alerts) {
    switchalert.type) {
      case "ssl.expiring":
      case "ssl.expired":
        // Page the on-call engineer
        console.log(`[${alert.severity}] ${alert.domain}: ${alert.message}`);
        break;
      case "dns.changed":
        // Log for security review
        console.log(`DNS change on ${alert.domain}: ${alert.message}`);
        break;
      default:
        console.log(`Unknown event: ${alert.type}`);
    }
  }

  // Always respond with 2xx to acknowledge receipt
  res.status(200).send("OK");
});

app.listen(3000, () => console.log("Webhook receiver on :3000"));
6

Connect AI assistants via MCP

Certack exposes a Model Context Protocol (MCP) endpoint at /api/mcp so AI assistants like Claude can query your monitoring data directly. Authenticate with your API key as a Bearer token. See the MCP section for the full method reference.

# List available MCP tools
curl -X POST https://app.certack.com/api/mcp \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

To use Certack with Claude Desktop, add it to your MCP config:

claude_desktop_config.json

json
{
  "mcpServers": {
    "certack": {
      "url": "https://app.certack.com/api/mcp",
      "headers": {
        "Authorization": "Bearer sp_YOUR_KEY"
      }
    }
  }
}

Once configured, you can ask Claude things like "Check the SSL certificate for example.com" or "Which of my sites are expiring this week?" — Claude will call the Certack MCP tools automatically.

Next steps

You're set up — now explore the rest of the API. These are the most common endpoints to integrate next:

인증

Every authenticated endpoint expects a Bearer token in the Authorization header. Certack accepts two token types — API keys (recommended for automation) and Supabase JWTs (issued by dashboard sessions). Both are sent the same way, so you can swap them without changing your client code.

Header format

bash
Authorization: Bearer sp_YOUR_API_KEY

API Keys — Built for programmatic access. Create and manage them via the API Keys endpoint. Available on every plan with per-plan limits. The full key value is returned only once at creation time — store it immediately in a secrets manager.

JWT — Short-lived session tokens issued by the Certack dashboard login flow. Useful for browser-based flows, but they expire and are not suitable for long-lived automation or CI/CD.

Security tip: Never embed API keys in client-side code or commit them to version control. Always route through a backend service or a secrets manager. If a key is compromised, delete it immediately via DELETE /api/api-keys?id=... — scripts using the revoked key will lose access instantly.

로그인 및 가입

Certack uses Supabase Auth (email/password, GitHub OAuth) with browser-based OAuth redirects. Authentication issues a short-lived session token that you can send as a Bearer token to other API endpoints.

SaaS (hosted)
Supabase Auth (email/password, magic link)
OAuth: GitHub
Session via HTTP-only cookie
OAuthGitHub (SaaS)

On the hosted SaaS, GitHub sign-in is handled by Supabase Auth via browser redirects — there is no REST endpoint that returns a token directly. Instead, the browser is redirected to the provider's consent screen, then back to /auth/callback, which exchanges the authorization code for a session and stores it in an HTTP-only cookie.

OAuth Flow

  1. Client calls supabase.auth.signInWithOAuth({ provider: "github" })
  2. Browser redirects to the provider's OAuth consent screen
  3. Provider redirects back to /auth/callback?code=...
  4. Server exchanges the code for a session via exchangeCodeForSession()
  5. Anti-abuse IP check runs; welcome email is sent for new users
  6. Browser is redirected to /dashboard (or the next param)

Client-side example (browser)

Trigger GitHub login from the browser

ts
import { createClient } from "@supabase/supabase-js";

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);

// GitHub
await supabase.auth.signInWithOAuth({
  provider: "github",
  options: { redirectTo: `${window.location.origin}/auth/callback` },
});

Note: OAuth providers must be enabled in your Supabase project (Authentication → Providers). The callback URL registered with the provider should be https://app.certack.com/auth/callback.

GET/api/auth/welcome

Pre-signup anti-abuse check. Call this before creating a new account to verify the requesting IP is allowed to register. Returns 403 with a reason if the IP has created too many free accounts.

FieldTypeDescription
allowedbooleantrue if signup is permitted from this IP
reasonstringPresent only when allowed is false (403 response)
curl https://app.certack.com/api/auth/welcome
POST/api/auth/welcome

Trigger the welcome email for a newly signed-up user (idempotent — only sends if the user was created within the last 5 minutes). Called automatically by the signup page after a successful email/password registration.

FieldTypeDescription
sentbooleantrue if the welcome email was sent
curl -X POST https://app.certack.com/api/auth/welcome \
  -H "Authorization: Bearer YOUR_JWT"
SESSIONLogout

Logout is handled client-side. Call supabase.auth.signOut() to clear the session cookie.

Logout (browser)

ts
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
await supabase.auth.signOut();
window.location.href = "/auth/login";

속도 제한

Certack enforces two layers of rate limiting to keep the service fair and stable: a short-term per-minute throttle (protects the API from bursts) and a monthly call quota (tied to your plan). Hitting either limit returns 429 Too Many Requests with a Retry-After header telling you exactly when to retry.

Per-minute throttle
Public endpoints: 10 req/min per IP
Authenticated: 60 req/min per IP (middleware)
QPS (per 10-second window)
Free: 10 (1 req/s)
Starter: 50 (5 req/s)
Pro: 100 (10 req/s)
Team: 300 (30 req/s)
Monthly call quota
Free: 100
Starter: 2,000
Pro: 10,000
Team: 50,000

Rate Limit Response Headers

Every API response includes these headers so you can proactively throttle your client before hitting the limit:

FieldTypeDescription
X-RateLimit-LimitintegerMaximum requests per minute
X-RateLimit-RemainingintegerRemaining requests in current window
X-RateLimit-ResetintegerUnix timestamp when the window resets
X-MonthlyLimit-LimitintegerMonthly API call limit for your plan
X-MonthlyLimit-UsedintegerAPI calls used this month
X-MonthlyLimit-RemainingintegerAPI calls remaining this month

사이트

A site is the central object in Certack — it represents a domain you want to monitor. Each site carries its own check types (ssl, dns,domain, ct), alert thresholds, and optional deployment configuration for automated certificate renewal. All check results, alerts, and history are scoped to a site, so creating and managing sites is usually your first step.

GET/api/sites

Returns all monitored sites for the authenticated user, along with the current plan and user ID.

Response

FieldTypeDescription
sitesSite[]Array of site objects
planstringCurrent plan: free, pro, team
userIdstringAuthenticated user UUID

Response example

json
{
  "sites": [
    {
      "id": "a1b2c3d4-...",
      "domain": "example.com",
      "check_types": ["ssl", "dns", "domain"],
      "alert_days": 14,
      "monitoring_enabled": true
    }
  ],
  "plan": "pro",
  "userId": "user-uuid-..."
}
curl https://app.certack.com/api/sites \
  -H "Authorization: Bearer sp_YOUR_KEY"
POST/api/sites

Add a new site to monitor. Returns the created site object.

Request Body

ParameterTypeRequiredDescription
domainstringYesDomain to monitor (e.g. example.com)
custom_portnumberNoCustom port for SSL check (1-65535, default 443)
origin_ipstringNoOverride DNS-resolved IP for SSL check
alert_daysnumberNoDays before expiry to alert (1-365, default 14)
check_typesstring[]NoTypes to monitor: ssl, dns, domain
dns_providerstringNoDNS provider for ACME challenges (e.g. cloudflare)
dns_provider_configobjectNoDNS provider credentials/config
deploy_targetstringNoDeployment target: download, cloudflare, etc.
deploy_configobjectNoDeployment configuration

Response

FieldTypeDescription
siteSiteThe created site object with id, domain, check_types, etc.
curl -X POST https://app.certack.com/api/sites \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"example.com","check_types":["ssl","dns","domain"]}'
PATCH/api/sites?id=<site_id>

Update site configuration. Only include fields you want to change. Returns the updated site object.

Query Parameters

ParameterTypeRequiredDescription
idstringYesSite UUID to update

Updatable Fields

custom_port, origin_ip, alert_days, check_types, dns_provider, dns_provider_config, deploy_target, deploy_config

Response

FieldTypeDescription
siteSiteThe updated site object
curl -X PATCH "https://app.certack.com/api/sites?id=SITE_ID" \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"alert_days": 7}'
DELETE/api/sites?id=<site_id>

Remove a site and all its associated data.

Query Parameters

ParameterTypeRequiredDescription
idstringYesSite UUID to delete

Response

FieldTypeDescription
successbooleantrue if the site was deleted
curl -X DELETE "https://app.certack.com/api/sites?id=SITE_ID" \
  -H "Authorization: Bearer sp_YOUR_KEY"

API 키

API keys are the recommended way to authenticate scripts, CI/CD pipelines, and automated tools. Each key starts with the sp_ prefix and is shown in full only once — at creation time. After that, only the key prefix is visible, so store the full value somewhere safe (a secrets manager, never in source control).

Per-plan key limits: Free (1 key), Pro (5), Team (10). Need more? Upgrade your plan from the dashboard or contact support.

GET/api/api-keys

List all API keys. Only the key prefix is returned, never the full key.

FieldTypeDescription
keysApiKey[]Array of key objects: id, key_prefix, name, last_used_at, created_at
curl https://app.certack.com/api/api-keys \
  -H "Authorization: Bearer sp_YOUR_KEY"
POST/api/api-keys

Create a new API key. The full key is shown only in this response.

ParameterTypeRequiredDescription
namestringYesA descriptive name for the key (e.g. my-agent-key)
FieldTypeDescription
keystringThe full API key (sp_...). Save this — it won't be shown again
prefixstringThe key prefix for display (e.g. sp_abc1...)
namestringThe name you assigned
curl -X POST https://app.certack.com/api/api-keys \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-agent-key"}'
DELETE/api/api-keys?id=<key_id>

Delete an API key. Any scripts using this key will immediately lose access.

FieldTypeDescription
successbooleantrue if the key was deleted
curl -X DELETE "https://app.certack.com/api/api-keys?id=KEY_ID" \
  -H "Authorization: Bearer sp_YOUR_KEY"

SSL 확인

Run an on-demand SSL/TLS certificate check against any domain. This endpoint performs a live TLS handshake, validates the certificate chain, inspects the cipher suite and protocol version, and returns a comprehensive report — including a letter grade (A+ through F) for the overall TLS posture. Use it for ad-hoc checks or to feed monitoring data into your own pipelines.

POST/api/check-ssl

Run an on-demand SSL certificate check on a domain. Returns certificate details, chain validation, and expiry information.

ParameterTypeRequiredDescription
domainstringYesDomain to check (e.g. example.com)
portnumberNoPort to check (default 443)
origin_ipstringNoOverride DNS-resolved IP
site_idstringNoSite UUID to save results to
FieldTypeDescription
validbooleanWhether the certificate is valid
issuerstringCertificate issuer (e.g. CN=WR3,O=Google Trust Services)
expires_atstringISO 8601 expiry date
days_remainingnumberDays until certificate expires
sanstring[]Subject Alternative Names
chainobject[]Certificate chain details
chain_completebooleanWhether the chain is complete
chain_errorstring|nullChain validation error, if any
protocol_versionstring|nullTLS protocol version (e.g. TLSv1.3)
cipher_namestring|nullCipher suite name
cipher_strengthnumber|nullCipher strength in bits
tls_gradestring|nullOverall TLS grade: A+, A, B, C, D, F
hstsobject|nullHSTS details: enabled, max_age, include_sub_domains, preload
ocsp_staplingboolean|nullWhether OCSP stapling is enabled
mixed_contentobject|nullMixed content details: passive_count, active_count, examples
errorstring|nullGeneral error, if any

Response example

json
{
  "valid": true,
  "issuer": "CN=WR3, O=Google Trust Services",
  "expires_at": "2026-09-15T00:00:00.000Z",
  "days_remaining": 98,
  "san": ["example.com", "www.example.com"],
  "chain_complete": true,
  "chain_error": null,
  "protocol_version": "TLSv1.3",
  "cipher_name": "TLS_AES_256_GCM_SHA384",
  "cipher_strength": 256,
  "tls_grade": "A+",
  "hsts": { "enabled": true, "max_age": 31536000, "include_sub_domains": true, "preload": true },
  "ocsp_stapling": true,
  "mixed_content": null,
  "error": null
}
curl -X POST https://app.certack.com/api/check-ssl \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'

DNS 확인

Query DNS records for any domain. Returns A, AAAA, CNAME, MX, TXT, and NS records, plus a DNSSEC validation status. Useful for detecting DNS hijacking, misconfigured records, or unexpected changes to name servers.

POST/api/check-dns

Run an on-demand DNS record check. Returns A, AAAA, CNAME, MX, TXT, and NS records for the domain.

ParameterTypeRequiredDescription
domainstringYesDomain to check
site_idstringNoSite UUID to save results to
FieldTypeDescription
recordsobject[]DNS records grouped by type
records[].typestringRecord type: A, AAAA, CNAME, MX, TXT, NS
records[].valuesstring[]Record values
dnssecobject|nullDNSSEC status: enabled (boolean), valid (boolean|null)
errorstring|nullError message, if any
curl -X POST https://app.certack.com/api/check-dns \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'

도메인 확인

Check domain registration expiry via WHOIS. Returns the registrar, registration and expiry dates, name servers, and whether WHOIS privacy is enabled. Plan ahead so your domain doesn't lapse and take your services offline.

POST/api/check-domain

Run an on-demand domain expiry check via WHOIS. Returns registration and expiry dates.

ParameterTypeRequiredDescription
domainstringYesDomain to check
site_idstringNoSite UUID to save results to
FieldTypeDescription
registrarstring|nullDomain registrar name
expires_atstring|nullISO 8601 expiry date
days_remainingnumber|nullDays until domain expires
name_serversstring[]|nullName servers
privacy_protectedboolean|nullWhether WHOIS privacy is enabled
errorstring|nullError message (e.g. tld_not_supported)
curl -X POST https://app.certack.com/api/check-domain \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'

검사 결과

Retrieve historical check results for a site — useful for building trend charts, auditing past incidents, or feeding data into your own analytics pipeline. Without filters, returns the latest result per check type. With filters, returns a paginated array suitable for time-series queries.

GET/api/checks?site_id=<id>

Get check results with optional filtering by type and date range. When check_type, from, or to filters are provided, returns a paginated array of check results. When no filters are provided, returns the latest check per type as an object keyed by check_type (not an array).

ParameterTypeRequiredDescription
site_idstringYesSite UUID
check_typestringNoFilter: ssl, dns, domain
fromstringNoISO date, start of range (e.g. 2026-05-01)
tostringNoISO date, end of range (e.g. 2026-05-27)
limitnumberNoResults per page (1-200, default 50)
offsetnumberNoPagination offset (>= 0, default 0)
FieldTypeDescription
checksCheck[]Array of check result objects
totalnumberTotal matching results
limitnumberApplied limit
offsetnumberApplied offset
curl "https://app.certack.com/api/checks?site_id=SITE_ID&check_type=ssl&limit=10" \
  -H "Authorization: Bearer sp_YOUR_KEY"
POST/api/checks

Save a check result. Used internally by the monitoring system.

ParameterTypeRequiredDescription
site_idstringYesSite UUID
check_typestringYesCheck type: ssl, dns, domain
resultobjectYesCheck result data
curl -X POST https://app.certack.com/api/checks \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"SITE_ID","check_type":"ssl","result":{"valid":true}}'

알림

Alerts are generated automatically when Certack detects an issue — a certificate nearing expiry, a DNS record change, a domain about to lapse, or a site going down. Each alert carries a type, severity (info / warning / critical), a human-readable message, and a suggested remediation. Use this endpoint to list, filter, and resolve alerts programmatically.

GET/api/alerts

List alerts. By default, returns unresolved alerts only.

ParameterTypeRequiredDescription
typestringNoFilter by type: ssl, dns, domain
severitystringNoFilter by severity: info, warning, critical
resolvedstringNo(default) unresolved only, true=resolved only, all=both
limitnumberNoResults per page (default 50)
offsetnumberNoPagination offset (default 0)
FieldTypeDescription
alertsAlert[]Array of alert objects
totalnumberTotal matching alerts
limitnumberApplied limit
offsetnumberApplied offset

Response example

json
{
  "alerts": [
    {
      "id": "alert-uuid-...",
      "type": "ssl",
      "severity": "critical",
      "message": "SSL certificate expires in 3 days",
      "suggestion": "Renew your SSL certificate immediately",
      "is_resolved": false,
      "site_id": "site-uuid-...",
      "created_at": "2026-06-06T08:00:01.000Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
curl "https://app.certack.com/api/alerts?severity=critical&limit=10" \
  -H "Authorization: Bearer sp_YOUR_KEY"
PATCH/api/alerts?id=<alert_id>

Mark an alert as resolved.

FieldTypeDescription
alertAlertThe resolved alert object
curl -X PATCH "https://app.certack.com/api/alerts?id=ALERT_ID" \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_resolved": true}'

인증서 기록

Audit trail of certificate changes for a site — every renewal, replacement, issuer change, or SAN modification is recorded. Use this to investigate "what changed?" when something breaks, or to verify that automated renewals are actually happening on schedule. Returns the last 50 changes.

GET/api/cert-history?site_id=<id>

Get certificate change history for a site. Returns the last 50 certificate changes.

ParameterTypeRequiredDescription
site_idstringYesSite UUID
FieldTypeDescription
historyobject[]Certificate change records (last 50)
history[].fingerprintstringCertificate fingerprint
history[].change_typestringChange type: renewal, replacement, issuer_change, san_change
history[].changed_atstringISO 8601 timestamp
history[].issuerstringCertificate issuer at time of change
curl "https://app.certack.com/api/cert-history?site_id=SITE_ID" \
  -H "Authorization: Bearer sp_YOUR_KEY"

Certificate Renewal (legacy)

Deprecated. Renewal endpoints remain available for existing configurations but are not available to new users.

POST/api/renewalPro+ plan

Trigger a certificate renewal via Let's Encrypt.

ParameterTypeRequiredDescription
site_idstringYesSite UUID to renew
FieldTypeDescription
messagestringStatus message (e.g. Renewal initiated)
site_idstringSite UUID
curl -X POST https://app.certack.com/api/renewal \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id": "SITE_ID"}'
GET/api/renewal?site_id=<id>

Get renewal logs for a site.

ParameterTypeRequiredDescription
site_idstringYesSite UUID
FieldTypeDescription
logsobject[]Renewal log entries
logs[].statusstringRenewal status: pending, success, failed
logs[].messagestringLog message
logs[].created_atstringISO 8601 timestamp

알림 채널

Configure where Certack sends alerts. Supported channels include email, Slack, Discord, Microsoft Teams, and a custom webhook URL (for routing to PagerDuty, incident management tools, or your own automation). The same endpoint also controls your public status page — title, logo, accent color, custom domain, and more.

Plan gating: Email is available on Pro and above; Slack, Discord, and Teams require Team or above; the custom webhook and status page customizations (custom domain, hide powered-by, custom CSS) require Team.

GET/api/settings/notifications

Get current notification channel settings.

FieldTypeDescription
settingsobjectCurrent notification settings
settings.emailbooleanEmail alerts enabled
settings.slack_webhook_urlstring|nullSlack webhook URL
settings.discord_webhook_urlstring|nullDiscord webhook URL
settings.teams_webhookstring|nullMicrosoft Teams webhook URL
settings.custom_webhook_urlstring|nullCustom webhook URL
status_page_enabledbooleanStatus page enabled
status_page_titlestringStatus page title
status_page_logo_urlstring|nullStatus page logo URL
status_page_accent_colorstringStatus page accent color (hex)
status_page_custom_domainstring|nullCustom domain (Team)
status_page_hide_powered_bybooleanHide 'Powered by' (Team)
status_page_custom_cssstring|nullCustom CSS (Team)
status_page_favicon_urlstring|nullStatus page favicon URL
planstringCurrent plan ID
PATCH/api/settings/notifications

Update notification settings. Only include channels you want to change.

ParameterTypeRequiredDescription
emailbooleanNoEnable email alerts (Pro+)
slack_webhook_urlstringNoSlack webhook URL (Team+)
discord_webhook_urlstringNoDiscord webhook URL (Team+)
teams_webhookstringNoMicrosoft Teams webhook URL (Team+)
custom_webhook_urlstringNoCustom webhook URL (Team)
status_page_enabledbooleanNoEnable public status page
status_page_titlestringNoStatus page title (max 100 chars, Team+)
status_page_logo_urlstringNoLogo URL (max 500 chars, Team+)
status_page_accent_colorstringNoAccent color hex like #6366f1 (Team+)
status_page_favicon_urlstringNoFavicon URL (max 500 chars, Team+)
status_page_custom_domainstringNoCustom domain without protocol (Team)
status_page_hide_powered_bybooleanNoHide powered-by badge (Team)
status_page_custom_cssstringNoCustom CSS (max 10000 chars, Team)
curl -X PATCH https://app.certack.com/api/settings/notifications \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": true, "slack_webhook_url": "https://hooks.slack.com/services/..."}'
POST/api/settings/notifications

Send a test notification to all configured channels.

FieldTypeDescription
messagestringConfirmation message
channelsstring[]Channels that received the test

공개 SSL 확인

A no-auth endpoint for quickly checking any domain's SSL certificate. Perfect for embedding in CI/CD pipelines, status pages, or public dashboards where you don't want to expose an API key. Rate limited to 10 requests per minute per IP address.

GET/api/public/check-ssl?domain=<domain>No auth required

Check any domain's SSL certificate without authentication. Returns a trimmed-down subset of the authenticated /api/check-ssl response (no chain details, cipher info, or TLS grade).

ParameterTypeRequiredDescription
domainstringYesDomain to check (e.g. google.com)
FieldTypeDescription
validbooleanWhether the certificate is valid
issuerstringCertificate issuer
expires_atstringISO 8601 expiry date
days_remainingnumberDays until expiry
sanstring[]Subject Alternative Names
chain_completebooleanWhether the chain is complete
errorstring|nullError message, if any
curl "https://app.certack.com/api/public/check-ssl?domain=google.com"

결제 및 구독

Certack is billed through Creem, a merchant-of-record payment provider that handles checkout, subscriptions, invoicing, and tax compliance. The API lets you start a checkout session, verify a completed payment, and cancel an active subscription. Subscription lifecycle events (activation, cancellation, pause, expiry) are delivered to your account via the /api/webhooks/creem endpoint and trigger automated emails.

Plans & pricing

All plans are billed in USD. Upgrade or downgrade at any time — proration is handled by Creem.

PlanMonthlyYearlySitesAPI calls/moKey features
Free$0$02100Dashboard alerts, 1 API key
Pro$19$2042010,000Email + Slack, 5 API keys
Team$39$4208050,000All channels + team (3), webhooks
POST/api/checkoutAuthenticated · upgrades only

Create a Creem checkout session for upgrading to a paid plan (or switching billing cycle). Returns a hosted checkoutUrl — redirect the user's browser there to complete payment. You can only upgrade to a higher tier than your current plan; downgrades are handled by cancelling the existing subscription. The userId, planId, and billing are embedded in the checkout metadata so the webhook can reconcile the payment to your account.

Request Body

ParameterTypeRequiredDescription
planIdstringYesTarget plan: pro, team (free is invalid)
billingstringNoBilling cycle: monthly (default) or yearly
emailstringNoPre-fill the customer email at checkout

Response (200 OK)

FieldTypeDescription
checkoutUrlstringCreem-hosted checkout URL — redirect the browser here

Error Responses

FieldTypeDescription
400Invalid plan, invalid billing cycle, or you already have this/higher plan
401Authentication required
413Request body too large (>10KB)
503Payment system (Creem) is not configured
# Upgrade to the Team plan, billed yearly
curl -X POST https://app.certack.com/api/checkout \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"planId":"team","billing":"yearly"}'
GET/api/billing/statusAuthenticated

Returns the caller's current plan. Used by the checkout success page to detect when the checkout.completed webhook has applied the new plan — Creem does not sign the success-URL redirect, so the webhook is the only authoritative source of plan changes. Poll this endpoint after redirect; once plan is no longer free, the upgrade is confirmed.

Response (200 OK)

FieldTypeDescription
planstringOne of: free, starter, pro, team
customerIdstring | nullThe Creem customer ID, if a subscription exists
curl https://app.certack.com/api/billing/status \
  -H "Authorization: Bearer sp_YOUR_KEY"
CANCELCancel subscription (stop payment)

To stop a recurring subscription, cancel via the dashboard (Dashboard → Settings → Billing → Cancel) or delete your account via DELETE /api/account. Cancelling immediately downgrades your plan to free and revokes the license key — Creem handles any grace period on their end. The Account section documents the full deletion flow.

What happens when you cancel

  1. Creem cancels each active subscription in immediate mode
  2. Your profile plan is set to free and license_key is cleared
  3. A subscription.canceled email is sent to the account email
  4. Sites exceeding the free plan limit remain visible but are no longer checked
# Cancel by deleting the account (also cancels subscription)
curl -X DELETE https://app.certack.com/api/account \
  -H "Authorization: Bearer sp_YOUR_KEY"
POST/api/webhooks/creemCreem → Certack (server-to-server)

This endpoint receives subscription lifecycle events from Creem. It is called by Creem's servers — not by you. Requests are verified via the creem-signature header, and every event is deduplicated using an idempotency key stored in the webhook_events table. The table below lists the events handled and their effect on the account.

Subscription lifecycle events

FieldTypeDescription
checkout.completedUpgrades plan to the purchased tier; sends purchase confirmation email
subscription.activeMarks subscription active; sets plan; sends activation email
subscription.canceledDowngrades plan to free; clears license_key; sends canceled email
subscription.pausedDowngrades plan to free; sends paused email
subscription.expiredDowngrades plan to free; clears license_key; sends expired email
subscription.paidRenewal charge succeeded; restores/maintains the plan
subscription.updatePlan change in the customer portal; re-maps the plan
refund.createdRefund processed; revokes access; downgrades to free; sends access-revoked email
dispute.createdChargeback; revokes access; downgrades to free; sends access-revoked email

Example: checkout.completed payload (Creem → Certack)

json
{
  "id": "evt_abc123",
  "type": "checkout.completed",
  "product": { "id": "prod_team_monthly" },
  "customer": { "id": "cust_xyz", "email": "you@example.com" },
  "metadata": { "planId": "team", "billing": "monthly", "userId": "user-uuid" }
}

Note: This endpoint is invoked by Creem, not by API clients. To receive your own real-time alerts (SSL expiring, DNS changed, etc.), configure a custom_webhook_url via the Notifications API — see the Webhooks section for that outbound payload format.

계정

Manage your Certack account profile. Retrieve your current plan and account info, update your display name, or permanently delete the account — which also cancels any active subscription (see Billing & Subscriptions). Deletion is irreversible and removes all sites, checks, alerts, API keys, and profile data.

GET/api/account

Get the current authenticated user's account info, including their active plan.

FieldTypeDescription
idstringUser UUID
emailstringAccount email
full_namestring|nullDisplay name (if set)
planstringCurrent plan: free, pro, team
created_atstringISO 8601 account creation timestamp
curl https://app.certack.com/api/account \
  -H "Authorization: Bearer sp_YOUR_KEY"
PATCH/api/account

Update your account profile. Only the fields you include are changed.

Request Body

ParameterTypeRequiredDescription
full_namestringNoDisplay name (max 200 characters)
FieldTypeDescription
profileobjectUpdated profile: id, email, full_name, plan, created_at
curl -X PATCH https://app.certack.com/api/account \
  -H "Authorization: Bearer sp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"full_name":"Jane Doe"}'
DELETE/api/account

Permanently delete your account and all associated data (sites, checks, alerts, API keys, profile). Any active Creem subscription is cancelled first — see Billing & Subscriptions for the cancellation flow. This action is irreversible.

FieldTypeDescription
successbooleantrue if the account was deleted
curl -X DELETE https://app.certack.com/api/account \
  -H "Authorization: Bearer sp_YOUR_KEY"

Invite teammates to collaborate on monitoring. Team members can view sites, acknowledge alerts, and (depending on their role) manage configuration. Roles available are admin (full access), editor (manage sites and alerts), and viewer (read-only). Team features require a Team plan.

GET/api/teamTeam+ plan

List team members and pending invitations.

FieldTypeDescription
membersobject[]Team members: id, member_id, role, email, full_name
invitationsobject[]Pending invitations: id, email, role, expires_at
planstringCurrent plan ID
teamMembersLimitnumberMax team members for current plan
POST/api/teamTeam+ plan

Invite a team member by email.

ParameterTypeRequiredDescription
emailstringYesEmail address to invite
rolestringNoRole: admin, editor, viewer (default: viewer)
FieldTypeDescription
invitationobjectCreated invitation: id, email, role, expires_at
PATCH/api/team/roleTeam+ plan

Update a team member's role.

ParameterTypeRequiredDescription
member_idstringYesTeam member UUID
rolestringYesNew role: admin, editor, viewer
FieldTypeDescription
memberobjectUpdated member object
POST/api/team/accept

Accept a team invitation. The logged-in user's email must match the invitation email.

ParameterTypeRequiredDescription
tokenstringYesInvitation token from the email
previewbooleanNoPreview invitation details without accepting
FieldTypeDescription
successbooleantrue if the invitation was accepted
team_owner_idstringUUID of the team owner
rolestringAssigned role
team_owner_emailstring|nullTeam owner email (preview or accept)
team_owner_namestring|nullTeam owner name (preview or accept)
DELETE/api/teamTeam+ plan

Remove a team member. The member_id is sent in the request body.

ParameterTypeRequiredDescription
member_idstringYesTeam member UUID to remove (in request body)
FieldTypeDescription
successbooleantrue if the member was removed

인시던트

Track and communicate service disruptions via incidents. Each incident has a severity (minor, major, critical), a status lifecycle (investigating → identified → monitoring → resolved), a list of affected sites, and a chronological stream of updates. Incidents feed your public status page so subscribers stay informed during outages.

GET/api/incidents

List incidents, optionally filtered by status.

ParameterTypeRequiredDescription
statusstringNoFilter by status: investigating, identified, monitoring, resolved
FieldTypeDescription
incidentsobject[]Array of incident objects
POST/api/incidents

Create a new incident. Use auto_create to auto-populate from current critical alerts.

ParameterTypeRequiredDescription
titlestringYes*Incident title (max 200 chars). Required unless auto_create is true.
severitystringNoSeverity: minor, major, critical (default: minor)
affected_sitesstring[]NoArray of site UUIDs affected
auto_createbooleanNoAuto-create from current critical alerts
FieldTypeDescription
incidentobjectCreated incident: id, title, severity, status, affected_sites, etc.
GET/api/incidents/[id]/updates

List all updates for an incident.

FieldTypeDescription
updatesobject[]Array of update objects: id, incident_id, status, message, author_id, created_at
totalnumberTotal number of updates
POST/api/incidents/[id]/updates

Add an update to an incident. Setting status to "resolved" resolves the incident.

ParameterTypeRequiredDescription
statusstringYesUpdate status: investigating, identified, monitoring, resolved
messagestringYesUpdate message
FieldTypeDescription
updateobjectCreated update: id, incident_id, status, message, created_at
GET/api/incidents/[id]

Get a single incident with its updates.

FieldTypeDescription
incidentobjectThe incident object
updatesobject[]Array of update objects for this incident
PATCH/api/incidents/[id]

Update an incident.

ParameterTypeRequiredDescription
statusstringNoNew status: investigating, identified, monitoring, resolved
affected_sitesstring[]NoArray of site UUIDs affected
FieldTypeDescription
incidentobjectThe updated incident object

유지보수 윈도우

Schedule maintenance windows to suppress alerts during planned downtime. During an active window, alerts for the affected site (or all sites) are silenced so your team isn't paged for expected disruptions. Windows can be scoped to a single site or apply globally.

GET/api/maintenance-windows

List all maintenance windows.

FieldTypeDescription
windowsobject[]Array of maintenance window objects
POST/api/maintenance-windows

Create a maintenance window.

ParameterTypeRequiredDescription
site_idstringNoSite UUID (null = all sites)
starts_atstringYesISO 8601 start time
ends_atstringYesISO 8601 end time (must be after starts_at)
descriptionstringNoDescription (max 500 chars)
FieldTypeDescription
windowobjectCreated maintenance window object
DELETE/api/maintenance-windows?id=<id>

Delete a maintenance window.

ParameterTypeRequiredDescription
idstringYesMaintenance window UUID
FieldTypeDescription
successbooleantrue if the window was deleted

예약된 검사

Internal endpoint that triggers scheduled monitoring checks across all sites. Typically invoked by a cron job (Vercel Cron, GitHub Actions, or a system crontab) every few minutes. Authenticates with a separate CRON_SECRET environment variable — not a user API key — so it can be safely embedded in scheduler configs.

POST/api/cronBearer token (CRON_SECRET)

Run scheduled monitoring checks for all sites. Authenticates via Authorization: Bearer <CRON_SECRET> header.

ParameterTypeRequiredDescription
typestringNoCheck type: all (default) or domain
FieldTypeDescription
checkednumberNumber of sites checked
errorsnumberNumber of sites that failed
alertsnumberNumber of new alerts created
curl -X POST "https://app.certack.com/api/cron" \
  -H "Authorization: Bearer YOUR_CRON_SECRET"

AI 어시스턴트용 MCP

Certack exposes a Model Context Protocol endpoint so AI assistants like Claude can query and act on your monitoring data directly. The endpoint speaks JSON-RPC 2.0 and supports the standard MCP methods: initialize, tools/list,tools/call, and ping. Two endpoints are available: a private endpoint (authenticated with your API key, exposes your monitoring data) and a public endpoint (no auth, read-only checks for any domain).

POST/api/mcpPrivate — requires Bearer token

Authenticated endpoint for AI assistants managing your monitoring data. Authenticate with your API key as a Bearer token — the same one you'd use for any other endpoint.

Private tools

FieldTypeDescription
list_sitesobjectYour sites with latest SSL/DNS/domain status summaries + plan
get_site_statusobjectFull status for one site: latest check results, alerts, metadata. Params: site_id
add_siteobjectAdd a site to monitor. Params: domain, check_types
update_siteobjectUpdate site settings. Params: site_id, domain, check_types, alert_days, monitoring_enabled
remove_siteobjectRemove a site from monitoring. Params: site_id
check_sslobjectLive SSL check for any domain. Params: domain
check_dnsobjectLive DNS check for any domain. Params: domain
check_domainobjectLive domain/WHOIS check for any domain. Params: domain
list_alertsobjectUnresolved alerts for the authenticated user
resolve_alertobjectResolve an alert by id. Params: alert_id
get_cert_historyobjectCertificate change history for a site. Params: site_id
list_private_certsobjectCertificates reported by your Private Certs agent

Response example — list_sites

Response

json
{
  "sites": [
    {
      "id": "uuid",
      "domain": "example.com",
      "check_types": ["ssl", "dns", "domain"],
      "created_at": "2026-01-01T00:00:00Z",
      "status": {
        "ssl": { "checked_at": "ISO", "valid": true, "days_remaining": 63, "issuer": "Google Trust Services", "error": null },
        "dns": { "checked_at": "ISO", "records": [{ "type": "A", "values": ["1.2.3.4"] }], "dnssec": { "enabled": true }, "error": null },
        "domain": { "checked_at": "ISO", "registrar": "Namecheap", "days_remaining": 120, "data_availability": "full", "error": null }
      }
    }
  ],
  "plan": "starter"
}
POST/api/public/mcpPublic — no authentication, rate-limited (10 req/min per IP)

Public endpoint for read-only checks on any domain. No API key required. Useful for building AI tools that inspect SSL / DNS / domain registration without an account. SSRF-protected (domains resolving to private IPs are rejected).

Public tools

FieldTypeDescription
check_sslobjectLive SSL check for any domain. Params: domain
check_dnsobjectLive DNS check for any domain. Params: domain
check_domainobjectLive domain/WHOIS check for any domain. Params: domain

Example request

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": { "name": "check_ssl", "arguments": { "domain": "example.com" } }
}

비공개 인증서 에이전트

Monitor internal/private certificates that aren't reachable from the public internet — intranet services, internal CAs, mTLS endpoints, IoT devices. Deploy a lightweight agent inside your network; it scans your internal hosts and reports certificate details back to Certack, where they're tracked and alerted on just like public certificates. Agent features require a Team plan.

GET/api/agent/keyTeam plan

List agent keys for the authenticated user.

FieldTypeDescription
agentsobject[]Agent keys: id, agent_name, last_seen_at, created_at
POST/api/agent/keyTeam plan

Generate a new agent key. The full key is shown only once. Max 10 agents per user.

ParameterTypeRequiredDescription
namestringNoAgent name (default: Default Agent)
FieldTypeDescription
agent_idstringAgent UUID
agent_keystringFull agent key (sp_agent_...). Save this — it won't be shown again
agent_namestringAgent name
DELETE/api/agent/key?id=<id>Team plan

Delete an agent key.

FieldTypeDescription
successbooleantrue if the agent key was deleted
POST/api/agent/registerTeam plan

Register an agent using its key. Returns the agent_id for subsequent report calls.

FieldTypeDescription
agent_idstringAgent UUID
statusstringRegistration status (registered)
POST/api/agent/reportTeam plan

Submit certificate scan results from an agent. Authenticated via agent key (sp_agent_...).

ParameterTypeRequiredDescription
agent_idstringYesAgent UUID from registration
resultsobject[]YesScan results: host, port, certificates[]
FieldTypeDescription
statusstringProcessing status (ok)
certs_processednumberNumber of certificates processed
alerts_creatednumberNumber of alerts created for expiring certs
GET/api/agent/certsTeam plan

List all private certificates reported by agents.

FieldTypeDescription
certificatesobject[]Certificate objects: id, host, port, subject, issuer, not_after, is_valid, etc.

웹훅

Webhooks let you receive real-time event notifications when Certack detects issues with your monitored sites. Instead of polling the API, Certack pushes event data to your endpoint as soon as an alert fires. This is ideal for integrating with incident management systems, Slack bots, custom dashboards, or automation pipelines.

Availability

Webhooks are available on the Team plan ($39/mo) and above, including all webhook features plus PagerDuty integration. Configure your webhook URL via the dashboard at Dashboard → Settings → Notifications or via the Notifications API.

How webhooks work

  1. Certack detects an issue (e.g., SSL certificate expiring, DNS record changed).
  2. Certack constructs an event payload with alert details and sends an HTTP POST request to your configured webhook URL.
  3. Your endpoint receives the payload, processes it, and responds with a 2xx status code.
  4. If your endpoint is unreachable or returns a non-2xx status, Certack retries delivery up to 2 times (at 1s and 3s delays).

Supported event types

Certack sends webhooks for the following event types. Each payload includes a type field that identifies the event, so you can route different events to different handlers.

FieldTypeDescription
ssl.expiringcriticalSSL/TLS certificate will expire soon (within alert_days threshold)
ssl.expiredcriticalSSL/TLS certificate has expired
ssl.invalidcriticalSSL/TLS certificate is invalid (chain break, hostname mismatch, etc.)
ssl.renewedinfoSSL/TLS certificate was renewed successfully
certificate.changedwarningCertificate for the domain was issued, replaced, or renewed
dns.changedwarningDNS record changed unexpectedly
domain.expiringwarningDomain registration will expire soon
domain.expiredcriticalDomain registration has expired

Webhook payload structure

All webhook payloads follow the same structure. The alerts array contains one or more alert objects with full details about the detected issue.

FieldTypeDescription
sourcestringAlways "Certack" — identifies the sender
timestampstring (ISO 8601)When the event was generated, e.g. "2026-06-23T08:00:01Z"
alertsAlert[]Array of alert objects (see below)

Alert object fields

FieldTypeDescription
domainstringThe affected domain, e.g. "example.com"
typestringEvent type (see table above), e.g. "ssl.expiring"
severitystringAlert severity: "critical", "warning", or "info"
messagestringHuman-readable description of the issue
suggestionstringRecommended action to resolve the issue

Example: SSL expiring soon

This is the payload sent when an SSL certificate is about to expire (within the configured alert_days threshold).

POST your-webhook-url — Content-Type: application/json

json
{
  "source": "Certack",
  "timestamp": "2026-06-23T08:00:01.000Z",
  "alerts": [
    {
      "domain": "example.com",
      "type": "ssl.expiring",
      "severity": "critical",
      "message": "SSL certificate expires in 3 days",
      "suggestion": "Renew your SSL certificate immediately to avoid service disruption"
    }
  ]
}

Example: DNS record changed

POST your-webhook-url — Content-Type: application/json

json
{
  "source": "Certack",
  "timestamp": "2026-06-23T10:30:00.000Z",
  "alerts": [
    {
      "domain": "example.com",
      "type": "dns.changed",
      "severity": "warning",
      "message": "DNS A record changed from 1.2.3.4 to 5.6.7.8",
      "suggestion": "Verify this DNS change was intentional — unexpected changes may indicate DNS hijacking"
    }
  ]
}

Receiving webhooks: Node.js / Express example

Here's a complete example of a webhook receiver using Express.js. This endpoint parses the payload, routes by event type, and responds with a 200 status.

webhook-receiver.js

ts
import express from "express";

const app = express();
app.use(express.json());

app.post("/webhook/certack", (req, res) => {
  const { source, timestamp, alerts } = req.body;

  // Verify the source
  ifsource !== "Certack") {
    return res.status(400).send("Invalid source");
  }

  // Process each alert
  forconst alert of alerts) {
    switchalert.type) {
      case "ssl.expiring":
      case "ssl.expired":
        // Page the on-call engineer
        console.log(`[${alert.severity}] ${alert.domain}: ${alert.message}`);
        break;
      case "dns.changed":
        // Log for security review
        console.log(`DNS change on ${alert.domain}: ${alert.message}`);
        break;
      default:
        console.log(`Unknown event: ${alert.type}`);
    }
  }

  // Always respond with 2xx to acknowledge receipt
  res.status(200).send("OK");
});

app.listen(3000, () => console.log("Webhook receiver on :3000"));

Receiving webhooks: Python / Flask example

webhook_receiver.py

python
from flask import Flask, request, jsonify
import logging

app = Flask(__name__)

@app.route("/webhook/certack", methods=["POST"])
def certack_webhook():
    data = request.json
    if data.get"source") != "Certack":
        return jsonify({"error": "Invalid source"}), 400

    for alert in data.get"alerts", []):
        event_type = alert["type"]
        domain = alert["domain"]
        message = alert["message"]

        if event_type in"ssl.expiring", "ssl.expired"):
            # Page the on-call engineer
            logging.critical(f"[{alert['severity']}] {domain}: {message}")
        elif event_type == "dns.changed":
            # Log for security review
            logging.warning(f"DNS change on {domain}: {message}")

    return jsonify({"status": "ok"}), 200

if __name__ == "__main__":
    app.run(port=3000)

Retry policy

Your endpoint must respond with a 2xx HTTP status code within 10 seconds to acknowledge receipt.

If the endpoint is unreachable, times out, or returns a non-2xx status, Certack retries delivery up to 2 additional times:

  • 1st retry: 1 second after the initial attempt
  • 2nd retry: 3 seconds after the 1st retry

After all retries are exhausted, the alert is still visible in the dashboard and delivered via other configured channels (Email, Slack, etc.).

Security

SSRF protection: Private/internal IP addresses (10.x, 172.16-31.x, 192.168.x, 127.x) and cloud metadata endpoints (169.254.169.254) are blocked to prevent Server-Side Request Forgery attacks.

HTTPS recommended: While HTTP URLs are accepted for local development, production webhook URLs should use HTTPS to encrypt the payload in transit.

Payload validation: Always verify the source field equals "Certack" before processing. For additional security, you can include a secret token in your webhook URL query string (e.g., ?token=your-secret) and verify it in your handler.

Testing your webhook

You can test your webhook configuration from the dashboard (Dashboard → Settings → Notifications → Test Webhook). This sends a test payload to your configured URL so you can verify your endpoint is working correctly.

Test webhook payload

json
{
  "source": "Certack",
  "timestamp": "2026-06-23T12:00:00.000Z",
  "alerts": [
    {
      "domain": "test.example.com",
      "type": "ssl.expiring",
      "severity": "info",
      "message": "This is a test webhook from Certack",
      "suggestion": "If you received this, your webhook is configured correctly"
    }
  ]
}

통합 예제

Copy-paste recipes for common Certack workflows — CI/CD gates, daily monitoring scripts, auto-ack during maintenance, webhook relays to PagerDuty, and infrastructure-as-code with Terraform. Each example is self-contained and ready to adapt to your stack.

CI/CD: Verify SSL after deployment

After deploying a new service, verify the SSL certificate is valid before releasing traffic. This example uses the public SSL check endpoint (no auth required) in a GitHub Actions workflow.

.github/workflows/verify-ssl.yml

bash
# .github/workflows/verify-ssl.yml
name: Verify SSL Certificate
on:
  deployment_status:
    states: [success]

jobs:
  verify-ssl:
    runs-on: ubuntu-latest
    steps:
      - name: Check SSL certificate
        run: |
          RESPONSE=$(curl -s \
            "https://app.certack.com/api/public/check-ssl?domain=${{ secrets.DOMAIN }}")
          VALID=$(echo "$RESPONSE" | jq -r '.valid')
          DAYS=$(echo "$RESPONSE" | jq -r '.days_remaining')

          if [ "$VALID" != "true" ]; then
            echo "::error::SSL certificate is invalid!"
            exit 1
          fi

          if [ "$DAYS" -lt 7 ]; then
            echo "::warning::SSL certificate expires in $DAYS days"
          fi

          echo "✅ SSL valid, $DAYS days remaining"

Daily monitoring: Check all sites

A Python script that runs daily (e.g., via cron or GitHub Actions) to check all monitored sites and send a summary to Slack if any issues are found.

daily-check.py

python
import requests
import json
from datetime import datetime

BASE = "https://app.certack.com"
HEADERS = {"Authorization": "Bearer sp_YOUR_KEY"}
SLACK_WEBHOOK = "https://hooks.slack.com/services/..."

# Get all monitored sites
sites = requests.getf"{BASE}/api/sites", headers=HEADERS).json()["sites"]

issues = []
for site in sites:
    domain = site["domain"]

    # Run SSL check
    ssl = requests.post(f"{BASE}/api/check-ssl",
        headers=HEADERS, json={"domain": domain}).json()

    if not ssl.get"valid") or ssl.get"days_remaining", 999) < 14:
        issues.append{
            "domain": domain,
            "valid": ssl.get"valid"),
            "days_remaining": ssl.get"days_remaining"),
            "error": ssl.get"error"),
        })

# Send Slack notification if issues found
if issues:
    blocks = [{"type": "section", "text": {"type": "mrkdwn",
        "text": f":warning: *{len(issues)} site(s) need attention*"}}]
    for issue in issues:
        status = "❌ Invalid" if not issue["valid"] else f"⚠️ {issue['days_remaining']} days left"
        blocks.append{"type": "section", "text": {"type": "mrkdwn",
            "text": f"*{issue['domain']}* — {status}"}})

    requests.post(SLACK_WEBHOOK, json={"blocks": blocks})
    printf"Sent alert for {len(issues)} issues")
else:
    printf"All {len(sites)} sites OK at {datetime.now()}")

Automation: Auto-ack known maintenance windows

When you have a scheduled maintenance window, auto-acknowledge alerts for affected domains to prevent unnecessary pages. This script runs before maintenance starts.

auto-ack.py

python
import requests

BASE = "https://app.certack.com"
HEADERS = {"Authorization": "Bearer sp_YOUR_KEY"}

# Domains under maintenance
MAINTENANCE_DOMAINS = ["staging.example.com", "api-staging.example.com"]

# Get all unresolved alerts
alerts = requests.get
    f"{BASE}/api/alerts",
    headers=HEADERS,
    params={"resolved": "false"}
).json()["alerts"]

# Acknowledge alerts for domains under maintenance
for alert in alerts:
    if alert["domain"] in MAINTENANCE_DOMAINS:
        requests.patch(
            f"{BASE}/api/alerts",
            headers=HEADERS,
            json={
                "id": alert["id"],
                "resolved": True,
                "note": "Auto-acked: scheduled maintenance window"
            }
        )
        printf"Acked alert #{alert['id']} for {alert['domain']}")

Webhook relay: Forward critical alerts to PagerDuty

If you're on the Team plan (no native PagerDuty), use a simple webhook relay to forward critical Certack alerts to PagerDuty's Events API.

pagerduty-relay.js (deploy to Vercel/Cloudflare Workers)

ts
// Deploy this as a serverless function
// Set CERTACK_WEBHOOK_SECRET and PAGERDUTY_INTEGRATION_KEY as env vars

export default async function handler(req: Request): Promise<Response> {
  const body = await req.json();

  // Verify source
  ifbody.source !== "Certack") {
    return new Response("Invalid source", { status: 400 });
  }

  // Forward each critical alert to PagerDuty
  forconst alert of body.alerts) {
    ifalert.severity !== "critical") continue;

    await fetch("https://events.pagerduty.com/v2/enqueue", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        routing_key: process.env.PAGERDUTY_INTEGRATION_KEY,
        event_action: "trigger",
        payload: {
          summary: `[${alert.type}] ${alert.message}`,
          severity: "critical",
          source: alert.domain,
          custom_details: {
            domain: alert.domain,
            suggestion: alert.suggestion,
          },
        },
      }),
    });
  }

  return new Response("OK", { status: 200 });
}

Infrastructure as Code: Manage sites with Terraform

Use the Terraform HTTP provider to manage Certack sites as part of your infrastructure code. This ensures monitoring is set up whenever new services are deployed.

main.tf

bash
# Add Certack monitoring for a new service
resource "http_request" "certack_site" {
  url = "https://app.certack.com/api/sites"
  method = "POST"

  headers = {
    Authorization = "Bearer sp_YOUR_KEY"
    Content-Type  = "application/json"
  }

  body = jsonencode({
    domain       = "api.example.com"
    check_types  = ["ssl", "dns", "domain"]
    alert_days   = 14
  })

  # Re-run when domain changes
  triggers = {
    domain = "api.example.com"
  }
}

# Output the site ID
output "certack_site_id" {
  value = jsondecode(http_request.certack_site.response_body).site.id
}

오류 코드

Certack uses standard HTTP status codes. Errors return a JSON body with an error field describing what went wrong. When debugging, check the status code first, then the error message — most issues map cleanly to one of the codes below.

StatusNameDescription
400Bad RequestInvalid parameters or malformed JSON body
401UnauthorizedMissing or invalid Authorization header
403ForbiddenYour plan does not include this feature
404Not FoundResource does not exist or does not belong to you
429Rate LimitedToo many requests; retry after the Retry-After header
500Server ErrorSomething went wrong on our end
503UnavailableService not configured (missing environment variables)

Error Response Format

{
  "error": "Unauthorized"
}

SDK 예제

Certack is a standard REST API — no official SDK required. Use any HTTP client in your preferred language. Below are minimal, copy-pasteable setup snippets for Python, Go, and TypeScript that cover the most common operations (list sites, add a site, run a check, fetch alerts).

Python (requests)

import requests

BASE = "https://app.certack.com"
HEADERS = {
    "Authorization": "Bearer sp_YOUR_KEY",
    "Content-Type": "application/json",
}

# List sites
sites = requests.getf"{BASE}/api/sites", headers=HEADERS).json()

# Add a site
new_site = requests.post(f"{BASE}/api/sites", headers=HEADERS, json={
    "domain": "example.com",
    "check_types": ["ssl", "dns", "domain"],
}).json()

# Run SSL check
ssl = requests.post(f"{BASE}/api/check-ssl", headers=HEADERS, json={
    "domain": "example.com",
}).json()
printf"SSL valid: {ssl['valid']}, Days left: {ssl['days_remaining']}")

# Get critical alerts
alerts = requests.getf"{BASE}/api/alerts", headers=HEADERS, params={
    "severity": "critical",
}).json()
for alert in alerts["alerts"]:
    printf"[{alert['severity']}] {alert['message']}")

Go (net/http)

package main

import
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

const base = "https://app.certack.com"
const apiKey = "sp_YOUR_KEY"

func main() {
    // Add a site
    payload, _ := json.Marshal(map[string]any{
        "domain":      "example.com",
        "check_types": []string{"ssl", "dns", "domain"},
    })
    req, _ := http.NewRequest("POST", base+"/api/sites", bytes.NewReader(payload))
    req.Header.Set("Authorization", "Bearer "+apiKey)
    req.Header.Set("Content-Type", "application/json")
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    fmt.Println("Status:", resp.StatusCode)

    // Public SSL check (no auth)
    resp, _ = http.Get(base + "/api/public/check-ssl?domain=google.com")
    defer resp.Body.Close()
    var result map[string]any
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Println("Valid:", result["valid"])
}

TypeScript (fetch)

const BASE = "https://app.certack.com";
const headers = {
  Authorization: "Bearer sp_YOUR_KEY",
  "Content-Type": "application/json",
};

// Add a site
const { site } = await fetch(`${BASE}/api/sites`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    domain: "example.com",
    check_types: ["ssl", "dns", "domain"],
  }),
}).then(r => r.json());

// Run SSL check
const ssl = await fetch(`${BASE}/api/check-ssl`, {
  method: "POST",
  headers,
  body: JSON.stringify({ domain: "example.com" }),
}).then(r => r.json());
console.log(`SSL valid: ${ssl.valid}, Days left: ${ssl.days_remaining}`);

// Get alerts
const { alerts } = await fetch(
  `${BASE}/api/alerts?severity=critical`,
  { headers }
).then(r => r.json());
alerts.forEach((a: any) => console.log(`[${a.severity}] ${a.message}`));

Agent Friendly

Certack is designed for automation. AI assistants can interact with this API directly using API keys.

Quick start for AI assistants

  1. Create an API key: POST /api/api-keys
  2. Add a site: POST /api/sites
  3. Run checks: POST /api/check-ssl, /api/check-dns, etc.
  4. Poll alerts: GET /api/alerts
  5. Resolve alerts: PATCH /api/alerts?id=...

Machine-readable docs

A complete API guide optimized for LLM context windows is available at /llms.txt.