Webhooks
Overview
Send finding events and remediation context to your own agents.
Use Webhooks to send finding lifecycle events to your own agents, ticketing systems, and remediation workflows. Webhooks are configured at the organization level from Settings (/app/settings).
Create a webhook target
- Open Settings and find the Webhooks section.
- Select Add webhook.
- Enter a target name, for example
Remediation agent. - Enter a valid HTTPS URL.
- Choose the events this target should receive.
- Save the target and copy the signing secret. The secret is shown only once.
You can create multiple webhook targets for the same organization. For example, one target can receive all finding events for an internal agent, while another target receives only finding.triage_completed events for an automated patch workflow.
Events
The first supported events are finding events:
| Event | When it fires |
|---|---|
finding.created |
A repository report or GitHub advisory creates a new finding. |
finding.triage_completed |
Automated triage completes and remediation context is available. |
finding.accepted |
A finding is resolved as accepted risk. |
finding.triage_completed is the main handoff event for remediation agents. It includes the triage summary, recommendation, evidence, code references, and proposed patch diff when Superagent produced one.
Delivery
Superagent sends webhook requests as POST requests with a JSON body.
Your endpoint should:
- Return any
2xxresponse to acknowledge delivery. - Be idempotent by event
id. - Verify the request signature before processing the payload.
- Respond quickly and do longer work asynchronously in your own system.
Superagent retries network errors, 408, 429, and 5xx responses with backoff.
Payload format
Every webhook uses a versioned envelope. The data.object field contains the finding.
{
"id": "evt_...",
"type": "finding.triage_completed",
"api_version": "2026-07-08",
"created_at": "2026-07-08T07:12:00.000Z",
"organization_id": "org_uuid",
"data": {
"object": {
"id": "finding_uuid",
"object": "finding",
"kind": "repository_red_team",
"title": "SQL injection in search endpoint",
"repository": "acme/web",
"risk_level": "high",
"triage_status": "resolved",
"triage": {
"summary": "The endpoint builds SQL using unsanitized input.",
"recommendation": "Use parameterized queries.",
"verification_status": "confirmed"
},
"remediation": {
"files": ["app/api/search/route.ts"],
"patch": {
"format": "unified_diff",
"diff": "diff --git ...",
"truncated": false
},
"code_references": []
}
}
}
}Remediation context
finding.triage_completed includes the context an agent needs to start remediation:
triage.summary— what Superagent found during triagetriage.recommendation— the recommended fixtriage.evidence— structured evidence when availableremediation.files— files likely involved in the fixremediation.patch.diff— a proposed unified diff when Superagent produced oneremediation.code_references— relevant files, line ranges, snippets, and reasons
Patch diffs are included inline by default. If a payload exceeds the size limit, Superagent marks the patch as truncated: true and includes finding_detail_url.
Fetch finding_detail_url with an organization API key when your agent needs the full context:
curl https://superagent.sh/api/findings/finding_uuid \
-H "x-api-key: sk_live_..."Signatures
Each request includes these headers:
X-Superagent-Event-IdX-Superagent-Event-TypeX-Superagent-TimestampX-Superagent-Signature
Verify the signature by computing HMAC-SHA256 over:
<timestamp>.<raw-json-body>using the webhook signing secret from Settings. The signature header format is:
t=<timestamp>,v1=<hex-hmac>Example verification in Node.js:
import { createHmac, timingSafeEqual } from "crypto";
function verifySuperagentWebhook(params: {
secret: string;
timestamp: string;
rawBody: string;
signature: string;
}) {
const expectedDigest = createHmac("sha256", params.secret)
.update(`${params.timestamp}.${params.rawBody}`)
.digest("hex");
const expected = `t=${params.timestamp},v1=${expectedDigest}`;
const expectedBuffer = Buffer.from(expected);
const actualBuffer = Buffer.from(params.signature);
return (
expectedBuffer.length === actualBuffer.length &&
timingSafeEqual(expectedBuffer, actualBuffer)
);
}Rotate or disable a target
Use the Webhooks list in Settings to:
- Enable or disable a target.
- Edit the target name, URL, and event subscriptions.
- Send a test event.
- Regenerate the signing secret.
- Delete the target.
Disabling a target stops new deliveries to that URL. Regenerating the signing secret invalidates the previous secret.