Documentation
Webhook Payload Reference
Complete reference for all 46 alert types delivered via webhook notifications.
Payload Schema
Every webhook delivery sends a JSON POST request with the following top-level fields. The structure is identical across all 46 alert types.
| Field | Type | Description |
|---|---|---|
| event | string | Always "alert.created" |
| source | string | Always "socwarden" |
| alert_id | string|null | UUID of the alert. Null for IP action notifications. |
| event_id | string|null | UUID of the source event that triggered this alert. |
| alert_type | string | Alert type identifier (one of 43 types documented below). |
| severity | string | "low", "medium", "high", or "critical". |
| actor | string|null | User or account identifier associated with the event. |
| ip | string|null | Source IP address. CIDR notation for IP actions. |
| project | string|null | Project slug where the event originated. |
| summary | string | Human-readable description of what was detected. |
| risk_score | number | Composite risk score from 0 to 100. |
| mitre | string|null | MITRE ATT&CK technique ID (e.g. T1110.003). Null when not applicable. |
| geo | object|null | GeoIP data: country, country_code, city, latitude, longitude, timezone. Null for IP actions. |
| network | object|null | Network intel: network_type, is_tor, is_vpn, is_proxy, is_datacenter, isp, asn. Null for IP actions. |
| tags | string[] | Array of detection tags applied during enrichment. |
| org_name | string | Name of the organization that owns this project. |
| event_type | string|null | Original event type that triggered this alert (e.g. auth.login.failure). |
| created_at | string | ISO 8601 timestamp of when the alert was created. |
Alert Types
SOCWarden produces 43 distinct alert types grouped into 5 categories. Click any alert type to view a full JSON sample payload.
Behavioral Detections(6)
Request Anomalies(9)
ML & Monitoring(3)
IP Actions(3)
Custom(1)
HMAC Signature Verification
Every webhook delivery includes HMAC-SHA256 signature headers so you can verify the payload was sent by SOCWarden and has not been tampered with.
Signature Headers
X-Signature-256HMAC-SHA256 hex digest of the signed payload.
X-TimestampUnix timestamp (seconds) when the signature was generated. Reject requests older than 5 minutes to prevent replay attacks.
Algorithm
HMAC-SHA256(timestamp + "." + raw_body, webhook_secret)Concatenate the X-Timestamp value, a literal dot character, and the raw request body. Sign with your webhook secret using HMAC-SHA256. Compare the hex digest against the X-Signature-256 header.
import crypto from 'crypto';
function verifyWebhook(req, secret) {
const signature = req.headers['x-signature-256'];
const timestamp = req.headers['x-timestamp'];
const body = req.rawBody; // raw request body as string
// Reject stale requests (>5 min)
const age = Math.floor(Date.now() / 1000) - parseInt(timestamp);
if (age > 300) throw new Error('Webhook timestamp too old');
const expected = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + body)
.digest('hex');
const valid = crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
if (!valid) throw new Error('Invalid webhook signature');
return JSON.parse(body);
}import hmac, hashlib, time, json
def verify_webhook(headers, body: bytes, secret: str):
signature = headers['X-Signature-256']
timestamp = headers['X-Timestamp']
# Reject stale requests (>5 min)
age = int(time.time()) - int(timestamp)
if age > 300:
raise ValueError('Webhook timestamp too old')
expected = hmac.new(
secret.encode(),
f"{timestamp}.{body.decode()}".encode(),
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
raise ValueError('Invalid webhook signature')
return json.loads(body)Delivery Behavior
Understand how SOCWarden delivers webhooks and how to handle failures.
HTTP Method & Content-Type
All webhooks are delivered as HTTP POST requests with Content-Type: application/json. Your endpoint must return a 2xx status code to acknowledge receipt.
Retry Policy
Failed deliveries (non-2xx response or timeout) are retried up to 5 times with exponential backoff: 10s, 30s, 90s, 270s, 810s. After 5 failures the webhook is marked as failed in the delivery log.
Timeout
Your endpoint must respond within 10 seconds. Responses that take longer are treated as failures and queued for retry.
Idempotency
Each delivery includes the alert_id (or event_id for IP actions) as a natural idempotency key. Your handler should deduplicate using this field to safely handle retries.