Skip to content

ACME check-ins & renewals

Preferred method: CertIntel Agent

The CertIntel Agent handles certificate workflows, renewals, check-ins and reporting automatically, making setup and ongoing management easier. Start with the Windows Agent or Linux Agent.

The scripts on this page are API reporting examples for cases where you need a custom integration or want to keep an existing ACME client. They report similar information, but require you to configure and maintain the client, scripts, credentials and scheduler yourself.

Four POST requests, all made with the same write-scoped API key (the API Keys page in your dashboard), cover a scheduled ACME renewal run. CertIntel bundles example wrappers for simple-acme, Certbot and Posh-ACME - see Download the scripts below. The same flow adapts to any other ACME client.

For DNS validation through CertIntel, install an ACME client plugin as well. Plugins handle challenge TXT values; these scripts report runs and certificate details. Use a separate DNS credential for the plugin and a write-scoped key for reporting. All four DNS plugins have been tested; the optional Certbot and Posh-ACME reporting wrappers below remain examples to test in your environment.

Call Fires when Status
POST /api/v1/checkins/start Before the scheduled task runs 202
POST /api/v1/checkins After the scheduled task finishes, whether or not anything was due 201
POST /api/v1/renewals/enrich During install/store, with the certificate's real details 201
POST /api/v1/renewals When a renewal actually runs (success or failure) 201

Every request carries one auth header and a JSON body:

X-Api-Key: cik_<prefix>.<secret>
Content-Type: application/json; charset=utf-8

Field sizes are enforced. A value over its limit makes the whole request fail with 422 and a body like {"type":"https://certin.tel/problems/unprocessable-entity","title":"Unprocessable Entity","status":422,"detail":"Request validation failed.","errors":[{"field":"log_output","message":"String should have at most 32768 characters","type":"string_too_long"}],"request_id":"…"}; nothing is stored. Truncate long logs and error text in your script before sending.

Policy ID and attempt ID

Send the stable certificate-policy ID as renewal_id, and a separate unique run_id for each new issuance/renewal attempt. Use that same run_id on every enrich, success, and failure report for the attempt. Persist it across restarts, installation retries, and report replay. A new attempt needs a new ID.

The native Agent handles this automatically. The platform correlates by reporting key and run_id (also accepted as client_run_id). A failed later attempt remains separate from an earlier success; the stable renewal_id groups their history and must not be reused as an attempt ID.

Legacy clients without a run ID are still accepted. Correlation uses thumbprint and compatible outcome, or adopts an unfinished pending stub for the same renewal policy. A thumbprint-less terminal report does not overwrite an earlier terminal result merely because both have the same policy ID. Prefer explicit run IDs for new integrations. Successful replacement links use old_certificate_thumbprint.

Error text follows the outcome. When a later report for the same run_id changes the attempt's status - the retry of a run that failed during a CA outage and then succeeded, for example - it replaces the earlier errors, even when it carries none, so a recovered attempt is not listed with both success and errors. A repeat report of the same outcome without errors keeps the earlier text.

On the dashboard Renewals page each failure shows the first line of its error. Repeated failures of one renewal (the same reporting key and renewal_id) show as one row, the newest, with +N earlier, which opens every attempt of that renewal; Every failed attempt (not grouped) lists each attempt instead. A failure's detail leads with the newest error of its renewal (an older failure says Newest error and offers Open the newest failure) and What to do, which names the exact record for a DNS-01 CNAME that points to the wrong place.

On the dashboard Renewals page, an administrator can acknowledge a failed renewal with an optional reason. Acknowledged events are hidden by default until Acknowledged is set to Yes or All; they also leave the renewal-failure attention count. Acknowledgement changes alert visibility, not the reported result or certificate state.

When the Agent tries again

A failure says what went wrong; whether to wait or to act depends on what the Agent does next. The CertIntel Agent (1.9.0+) reports, for each certificate whose issuance, renewal or installation is not settled, what it does next by itself, and the dashboard shows it beside the failure:

  • on the Renewals list and in a renewal's pop-out;
  • on the certificate's page (Next attempt);
  • in the Agent's detail pop-out on the Agents page, under Failing certificates, with the command that tries now;
  • on a proposal's card on a workflow's page (Next attempt);
  • in the steps of Get a certificate for a server;
  • in the failure alert (Next attempt; next_attempt in the generic webhook JSON).

Times are shown in your display time zone, with how far away they are.

What you read What it means
The agent tries the renewal again by itself in 42 minutes, at 14:05 CST. 3 attempts in a row have failed so far. A failed issuance or renewal is tried again with a growing wait. Nothing to do if the cause was temporary.
Stopped retrying - The agent will not try the renewal again by itself: the certificate authority refused the request for a reason that a retry cannot fix. The CA refused the request and a retry cannot change that, for example a CAA record that does not allow the CA. Fix what the error names, then start it on the device.
Stopped retrying - … it stopped after 12 failed attempts in a row. The Agent stops after 12 failed attempts in a row. Fix the cause, then start it on the device.
The agent tries the installation again by itself every 30 seconds while the certificate is new on the device. A certificate that is new on the device is installed and checked again every 30 seconds for about 15 minutes, then less often.
The agent installs the renewed certificate when its deployment window opens, in 3 hours, at 22:00 CET. The renewed certificate waits for its deployment window.
The agent's next try of the renewal was due at 14:05 CST; waiting for the agent's next report. The planned time passed and the Agent has not reported since.
The agent has no further attempt planned for this certificate. The Agent reports that it plans nothing for it.

To act instead of waiting, run the command the page names on the device (with sudo on Linux, from an elevated prompt on Windows):

Command Use it
certintel certificates issue ID For a certificate that was never issued.
certintel certificates force-renew ID For a renewal.
certintel deployments retry ID To install an issued certificate at once: after fixing a failed installation, or without waiting for the deployment window.

Renew now in the dashboard is not offered for a certificate the Agent stopped retrying; the Agent refuses such a request. Start it on the device.

The Agent's regular report is hourly. When what it does next for a certificate changes, it reports right away, at most once every two minutes, so the time of the next try arrives with the failure.

Check-in: start signal

A lightweight "I'm about to run" signal. A host that stalls before it can post its completion still leaves a record that it started.

Field Type Notes
task_name string optional label, e.g. simple-acme
computer_name string optional; labels the device

Check-in: completion

Posted after the scheduled task finishes. Backs the Agents page's freshness tracking.

Field Type Notes
status enum started / success / failure / completed / skipped. Use completed for a plain "the run reached its end" bookend that asserts nothing about whether renewals succeeded - pair it with a started check-in so a run that dies partway leaves a started with no completed.
task_name string optional
computer_name string optional
started_at, completed_at string (ISO-8601) optional
message string optional; captured console output, at most 8,192 characters
renewals_attempted, renewals_succeeded integer optional, default 0

Renewal event

Posted whenever a renewal actually runs - success or failure.

A success or failure report is also the earliest sign that what an endpoint serves has changed, so CertIntel immediately re-checks every endpoint in the same organization whose hostname is covered by the renewed certificate's subject or SANs (a wildcard covers one label, as in TLS): public endpoints are probed right away, exactly like their Check now button, and internal endpoints are flagged for the agent's next check-in. Paused and deleted endpoints, and pending reports, are left alone. Without this the inventory would show the old and new certificate side by side until the endpoint's next scheduled check.

A successful report that carries a renewal_id (up to 128 characters) also links each covered public endpoint, paused ones included, to that certificate, so CertIntel can tell when the endpoint is still serving an older certificate after a grace period (24 hours by default); see Served versus issued. Send renewal_id and certificate_sha256 (or certificate_b64) for the most reliable comparison.

Field Type Notes
status enum success / failure / pending / superseded
event_type string optional; the ACME client's own verbatim event label, stored as sent (max 60 chars). Client-agnostic and open-ended - simple-acme sends created / success / success-with-errors / failure / cancel / test; another client may send anything else (e.g. renewed, deployed). Independent of status: status is CertIntel's normalised outcome, event_type is the client's raw word. Not validated against any list; an over-length value is a 422.
subject string certificate common name / CN (accepts common_name as an alias)
friendly_name string optional; the client's own label for the certificate (e.g. simple-acme's friendly name) - not the subject/CN. Shown next to the subject, never in place of it.
sans string[] subject alternative names; at most 100 entries of up to 253 characters
certificate_thumbprint string SHA-1 thumbprint; identifies the certificate and supports legacy correlation (accepts thumbprint).
old_certificate_thumbprint string blank on first issuance; links the replacement chain (accepts old_thumbprint)
renewal_id string Optional stable certificate-policy ID, shared across renewals; groups history (also accepted as client_renewal_id). Maximum 200 characters.
run_id string Unique ID for one issuance/renewal attempt; send unchanged on all its reports and retries (also accepted as client_run_id or event_id). Maximum 200 characters.
cache_file string optional; path the client wrote the issued cert to
store_path string optional; the store / directory the client installed into, e.g. My / WebHosting / an IIS site / a filesystem path
store_type string optional; the store kind, e.g. WinCertStore / PEM / PFX / IIS
certificate_not_before, certificate_expiry, certificate_issued_at string (ISO-8601) optional
acme_client string e.g. simple-acme, certbot, posh-acme
serial_number, certificate_sha256, spki_sha256 string optional additional identifiers of the issued certificate (certificate_sha256 also accepts fingerprint_sha256, which the Agent sends)
certificate_b64 base64 DER optional issued certificate (up to 32,768 characters); lets CertIntel record the real SHA-256 and merge the renewal with probe sightings of the same certificate. No chain field is accepted on renewal reports.
x509_extensions object[] optional, at most 32 entries of {oid, critical, value} where value is base64 DER up to 1,024 bytes (16,384 bytes in total); OIDs must be unique. Normally supplied only by the Agent.
computer_name string optional
errors string optional; client-reported error text (accepts error), at most 8,192 characters - shown as a first-class failure reason; cleared when a later report for the same run_id changes the status
log_output string optional; run log, at most 32,768 characters (truncate before sending)
failed_step object optional, on a failure report for an installation step (the Agent sends it with event_type: installation_failed): step_id, action, exit_code, stdout_tail, stderr_tail (the redacted end of each stream), truncated and redacted. Each tail is stored capped at 8,192 characters with control characters other than newline and tab removed, shown as Failed step output on the renewal and sent with the renewal.failure alert; see Failed step output.
deployment_window_override object optional, on a success report: reason (expires_before_window), window_opens_at, certificate_expires_at, margin_hours. Sent when the Agent installed a renewed certificate outside its deployment window; raises the deployment.window_override alert.

Renewal enrich

Posted from the install/store step. Same body shape as the renewal event; the server forces status = pending. Send the same run_id and renewal_id on enrich and the subsequent terminal event so they complete one attempt. A pending report never replaces a failure or success already recorded for the run: it adds its details and keeps that status (and a failure's error and step output, until the success replaces them), and the answer's status is the row's. Send the issued certificate_thumbprint, subject, sans, certificate_not_before, certificate_expiry, and predecessor old_certificate_thumbprint when available.

Download the scripts

The files below are published here for download without signing in; copies bundled under scripts/ in a CertIntel deployment may be older. Each family has a README.md with a full setup and troubleshooting walkthrough. All scripts read CERTINTEL_API_BASE (or CERTINTEL_API_URL / CERTINTEL_CHECKINS_URL) and CERTINTEL_API_KEY from the environment, falling back to values you edit at the top of the file.

simple-acme (example; verified end-to-end)

Use all three on a host; Checkin-Wrapper.ps1 replaces wacs.exe as the scheduled-task action and exports the config the other two inherit.

Warning

Certbot and Posh-ACME below are example scripts. Review them and test against Let's Encrypt staging before relying on them in production.

Certbot (PowerShell 7 / Linux)

Posh-ACME (Windows PowerShell 5.1+ / PowerShell 7)