Skip to content

Webhooks Integration Guide

Webhooks deliver event notifications, on each 15-minute alert run, to any HTTP endpoint you control. Use webhooks to build custom alert pipelines, trigger automation, or feed your SIEM.

Creating a Webhook

curl -X POST \
  -H "Authorization: Bearer bs_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "label": "SOC Alert Pipeline",
    "url": "https://your-server.com/breachspider-webhook"
  }' \
  "https://breachspider.com/api/v1/webhooks"

Event Types

Webhooks receive a single event type, cve.alert, for every alert the alert engine sends. There is no per-webhook event filter: filter in your receiver using the payload fields. The signing secret is generated by BreachSpider and returned once when you create the webhook. See How Alerts Work for which CVEs are alerted.

Webhook Payload

{
  "event": "cve.alert",
  "version": "1.0",
  "timestamp": "2026-09-28T02:15:03.412000+00:00",
  "data": {
    "cve_id": "CVE-2025-32433",
    "title": "Erlang/OTP SSH pre-authentication remote code execution",
    "cvss_score": 10.0,
    "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
    "patch_status": "patched",
    "kev_flagged": true,
    "epss_score": 0.97,
    "sage_priority": "PATCH NOW",
    "published_at": "2025-04-16T22:15:14+00:00",
    "url": "https://breachspider.com/ics-cve/CVE-2025-32433",
    "executive_summary": "AI-generated summary of the vulnerability.",
    "mitigation": "AI-generated mitigation guidance.",
    "causal_boundary": "AI-generated scope note.",
    "virtual_patch": "AI-drafted detection rule, or null. Review before deploying.",
    "watchlist_match": {
      "entity_type": "environment",
      "entity_name": "SCADA Workstation 01 in Water Treatment Plant Alpha"
    }
  }
}

event is always cve.alert. sage_priority is one of PATCH NOW, PATCH NEXT, MONITOR, IGNORE. watchlist_match.entity_type is vendor or product for watchlist matches and environment for asset matches. The AI fields can be null.

Verifying Signatures

Every webhook delivery includes an X-BreachSpider-Signature header. Verify it to confirm the request came from BreachSpider.

import hashlib
import hmac

def verify_signature(payload_body: bytes, secret: str, signature_header: str) -> bool:
    # BreachSpider signs with the SHA-256 hex digest of your webhook secret as the HMAC key.
    key = hashlib.sha256(secret.encode("utf-8")).hexdigest().encode("utf-8")
    expected = hmac.new(key, payload_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature_header)

Retry Policy

BreachSpider waits up to 10 seconds for a 2xx response. Failed deliveries are not retried: the alert is recorded as failed and is not sent again. After 5 failed deliveries the webhook is disabled; re-enable it from the dashboard or with POST /api/v1/webhooks/{id}/enable.