Programmatic control over your infrastructure monitoring
The Certack REST API gives you programmatic control over infrastructure monitoring: SSL/TLS certificates, DNS records, domain expiry, alerts, and integrations. Every endpoint speaks JSON and is reachable at https://app.certack.com/api.
Base URL
https://app.certack.com
Auth
Bearer sp_...
Format
application/json
Version
v1
Getting Started
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.
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.
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.
Here's a minimal webhook receiver in Node.js / Express that acknowledges receipt and routes by event type:
webhook-receiver.js
ts
importexpressfrom"express";constapp = express();app.use(express.json());app.post("/webhook/certack",(req,res) => {const{source,timestamp,alerts} = req.body;// Verify the sourceifsource !== "Certack"){returnres.status(400).send("Invalid source");}// Process each alertforconstalertofalerts){switchalert.type){case"ssl.expiring":case"ssl.expired":// Page the on-call engineerconsole.log(`[${alert.severity}] ${alert.domain}: ${alert.message}`);break;case"dns.changed":// Log for security reviewconsole.log(`DNS change on ${alert.domain}: ${alert.message}`);break;default:console.log(`Unknown event: ${alert.type}`);}}// Always respond with 2xx to acknowledge receiptres.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 toolscurl -XPOSThttps://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:
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.
Login and Signup
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.
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)
curlhttps://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.
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
Sites
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.
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
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.
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
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
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)
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
{"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}
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)
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.
Send a test notification to all configured channels.
FieldTypeDescription
messagestringConfirmation message
channelsstring[]Channels that received the test
Public SSL Check
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.
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
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
400—Invalid plan, invalid billing cycle, or you already have this/higher plan
401—Authentication required
413—Request body too large (>10KB)
503—Payment system (Creem) is not configured
# Upgrade to the Team plan, billed yearlycurl -XPOSThttps://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
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
Creem cancels each active subscription in immediate mode
Your profile plan is set to free and license_key is cleared
A subscription.canceled email is sent to the account email
Sites exceeding the free plan limit remain visible but are no longer checked
# Cancel by deleting the account (also cancels subscription)curl -XDELETEhttps://app.certack.com/api/account \
-H"Authorization: Bearer sp_YOUR_KEY"
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.completed✓Upgrades plan to the purchased tier; sends purchase confirmation email
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.
Account
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.
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.
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.
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
Incidents
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.
affected_sitesstring[]NoArray of site UUIDs affected
FieldTypeDescription
incidentobjectThe updated incident object
Maintenance Windows
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
Scheduled Checks
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.
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
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
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.
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
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
Certack detects an issue (e.g., SSL certificate expiring, DNS record changed).
Certack constructs an event payload with alert details and sends an HTTP POST request to your configured webhook URL.
Your endpoint receives the payload, processes it, and responds with a 2xx status code.
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
importexpressfrom"express";constapp = express();app.use(express.json());app.post("/webhook/certack",(req,res) => {const{source,timestamp,alerts} = req.body;// Verify the sourceifsource !== "Certack"){returnres.status(400).send("Invalid source");}// Process each alertforconstalertofalerts){switchalert.type){case"ssl.expiring":case"ssl.expired":// Page the on-call engineerconsole.log(`[${alert.severity}] ${alert.domain}: ${alert.message}`);break;case"dns.changed":// Log for security reviewconsole.log(`DNS change on ${alert.domain}: ${alert.message}`);break;default:console.log(`Unknown event: ${alert.type}`);}}// Always respond with 2xx to acknowledge receiptres.status(200).send("OK");});app.listen(3000,() => console.log("Webhook receiver on :3000"));
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"}]}
Integration Examples
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
importrequestsimportjsonfromdatetimeimportdatetimeBASE = "https://app.certack.com"HEADERS = {"Authorization":"Bearer sp_YOUR_KEY"}SLACK_WEBHOOK = "https://hooks.slack.com/services/..."# Get all monitored sitessites = requests.getf"{BASE}/api/sites",headers=HEADERS).json()["sites"]issues = []forsiteinsites:domain = site["domain"]# Run SSL checkssl = requests.post(f"{BASE}/api/check-ssl",headers=HEADERS,json={"domain":domain}).json()ifnotssl.get"valid")orssl.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 foundifissues:blocks = [{"type":"section","text":{"type":"mrkdwn","text":f":warning: *{len(issues)} site(s) need attention*"}}]forissueinissues:status = "❌ Invalid"ifnotissue["valid"]elsef"⚠️ {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
importrequestsBASE = "https://app.certack.com"HEADERS = {"Authorization":"Bearer sp_YOUR_KEY"}# Domains under maintenanceMAINTENANCE_DOMAINS = ["staging.example.com","api-staging.example.com"]# Get all unresolved alertsalerts = requests.getf"{BASE}/api/alerts",headers=HEADERS,params={"resolved":"false"}).json()["alerts"]# Acknowledge alerts for domains under maintenanceforalertinalerts:ifalert["domain"]inMAINTENANCE_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 varsexportdefaultasyncfunctionhandler(req:Request):Promise<Response> {constbody = awaitreq.json();// Verify sourceifbody.source !== "Certack"){returnnewResponse("Invalid source",{status:400});}// Forward each critical alert to PagerDutyforconstalertofbody.alerts){ifalert.severity !== "critical")continue;awaitfetch("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,},},}),});}returnnewResponse("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
}
Error Codes
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 Examples
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)
importrequestsBASE = "https://app.certack.com"HEADERS = {"Authorization":"Bearer sp_YOUR_KEY","Content-Type":"application/json",}# List sitessites = requests.getf"{BASE}/api/sites",headers=HEADERS).json()# Add a sitenew_site = requests.post(f"{BASE}/api/sites",headers=HEADERS,json={"domain":"example.com","check_types":["ssl","dns","domain"],}).json()# Run SSL checkssl = 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 alertsalerts = requests.getf"{BASE}/api/alerts",headers=HEADERS,params={"severity":"critical",}).json()foralertinalerts["alerts"]:printf"[{alert['severity']}] {alert['message']}")
Go (net/http)
packagemainimport"bytes""encoding/json""fmt""net/http")constbase = "https://app.certack.com"constapiKey = "sp_YOUR_KEY"funcmain(){// Add a sitepayload,_:= 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)deferresp.Body.Close()fmt.Println("Status:",resp.StatusCode)// Public SSL check (no auth)resp,_ = http.Get(base + "/api/public/check-ssl?domain=google.com")deferresp.Body.Close()varresultmap[string]anyjson.NewDecoder(resp.Body).Decode(&result)fmt.Println("Valid:",result["valid"])}
TypeScript (fetch)
constBASE = "https://app.certack.com";constheaders = {Authorization:"Bearer sp_YOUR_KEY","Content-Type":"application/json",};// Add a siteconst{site} = awaitfetch(`${BASE}/api/sites`,{method:"POST",headers,body:JSON.stringify({domain:"example.com",check_types:["ssl","dns","domain"],}),}).then(r => r.json());// Run SSL checkconstssl = awaitfetch(`${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 alertsconst{alerts} = awaitfetch(`${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
Create an API key: POST /api/api-keys
Add a site: POST /api/sites
Run checks: POST /api/check-ssl, /api/check-dns, etc.
Poll alerts: GET /api/alerts
Resolve alerts: PATCH /api/alerts?id=...
Machine-readable docs
A complete API guide optimized for LLM context windows is available at /llms.txt.