Webhooks

Receive signed JSON events from TrekShield at your HTTPS endpoint, verify the HMAC-SHA256 signature, and understand event names, delivery and history.

A webhook posts a JSON event to your HTTPS endpoint when something changes in TrekShield.

Webhooks are created and managed through the API; there is no screen for them in the web app.

Create one

Platform Administrators and Engagement Managers call POST /webhooks/outgoing with a name, an https url, an events array and an optional secret. Without one, TrekShield generates a 64-character secret. The secret is returned once, in the response, and again only by POST /webhooks/outgoing/{id}/rotate-secret; store it immediately. Plain http URLs are refused. POST /webhooks/outgoing/{id}/test sends a webhook.test event, and PATCH with is_active: false pauses a webhook.

Events

Shown in SettingsDelivered by the API as
engagement.state_changeengagement.state_changed
finding.state_changefinding.state_changed
remediation.state_changeremediation.state_changed
retest.completedretest.completed
finding.creatednot delivered today
report.readynot delivered today

Also available: engagement.delivered, .completed and .cancelled; finding.risk_accepted; remediation.created, .verified, .blocked and .risk_accepted; retest.created, .scheduled and .started; and comment.created (never for internal comments). Attack surface events (launching soon) are exposure_signal.opened, asm.asset.discovered, asm.asset.disappeared, asm.change.detected, asm.authorization.expiring and asm.authorization.expired.

Request format

Each delivery is a POST with headers X-TrekShield-Event, X-TrekShield-Timestamp, X-TrekShield-Signature (sha256=<hex>) and User-Agent: TrekShield-Webhooks/1.0:

{
  "event": "finding.state_changed",
  "timestamp": "2026-10-18T09:30:00.000Z",
  "data": { "findingId": "…", "fromState": "reported", "toState": "in_remediation" }
}

data carries identifiers and states, and varies by event. Events are organization-wide and include internal states such as Draft and Submitted findings, so send them only to a trusted endpoint.

Verify the signature

The signature is the HMAC-SHA256 of the exact raw request body, keyed with your secret, hex-encoded. Verify before parsing, and compare in constant time:

const crypto = require("crypto");
function verify(rawBody, header, secret) {
  const expected = "sha256=" +
    crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(expected), b = Buffer.from(header || "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

The body includes timestamp, so you can reject stale events with your own window.

Delivery

Respond with any 2xx status within 10 seconds. Each event is attempted once: there are no automatic retries, redirects are not followed, and a timeout or non-2xx response is recorded as failed. GET /webhooks/outgoing/{id}/deliveries lists recent attempts with status, HTTP code and duration, without payloads or secrets.

Last updated: 2026-10-18

Questions about the platform?

Book a call and we will walk you through it.