Skip to content

Webhook events reference

View as Markdown

A v2 webhook receives an HTTPS POST for each event it subscribes to. This page lists every event and its payload. How to create webhooks, verify signatures and handle retries is on the Webhooks page.

Every delivery body has the same five members:

Member Type Meaning
id string The delivery id, d_ + 32 hex characters. Same as the HT-Delivery header; stable across retries and redeliveries. Deduplicate on it.
event string The event name (case-sensitive).
occurredAt integer When the event happened, Unix seconds (not when this attempt was sent).
apiVersion string Always "v2".
data object The event’s payload - see below.

Members with no value are omitted. New members may be added; ignore ones you do not know.

Headers: HT-Event, HT-Delivery, HT-Webhook, HT-Attempt, HT-Signature, and the Standard Webhooks trio webhook-id, webhook-timestamp, webhook-signature, plus any custom headers you configured.

Event Fires when Addressed to Retried
monitor.down An alert-grade down transition - after recheck confirmation and any alert delay. webhooks whose scope covers the monitor yes
monitor.up The matching recovery. scope yes
monitor.repeatedlyDown The “still down” reminder tier is reached. scope yes
incident.opened A down episode opens - every episode, including one inside a maintenance window. scope yes
incident.closed The episode resolves. scope yes
monitor.created A monitor is created (one event per monitor, including each one in a bulk create). scope no
monitor.updated A monitor’s configuration changes (one per monitor, including bulk updates). scope no
monitor.deleted A monitor is deleted (one per monitor, including bulk deletes). scope no
maintenance.ended A maintenance window ends on schedule (endedEarly: false) or is cancelled while active (endedEarly: true). scope on schedule: yes; cancel: no
certificate.expiring An SSL certificate check crosses a warning threshold. scope yes
domain.expiring A domain expiry check crosses a warning threshold. scope yes
contact.confirmed A contact becomes confirmed. every enabled webhook of the account subscribed to it (scope does not apply) no
contact.updated A contact’s configuration changes, including bulk updates and a create that resolves to an existing contact. account-wide, as above no
job.completed An async job reaches succeeded, partial, failed or cancelled. Callback only. the webhook named in the job request’s callback no
job.progress A running job reports progress (throttled). Callback only, with callback.on: "progress". the callback webhook no

There is no maintenance.started event. GET /webhook returns the live catalogue in summary.eventTypes, and the OpenAPI document (/openapi/v2.json) publishes each payload schema under webhooks.

monitor.down, monitor.up, monitor.repeatedlyDown

Section titled “monitor.down, monitor.up, monitor.repeatedlyDown”
Field Type Meaning
monitor.id, monitor.name, monitor.url, monitor.type string The monitor.
state up / down The monitor’s state as of this alert (down for both down events).
occurredAt integer When the alert was decided.
checkNumber integer The check’s number in the monitor’s series.
error.code, error.message, error.codename int / string The failure; on monitor.up, the outage that just ended. codename is the value to switch on - see error codes.
failedAt integer When the failing check ran (monitor.down only).
firstFailedAt, lastFailedAt integer When the outage began, and its last failing check (monitor.up, monitor.repeatedlyDown).
failedChecks integer Failing checks during the outage (monitor.up, monitor.repeatedlyDown).
downtimeSec integer How long the outage lasted.
recheck[] array What each location saw during the confirming recheck: location (id, country, region, city, ip), state, error. Empty on monitor.repeatedlyDown.
{
"id": "d_e944b34a57924935968d32ea94a07832",
"event": "monitor.down",
"occurredAt": 1790000120,
"apiVersion": "v2",
"data": {
"monitor": { "id": "79c21af5-0f43-4262-b7b6-841cd3b39b19", "name": "Shop", "url": "https://shop.example.com/", "type": "http" },
"state": "down",
"occurredAt": 1790000120,
"failedAt": 1790000060,
"error": { "code": 503, "message": "Service Unavailable", "codename": "Http 503" },
"recheck": [
{ "location": { "country": "Germany", "city": "Frankfurt" }, "state": "down",
"error": { "code": 503, "message": "Service Unavailable", "codename": "Http 503" } }
]
}
}
Field Type Meaning
incidentId string The incident id - use it with GET /monitor/incident/{id}. The same id on open and close.
monitorId string The monitor.
start integer When the episode began.
cause string The failure that opened it, as described by the engine.
underMaintenance boolean True when it began inside a maintenance window (no alert was sent).
end integer When it resolved (incident.closed only).
durationSec integer Its length (incident.closed only).
checkCount integer Failing checks observed; 0 when not counted (incident.closed only).

monitor.created, monitor.updated, monitor.deleted

Section titled “monitor.created, monitor.updated, monitor.deleted”
  • monitor.created and monitor.updated: data is the full monitor, exactly as GET /monitor/{id} returns it.
  • monitor.deleted: data is the delete receipt - id, deleted, type, name, url and cascaded (what was removed with it).
Field Type Meaning
maintenanceId string The window - use it with GET /maintenance/{id}.
name string The window’s name.
from integer The window’s start.
to integer The scheduled end (not reached when cancelled early).
endedAt integer When it actually ended.
endedEarly boolean True when cancelled while active.
monitorIds array The window’s monitors that this webhook’s scope covers.
Field Type Meaning
monitorId string The monitor whose certificate is expiring.
notAfter integer When the certificate expires.
daysLeft integer Days until expiry.
issuer string The issuing authority, when known.
threshold integer The warning threshold crossed, in days.
endpoint string host:port.
Field Type Meaning
monitorId string The monitor whose domain is expiring.
expiresAt integer When the registration expires.
daysLeft integer Days until expiry.
registrar string The registrar, when known.
sharedDomain string The registered domain the expiry belongs to (it can answer for several monitors).
threshold integer The warning threshold crossed, in days.
  • contact.confirmed: contactId, type (email, sms, …), address, confirmedAt, via (code - a code was entered; inherit - the address was already confirmed on the account).
  • contact.updated: data is the full contact, as GET /contact/{id} returns it. This event is the only way to hear about contact edits - GET /contact?updatedSince= does not show them.
Field Type Meaning
jobId string Use it with GET /job/{id}.
kind string What the job does (monitor.bulkCreate, contact.bulkWrite, …).
state string job.completed: succeeded, partial, failed or cancelled. job.progress: queued or running.
summary object Counts of created, updated, skipped, failed, deleted items.
progress object done and total.
created, finishedAt integer Submission and completion time (job.completed).
error string Why the whole job failed, if it did (job.completed).
results[], resultsTruncated array / boolean The first page of per-item receipts (job.completed).
resultsUrl string Where to read every receipt, paged.