API Access
CertTracker exposes a read-only HTTP API for integrating with NMS systems (LibreNMS, Zabbix, Datadog), dashboards, scripts, and any tooling that already knows how to make an HTTP request. Same data the web UI uses — just JSON.
Plan required. API access is a Business and Enterprise feature. Other plans can mint tokens but every request will return
HTTP 402 plan_requireduntil the company is upgraded. Tokens are not destroyed by a downgrade, so re-upgrading restores access immediately.
Creating a token
- Go to Administration.
- Find the API Tokens card.
- Enter a descriptive name (e.g.
LibreNMS prod,Datadog read-only,incident-response-runbook). - Click Create token.
- The raw token is shown exactly once in a green banner. Copy it into your secrets manager / NMS config now — there is no recovery path. CertTracker only stores a SHA-256 hash plus the first 12 characters of the token for display in the admin list.
Tokens look like ct_live_<32 lowercase characters>. The ct_live_ prefix is deliberate — it makes accidental commits to git or pastes into chat trivially greppable.
Authentication
Every request must include an Authorization: Bearer <token> header:
GET /api/v1/monitors HTTP/1.1
Host: certtracker.12squared.com
Authorization: Bearer ct_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
Accept: application/json
A curl example:
curl -fsS \
-H "Authorization: Bearer $CT_TOKEN" \
https://certtracker.12squared.com/api/v1/monitors
Revoking a token
In the API Tokens card, click Revoke on the row. The token row stays in the list (so the audit trail survives revocation) but every subsequent request that uses it gets HTTP 401. There is no undo — mint a new token if you revoked the wrong one.
Error envelope
All API errors are JSON with a uniform shape so clients can branch on the error code instead of parsing message strings:
{
"error": "plan_required",
"message": "API access requires the Business or Enterprise plan...",
"required_plans": ["business", "enterprise"],
"upgrade_url": "https://certtracker.12squared.com/billing"
}
| HTTP | error code |
Meaning |
|---|---|---|
400 |
bad_request |
Invalid query parameters. Message specifies what. |
401 |
invalid_token |
Authorization header missing, malformed, or token unknown / revoked. |
402 |
plan_required |
Token is valid but the company is not on Business or Enterprise. |
404 |
not_found |
Resource (monitor ID, etc.) not found in your company. |
503 |
api_disabled |
Global kill switch on; retry later. |
503 |
server_error |
Auth backend hiccup; retry. |
Endpoints
GET /api/v1/monitors
List monitors for the authenticated company with cert summary, TLS metadata, and an advisories array per monitor.
Query parameters (all optional):
| Param | Type | Description |
|---|---|---|
status |
string | Exact-match filter on monitor status: Online, Unreachable. |
expires_within_days |
int | Only certificates expiring within N days. |
advisories |
string | Pass open to only return monitors with at least one open advisory. |
Response:
{
"generated_at": "2026-05-28T17:00:00Z",
"company": "12 Squared Technologies LLC",
"count": 7,
"monitors": [
{
"id": 401,
"fqdn": "certtracker.12squared.com",
"port": 443,
"path": "/",
"url": "https://certtracker.12squared.com:443/",
"status": "Online",
"availability_status": "Online",
"certificate_status": "Valid",
"expiration": "2026-07-16T07:27:32",
"days_to_expiry": 49,
"subject": "CN:*.12squared.com",
"issuer": "C:US,O:LetsEncrypt,CN:R12",
"signature_algorithm": "sha256WithRSAEncryption",
"public_key_bits": 2048,
"public_key_type": "RSA",
"tls_version": "TLSv1.3",
"cipher_suite": "TLS_AES_256_GCM_SHA384",
"hostname_match": true,
"advisories": [],
"advisory_count": 0,
"last_polled": "2026-05-28T16:45:00"
}
]
}
GET /api/v1/monitors/<id>
Full detail for a single monitor — same fields as the list endpoint plus the complete TLS audit block (protocol acceptance, cipher suites, HSTS, OCSP, CAA, compliance rollups). Use this when you need everything; use the list endpoint for periodic scrapes.
GET /api/v1/advisories
Flat list of every open (unacknowledged) advisory across your company. Each row carries enough monitor context (monitor_id, monitor_fqdn, monitor_port) for an NMS adapter to file the alert without an extra round-trip.
{
"generated_at": "2026-05-28T17:00:00Z",
"company": "12 Squared Technologies LLC",
"count": 1,
"advisories": [
{
"monitor_id": 401,
"monitor_fqdn": "certtracker.12squared.com",
"monitor_port": 443,
"alert_type": "weak_key_size",
"detail": "RSA 1024-bit key — below the 2048-bit minimum...",
"first_seen": "2026-05-28T16:00:00",
"last_seen": "2026-05-28T17:00:00"
}
]
}
GET /api/v1/integrations/librenms/services
Nagios-shaped JSON list, one entry per monitor. Used by the LibreNMS check script. See the LibreNMS integration recipe for end-to-end wiring.
GET /api/v1/integrations/librenms/check?label=<fqdn>:<port>
Single nagios-format plain-text response with an X-Nagios-Exit-Code HTTP header. Designed to be wrapped by a tiny shell script that calls curl and exit $code. Returns UNKNOWN/3 if no monitor matches.
Rate limits
There is no per-token rate limit in the current release. If we add one later it will be configurable per-deploy via settings.api.rate_limit_per_minute (default 0 = unlimited) and will surface as HTTP 429 with a retry_after field. Build clients defensively — assume the limit may exist tomorrow.
What is not in v1
- No write operations. Acknowledging an advisory or force-polling a monitor still requires the web UI.
- No per-token scoping (read-only vs admin). Every token has identical, full read access to the company's data.
- No webhook / push delivery. The API is pull-only.
These are deliberate v1 cuts and on the roadmap — vote for the ones you want next.