Webhooks push events to your endpoint as they happen, so your systems react without polling. Use them to open tickets, notify chat, or drive a SOAR playbook. The case events they carry come out of the SIEM correlation and SOAR response engine, so your systems learn about an incident at the same moment your analysts do.
Subscribe
Register an endpoint (scope webhooks:write):
curl -X POST https://api.intsignal.com/v1/webhooks \
-H "Authorization: Bearer $INTSIGNAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/intsignal",
"events": ["case.opened", "case.updated", "case.closed"]
}'
The response includes a signing secret — store it to verify deliveries.
Event types
| Event | Fires when |
|---|---|
case.opened | A new SOC case is created |
case.updated | A case changes status or gains a note |
case.closed | A case is resolved |
device.status_changed | A monitored device changes health/state |
Payload
{
"id": "evt_71b0a4",
"type": "case.opened",
"created_at": "2026-07-29T09:12:44Z",
"data": { "id": "case_8f21c0", "severity": "high", "status": "open" }
}
Verify signatures
Every delivery includes an X-IntSignal-Signature header — an HMAC-SHA256 of
the raw request body using your signing secret. Recompute it over the raw
bytes and compare, in constant time, before trusting the payload.
// Node / Express — verify(req) used by the recipes
import crypto from "node:crypto";
export function verify(req) {
const sig = req.get("X-IntSignal-Signature") || "";
const expected = crypto
.createHmac("sha256", process.env.INTSIGNAL_WEBHOOK_SECRET)
.update(req.body) // req.body must be the RAW buffer (express.raw)
.digest("hex");
const a = Buffer.from(sig), b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
# Flask — read the raw body, compare in constant time
import hmac, hashlib
def verify(request):
sig = request.headers.get("X-IntSignal-Signature", "")
expected = hmac.new(
os.environ["INTSIGNAL_WEBHOOK_SECRET"].encode(),
request.get_data(), # raw body bytes
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(sig, expected)
Warning
Verify against the raw body (parse it only after verifying), use a constant-time comparison, and reject anything that doesn't match — an unverified endpoint can be spoofed.
Delivery & retries
- Respond
2xxquickly (within a few seconds). Do heavy work asynchronously. - Non-
2xxor timeouts are retried with exponential backoff for up to 24 hours. - Deliveries can arrive more than once — make handlers idempotent by keying
on the event
id. - Inspect recent deliveries and redeliver from Portal → Settings → Webhooks.
