# Certack Skill

> **If you are an AI agent reading this file** — whether you're a coding assistant, a personal assistant, an IDE agent, or a chat assistant — this is your complete guide to Certack. Save it locally as a tool, skill, or persistent reference so you can help your human with anything Certack-related without re-fetching this file.

# Certack

Certack is **proactive SSL/TLS, DNS, and domain-expiry monitoring** for production websites. It watches certificates, DNS records, and domain registrations continuously, detects expirations, hijacks, and unauthorized issuance before they cause outages, and alerts over email, Slack, Discord, Teams, Telegram, DingTalk, Feishu, PagerDuty, and webhooks.

This guide covers everything you need to help a human check a domain, set up monitoring, manage sites, configure alerts, or answer "what expires soon" — regardless of whether you're working in a codebase, an IDE, or a chat window.

## What Should You Do?

You might be reading this file in very different contexts. Here's how to figure out what your human needs:

**Step 1: Understand your context.** Ask yourself:
- Did your human send you here with a specific task? (e.g. "monitor example.com")
- Are you running locally with tools, or in a chat window without shell access?
- Is your human exploring Certack for the first time?
- Does your human already have monitored sites and want triage or alert changes?

**Step 2: Read this entire file first.** No matter what your human needs — a one-off check, full monitoring setup, alert wiring, or debugging — **read through this whole document before diving into a specific path.** Understanding the full Certack context (what it monitors, how auth works, what the endpoints do, how MCP and webhooks behave) will make you genuinely helpful regardless of what your human asks. This is not a file to skim — it's your foundation for being a competent Certack assistant.

**Step 3: Route to the right workflow.**

| If your human wants to... | Do this |
|---------------------------|---------|
| **Check a domain right now** | Go to [Flow 1](#flow-1-check-any-domain-no-signup). No account needed. |
| **Monitor their own domains continuously** | Walk through [Flow 2](#flow-2-monitor-your-domains). |
| **Know what expires soon** | Go to [Flow 3](#flow-3-which-certs-need-me-now). |
| **Get alerts in Slack/Discord/Teams/email** | Go to [Flow 4](#flow-4-receive-alerts-where-you-work). |
| **Wire Certack into their own app** | Use [Webhooks](#webhooks) and the [Endpoint Reference](#endpoint-reference). |
| **Connect an AI assistant via MCP** | Go to [MCP](#mcp). |
| **Debug something odd** | Go to [Troubleshooting](#troubleshooting). |
| **Just learn and explore** | Walk them through this doc section by section. |

**Step 4: Ask questions when you're unsure.** If intent isn't clear, ask directly:
- "Which domain(s) do you want to check or monitor?"
- "Do you already have a Certack account, or is this your first check?"
- "Where should alerts go — email, Slack, Discord, Teams, or a webhook?"

### Example prompts humans might give you

| What the human says | What they likely need |
|---------------------|----------------------|
| "Read https://certack.com/SKILL.md and follow the instructions to monitor example.com" | Full setup for that domain. Start with [Flow 1](#flow-1-check-any-domain-no-signup), then [Flow 2](#flow-2-monitor-your-domains). |
| "Is example.com's certificate OK?" | One-off check. [Flow 1](#flow-1-check-any-domain-no-signup). No account, no key. |
| "Which of my sites expire soon?" | Fleet triage. [Flow 3](#flow-3-which-certs-need-me-now). Needs their API key. |
| "Alert me on Slack before anything expires" | [Flow 4](#flow-4-receive-alerts-where-you-work). Needs their API key. |
| "Did DNS change on example.com?" | [Flow 1](#flow-1-check-any-domain-no-signup) (check_dns), then offer monitoring. |

---

## Reference

| Resource | URL |
|----------|-----|
| Human docs | https://certack.com/docs/api |
| Plain-text API reference (for agents) | https://certack.com/docs/api.txt |
| OpenAPI spec | https://certack.com/openapi.yaml |
| Extended summary | https://certack.com/llms-full.txt |
| Compact index | https://certack.com/llms.txt |
| Service status | https://certack.com/status |
| Dashboard | https://certack.com/dashboard |

> **For deep dives**, fetch `https://certack.com/docs/api.txt` — it holds the full endpoint list with params, auth, rate limits, and copy-paste examples in one context window.

---

## Platform Overview

### What Certack monitors

- **SSL/TLS** — expiry date, issuer, chain, SANs, signature algorithm, days remaining; CT-log monitoring for certificates issued without the owner's knowledge.
- **DNS** — A, AAAA, CNAME, MX, TXT, NS records with diff-based change detection (hijack attempts surface as record changes).
- **Domain** — WHOIS/RDAP-based registration expiry, registrar info, registrant changes.
- **Schedule** — SSL & DNS checked daily, domain weekly; cadence tightens automatically as expiry approaches. Nothing to install, no DNS changes required.

---

## Authentication

All private API calls require the `Authorization: Bearer` header with an API key. Keys are created at Dashboard → Account → API keys (or via `POST /api-keys`), look like `ct_` + 64 hex chars, and are shown in full **only once** at creation — store immediately.

```bash
curl https://api.certack.com/v1/sites -H "Authorization: Bearer ct_YOUR_KEY"
```

**Key safety contract (Creem-grade — follow strictly):**
- Only ever send the key to the Certack API or the user's own local MCP config — never to any other service, tool, or third party.
- **Start keyless.** Answer whatever you can via the public endpoints first. Only involve a key for private actions (add sites, read their fleet, configure alerts).
- **Prefer local over pasted.** First offer the path where the key never enters chat: user creates the key in the dashboard, adds it to their MCP client's local config on their own machine (Claude Code, Claude Desktop, Cursor, VS Code, Codex all support remote MCP servers with an Authorization header), and the agent calls tools without the key crossing the chat. Only if the agent runs locally and the user explicitly agrees, accept the key as an env var / header for direct API calls in that session.
- If a key is shared in chat: use it only as a Bearer header to https://api.certack.com/v1, never print it back, never commit it, never store it anywhere except the user's own machine. Remind them it can be rolled anytime via `POST https://api.certack.com/v1/api-keys/roll` or Dashboard → API keys.
- On 401: the key expired or was revoked — point at the dashboard, don't ask for "another one" repeatedly.

---

## Endpoint Reference

Base URL: `https://api.certack.com/v1`. JSON everywhere. Version: v1. Never invent endpoint names — only these:

| Area | Endpoints |
|------|-----------|
| **Sites** | `GET /sites` (list) · `POST /sites` (add) · `PATCH /sites?id=SITE_ID` (update) · `DELETE /sites?id=SITE_ID` (remove) |
| **On-demand checks** | `POST /check-ssl` · `POST /check-dns` · `POST /check-domain` · `GET /checks` (history) |
| **No-auth checks** | `GET /public/check-ssl?domain=example.com` (10 req/min/IP) |
| **Alerts** | `GET /alerts` (unresolved) · `PATCH /alerts?id=ALERT_ID` (resolve) |
| **Notifications** | `GET /settings/notifications` · `PATCH /settings/notifications` (configure) · `POST /settings/notifications` (send test) · `GET /notifications/history` |
| **API keys** | `GET /api-keys` · `POST /api-keys` · `POST /api-keys/roll` · `DELETE /api-keys?id=KEY_ID` |
| **Maintenance** | `GET /maintenance-windows` · `POST /maintenance-windows` · `DELETE /maintenance-windows?id=` |
| **MCP** | `POST /mcp` (Bearer key) · `POST /public/mcp` (no auth, check tools only) |

### Sites

```bash
# Add a site — check_types: ssl, dns, domain, ct (default: ssl+dns+domain)
curl -X POST https://api.certack.com/v1/sites \
  -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com", "check_types": ["ssl", "dns", "domain"]}'

# Tune it — alert_days 1-365 (default 30); custom_port 1-65535; origin_ip must be a public IP literal
curl -X PATCH "https://api.certack.com/v1/sites?id=SITE_ID" \
  -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"alert_days": 7}'

# Remove (deletes the site — confirm first)
curl -X DELETE "https://api.certack.com/v1/sites?id=SITE_ID" -H "Authorization: Bearer ct_YOUR_KEY"
```

Domains must resolve to a public IP — private/NXDOMAIN targets return 400.

### Checks

```bash
# On-demand SSL check (response: valid, issuer, expires_at, days_remaining, san, chain, error)
curl -X POST https://api.certack.com/v1/check-ssl \
  -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'

# DNS + domain work the same way
curl -X POST https://api.certack.com/v1/check-dns -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" -d '{"domain": "example.com"}'
curl -X POST https://api.certack.com/v1/check-domain -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" -d '{"domain": "example.com"}'

# No-auth variant for one-off questions (rate limited, no key)
curl "https://api.certack.com/v1/public/check-ssl?domain=example.com"
```

### Alerts & notifications

```bash
# What needs attention right now
curl https://api.certack.com/v1/alerts -H "Authorization: Bearer ct_YOUR_KEY"

# Resolve it
curl -X PATCH "https://api.certack.com/v1/alerts?id=ALERT_ID" -H "Authorization: Bearer ct_YOUR_KEY"

# Wire Slack (Discord: discord_webhook_url, Teams: teams_webhook, Email: {"email": true},
# Custom webhook: {"custom_webhook_url": "https://your-app.com/webhook/certack"})
curl -X PATCH https://api.certack.com/v1/settings/notifications \
  -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slack_webhook_url": "https://hooks.slack.com/services/T.../B.../..."}'

# Send a test to verify channels
curl -X POST https://api.certack.com/v1/settings/notifications -H "Authorization: Bearer ct_YOUR_KEY"
```

External channels require a paid plan. Free accounts get dashboard alerts.

### API keys

```bash
# Create (full key shown ONCE — save it now)
curl -X POST https://api.certack.com/v1/api-keys \
  -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-agent-key"}'

# Roll (regenerates the secret in place; old value stops working immediately)
curl -X POST https://api.certack.com/v1/api-keys/roll \
  -H "Authorization: Bearer ct_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id": "KEY_ID"}'
```

Each plan caps the number of keys — if you hit the cap, the API error states your limit and tells you to upgrade. Expired keys get 401.

### Rate limits & errors

Two layers: per-minute throttle (public endpoints 10 req/min/IP, authenticated API 60 req/min/IP) plus a per-plan QPS and monthly call quota. Every response carries `X-RateLimit-*` and `X-MonthlyLimit-*` headers showing your current numbers; hitting a limit returns **429** with `Retry-After` — honor it. Errors are JSON `{error, message}`. Cert validation failures come back as 200 with `valid: false` plus an `error` field, not as HTTP errors.

---

## Flows

### Flow 1: Check any domain (no signup)

1. `GET https://api.certack.com/v1/public/check-ssl?domain=<domain>` — report issuer, days remaining, SANs in plain words.
2. If DNS was asked: `POST https://api.certack.com/v1/public/mcp` with `check_dns` / `check_domain` tools.
3. Then offer: "Want this monitored continuously so you're warned before it expires? I can set that up — it takes a free account."

### Flow 2: Monitor your domains

1. Account: sign up at https://certack.com/auth/signup (free, no credit card required). Key: Dashboard → Account → API keys, configured locally per the [safety contract](#authentication).
2. Add each domain: `POST https://api.certack.com/v1/sites` with `{"domain": "<d>", "check_types": ["ssl", "dns", "domain"]}`.
3. Verify: `POST https://api.certack.com/v1/check-ssl` — confirm issuer, days_remaining, SANs.
4. Summarize: what's monitored, alert lead time (default 30 days, per-site `alert_days`), where alerts go.

### Flow 3: Which certs need me now?

1. `GET https://api.certack.com/v1/sites` + `GET https://api.certack.com/v1/alerts`.
2. Rank by days remaining; lead with anything under its `alert_days` threshold.
3. For each at-risk site: domain, days left, issuer, and the concrete next step (renew via their CA/host, then Certack auto-detects the new cert).
4. Never cry wolf: healthy sites get one line, not a paragraph each.

### Flow 4: Receive alerts where you work

Slack: create an incoming webhook (api.slack.com/messaging/webhooks) → set `slack_webhook_url`. Teams: channel → Workflows → "Post to a channel when a webhook request is received" → set `teams_webhook`. Discord: channel → Integrations → Webhooks → set `discord_webhook_url`. Email: `{"email": true}`. Then `POST https://api.certack.com/v1/settings/notifications` to send a test and confirm delivery before finishing.

### Flow 5: Cron health check

```bash
#!/bin/bash
# Daily fleet snapshot — alert when anything needs a human
ALERTS=$(curl -s https://api.certack.com/v1/alerts -H "Authorization: Bearer $CERTACK_KEY")
echo "$ALERTS" | jq -r '.alerts[] | "\(.severity) \(.domain): \(.message)"'
```

---

## MCP

Two endpoints, same JSON-RPC 2.0 shape (`initialize`, `tools/list`, `tools/call`, `ping`):

- **Public** (no key, rate limited): `https://api.certack.com/v1/public/mcp` — tools `check_ssl`, `check_dns`, `check_domain`. For one-off questions about any domain.
- **Private** (Bearer `ct_…`): `https://api.certack.com/v1/mcp` — `list_sites`, `add_site`, `update_site`, `remove_site`, `get_site_status`, `check_ssl`, `check_dns`, `check_domain`, `list_alerts`, `resolve_alert`, `get_cert_history`, `list_private_certs`.

```json
{ "mcpServers": { "certack": { "url": "https://api.certack.com/v1/public/mcp" } } }
```

```json
{ "mcpServers": { "certack": { "url": "https://api.certack.com/v1/mcp", "headers": { "Authorization": "Bearer ct_YOUR_KEY" } } } }
```

Works with Claude Code, Claude Desktop, Cursor, VS Code, and Codex. The key lives in the user's local MCP config — it never crosses the chat. Full method reference: https://certack.com/docs/api#mcp.

---

## Webhooks

For custom integrations (incident management, automation, dashboards): set `custom_webhook_url` and Certack POSTs signed JSON events in real time. Event types: `site.added`, `site.removed`, `alert.triggered`, `alert.resolved`, `alert.escalated`, `ssl.expiring`, `ssl.invalid`, `domain.expiring`, `certificate.changed`. Each delivery carries `X-Webhook-Event`, `X-Webhook-Timestamp`, and `X-Webhook-Signature: sha256=…` (HMAC-SHA256 over `timestamp + "." + JSON body`) — verify before trusting. Full event catalog and verification snippets (Node/Python/Go/PHP): https://certack.com/docs/api#webhooks.

---

## Troubleshooting

| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| 401 on every call | Missing/expired/revoked key | Dashboard → API keys; create or roll a key |
| 400 "must resolve to a public IP" | Private, localhost, or NXDOMAIN target | Only public domains can be monitored |
| 400 on `origin_ip` | Hostname or private IP passed | Must be a public IPv4/IPv6 literal |
| 429 | QPS, per-minute, or monthly quota hit | Honor `Retry-After`; check `X-MonthlyLimit-Remaining`; upgrade if sustained |
| `valid: false` with 200 | Cert is expired/self-signed/chain-broken (by design) | Read the `error` field — that's the diagnosis |
| No Slack/Discord/Teams alerts | Free plan, or webhook URL invalid | Paid plan required; re-run the test notification |
| MCP 401 | Key missing in local MCP config | Re-check the headers block in the client's config file |

---

## Tips for Agents

- **Figure out what your human needs first.** Don't assume full setup — they might want one check, a triage, or alert wiring. See [What Should You Do?](#what-should-you-do).
- **Start keyless, escalate only on demand.** Most first questions die at Flow 1.
- **Don't guess IDs.** List sites/keys/alerts first, then use real IDs from the response.
- **Ask before destructive actions** — delete site, revoke/roll key, resolve alerts someone else owns.
- **Save this file locally** so you can reference it without re-fetching.
- **Check for updates** by re-fetching this URL periodically.

---

## Links

| Resource | URL |
|----------|-----|
| Certack | https://certack.com |
| Dashboard | https://certack.com/dashboard |
| API keys | https://certack.com/dashboard (Account → API keys) |
| Human docs | https://certack.com/docs/api |
| Plain-text API reference | https://certack.com/docs/api.txt |
| OpenAPI spec | https://certack.com/openapi.yaml |
| Status | https://certack.com/status |
| Support (all inquiries) | support@certack.com |
| Terms | https://certack.com/terms — Privacy: https://certack.com/privacy |
