Agent skill

Checkly Webhooks Skill

Receive and verify Checkly webhooks. Use when setting up Checkly alert channel webhook handlers, debugging x-checkly-signature verification, or handling ALERT_FAILURE, ALERT_RECOVERY and ALERT_DEGRADED check alerts.

Install this skill

npx skills add hookdeck/webhook-skills --skill checkly-webhooks


When to Use This Skill

  • How do I receive Checkly webhooks?
  • How do I verify the x-checkly-signature header?
  • How do I handle ALERT_FAILURE, ALERT_RECOVERY and ALERT_DEGRADED alerts?
  • Why does my Checkly webhook signature verification fail?
  • How do I set a Checkly webhook secret and a custom payload template?

Verification (core)

Checkly signs the raw, rendered request body with HMAC-SHA256 keyed on your webhook secret and sends the lowercase hex digest in x-checkly-signature. There is no prefix and no signed timestamp. The secret is optional in Checkly, so you must set one for the header to be sent.

Node:

const crypto = require('crypto');

function verify(rawBody, signature, secret) {
  if (!signature || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  try {
    return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  } catch {
    return false; // different lengths
  }
}

Python:

import hmac, hashlib

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    if not signature or not secret:
        return False
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature.encode(), expected.encode())

The body is a template you write, so the content type can be anything. In Express use express.raw({ type: '*/*' }), not express.json(). Re-serializing parsed JSON changes whitespace and breaks the digest.

For complete handlers with route wiring, event dispatch, and tests, see:

Common Alert Types

The payload has no fixed schema. You choose the fields in the webhook template; the examples assume alertType, checkName and checkId.

ALERT_TYPE valueMeaning
ALERT_FAILURECheck failed
ALERT_RECOVERYCheck recovered from failing
ALERT_DEGRADEDCheck is degraded
ALERT_DEGRADED_RECOVERYCheck recovered from degraded
ALERT_DEGRADED_FAILUREDegraded check escalated to failing
ALERT_FAILURE_DEGRADEDFailing check de-escalated to degraded
ALERT_FAILURE_REMAIN / ALERT_DEGRADED_REMAINStill failing or degraded after a threshold
ALERT_SSLSSL certificate expiry alert

For all alert states, see Checkly alerts overview

Important Headers

HeaderDescription
x-checkly-signatureHex HMAC-SHA256 of the raw body (only when a webhook secret is set)
x-checkly-timestampWhen the webhook was sent. Not signed; use only to ignore late deliveries

Environment Variables

CHECKLY_WEBHOOK_SECRET=your_webhook_secret   # Set in the webhook alert channel in Checkly

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 checkly --path /webhooks/checkly

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 4, 2026

View on GitHub →