> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open-cluster.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Generic Webhook

> Create incidents from canonical alert events sent by unsupported alert sources.

Use Generic Webhook when an alert source can send an outbound HTTP request but does not
have a first-class OpenCluster integration. The sender must produce the canonical schema;
OpenCluster does not run field mappings or transformations.

## Prerequisites

* Network access from the sender to the OpenCluster intake endpoint over HTTPS.
* A sender that can set the `X-OpenCluster-Token` header and send JSON.
* The **Admin** role in OpenCluster.

## Least-privilege access

The sender needs permission only to reach its generated webhook URL and read the
one-time secret. The credential authenticates this Integration only; it is not a product
API credential.

## Connect

Create a **Generic Webhook** integration, then copy its webhook URL and one-time secret.
Send each alert to that URL with the secret in `X-OpenCluster-Token`.

```json theme={null}
{
  "eventId": "alert-2026-0042",
  "status": "firing",
  "title": "Database latency is high",
  "severity": "critical",
  "startedAt": "2026-08-28T07:00:00Z",
  "deduplicationKey": "production/database-latency",
  "labels": { "region": "eu-central-1" },
  "annotations": { "runbook": "Check the primary database" },
  "sourceUrl": "https://monitor.example/alerts/42"
}
```

Use the same `eventId`, `startedAt`, and `deduplicationKey` for the matching resolution,
set `status` to `resolved`, and add `resolvedAt`. Repeating the same phase is safe. Reusing
an `eventId` with different content in the same phase returns `400`.

## Schema limits

| Field              | Requirement                                                             |
| ------------------ | ----------------------------------------------------------------------- |
| `eventId`          | 1–256 characters; stable for the alert lifecycle                        |
| `status`           | `firing` or `resolved`                                                  |
| `title`            | 1–512 characters after trimming                                         |
| `severity`         | `info`, `warning`, or `critical`                                        |
| `startedAt`        | RFC 3339 timestamp                                                      |
| `resolvedAt`       | Required only for `resolved`; not before `startedAt`                    |
| `deduplicationKey` | 1–256 characters; groups related alerts                                 |
| `labels`           | At most 32 string entries; keys up to 64, values up to 256 characters   |
| `annotations`      | At most 32 string entries; keys up to 64, values up to 2,048 characters |
| `sourceUrl`        | Optional absolute HTTP or HTTPS URL up to 2,048 characters              |

Unknown or duplicate fields, invalid UTF-8, trailing JSON, and an Organization identifier
are rejected. Annotation text is displayed as untrusted source content. OpenCluster never
fetches `sourceUrl` during intake.

## Verify

Send one firing event and confirm the response is `202 Accepted`. Open the matching
Webhook Delivery, Alert Event, and Incident. An exact retry should return `200 OK` without
creating another lifecycle phase.

## Evidence available

The Alert Event supplies its title, severity, lifecycle timestamps, labels, annotations,
deduplication key, and optional source URL. It creates Incident context but does not let
OpenCluster read the sender or the linked source URL during an Investigation.

## Limitations

Generic Webhook performs no field mapping or enrichment. The sender must preserve one
stable lifecycle identity and canonical schema. Connect a separate evidence Integration
when an Investigation needs runtime, change, or conversation data.

## Delivery responses

| Response | Meaning                                                                |
| -------- | ---------------------------------------------------------------------- |
| `202`    | This lifecycle phase was durably accepted.                             |
| `200`    | The same phase and normalized content was already accepted.            |
| `400`    | The schema is invalid or the identity conflicts with accepted content. |
| `401`    | The secret is wrong, was rotated, or the integration is disabled.      |
| `413`    | The body is larger than 1 MiB.                                         |
| `429`    | Retry after the `Retry-After` interval.                                |
| `503`    | OpenCluster could not record the delivery; retry.                      |

## Troubleshooting

* `400`: validate the canonical fields, lifecycle identity, timestamps, and body size.
* `401`: check the Integration ID and current secret; rotate it if the stored value is
  uncertain.
* `429` or `503`: retry with bounded backoff and preserve the same lifecycle identity.

## Rotate, disable, or remove

Rotate the webhook secret, store the replacement immediately, and update the sender
before its next delivery. Rotation invalidates the old value. Disable the Integration to
stop new deliveries while retaining history. Deletion is refused when retained records
depend on it.

## Next step

Connect an [evidence source](/integrations/overview), then
[run the first Investigation](/getting-started/run-your-first-investigation) from a test Alert Event.

## Availability

Generic Webhook is available in OSS v0.1 and has no third-party provider mark.
