> For clean Markdown of this page, append .md to its URL. For the complete documentation index, see https://www.superagent.sh/llms.txt.


Send red-team report, finding, dependency update, contributor trust, and agent monitoring events to your own systems.

# Webhooks

Use **Webhooks** to send repository, application, and Agent red-team report
lifecycle events, findings, Secure Dependency Updates, contributor trust, and
agent monitoring alerts to your own agents, ticketing systems, and remediation
workflows. Webhooks are configured at the organization level from **Webhooks**
(`/app/webhooks`).

## Create a webhook target

1. Open **Webhooks** in the sidebar.
2. Select **Add webhook**.
3. Enter a target name, for example `Remediation agent`.
4. Enter a valid HTTPS URL.
5. Optionally add request headers, for example `Authorization` for an authenticated receiver such as a Cursor automation webhook. Header values are encrypted at rest.
6. Choose the events this target should receive.
7. In the grouped **Sources** dropdown, select one or more entire groups or specific repositories, applications, and agents.
8. 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 newly added report, dependency update, contributor trust, and agent events from their event subscriptions.

## Filter by source

Source filters route events by Security Factory modality:

- **Repositories** includes repository reports, pull request findings, Secure
  Dependency Updates, Contributor Trust, and GitHub advisories.
- **Applications** includes application reports and findings.
- **Agents** includes Agent red-team and Runtime Guardrails events.
- **Infrastructure** is reserved for future infrastructure events.

The Sources dropdown supports multiple selections grouped under Repositories,
Applications, Agents, and Infrastructure. Select an **All** option to include
every current and future source in that group, or select exact persistent
sources. New and existing webhook targets default to all sources.

An event without a persistent source association, such as an organization-wide
Contributor Trust scan or an ad hoc report, is sent only to endpoints that
include all sources in its group. Filters are evaluated when the event is first
enqueued, so retries continue to use the same matched targets.

## Events

| Event | When it fires |
| --- | --- |
| `report.started` | A customer-visible repository, application, or Agent red-team 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, application, or Agent red-team 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. |
| `dependency_update.published` | A Secure Dependency Update pull request is published after policy evaluation. |
| `contributor_trust.finished` | An API-started Contributor Trust scan completes or fails. |
| `agent.finding_created` | An endpoint security rule detects agent activity that was not paired with a blocked action. |
| `agent.action_blocked` | Agent monitoring denies an action. A linked finding and enforcement decision produce one event. |

`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.

`dependency_update.published` fires once for each Secure Dependency Update
proposal that reaches GitHub as a pull request. Proposals withheld by policy,
superseded before publication, or failed before a pull request is opened do not
emit this event.

`contributor_trust.finished` is sent to every enabled endpoint in the scan's
organization that subscribes to the event. It fires for both completed and
failed API scans. See the
[Contributor Trust API](https://www.superagent.sh/docs/api/contributor-trust) to start and poll scans.

## Delivery

Superagent sends webhook requests as `POST` requests with a JSON body.

Your endpoint should:

- Return any `2xx` response 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.

You can attach custom request headers to every delivery, including test events. Use this for receivers that require an `Authorization` bearer token. Superagent always sets `Content-Type`, `User-Agent`, and the `X-Superagent-*` signature headers, and those names cannot be overridden.

## Payload format

Every webhook uses a versioned envelope. The `data.object` field contains a
report, finding, dependency update, Contributor Trust scan, or agent alert.

```json
{
  "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`, `web_app`,
or `agent`:

```json
{
  "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 application reports, the object contains `target_url`, `allowed_host`, and
`request_throttle_rpm` instead of repository fields.

For Agent red-team reports, the object includes `agent_id` when the report is
linked to a persistent Agent, plus `description`, `agent_type`, `target_kind`,
`target_url`, `allowed_host`, `request_throttle_rpm`, and `trigger_source`.
Credentials, target headers, API request bodies, 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.

### Contributor Trust payload

Contributor Trust events use `object: "contributor_trust_scan"`. Completed and
failed scans share the same payload shape:

```json
{
  "id": "evt_...",
  "type": "contributor_trust.finished",
  "api_version": "2026-07-08",
  "created_at": "2026-08-10T12:00:00.000Z",
  "organization_id": "org_uuid",
  "data": {
    "object": {
      "id": "scan_uuid",
      "object": "contributor_trust_scan",
      "login": "octocat",
      "status": "completed",
      "score": 91,
      "score_version": "deterministic-v2.1",
      "verdict": "trusted",
      "confidence": "high",
      "sub_scores": {
        "identity": 92,
        "behavior": 90,
        "content": 91
      },
      "analyzed_pr_count": 10,
      "public_evidence": [
        {
          "repo": "octocat/hello-world",
          "number": 12,
          "title": "Harden request validation",
          "url": "https://github.com/octocat/hello-world/pull/12",
          "verdict": "clean",
          "files_reviewed": ["src/validator.ts"]
        }
      ],
      "error": null,
      "started_at": "2026-08-10T11:58:00.000Z",
      "completed_at": "2026-08-10T12:00:00.000Z",
      "created_at": "2026-08-10T11:58:00.000Z",
      "updated_at": "2026-08-10T12:00:00.000Z"
    }
  }
}
```

For failed scans, `status` is `failed`, score fields are `null`, and
`error.message` contains a safe failure summary. Private repository names,
private pull request identifiers, patches, signals, threats, and free-form agent
evidence are not included. Public evidence is limited to GitHub source metadata
and reviewed file names. Delivery uses the same signatures and retry policy as
every other event.

### Dependency update payload

Secure Dependency Update events use `object: "dependency_update"` and include
the published pull request:

```json
{
  "id": "evt_...",
  "type": "dependency_update.published",
  "api_version": "2026-07-08",
  "created_at": "2026-09-18T07:00:00.000Z",
  "organization_id": "org_uuid",
  "data": {
    "object": {
      "id": "proposal_uuid",
      "object": "dependency_update",
      "status": "published",
      "run_id": "run_uuid",
      "repository": {
        "id": "123456789",
        "full_name": "octocat/hello-world"
      },
      "title": "chore(deps): bump example from 1.0.0 to 1.0.1",
      "pull_request": {
        "number": 42,
        "url": "https://github.com/octocat/hello-world/pull/42"
      }
    }
  }
}
```

### Agent alert payload

Agent monitoring events use `object: "agent_alert"` and include the rule, client, severity, and alert URL:

```json
{
  "id": "evt_...",
  "type": "agent.action_blocked",
  "api_version": "2026-07-08",
  "created_at": "2026-08-04T17:40:00.000Z",
  "organization_id": "org_uuid",
  "data": {
    "object": {
      "id": "record_uuid",
      "object": "agent_alert",
      "type": "action_blocked",
      "rule": {
        "id": "exec.reverse_shell",
        "title": "Reverse shell execution",
        "severity": "high"
      },
      "client": {
        "id": "client_uuid",
        "name": "Developer workstation"
      },
      "dashboard_url": "https://superagent.sh/app/agents/alert/record_uuid"
    }
  }
}
```

The payload does not include the full normalized endpoint event stream or raw command output. Fetch the alert details in Superagent when more context is required.

## Remediation context

`finding.triage_completed` includes the context an agent needs to start remediation:

- `triage.summary` — what Superagent found during triage
- `triage.recommendation` — the recommended fix
- `triage.evidence` — structured evidence when available
- `remediation.files` — files likely involved in the fix
- `remediation.patch.diff` — a proposed unified diff when Superagent produced one
- `remediation.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:

```bash
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 [REST API](https://www.superagent.sh/docs/api) for the versioned endpoint.

## Signatures

Each request includes these headers:

- `X-Superagent-Event-Id`
- `X-Superagent-Event-Type`
- `X-Superagent-Timestamp`
- `X-Superagent-Signature`

Verify the signature by computing HMAC-SHA256 over:

```text
<timestamp>.<raw-json-body>
```

using the webhook signing secret from Webhooks. The signature header format is:

```text
t=<timestamp>,v1=<hex-hmac>
```

Example verification in Node.js:

```ts
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 dedicated **Webhooks** page to:

- Enable or disable a target.
- Edit the target name, URL, custom request headers, event subscriptions, and sources.
- 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.

## Next steps

- [Understand findings and reports](https://www.superagent.sh/docs/concepts/findings-and-reports)
- [Use Superagent MCP](https://www.superagent.sh/docs/mcp)
- [Review organization settings](https://www.superagent.sh/docs/reference/settings)

---
Source: https://www.superagent.sh/docs/webhooks
Index: https://www.superagent.sh/llms.txt
