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-signatureheader? - How do I handle
ALERT_FAILURE,ALERT_RECOVERYandALERT_DEGRADEDalerts? - 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 value | Meaning |
|---|---|
ALERT_FAILURE | Check failed |
ALERT_RECOVERY | Check recovered from failing |
ALERT_DEGRADED | Check is degraded |
ALERT_DEGRADED_RECOVERY | Check recovered from degraded |
ALERT_DEGRADED_FAILURE | Degraded check escalated to failing |
ALERT_FAILURE_DEGRADED | Failing check de-escalated to degraded |
ALERT_FAILURE_REMAIN / ALERT_DEGRADED_REMAIN | Still failing or degraded after a threshold |
ALERT_SSL | SSL certificate expiry alert |
For all alert states, see Checkly alerts overview
Important Headers
| Header | Description |
|---|---|
x-checkly-signature | Hex HMAC-SHA256 of the raw body (only when a webhook secret is set) |
x-checkly-timestamp | When 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
- references/overview.md - Checkly webhook concepts, alert types, template variables
- references/setup.md - Configure the webhook alert channel and secret
- references/verification.md - Signature verification details and gotchas