API reference
Everything you can do in the dashboard for domains, certificates, alert rules, channels and tags, you can do from a script or CI job. Requests and responses are JSON, and every path below starts with /api/v1.
Authentication
An owner or admin creates a key under Settings, API keys. The key belongs to one organization and only ever sees that organization's data. Send it as a Bearer token:
curl https://<your CertiMonitor host>/api/v1/domains \ -H "Authorization: Bearer cm_live_…"
- The full key is shown once, when it's created. We only store a hash of it.
- A key stops working when it's revoked, when it expires, or when the person who created it is removed or is no longer an owner or admin.
- Keys aren't asked for two-factor authentication, even when your organization requires it for people. Treat a key like a password and keep it in your CI's secret store.
Scopes
Each key has read or write access, or none, to each resource. Write includes read. Organization settings, members and API keys can't be changed with a key.
| Resource | Read | Write |
|---|---|---|
| Domains | domains:read | domains:write |
| Certificates | certificates:read | certificates:write |
| Alert rules | rules:read | rules:write |
| Channels | channels:read | channels:write |
| Tags | tags:read | tags:write |
Endpoints
Domains
GET
/domainsdomains:readEvery monitored domain
POST
/domainsdomains:writeStart monitoring a domain. Checks default to TLS and registration on, email off; at least one must be on
{ hostname, port?, tlsChecks?, registrationChecks?, emailChecks? }
GET
/domains/:iddomains:readOne domain with its latest results
PATCH
/domains/:iddomains:writeChange a domain. Turning a check off quietly closes its open alerts
{ port?, enabled?, tags?, tlsChecks?, registrationChecks?, emailChecks? }
DELETE
/domains/:iddomains:writeStop monitoring and delete its history
GET
/domains/:id/checksdomains:readThe 50 most recent check results
POST
/domains/:id/checkdomains:writeRun the domain's checks now, e.g. right after renewing
Certificates
GET
/certificatescertificates:readTracked certificates (pasted PEMs)
POST
/certificatescertificates:writeTrack a certificate from its PEM; private keys are rejected
{ certificate, name?, kind?, notes? }
GET
/certificates/:idcertificates:readOne tracked certificate
PATCH
/certificates/:idcertificates:writeChange it, or replace the PEM after a renewal
{ name?, kind?, notes?, tags?, certificate?, confirmSubjectChange? }
DELETE
/certificates/:idcertificates:writeStop tracking it
GET
/domains/:id/certificatescertificates:readEvery certificate a domain has served, newest first
Alert rules
GET
/domains/:id/rulesrules:readA domain's rules
POST
/domains/:id/rulesrules:writeAdd a rule to a domain
{ type, threshold?, severity?, enabled?, suppressIfAutoRenew? }
GET
/certificates/:id/rulesrules:readA tracked certificate's rules
POST
/certificates/:id/rulesrules:writeAdd an expiry rule to a certificate
{ type: "CERT_EXPIRY", threshold, severity? }
GET
/rules/:idrules:readOne rule
PATCH
/rules/:idrules:writeChange a rule
{ type?, threshold?, severity?, enabled?, suppressIfAutoRenew? }
DELETE
/rules/:idrules:writeDelete a rule
Channels
GET
/channelschannels:readAlert channels. Targets are described, never returned
POST
/channelschannels:writeAdd a channel. A webhook's signing secret is in this response only
{ type, name, target, isDefault?, sendResolved?, criticalOnly?, mentionOnCritical? }
PATCH
/channels/:idchannels:writeChange a channel
{ name?, target?, enabled?, isDefault?, sendResolved?, criticalOnly?, mentionOnCritical?, rotateSecret? }
DELETE
/channels/:idchannels:writeDelete it and unlink it from every rule
POST
/channels/testchannels:writeSend a test message before saving
{ type, target }
POST
/channels/:id/testchannels:writeSend a test message to a saved channel
Tags
GET
/tagstags:readTags with how many items use each
POST
/tagstags:writeCreate a tag
{ name, color? }
PATCH
/tags/:idtags:writeRename or recolor a tag
{ name?, color? }
DELETE
/tags/:idtags:writeDelete a tag and untag everything
Errors
Errors share one shape. error is readable, reason tells apart cases that share a status, and details lists the fields a 400 rejected. Quote the requestId if you contact us about a failed request.
{
"error": "API key is missing the domains:write scope",
"reason": "insufficient_scope",
"requestId": "…"
}- 400
- The body isn't valid JSON or fails validation. details lists the fields
- 401
- Missing, unknown, revoked or expired key, or its creator is no longer an owner or admin (reason: api_key_creator_removed)
- 402
- Your plan's limit, e.g. the number of domains
- 403
- The key lacks the scope (reason: insufficient_scope), or the endpoint needs a signed-in person (reason: session_only)
- 404
- Not found in your organization
- 409
- Already exists, e.g. the same hostname and port twice
- 429
- Rate limited. Wait for the Retry-After header's seconds
Rate limits
Each key can make 300 requests a minute. Running a check has its own limits: 60 an hour per organization and 5 per domain every 10 minutes. Over a limit, you get a 429 with a Retry-After header in seconds.