Custom webhook integration
Send signed JSON payloads to any HTTPS endpoint for custom automation.
The custom webhook integration POSTs (or PUTs) a JSON payload to any HTTPS endpoint you control. Use it to wire StatusOwl into incident tools, ticketing systems, internal dashboards, chat platforms we don't natively support, or auto-remediation scripts.
Overview
- HTTP method:
POSTorPUT. - Content type:
application/json. - User agent:
StatusOwl-Webhook/1.0. - Optional HMAC-SHA256 signature in the
X-StatusOwl-Signatureheader.
Setting up a webhook
- Go to Integrations → Add Integration and choose Webhook.
- Enter the target URL (must be HTTPS in production).
- Pick the HTTP method (
POSTis almost always correct). - Optional: paste a shared secret. StatusOwl will sign every outgoing payload with HMAC-SHA256 using that secret so your receiver can verify the request came from us.
- Select which events to fire on.
- Click Save, then Send Test to confirm delivery.
Payload shape
A test payload looks like this:
{
"event": "integration.test",
"integration_uuid": "9a0c...",
"integration_name": "On-call automation",
"organization_uuid": "3f5b...",
"timestamp": "2026-04-21T14:03:22.184Z",
"message": "StatusOwl webhook integration test"
}Real monitor events include the monitor identity, state transition, and a link back to the incident. Always dispatch based on the top-level event field and treat unknown fields as forward-compatible additions.
HMAC signature verification
When a secret is configured, StatusOwl computes HMAC-SHA256(secret, raw_body) and sends the hex digest in the header X-StatusOwl-Signature: sha256=<hex>. Verify in your receiver using constant-time comparison:
import crypto from 'node:crypto';
function verifyStatusOwlSignature(rawBody, headerValue, secret) {
if (!headerValue?.startsWith('sha256=')) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
const given = headerValue.slice('sha256='.length);
// Lengths must match before timingSafeEqual
if (expected.length !== given.length) return false;
return crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(given, 'hex'),
);
}Verify the raw body
Compute the HMAC over the raw request bytes, not a re-serialized JSON object. Many web frameworks discard the raw body after parsing — configure yours to keep it (e.g. Express express.raw() or verify callback on express.json()).
Retries and SSRF protection
- Delivery retries up to 3 times with exponential backoff (500 ms, 1 s) on network errors and non-2xx responses.
- The target URL is validated both at save time and at dispatch time. Private network ranges (
127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16), link-local addresses, and cloud metadata endpoints are rejected to prevent SSRF. - If SSRF protection blocks a request, delivery fails immediately with no retry.