When configuring custom Webhook channels, SteadyStack sends cryptographically signed HTTP POST requests to your endpoint.
Verifying Signatures
Every webhook delivery includes an X-SteadyStack-Signature header containing a computed HMAC-SHA256 signature using your channel's webhook secret.
Verification Example (Node.js / TypeScript)
TYPESCRIPT
import crypto from "node:crypto";
export function verifySteadyStackWebhook(
rawBody: string,
signatureHeader: string,
secret: string
): boolean {
const expectedSignature = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expectedSignature)
);
}Verification Example (Go)
GO
package webhook
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)
func VerifySignature(rawPayload []byte, signature string, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(rawPayload)
expectedMAC := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(signature), []byte(expectedMAC))
}Webhook Payload Schema
JSON
{
"event": "incident.triggered",
"timestamp": "2026-08-22T21:00:00.000Z",
"incident": {
"id": "inc_9a8b7c6d5e",
"status": "DOWN",
"cause": "HTTP_STATUS_500",
"severity": "CRITICAL",
"runbook_url": "https://wiki.company.com/runbooks/api-500"
},
"monitor": {
"id": "mon_123456",
"name": "Production API Gateway",
"url": "https://api.example.com/health",
"type": "HTTP"
},
"quorum": {
"total_regions": 7,
"failing_regions": 6,
"breakdown": {
"wnam": { "status": 500, "latency_ms": 142 },
"enam": { "status": 500, "latency_ms": 98 },
"weur": { "status": 500, "latency_ms": 112 },
"apac": { "status": 500, "latency_ms": 230 }
}
}
}