CertiMonitor

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.

ResourceReadWrite
Domainsdomains:readdomains:write
Certificatescertificates:readcertificates:write
Alert rulesrules:readrules:write
Channelschannels:readchannels:write
Tagstags:readtags:write

Endpoints

Domains

  • GET/domainsdomains:read

    Every monitored domain

  • POST/domainsdomains:write

    Start 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:read

    One domain with its latest results

  • PATCH/domains/:iddomains:write

    Change a domain. Turning a check off quietly closes its open alerts

    { port?, enabled?, tags?, tlsChecks?, registrationChecks?, emailChecks? }

  • DELETE/domains/:iddomains:write

    Stop monitoring and delete its history

  • GET/domains/:id/checksdomains:read

    The 50 most recent check results

  • POST/domains/:id/checkdomains:write

    Run the domain's checks now, e.g. right after renewing

Certificates

  • GET/certificatescertificates:read

    Tracked certificates (pasted PEMs)

  • POST/certificatescertificates:write

    Track a certificate from its PEM; private keys are rejected

    { certificate, name?, kind?, notes? }

  • GET/certificates/:idcertificates:read

    One tracked certificate

  • PATCH/certificates/:idcertificates:write

    Change it, or replace the PEM after a renewal

    { name?, kind?, notes?, tags?, certificate?, confirmSubjectChange? }

  • DELETE/certificates/:idcertificates:write

    Stop tracking it

  • GET/domains/:id/certificatescertificates:read

    Every certificate a domain has served, newest first

Alert rules

  • GET/domains/:id/rulesrules:read

    A domain's rules

  • POST/domains/:id/rulesrules:write

    Add a rule to a domain

    { type, threshold?, severity?, enabled?, suppressIfAutoRenew? }

  • GET/certificates/:id/rulesrules:read

    A tracked certificate's rules

  • POST/certificates/:id/rulesrules:write

    Add an expiry rule to a certificate

    { type: "CERT_EXPIRY", threshold, severity? }

  • GET/rules/:idrules:read

    One rule

  • PATCH/rules/:idrules:write

    Change a rule

    { type?, threshold?, severity?, enabled?, suppressIfAutoRenew? }

  • DELETE/rules/:idrules:write

    Delete a rule

Channels

  • GET/channelschannels:read

    Alert channels. Targets are described, never returned

  • POST/channelschannels:write

    Add a channel. A webhook's signing secret is in this response only

    { type, name, target, isDefault?, sendResolved?, criticalOnly?, mentionOnCritical? }

  • PATCH/channels/:idchannels:write

    Change a channel

    { name?, target?, enabled?, isDefault?, sendResolved?, criticalOnly?, mentionOnCritical?, rotateSecret? }

  • DELETE/channels/:idchannels:write

    Delete it and unlink it from every rule

  • POST/channels/testchannels:write

    Send a test message before saving

    { type, target }

  • POST/channels/:id/testchannels:write

    Send a test message to a saved channel

Tags

  • GET/tagstags:read

    Tags with how many items use each

  • POST/tagstags:write

    Create a tag

    { name, color? }

  • PATCH/tags/:idtags:write

    Rename or recolor a tag

    { name?, color? }

  • DELETE/tags/:idtags:write

    Delete 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.