Webhooks
Overview
Send report and finding lifecycle events to your own agents.
Use Webhooks to send report and 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. New targets subscribe to all events by default. Existing targets must opt in to report events from their event subscriptions.
Events
| Event | When it fires |
|---|---|
report.started |
A customer-visible repository or Web app report is created and accepted for provisioning. |
report.finished |
The report's agent run completes, enters review, or fails, including provisioning failures. |
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. |
report.finished fires once per report. A successful run usually finishes with report status in_review; a failed run has outcome: "failed". Retrying the same report does not produce another lifecycle pair. Internal reports used to triage individual findings do not emit report events.
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 a report or 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": []
}
}
}
}Report payload
Report events use object: "report" and a type of repository or web_app:
{
"id": "evt_...",
"type": "report.finished",
"api_version": "2026-07-08",
"created_at": "2026-07-22T07:45:00.000Z",
"organization_id": "org_uuid",
"data": {
"object": {
"id": "report_uuid",
"object": "report",
"type": "repository",
"repository": "https://github.com/acme/web",
"trigger_source": "manual",
"custom_goal_prompt": "Focus on authorization boundaries.",
"status": "in_review",
"sandbox_status": "ready",
"agent_status": "completed",
"dashboard_url": "https://superagent.sh/app/reports/repository/report_uuid",
"outcome": "succeeded",
"error": null,
"agent_started_at": "2026-07-22T07:01:00.000Z",
"agent_completed_at": "2026-07-22T07:45:00.000Z",
"created_at": "2026-07-22T07:00:00.000Z",
"updated_at": "2026-07-22T07:45:00.000Z"
}
}
}For Web app reports, the object contains target_url, allowed_host, and request_throttle_rpm instead of repository fields. Credentials, browser headers, sandbox identifiers and configuration, runner tokens, and encrypted values are never included.
When outcome is failed, error contains a phase of provisioning or agent and a safe error message. report.started has outcome: null, error: null, and reflects the report's initial provisioning state.
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/v1/findings/finding_uuid \
-H "Authorization: Bearer sk_live_..."Existing integrations can continue using GET /api/findings/{finding_id} with the x-api-key header. See the API overview for the versioned endpoint.
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.