Skip to main content

Overview

Webhooks deliver events to your endpoint as they happen. Use them to trigger remediation workflows, update dashboards, or notify your team.

Events

EventDescription
scan.createdA new pentest has been started
scan.completedA pentest finished successfully
scan.failedA pentest failed during execution
scan.cancelledA pentest was cancelled
vulnerability.createdA new vulnerability was found
vulnerability.status_changedA vulnerability status was updated
vulnerability.severity_changedA vulnerability severity was changed with an override reason
*Subscribe to all events

Payload format

Every delivery is a POST with a stable JSON envelope. The data object is event-specific and documented per event below.
FieldTypeDescription
iduuidUnique delivery id. Also sent as X-Strix-Delivery.
eventstringWebhook event type, such as scan.completed.
created_atISO 8601 timestampTime the delivery was created.
dataobjectEvent-specific payload.

scan.created

A pentest was created and queued.
FieldTypeDescription
scan_idstringScan id
organization_idstringOrganization that owns the scan
statusstringCurrent scan status
titlestring | nullScan title
created_atISO 8601 timestampScan creation time
{
  "id": "delivery_123",
  "event": "scan.created",
  "created_at": "2026-05-19T04:30:00.000Z",
  "data": {
    "scan_id": "scan_123",
    "organization_id": "org_123",
    "status": "pending",
    "title": "Production API pentest",
    "created_at": "2026-05-19T04:30:00.000Z"
  }
}

scan.completed, scan.failed, scan.cancelled

A pentest status changed. The three events share the same payload shape; status is completed, failed, or cancelled respectively.
FieldTypeDescription
scan_idstringScan id
organization_idstringOrganization that owns the scan
statusstringNew scan status
previous_statusstring | nullPrevious scan status
titlestring | nullScan title
schedule_idstring | nullSchedule that launched the scan, when applicable
updated_atISO 8601 timestampTime the status change was observed
{
  "id": "delivery_123",
  "event": "scan.completed",
  "created_at": "2026-05-19T05:12:00.000Z",
  "data": {
    "scan_id": "scan_123",
    "organization_id": "org_123",
    "status": "completed",
    "previous_status": "running",
    "title": "Production API pentest",
    "schedule_id": "schedule_123",
    "updated_at": "2026-05-19T05:12:00.000Z"
  }
}

vulnerability.created

A vulnerability was created for a pentest.
FieldTypeDescription
vulnerability_idstringVulnerability id
organization_idstringOrganization that owns the vulnerability
scan_idstringScan that found the vulnerability
titlestringVulnerability title
severitycritical | high | medium | lowCurrent severity
statusstringCurrent vulnerability status
created_atISO 8601 timestampVulnerability creation time
{
  "id": "delivery_123",
  "event": "vulnerability.created",
  "created_at": "2026-05-19T05:08:00.000Z",
  "data": {
    "vulnerability_id": "vuln_123",
    "organization_id": "org_123",
    "scan_id": "scan_123",
    "title": "Unauthenticated account export",
    "severity": "high",
    "status": "open",
    "created_at": "2026-05-19T05:08:00.000Z"
  }
}

vulnerability.status_changed

A vulnerability status was changed.
FieldTypeDescription
vulnerability_idstringVulnerability id
organization_idstringOrganization that owns the vulnerability
scan_idstring | nullRelated scan, when present
pr_review_idstring | nullRelated PR review, when present
statusstringNew vulnerability status
previous_statusstring | nullPrevious vulnerability status
status_changed_atISO 8601 timestamp | nullStatus change time
status_changed_bystring | nullActor that changed the status
updated_atISO 8601 timestampTime the webhook event was created
{
  "id": "delivery_123",
  "event": "vulnerability.status_changed",
  "created_at": "2026-05-19T06:45:00.000Z",
  "data": {
    "vulnerability_id": "vuln_123",
    "organization_id": "org_123",
    "scan_id": "scan_123",
    "pr_review_id": null,
    "status": "fixed",
    "previous_status": "open",
    "status_changed_at": "2026-05-19T06:45:00.000Z",
    "status_changed_by": "user@example.com",
    "updated_at": "2026-05-19T06:45:00.000Z"
  }
}

vulnerability.severity_changed

A vulnerability severity was changed with an override reason.
FieldTypeDescription
vulnerability_idstringVulnerability id
organization_idstringOrganization that owns the vulnerability
scan_idstring | nullRelated scan, when present
pr_review_idstring | nullRelated PR review, when present
severitycritical | high | medium | lowNew severity
previous_severitycritical | high | medium | low | nullPrevious severity
original_severitycritical | high | medium | low | nullOriginal severity before overrides
severity_changed_atISO 8601 timestamp | nullSeverity change time
severity_changed_bystring | nullActor that changed the severity
severity_override_reasonstring | nullReason supplied for the change
updated_atISO 8601 timestampTime the webhook event was created
{
  "id": "delivery_123",
  "event": "vulnerability.severity_changed",
  "created_at": "2026-05-19T06:52:00.000Z",
  "data": {
    "vulnerability_id": "vuln_123",
    "organization_id": "org_123",
    "scan_id": "scan_123",
    "pr_review_id": null,
    "severity": "medium",
    "previous_severity": "high",
    "original_severity": "high",
    "severity_changed_at": "2026-05-19T06:52:00.000Z",
    "severity_changed_by": "user@example.com",
    "severity_override_reason": "Compensating control is deployed.",
    "updated_at": "2026-05-19T06:52:00.000Z"
  }
}

Create a webhook

curl -X POST "https://app.strix.ai/api/v1/webhooks" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/strix-webhook",
    "events": ["scan.completed", "vulnerability.created"],
    "is_active": true
  }'
Required scope: webhooks:write The response includes a secret field — store it securely. It will not be shown again.

Verify webhook signatures

Every webhook delivery includes signature headers for verification:
HeaderDescription
X-Strix-EventThe event type (e.g. scan.completed)
X-Strix-DeliveryUnique delivery ID (use as idempotency key)
X-Strix-TimestampISO 8601 timestamp of when the event was sent
X-Strix-SignatureHMAC-SHA256 signature for payload verification

Signature verification (Node.js)

import crypto from "crypto";

export function verifyStrixWebhook(rawBody, headers, secret) {
  const signature = headers["x-strix-signature"];
  const timestamp = headers["x-strix-timestamp"];
  if (!signature || !timestamp) return false;

  const parsedTime = Date.parse(timestamp);
  const ageMs = Math.abs(Date.now() - parsedTime);
  if (!Number.isFinite(parsedTime) || ageMs > 5 * 60 * 1000) return false;

  const payload = `${timestamp}.${rawBody}`;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}
Always verify the signature before processing webhook payloads. Reject requests with expired timestamps (older than 5 minutes) to prevent replay attacks.

Delivery and retries

Events are delivered asynchronously with retries and exponential backoff. Use the X-Strix-Delivery header as an idempotency key when processing events to handle potential duplicate deliveries.

Manage webhooks

List webhooks

curl -X GET "https://app.strix.ai/api/v1/webhooks" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"
Required scope: webhooks:read

Update a webhook

curl -X PATCH "https://app.strix.ai/api/v1/webhooks/<WEBHOOK_ID>" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"events": ["*"], "is_active": true}'
Required scope: webhooks:write

Rotate webhook secret

curl -X PATCH "https://app.strix.ai/api/v1/webhooks/<WEBHOOK_ID>" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"rotate_secret": true}'
The response includes the new secret. The old secret is invalidated immediately. Required scope: webhooks:write

Delete a webhook

curl -X DELETE "https://app.strix.ai/api/v1/webhooks/<WEBHOOK_ID>" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"
Required scope: webhooks:write

Inspect deliveries

curl -X GET "https://app.strix.ai/api/v1/webhooks/<WEBHOOK_ID>/deliveries?limit=25" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>"
Required scope: webhooks:read