Skip to content

Custom webhook integration

Send signed JSON payloads to any HTTPS endpoint for custom automation.

Last updated April 21, 2026

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: POST or PUT.
  • Content type: application/json.
  • User agent: StatusOwl-Webhook/1.0.
  • Optional HMAC-SHA256 signature in the X-StatusOwl-Signature header.

Setting up a webhook

  1. Go to Integrations → Add Integration and choose Webhook.
  2. Enter the target URL (must be HTTPS in production).
  3. Pick the HTTP method (POST is almost always correct).
  4. 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.
  5. Select which events to fire on.
  6. Click Save, then Send Test to confirm delivery.

Payload shape

A test payload looks like this:

json
{
  "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:

node.js
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.