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

# Webhooks

> Automatisierte HTTP-Callbacks von Corgea an externe Systeme senden

## Was sind Webhooks?

Webhooks sind automatisierte HTTP-Callbacks. Damit sendet Corgea beim Eintreten bestimmter Events Benachrichtigungen in Echtzeit an externe Systeme. Statt die API kontinuierlich auf Änderungen abzufragen, erhalten Sie die Event-Daten unmittelbar an Ihrem konfigurierten Endpunkt.

### Zentrale Vorteile

* **Echtzeit-Benachrichtigungen** – Sofort über neue Security-Issues, Statusänderungen und abgeschlossene Scans informiert werden
* **Automatisierung** – Workflows in externen Tools wie Slack, Zapier oder eigenen Anwendungen auslösen
* **Effizienz** – Änderungen ohne wiederholte API-Abfragen direkt empfangen
* **Flexibilität** – Nur relevante Events abonnieren und nach Projekt, Status oder Scheduled Scan filtern
* **Zuverlässigkeit** – Integrierte Wiederholungslogik und Zustellungsverfolgung

### Unterstützte Event-Typen

Corgea unterstützt Webhooks für die folgenden Events:

**Issue Events:**

* `issue.status_changed` – Wird bei einer Änderung des Issue-Status ausgelöst, beispielsweise `open` → `fixed`.
* `issue.assigned` – Wird ausgelöst, wenn ein Issue einem Teammitglied zugewiesen wird.

**SLA Events:**

* `sla.violation` – Wird ausgelöst, wenn der tägliche SLA-Job mindestens ein SAST- oder SCA-Issue mit überschrittener Behebungs- oder Eskalationsfrist erkennt. Die Fristen werden je SLA unter [SLA Management](sla_management) konfiguriert.

**Scan Events:**

* `scan.started` – Wird beim Start eines Security-Scans ausgelöst.
* `scan.completed` – Wird nach erfolgreichem Abschluss eines Scans ausgelöst.
* `scan.failed` – Wird ausgelöst, wenn bei einem Scan ein Fehler auftritt.
* `scheduled_scan.daily_report` – Wird täglich nach Abschluss der Scheduled-Scan-Läufe ausgelöst und fasst alle neuen Issues aus den vergangenen 24 Stunden zusammen. Das E-Mail- und Payload-Schema ist unter [Benachrichtigungen](notifications#daily-scan-report) beschrieben.

<Note>
  Scan-Lifecycle-Events (`scan.started`, `scan.completed`, `scan.failed`) enthalten in `data.message` eine kurze Klartextzusammenfassung für Slack, Zapier oder andere Chat-Tools. Außerdem enthalten sie die Triage-Felder `pull_request_id`, `scan_url`, `true_positive_count`, `project_name` und `status`.

  Für den Slack Workflow Builder (`Type = Slack` und `hooks.slack.com/triggers/...`) überträgt Corgea **nur** `scan.started`, `scan.completed`, `scan.failed` und `webhook.test` als Top-Level-Schlüssel. Ordnen Sie in Slack keine verschachtelten `data.*`-Felder zu, da dies HTTP 400 verursacht. Andere Event-Typen desselben Slack-Webhooks behalten die verschachtelte Struktur bei. Weitere Informationen finden Sie unter [Slack](slack).
</Note>

**User Auth Events:**

* `user.login` – Wird bei einer erfolgreichen Benutzeranmeldung ausgelöst.
* `user.login_failed` – Wird bei einem fehlgeschlagenen Anmeldeversuch ausgelöst.

***

## Wie Webhooks funktionieren

### Webhook-Lifecycle

<Steps>
  <Step title="Event tritt ein">
    In Corgea wird beispielsweise ein Scan abgeschlossen oder der Status eines Issues geändert.
  </Step>

  <Step title="Webhook wird ausgelöst">
    Das System ermittelt alle Webhooks, die diesen Event-Typ abonniert haben.
  </Step>

  <Step title="Filter werden angewendet">
    Projekt-, Status-, Scheduled-Scan-, PR-only- und Findings-Filter bestimmen, ob der Webhook ausgelöst wird.
  </Step>

  <Step title="Payload erstellt">
    Standardmäßig erstellt Corgea eine einheitliche JSON-Struktur mit den Event-Details. Falls konfiguriert, wird stattdessen Ihr Custom-Body-Template verwendet. Für den Slack Workflow Builder (`Type = Slack` und `triggers/`-URL) überträgt Corgea den HTTP-Body nur bei `scan.*` und `webhook.test` als flache Struktur; andere Events bleiben verschachtelt.
  </Step>

  <Step title="HTTP-POST-Request">
    Der Payload wird mit Security-Headern an Ihre Webhook-URL gesendet.
  </Step>

  <Step title="Wiederholungslogik">
    Bei einem fehlgeschlagenen Request erfolgen automatische Wiederholungsversuche mit exponentiellem Backoff.
  </Step>

  <Step title="Zustellung wird protokolliert">
    Alle Versuche werden zur Fehleranalyse im Zustellungsverlauf erfasst.
  </Step>
</Steps>

### Payload-Struktur

Webhook-Payloads verwenden standardmäßig eine einheitliche verschachtelte Struktur für Zapier und andere Ziele. Scan-Lifecycle-Events enthalten `data.message` und zusätzliche Triage-Felder:

```json webhook-payload.json theme={null}
{
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_type": "scan.completed",
  "timestamp": "2025-01-15T14:30:00.000Z",
  "data": {
    "company": "company-uuid",
    "scan_id": "scan-uuid",
    "run_id": "run-12345",
    "project": {
      "id": "project-uuid",
      "name": "My Application"
    },
    "project_name": "My Application",
    "branch": "feature/auth",
    "engine": "corgea-blast",
    "scan_type": "full",
    "status": "completed",
    "pull_request_id": "42",
    "scan_url": "https://app.corgea.app/project/project-uuid/?scan_id=scan-uuid",
    "true_positive_count": 5,
    "summary": {
      "total_issues": 12,
      "issues_with_fixes": 7,
      "issues_without_fixes": 5,
      "true_positive_count": 5,
      "true_positive_issues_with_fixes": 3
    },
    "message": "Scan completed for My Application (PR #42): 5 true-positive findings (3 with fixes). View: https://app.corgea.app/project/project-uuid/?scan_id=scan-uuid",
    "scheduled_scan_ids": ["scheduled-scan-uuid"],
    "processed_at": "2025-01-15T14:30:00.000Z",
    "created_at": "2025-01-15T14:00:00.000Z"
  }
}
```

`summary.total_issues` zählt alle nicht gelöschten Issues einschließlich False Positives und Code-Quality-Issues. `true_positive_count` ist die für `message` und Scan-Event-Filter verwendete Triage-Anzahl.

| Event            | Beispiel für `data.message`                                                       |
| ---------------- | --------------------------------------------------------------------------------- |
| `scan.started`   | `Scan started for My Application (PR #42).`                                       |
| `scan.completed` | `Scan completed for My Application (PR #42): 5 true-positive findings. View: ...` |
| `scan.failed`    | `Scan failed for My Application (PR #42): Scanner timed out. View: ...`           |

`true_positive_count` zählt nicht gelöschte Security-Findings, die keine False Positives sind. Dies entspricht der Logik der Scan-Benutzeroberfläche und schließt `status=false_positive`, `hold_reason=false_positive` sowie `detected_by=code-quality` aus. Das optionale Suffix `(N with fixes)` in `scan.completed`-Meldungen zählt nur Fixes für diese True-Positive-Findings, nicht für sämtliche Issues des Scans.

<Tip>
  **Slack Workflow Builder:** Bei `Type = Slack` und einer URL unter `hooks.slack.com/triggers/...` sendet Corgea für `scan.*` und `webhook.test` einen **flachen** Body mit Top-Level-Feldern wie `message`, `pull_request_id`, `scan_url`, `true_positive_count` und `company`. Slack unterstützt keine Zuordnung verschachtelter `data.*`-Felder und gibt andernfalls HTTP 400 zurück. Andere Events dieses Webhooks werden **nicht** abgeflacht. Weitere Informationen finden Sie unter [Slack](slack).
</Tip>

**Beispiel-Payload für `sla.violation`** (aus dem täglichen SLA-Management-Job):

```json sla-violation-payload.json theme={null}
{
  "event_id": "550e8400-e29b-41d4-a716-446655440001",
  "event_type": "sla.violation",
  "timestamp": "2025-01-15T14:30:00.000Z",
  "data": {
    "company": "1",
    "sla": {
      "id": 3,
      "rule_type": "code",
      "urgency": ["CR", "HI"],
      "remediation_days": 7,
      "escalation_days": 3
    },
    "notification_type": "remediation",
    "issue_kind": "SAST",
    "issue_count": 5,
    "summary_message": "Plain-text summary (same style as email body)...",
    "projects": [
      {
        "id": "project-uuid",
        "name": "My Application",
        "url": "https://app.corgea.com/project/project-uuid",
        "issue_count": 5,
        "urgency_counts": {
          "Critical": 2,
          "High": 3
        }
      }
    ]
  }
}
```

| Feld                | Beschreibung                                                                      |
| ------------------- | --------------------------------------------------------------------------------- |
| `notification_type` | `remediation` oder `escalation`                                                   |
| `issue_kind`        | `SAST` oder `SCA`                                                                 |
| `sla.rule_type`     | `code` (SAST) oder `sca` (Abhängigkeit)                                           |
| `projects`          | Ein Eintrag pro betroffenem Projekt; wird für Webhook-**Projektfilter** verwendet |

Abonnieren Sie `sla.violation` unter **Integrations → Webhooks** oder verknüpfen Sie einen Webhook im Formular unter [SLA Management](sla_management). Vorhandene Webhooks werden automatisch für das Event registriert.

**Beispiel-Payload für `scheduled_scan.daily_report`**:

```json scheduled-scan-daily-report-payload.json theme={null}
{
  "event_id": "550e8400-e29b-41d4-a716-446655440002",
  "event_type": "scheduled_scan.daily_report",
  "timestamp": "2025-01-15T14:30:00.000Z",
  "data": {
    "title": "Corgea Daily Scan Report",
    "company": "1",
    "company_name": "Acme Security",
    "total_new_issues": 7,
    "message": "Daily scan report for Acme Security: 7 new issues detected across 2 scan runs.",
    "scan_runs": [
      {
        "scheduled_scan_name": "Weekly Production Scan",
        "project": "Payments API",
        "new_issue_count": 4,
        "scan_url": "https://www.corgea.app/scans/scan-uuid"
      }
    ]
  }
}
```

Unternehmensadministratoren legen unter **Settings → Notifications → Company Defaults** fest, ob dieses Event an Webhooks gesendet wird.

Wenn Sie bei der Webhook-Einrichtung einen **Custom Body** konfigurieren, sendet Corgea das gerenderte JSON-Objekt anstelle der Standard-Payload-Struktur.

<Note>Das Event `scheduled_scan.daily_report` verwendet dieselbe äußere Struktur, aber ein eigenes `data`-Schema. Die vollständige Referenz finden Sie unter [Payload-Beispiele](#payload-examples).</Note>

### Sicherheitsfunktionen

<AccordionGroup>
  <Accordion title="HMAC-Signaturprüfung" icon="shield-check">
    * Corgea generiert beim Erstellen eines Webhooks automatisch einen Secret Key.
    * Jede Anfrage enthält einen `X-Corgea-Signature`-Header mit einem HMAC-SHA256-Hash der Payload
    * Verifizieren Sie die Signatur mit dem Secret Key, um die Herkunft des Webhooks von Corgea zu bestätigen.
  </Accordion>

  <Accordion title="Benutzerdefinierte Header" icon="key">
    * Fügen Sie die von Ihrem Endpunkt erforderlichen Header ein (z. B. Authentifizierungstoken)
    * Konfigurieren Sie benutzerdefinierte Header während der Einrichtung des Webhooks
  </Accordion>

  <Accordion title="HTTPS erforderlich" icon="lock">
    * Alle Webhook-URLs müssen HTTPS verwenden (nur Ports 443 oder 80)
    * URLs dürfen keine Anmeldeinformationen enthalten
    * Ziele, die auf private, Loopback-, Link-Local-, reservierte oder Multicast-Adressen auflösen, werden abgelehnt (SSRF-Schutz)
    * Operatoren können Hosts optional mit der `WEBHOOK_ALLOWED_HOSTS`-Einstellung einschränken
  </Accordion>
</AccordionGroup>

### Automatische Wiederholungslogik

<Info>Wenn die Webhook-Zustellung fehlschlägt, versucht Corgea automatisch erneut mit der folgenden Strategie:</Info>

* **Erster Versuch** + **2 Wiederholungen** = insgesamt 3 Versuche
* **Exponentieller Backoff**: 2 Sekunden und 4 Sekunden zwischen den Wiederholungsversuchen
* **Timeout**: 10 Sekunden pro Request
* **Automatische Pause**: Nach 10 aufeinanderfolgenden Fehlschlägen wird der Webhook automatisch pausiert

### Mit jedem Webhook gesendete Header

```text webhook-headers.txt theme={null}
Content-Type: application/json
X-Corgea-Event: issue.status_changed
X-Corgea-Delivery: <delivery-uuid>
X-Corgea-Timestamp: <unix-timestamp>
X-Corgea-Signature: <hmac-signature>
User-Agent: Corgea-Webhooks/1.0
```

***

## Webhook einrichten

<Frame>
  <img src="https://mintcdn.com/corgea/JgeRsjW5cn2yU52a/images/webhooks/webhooks_table.png?fit=max&auto=format&n=JgeRsjW5cn2yU52a&q=85&s=23c5fe597820ac3bdb57560ef29c3b9d" alt="Webhooks-Verwaltungsschnittstelle, die die Liste der konfigurierten Webhooks anzeigt" style={{ borderRadius: '0.5rem' }} width="3108" height="798" data-path="images/webhooks/webhooks_table.png" />
</Frame>

### Voraussetzungen

<Check>Administrations- oder Integrationsverwaltungsberechtigungen in Ihrem Corgea-Konto</Check>
<Check>Eine Webhook-Endpunkt-URL, die POST-Requests akzeptiert</Check>
<Check>HTTPS-Endpunkt (für Sicherheit erforderlich)</Check>

### Schritt-für-Schritt-Einrichtung

<Steps>
  <Step title="Integrations öffnen">
    * Öffnen Sie **Integrations** in Corgea.
    * Öffnen Sie unter **Automation Integrations** den Eintrag **Webhooks**.

    <Frame>
      <img src="https://mintcdn.com/corgea/bUShOerLaxHbdmO7/images/webhooks/webhooks_integrations.png?fit=max&auto=format&n=bUShOerLaxHbdmO7&q=85&s=e84b9d7d75569f68d644ada376ea16bf" alt="Automatisierungsintegrationen mit aktiven Webhooks, wobei Slack und Zapier als veraltet markiert sind" style={{ borderRadius: '0.5rem' }} width="1641" height="240" data-path="images/webhooks/webhooks_integrations.png" />
    </Frame>

    <Warning>
      Die eigenständigen Einträge **Slack** und **Zapier** sind veraltet. Verwenden Sie für neue Konfigurationen **Webhooks**. Vorhandene Slack- und Zapier-Integrationen funktionieren weiterhin. Über **View All** können Sie diese testen oder löschen.
    </Warning>
  </Step>

  <Step title="Grundlegende Einstellungen konfigurieren">
    <Frame>
      <img src="https://mintcdn.com/corgea/bUShOerLaxHbdmO7/images/webhooks/create_webhook_basic.png?fit=max&auto=format&n=bUShOerLaxHbdmO7&q=85&s=64b04b74bc95600f1c4e58c9a8b94398" alt="Erstellen von Webhook-Formular mit den Feldern Name, Webhook-URL und Typ" style={{ borderRadius: '0.5rem' }} width="1107" height="433" data-path="images/webhooks/create_webhook_basic.png" />
    </Frame>

    * **Name**: Eine eindeutige Bezeichnung, beispielsweise „Slack Notifications“ oder „Production Scan Alerts“
    * **Webhook-URL**: Ihr HTTPS-Endpunkt
    * **Type**:
      * `Slack` — Slack Workflow Builder oder Incoming-Webhooks
      * `Zapier` — Zapier Catch Hooks
      * `Other` — benutzerdefinierte Endpunkte

    <Tip>
      Verwenden Sie für Slack vorzugsweise eine Workflow-Builder-URL (`hooks.slack.com/triggers/...`). Corgea sendet `scan.*` und `webhook.test` für diese Ziele als flache Struktur. Ordnen Sie das Top-Level-Feld `message` zu, nicht das verschachtelte `data.*`. Andere Events bleiben verschachtelt. Incoming-Webhooks (`hooks.slack.com/services/...`) werden abgelehnt, sofern Sie keinen Custom Body konfigurieren, dessen gerendertes JSON auf oberster Ebene das nicht leere String-Feld `text` enthält. `{"text": "{{message}}"}` ist nur für Scan-Lifecycle-Events und `scheduled_scan.daily_report` zulässig. Weitere Informationen finden Sie unter [Slack](slack).
    </Tip>
  </Step>

  <Step title="Events abonnieren">
    <Frame>
      <img src="https://mintcdn.com/corgea/bUShOerLaxHbdmO7/images/webhooks/create_webhook_events.png?fit=max&auto=format&n=bUShOerLaxHbdmO7&q=85&s=dffd5f8c779ea28405555be193aae289" alt="Ereignis-Abonnementformular mit Umschaltern für Probleme, SLA, Scan, Benutzer und geplante Scan-Ereignisse" style={{ borderRadius: '0.5rem' }} width="1089" height="761" data-path="images/webhooks/create_webhook_events.png" />
    </Frame>

    Schalten Sie die Ereignisse ein, die für Sie wichtig sind. Sie können mehr als eines auswählen:

    * Issue Status Changed
    * Issue Assigned
    * SLA Violation (`sla.violation`)
    * Scan Started / Completed / Failed
    * User Login / User Login Failed
    * Scheduled Scan Daily Report (`scheduled_scan.daily_report`)
  </Step>

  <Step title="Filter konfigurieren (optional)">
    <Frame>
      <img src="https://mintcdn.com/corgea/bUShOerLaxHbdmO7/images/webhooks/create_webhook_scopes.png?fit=max&auto=format&n=bUShOerLaxHbdmO7&q=85&s=b77a4be9aeb754e6b411ca55714f84f6" alt="Projektumfang, geplanter Scanbereich, benutzerdefinierte Header und benutzerdefinierte Body-Abschnitte" style={{ borderRadius: '0.5rem' }} width="1089" height="594" data-path="images/webhooks/create_webhook_scopes.png" />
    </Frame>

    **Scan Event Filters** (für `scan.*`-Events)

    * **Only pull request / merge request scans** – Scans ohne `pull_request_id` überspringen
    * **Only completed scans with true-positive findings** – `scan.completed` überspringen, wenn `true_positive_count` den Wert 0 hat; `scan.failed` und `scan.started` sind nicht betroffen

    **Project Scope**

    * Deaktiviert lassen, um Events aus allen Projekten zu erhalten
    * Filterung aktivieren, um den Webhook auf ausgewählte Projekte zu beschränken
    * Bei `sla.violation` wird der Webhook ausgelöst, wenn **mindestens ein** Projekt im Payload übereinstimmt

    **Status Change Filter** (für `issue.status_changed`)

    * Leer lassen für alle Statusänderungen
    * Oder auf Status wie `fixed` oder `false_positive` beschränken

    **Scheduled Scan Scope** (für `scan.*`-Events)

    * Deaktiviert lassen, um alle Scans (manuell und geplant) zu erhalten
    * Aktivieren, damit der Webhook nur für ausgewählte Scheduled Scans ausgelöst wird
  </Step>

  <Step title="Custom Header und Body hinzufügen (optional)">
    **Custom Header**

    Fügen Sie die vom Webhook-Ziel benötigten Header hinzu. Die Anforderungen unterscheiden sich je nach Dienst:

    <AccordionGroup>
      <Accordion title="JIRA Automation" icon="jira">
        **Erforderlicher Header:**

        ```text theme={null}
        X-Automation-Webhook-Token: <your-jira-webhook-secret>
        ```

        **Token abrufen:**

        1. Erstellen Sie in JIRA eine Automatisierungsregel mit dem Trigger **Incoming webhook**.
        2. Kopieren Sie das von JIRA bereitgestellte Secret Token.
        3. Tragen Sie es in Corgea als Header-Wert ein.

        [JIRA-Webhook-Dokumentation](https://support.atlassian.com/cloud-automation/docs/configure-the-incoming-webhook-trigger-in-atlassian-automation/)
      </Accordion>

      <Accordion title="Slack" icon="slack">
        **Keine Custom Header erforderlich** – die Slack-URL enthält die Authentifizierungsdaten.

        Verwenden Sie vorzugsweise eine Workflow-Builder-URL (`https://hooks.slack.com/triggers/...`). Mit `Type = Slack` überträgt Corgea `scan.*` und `webhook.test` als flache Struktur. Ordnen Sie `message`, `pull_request_id`, `scan_url`, `true_positive_count` und `company` zu. Verschachtelte `data.*`-Felder dürfen **nicht** zugeordnet werden, da Slack HTTP 400 zurückgibt. Andere Event-Typen werden nicht abgeflacht. Weitere Informationen finden Sie unter [Slack](slack).

        Incoming-Webhooks (`https://hooks.slack.com/services/...`) benötigen einen Custom Body, dessen gerendertes JSON auf oberster Ebene das nicht leere String-Feld `text` enthält. Verwenden Sie `{"text": "{{message}}"}` nur für Scan-Lifecycle-Events und `scheduled_scan.daily_report`.
      </Accordion>

      <Accordion title="Microsoft Teams" icon="microsoft">
        **Keine Custom Header erforderlich** – Teams-Webhook-URLs enthalten die Authentifizierung direkt in der URL.

        Fügen Sie Ihre Teams-Webhook-URL ein. Format: `https://xxx.webhook.office.com/webhookb2/xxx/IncomingWebhook/xxx`

        <Note>Incoming-Webhooks von Teams validieren keine Custom Header. Der Schutz beruht auf der Geheimhaltung der Webhook-URL.</Note>

        [Teams Webhook Dokumentation](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook)
      </Accordion>

      <Accordion title="Benutzerdefinierte API mit Bearer-Token" icon="key">
        **Header:**

        ```text theme={null}
        Authorization: Bearer <your-api-token>
        ```

        Üblich für REST-APIs, die JWT- oder OAuth-Token verwenden.
      </Accordion>

      <Accordion title="Splunk HEC" icon="bolt">
        **Header:**

        ```text theme={null}
        Authorization: Splunk <your-hec-token>
        ```

        Verwenden Sie diesen Header, wenn Sie Webhook-Events an einen Endpunkt des Splunk HTTP Event Collector (HEC) senden.
      </Accordion>

      <Accordion title="Benutzerdefinierte API mit API-Key" icon="lock">
        **Header (wählen Sie einen):**

        ```text theme={null}
        X-API-Key: <your-api-key>
        ```

        oder

        ```text theme={null}
        Authorization: ApiKey <your-api-key>
        ```

        Üblich für einfache API-Key-Authentifizierung.
      </Accordion>

      <Accordion title="PagerDuty" icon="bell">
        **Keine Custom Header erforderlich** – die PagerDuty Events API v2 verwendet den `routing_key` im JSON-Payload zur Authentifizierung.

        Verwenden Sie den PagerDuty Events API-Endpunkt: `https://events.pagerduty.com/v2/enqueue`

        <Note>PagerDuty validiert keine Custom Header. Die Authentifizierung erfolgt über `routing_key` im Request-Body.</Note>

        [PagerDuty Webhook-Dokumentation](https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTgw-events-api-v2-overview)
      </Accordion>

      <Accordion title="Zapier" icon="bolt">
        **Keine Custom Header erforderlich** – Zapier-Webhook-URLs enthalten die Authentifizierung direkt in der URL.

        Erstellen Sie einen Trigger mit **Webhooks by Zapier** und verwenden Sie die bereitgestellte URL.

        <Note>Zapier Catch Hook validiert standardmäßig keine Custom Header. Der Schutz beruht auf der Geheimhaltung der Webhook-URL. Bei Bedarf können Sie in Ihrem Zap eine Prüfung der Header implementieren.</Note>

        [Zapier Webhook-Dokumentation](https://zapier.com/help/create/code-webhooks/trigger-zaps-from-webhooks)
      </Accordion>
    </AccordionGroup>

    <Tip>
      Wenn Ihr Dienst nicht aufgeführt ist, entnehmen Sie die erforderlichen Header der Webhook- oder Incoming-Webhook-Dokumentation des Dienstes.
    </Tip>

    <Warning>
      **Wichtig:** Corgea sendet alle konfigurierten Custom Header, aber nicht jedes Webhook-Ziel validiert sie. Dienste wie Slack, Teams und Zapier verwenden geheime URLs anstelle einer Header-Validierung. Fügen Sie Custom Header nur hinzu, wenn der Zieldienst diese tatsächlich benötigt oder validiert, beispielsweise JIRA oder eine eigene API.
    </Warning>

    **Custom Body**

    * Optional ein JSON-Objekt-Template für den Webhook-Request-Body angeben
    * Lassen Sie es leer, um die Standard-Payload-Struktur von Corgea zu verwenden
    * Unterstützte Platzhalter:
      * `{{payload}}` (vollständiges Standard-Payload-Objekt)
      * `{{time}}` (Unix-Sekunden)
      * `{{timestamp}}` (ISO-8601-Zeitstempel)
      * `{{event_type}}`
      * `{{event_id}}`
      * `{{message}}` (aus `data.message`, sofern vorhanden – Scan-Lifecycle und täglicher Bericht)
    * Ist das gerenderte Template kein gültiges JSON, schlägt die Zustellung fehl und der Fehler erscheint im Webhook-Verlauf.
  </Step>

  <Step title="Speichern und Aktivieren">
    * Klicken Sie auf **Create Webhook**.
    * Kopieren Sie den Secret Key aus dem Popup. Corgea zeigt ihn nur einmal an.

    <Frame>
      <img src="https://mintcdn.com/corgea/bUShOerLaxHbdmO7/images/webhooks/webhook_secret_key.png?fit=max&auto=format&n=bUShOerLaxHbdmO7&q=85&s=e219c00690cd7873f987954a632fec23" alt="Webhook-Geheimschlüssel-Popup wird einmal nach Erstellung eines Webhooks angezeigt" style={{ borderRadius: '0.5rem' }} width="506" height="610" data-path="images/webhooks/webhook_secret_key.png" />
    </Frame>

    <Warning>
      Speichern Sie den Secret Key, bevor Sie den Dialog schließen. Er kann später nicht erneut angezeigt werden. Wenden Sie sich an den Support, wenn Sie ihn rotieren müssen.
    </Warning>

    * Klicken Sie auf **I've saved the Secret Key**.
    * Der Webhook ist jetzt aktiv und empfängt Events.
  </Step>

  <Step title="Webhook testen">
    * Öffnen Sie den Webhook und klicken Sie auf **Test Webhook**.
    * Prüfen Sie, ob Ihr Endpunkt eine 2xx-Response zurückgibt.
    * Beim Slack Workflow Builder wird ein flacher Body mit dem nicht leeren Top-Level-Feld `message` und beispielhaften Triage-Schlüsseln wie `pull_request_id`, `scan_url` und `true_positive_count` gesendet. Dadurch können Sie die Variablen beim Test zuordnen. Konfigurationen, die ausschließlich verschachtelte Felder verwenden, werden nicht unterstützt.
  </Step>
</Steps>

### Webhook-Signaturen verifizieren

<Note>Verifizieren Sie den `X-Corgea-Signature`-Header jedes Requests mit dem bei der Erstellung angezeigten Secret Key.</Note>

<Tabs>
  <Tab title="Python">
    ```python verify-signature.py theme={null}
    import hmac
    import hashlib

    def verify_webhook_signature(payload, signature, secret):
        """Verify Corgea webhook signature"""
        expected_signature = hmac.new(
            secret.encode('utf-8'),
            payload.encode('utf-8'),
            hashlib.sha256
        ).hexdigest()

        return hmac.compare_digest(expected_signature, signature)

    # In your webhook handler:
    if not verify_webhook_signature(request.body, request.headers['X-Corgea-Signature'], SECRET_KEY):
        return HttpResponse(status=403)  # Reject invalid signatures
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript verify-signature.js theme={null}
    const crypto = require('crypto');

    function verifyWebhookSignature(payload, signature, secret) {
      const expectedSignature = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');

      return crypto.timingSafeEqual(
        Buffer.from(expectedSignature),
        Buffer.from(signature)
      );
    }
    ```
  </Tab>
</Tabs>

***

## Anwendungsfälle

### 1. Echtzeit-Slack-Benachrichtigungen

**Szenario**: Das Security-Team bei neuen Issues mit hohem Schweregrad über Slack benachrichtigen

**Einrichtung**:

* Erstellen Sie in Ihrem Slack-Workspace eine Incoming-Webhook-URL.
* In Corgea erstellen Sie einen Webhook mit:
  * Type: `Slack`
  * URL: Ihre Slack-Webhooks-URL
  * Events: `scan.completed`
  * Project Filter: Kritische Produktionsprojekte

**Ergebnis**: Der Channel #security wird unmittelbar über abgeschlossene Scans informiert.

***

### 2. Automatisches Ticketing für kritische Issues

**Szenario**: Bei kritischen Issues automatisch Tickets in JIRA oder Linear erstellen

**Einrichtung**:

* Erstellen Sie einen Zapier-Zap oder einen benutzerdefinierten Endpunkt, der Tickets erstellt
* In Corgea erstellen Sie einen Webhook mit:
  * Events: `scan.completed`, `issue.status_changed`
  * Status Filter: Nur Status `open`, um doppelte Tickets zu vermeiden
  * Project Filter: Produktionsprojekte

**Ergebnis**: Issues mit hohem oder kritischem Schweregrad werden automatisch als Tickets im Projektmanagement-Tool angelegt.

***

### 3. Integration eines Workflows zur Risikoakzeptanz

**Szenario**: Akzeptierte Risiken automatisch in JIRA oder Linear dokumentieren, sobald Security-Issues als **Accepted Risk** markiert werden

**Einrichtung**:

* Erstellen Sie einen Endpunkt oder eine Zapier-Integration, die Dokumentationstickets erstellt
* In Corgea erstellen Sie einen Webhook mit:
  * Events: `issue.status_changed`
  * Status Filter: Nur Status `accepted_risk`
  * Project Filter: Alle Projekte oder ausgewählte Projekte mit hohen Compliance-Anforderungen
* Konfigurieren Sie die Integration, um:
  * Ein Ticket zur Dokumentation der Risikoakzeptanz zu erstellen
  * Issue-Details wie Klassifizierung, Dateipfad und Dringlichkeit einzubeziehen
  * das Label `risk-acceptance` zu setzen
  * das Ticket dem Security Lead zur Prüfung zuzuweisen

**Ergebnis**: Jedes akzeptierte Risiko wird automatisch mit vollständigem Kontext im Projektmanagementsystem erfasst. So entsteht ein Audit-Trail für Compliance- und Risikomanagement-Prüfungen.

***

### 4. Integration benutzerdefinierter Dashboards

**Szenario**: Security-Metriken in Echtzeit auf einem internen Dashboard darstellen

**Einrichtung**:

* Erstellen Sie einen Endpunkt, der Webhook-Daten empfängt und Ihr Dashboard aktualisiert
* In Corgea erstellen Sie einen Webhook mit:
  * Events: Alle Scan und Issue Events
  * Keine Filter (alles empfangen)

**Ergebnis**: Das Dashboard zeigt aktuelle Ergebnisse der Security-Scans und Trends bei den Issues.

***

### 5. Routing an mehrere Teams

**Szenario**: Verschiedene Projektbenachrichtigungen an verschiedene Teams weiterleiten

**Einrichtung**:

* Erstellen Sie separate Webhooks für jedes Team:
  * **Backend-Team-Webhook**: Projektfilter = Backend-Projekte, Slack-Kanal #backend-security
  * **Frontend-Team-Webhook**: Projektfilter = Frontend-Projekte, Slack-Kanal #frontend-security
  * **DevOps-Team-Webhook**: Projektfilter = Infrastrukturprojekte, Slack-Kanal #devops-security

**Ergebnis**: Jedes Team sieht nur die für seine Projekte relevanten Security-Issues.

***

### 6. Compliance-Reporting

**Szenario**: Alle Security-Findings automatisch in einem Compliance-System protokollieren

**Einrichtung**:

* Erstellen Sie einen Endpunkt, der in Ihre Compliance-Datenbank schreibt
* In Corgea erstellen Sie einen Webhook mit:
  * Events: `scan.completed`
  * Alle Projekte
  * Zustellungsverlauf des Webhooks für den Audit-Trail speichern

**Ergebnis**: Vollständiger Audit-Trail aller Security-Scans für Compliance-Zwecke

***

## Fehlerbehebung

### Webhook-Zustellungshistorie anzeigen

<Steps>
  <Step title="Webhook-Verlauf öffnen">
    Öffnen Sie **Integrations → Webhooks**.

    <Frame>
      <img src="https://mintcdn.com/corgea/JgeRsjW5cn2yU52a/images/webhooks/webhook_history.png?fit=max&auto=format&n=JgeRsjW5cn2yU52a&q=85&s=e0c209104347995d1bde95b867a6bb7d" alt="Webhook-Zustellhistorie zeigt die neuesten Webhook-Versuche" style={{ borderRadius: '0.5rem' }} width="3112" height="1466" data-path="images/webhooks/webhook_history.png" />
    </Frame>
  </Step>

  <Step title="Zustellungsprotokoll öffnen">
    Klicken Sie auf **History** oder **Delivery Log**.
  </Step>

  <Step title="Zustellungsdetails prüfen">
    <Frame>
      <img src="https://mintcdn.com/corgea/JgeRsjW5cn2yU52a/images/webhooks/webhook_history_details.png?fit=max&auto=format&n=JgeRsjW5cn2yU52a&q=85&s=14c49d0e334a55ee79a2bdb7f8b5126b" alt="Detaillierte Webhook-Zustellinformationen einschließlich Anfrage und Antwort" style={{ borderRadius: '0.5rem' }} width="2806" height="2094" data-path="images/webhooks/webhook_history_details.png" />
    </Frame>

    Für jeden Zustellungsversuch werden folgende Informationen angezeigt:

    * Ereignistyp und Zeitstempel
    * HTTP-Statuscode
    * Request- und Response-Details
    * Fehlermeldungen (falls vorhanden)
    * Wiederholungsversuche
  </Step>
</Steps>

### Häufige Probleme und Lösungen

<AccordionGroup>
  <Accordion title="Webhook erhält keine Ereignisse" icon="circle-xmark">
    **Mögliche Ursachen:**

    * Webhook ist pausiert oder inaktiv.
    * Event-Abonnements sind nicht konfiguriert.
    * Projekt-, Status- oder Scheduled-Scan-Filter schließen Events aus.
    * Endpunkt gibt keinen 2xx-Statuscode zurück.

    **Lösungen:**

    1. Prüfen Sie, ob der Webhook aktiv und nicht pausiert ist.
    2. Prüfen Sie, ob Event-Abonnements ausgewählt sind.
    3. Entfernen Sie Projekt-, Status- oder Scheduled-Scan-Filter vorübergehend zum Testen.
    4. Prüfen Sie die Logs des Endpunkts auf eingehende Requests.
    5. Testen Sie den Webhook über **Test Webhook**.
  </Accordion>

  <Accordion title="Webhook automatisch pausiert" icon="pause">
    **Ursache:** Zehn aufeinanderfolgende Zustellungsfehler

    **Lösungen:**

    1. Prüfen Sie den Zustellungsverlauf auf Fehlerdetails.
    2. Prüfen Sie, ob die Endpunkt-URL korrekt und erreichbar ist.
    3. Stellen Sie sicher, dass der Endpunkt 2xx-Statuscodes zurückgibt.
    4. Prüfen Sie, ob Firewall- oder Security-Regeln Requests von Corgea blockieren.
    5. Beheben Sie die Ursache und **reaktivieren Sie den Webhook manuell**.
    6. Prüfen Sie die Funktion vor dem erneuten Aktivieren über **Test Webhook**.
  </Accordion>

  <Accordion title="Zu viele Webhook-Aufrufe" icon="volume-high">
    **Lösungen:**

    1. **Statusfilter verwenden**: Bei `issue.status_changed` nur relevante Status wie `fixed` und `false_positive` auswählen
    2. **Projektfilter verwenden**: Nur ausgewählte kritische Projekte abonnieren
    3. **Scheduled-Scan-Filter verwenden**: Für Scan-Events nur die Scheduled Scans auswählen, die den Webhook auslösen sollen
    4. **Event-Abonnements reduzieren**: Nicht benötigte Events abbestellen
    5. **Rate Limiting implementieren**: Am Endpunkt Rate Limiting oder eine Queue implementieren
  </Accordion>

  <Accordion title="Signaturprüfung schlägt fehl" icon="shield-xmark">
    **Mögliche Ursachen:**

    * Falscher Secret Key
    * Falsche Logik zur Signaturüberprüfung
    * Probleme mit der Zeichencodierung

    **Lösungen:**

    1. Verwenden Sie exakt den von Corgea bereitgestellten Secret Key.
    2. Verwenden Sie den HMAC-SHA256-Algorithmus.
    3. Verifizieren Sie den unverarbeiteten Request-Body, nicht das geparste JSON.
    4. Prüfen Sie auf beiden Seiten die UTF-8-Codierung.
    5. Verwenden Sie `hmac.compare_digest()` (Python) oder `crypto.timingSafeEqual()` (Node.js) für einen Timing-Attack-sicheren Vergleich.

    <Tip>Protokollieren Sie zum Vergleich sowohl die empfangene als auch die berechnete Signatur.</Tip>
  </Accordion>

  <Accordion title="Timeout am Endpunkt" icon="clock">
    **Ursache:** Ihr Endpunkt benötigt länger als 10 Sekunden für die Antwort

    **Lösungen:**

    1. **Sofort bestätigen**: Unmittelbar `200 OK` zurückgeben und anschließend asynchron verarbeiten
    2. **Queue verwenden**: Webhook-Payloads zur Verarbeitung im Hintergrund in eine Queue einreihen
    3. **Verarbeitung optimieren**: Logik des Webhook-Handlers beschleunigen
    4. **Ressourcen erhöhen**: Infrastruktur des Endpunkts skalieren

    **Best-Practice-Muster:**

    ```python webhook-handler.py theme={null}
    @app.route('/webhook', methods=['POST'])
    def handle_webhook():
        payload = request.json

        # Immediately acknowledge receipt
        queue.add(process_webhook, payload)

        # Return quickly
        return '', 200

    def process_webhook(payload):
        # Do time-consuming work here
        ...
    ```
  </Accordion>

  <Accordion title="Doppelte Ereignisse" icon="copy">
    **Mögliche Ursachen:**

    * Mehrere Webhooks abonnieren dasselbe Ereignis
    * Retry-Logik wird nach verzögertem Erfolg ausgelöst

    **Lösungen:**

    1. Prüfen Sie, ob Webhooks doppelt konfiguriert wurden.
    2. Verwenden Sie das Feld `event_id` für Idempotenz: Speichern Sie IDs bereits verarbeiteter Events und überspringen Sie Duplikate.
    3. Implementieren Sie Idempotency Keys am Endpunkt.

    **Idempotenz-Muster:**

    ```python idempotency.py theme={null}
    processed_events = set()  # Or use Redis/database

    @app.route('/webhook', methods=['POST'])
    def handle_webhook():
        event_id = request.json['event_id']

        if event_id in processed_events:
            return '', 200  # Already processed

        # Process event...
        processed_events.add(event_id)
        return '', 200
    ```
  </Accordion>

  <Accordion title="Fehlende Daten im Payload" icon="question">
    **Lösungen:**

    1. Prüfen Sie den vollständigen Payload im Zustellungsverlauf.
    2. Einige Felder können `null` sein, wenn keine Daten vorliegen, beispielsweise bei nicht zugewiesenen Issues.
    3. Implementieren Sie Null-Prüfungen im Handler-Code.
    4. Prüfen Sie im Zustellungsverlauf die Payload-Struktur des jeweiligen Events.
  </Accordion>
</AccordionGroup>

### Webhook-Statistiken abrufen

So rufen Sie Performance-Metriken für Ihre Webhooks auf:

1. Öffnen Sie **Integrations → Webhooks**.
2. Prüfen Sie die Statistiken des jeweiligen Webhooks:
   * **Total Deliveries**: Gesamtzahl der Webhook-Aufrufe
   * **Successful Deliveries**: Aufrufe mit 2xx-Response
   * **Failed Deliveries**: Fehlgeschlagene Aufrufe und Timeouts
   * **Success Rate**: Anteil erfolgreicher Zustellungen
   * **Consecutive Failures**: Aktuelle Anzahl aufeinanderfolgender Fehler
   * **Last Triggered**: Zeitpunkt der letzten Auslösung

***

### Manuelle Wiederholung

Fehlgeschlagene Webhook-Zustellungen können Sie manuell wiederholen:

1. Öffnen Sie **Integrations → Webhooks → History**.
2. Suchen Sie die fehlgeschlagene Zustellung.
3. Klicken Sie auf **Retry**.
4. Corgea erstellt und sendet sofort einen neuen Zustellungsversuch.

***

### Zustellungsverlauf exportieren

So exportieren Sie den Webhook-Zustellungsverlauf für Compliance- oder Debugging-Zwecke:

1. Öffnen Sie **Integrations → Webhooks → History**.
2. Wenden Sie Filter für Datumsbereich, Event-Typ, Status oder Webhook an.
3. Klicken Sie auf **Export**, um die CSV-Datei herunterzuladen.
4. Verwenden Sie den Export für:
   * Compliance-Audits
   * Performance-Analysen
   * Analyse von Fehlermustern
   * Nachverfolgung der Issue-Behebung

***

### Tipps zum Testen

<Accordion title="Vor dem Produktivbetrieb">
  1. Verwenden Sie [webhook.site](https://webhook.site) oder [RequestBin](https://requestbin.com), um Payloads zu prüfen.
  2. Testen Sie zunächst mit Projekten mit geringem Volumen.
  3. Überwachen Sie in den ersten Tagen die Erfolgsquote der Zustellungen.
  4. Richten Sie im eigenen System Alerts für Webhook-Fehler ein.
</Accordion>

<Accordion title="Debug-Checkliste">
  * Webhook-URL ist korrekt und zugänglich
  * Endpunkt gibt innerhalb von 10 Sekunden einen 2xx-Statuscode zurück
  * Firewall erlaubt die Anfragen von Corgea
  * Ereignisabonnements sind ausgewählt
  * Filter sind korrekt konfiguriert (oder für Tests entfernt)
  * Signaturprüfung funktioniert, sofern ein Secret verwendet wird
  * Webhook ist aktiv (nicht pausiert)
</Accordion>

***

## Beispiel-Payloads

<Tabs>
  <Tab title="Status des Problems geändert">
    ```json issue-status-changed.json theme={null}
    {
      "event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "event_type": "issue.status_changed",
      "timestamp": "2025-01-15T14:30:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "issue_id": "issue-uuid-5678",
        "classification": "SQL Injection",
        "urgency": "HI",
        "status": "fixed",
        "previous_status": "open",
        "file_path": "src/controllers/user.py",
        "line_num": 45,
        "project": {
          "id": "proj-uuid-9012",
          "name": "Production API"
        },
        "scan_id": "scan-uuid-3456",
        "url": "https://app.corgea.com/issue/issue-uuid-5678/"
      }
    }
    ```
  </Tab>

  <Tab title="Scan gestartet">
    ```json scan-started.json theme={null}
    {
      "event_id": "a0b1c2d3-e4f5-6789-abcd-ef0123456789",
      "event_type": "scan.started",
      "timestamp": "2025-01-15T15:40:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "scan_id": "scan-uuid-7890",
        "run_id": "run-12345",
        "project": {
          "id": "proj-uuid-9012",
          "name": "Production API"
        },
        "project_name": "Production API",
        "branch": "main",
        "engine": "corgea-blast",
        "scan_type": "full",
        "status": "started",
        "pull_request_id": "42",
        "scan_url": "https://app.corgea.app/project/proj-uuid-9012/?scan_id=scan-uuid-7890",
        "true_positive_count": 0,
        "message": "Scan started for Production API (PR #42).",
        "scheduled_scan_ids": ["scheduled-scan-uuid"],
        "created_at": "2025-01-15T15:40:00.000Z"
      }
    }
    ```
  </Tab>

  <Tab title="Scan abgeschlossen">
    ```json scan-completed.json theme={null}
    {
      "event_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "event_type": "scan.completed",
      "timestamp": "2025-01-15T15:45:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "scan_id": "scan-uuid-7890",
        "run_id": "run-12345",
        "project": {
          "id": "proj-uuid-9012",
          "name": "Production API"
        },
        "project_name": "Production API",
        "branch": "main",
        "engine": "corgea-blast",
        "scan_type": "full",
        "status": "completed",
        "pull_request_id": "42",
        "scan_url": "https://app.corgea.app/project/proj-uuid-9012/?scan_id=scan-uuid-7890",
        "true_positive_count": 5,
        "summary": {
          "total_issues": 8,
          "issues_with_fixes": 5,
          "issues_without_fixes": 3,
          "severity_breakdown": {
            "HI": {
              "name": "High",
              "count": 2
            },
            "ME": {
              "name": "Medium",
              "count": 6
            }
          },
          "classification_breakdown": [
            {
              "classification": "SQL Injection",
              "count": 2
            },
            {
              "classification": "Cross-Site Scripting (XSS)",
              "count": 1
            }
          ]
        },
        "message": "Scan completed for Production API (PR #42): 5 true-positive findings (5 with fixes). View: https://app.corgea.app/project/proj-uuid-9012/?scan_id=scan-uuid-7890",
        "scheduled_scan_ids": ["scheduled-scan-uuid"],
        "processed_at": "2025-01-15T15:45:00.000Z",
        "created_at": "2025-01-15T15:40:00.000Z"
      }
    }
    ```

    Zapier und andere Ziele erhalten die oben dargestellte verschachtelte Struktur; Corgea speichert sie auch im Zustellungsverlauf. Nur bei `scan.*` und `webhook.test` erhält der Slack Workflow Builder die Triage-Felder als **Top-Level-Schlüssel** im HTTP-Request-Body: `message`, `scan_id`, `scan_url`, `pull_request_id`, `true_positive_count`, `status`, `branch`, `project_name`, `company`, `run_id`, `engine` und `scan_type`; bei `scan.failed` gegebenenfalls zusätzlich `error`, bei `webhook.test` außerdem `company_id`, `test` und `webhook_name`. Die Felder `summary`, `project`, `scheduled_scan_ids`, `scan_errors`, `created_at` und `processed_at` werden nicht verschachtelt übertragen. `data.message` beziehungsweise das Top-Level-Feld `message` enthält eine Klartextzusammenfassung. Das Suffix „(N with fixes)“ zählt nur Fixes für True-Positive-Findings, nicht für sämtliche Issues des Scans.
  </Tab>

  <Tab title="Scan fehlgeschlagen">
    ```json scan-failed.json theme={null}
    {
      "event_id": "c1d2e3f4-a5b6-7890-cdef-1234567890ab",
      "event_type": "scan.failed",
      "timestamp": "2025-01-15T15:42:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "scan_id": "scan-uuid-7890",
        "run_id": "run-12345",
        "project": {
          "id": "proj-uuid-9012",
          "name": "Production API"
        },
        "project_name": "Production API",
        "branch": "main",
        "engine": "corgea-blast",
        "scan_type": "full",
        "status": "failed",
        "pull_request_id": "42",
        "scan_url": "https://app.corgea.app/project/proj-uuid-9012/?scan_id=scan-uuid-7890",
        "true_positive_count": 0,
        "error": "Scanner timed out",
        "scan_errors": null,
        "message": "Scan failed for Production API (PR #42): Scanner timed out. View: https://app.corgea.app/project/proj-uuid-9012/?scan_id=scan-uuid-7890",
        "scheduled_scan_ids": ["scheduled-scan-uuid"],
        "created_at": "2025-01-15T15:40:00.000Z"
      }
    }
    ```

    `data.message` enthält den Fehlergrund, bei mehr als 200 Zeichen gekürzt, und gegebenenfalls die Scan-URL. Die unverarbeiteten Fehlerdetails stehen in `data.error` und `data.scan_errors`. Im Slack Workflow Builder ist `error` zusätzlich als flaches Top-Level-Feld verfügbar.
  </Tab>

  <Tab title="Issue zugewiesen">
    ```json issue-assigned.json theme={null}
    {
      "event_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "event_type": "issue.assigned",
      "timestamp": "2025-01-15T16:00:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "issue_id": "issue-uuid-5678",
        "classification": "Cross-Site Scripting (XSS)",
        "urgency": "ME",
        "status": "open",
        "assigned_to": {
          "id": "user-uuid-1111",
          "email": "jane.doe@company.com",
          "name": "Jane Doe"
        },
        "previously_assigned_to": {
          "id": "user-uuid-2222",
          "email": "john.smith@company.com",
          "name": "John Smith"
        },
        "project": {
          "id": "proj-uuid-9012",
          "name": "Production API"
        },
        "url": "https://app.corgea.com/issue/issue-uuid-5678/"
      }
    }
    ```
  </Tab>

  <Tab title="SLA-Verstoß">
    ```json sla-violation.json theme={null}
    {
      "event_id": "f6a7b8c9-d0e1-2345-f012-345678901234",
      "event_type": "sla.violation",
      "timestamp": "2025-01-15T16:20:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "sla": {
          "id": 3,
          "rule_type": "sca",
          "urgency": ["CR", "HI"],
          "remediation_days": 14,
          "escalation_days": 7
        },
        "notification_type": "escalation",
        "issue_kind": "SCA",
        "issue_count": 12,
        "summary_message": "Plain-text summary of breached issues...",
        "projects": [
          {
            "id": "proj-uuid-9012",
            "name": "Production API",
            "url": "https://app.corgea.com/project/proj-uuid-9012",
            "issue_count": 12,
            "urgency_counts": {
              "Critical": 4,
              "High": 8
            }
          }
        ]
      }
    }
    ```
  </Tab>

  <Tab title="Benutzeranmeldung">
    ```json user-login.json theme={null}
    {
      "event_id": "d4e5f6a7-b8c9-0123-def0-123456789012",
      "event_type": "user.login",
      "timestamp": "2025-01-15T16:10:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "user_id": 123,
        "username": "jane.doe",
        "email": "jane.doe@company.com",
        "first_name": "Jane",
        "last_name": "Doe",
        "user_agent": "Mozilla/5.0",
        "path": "/login/"
      }
    }
    ```
  </Tab>

  <Tab title="Benutzeranmeldung fehlgeschlagen">
    ```json user-login-failed.json theme={null}
    {
      "event_id": "e5f6a7b8-c9d0-1234-ef01-234567890123",
      "event_type": "user.login_failed",
      "timestamp": "2025-01-15T16:12:00.000Z",
      "data": {
        "company": "comp-uuid-1234",
        "username": "jane.doe",
        "user_agent": "Mozilla/5.0",
        "path": "/login/"
      }
    }
    ```
  </Tab>

  <Tab title="Täglicher Scheduled-Scan-Bericht">
    ```json scheduled-scan-daily-report.json theme={null}
    {
      "event_id": "3282dbbb-7392-476b-8ce2-19fc1070342c",
      "event_type": "scheduled_scan.daily_report",
      "timestamp": "2026-05-13T12:29:53.083616+00:00",
      "data": {
        "title": "🐕 Corgea Daily Scan Report",
        "company": "123",
        "company_name": "Acme Corp",
        "total_new_issues": 7,
        "message": "Daily scan report for Acme Corp: 7 new issues detected across 2 scan runs.",
        "scan_runs": [
          {
            "scheduled_scan_name": "Nightly API Scan",
            "project": "api-service",
            "new_issue_count": 5,
            "scan_url": "https://app.corgea.com/scans/abc123"
          },
          {
            "scheduled_scan_name": "Nightly Frontend Scan",
            "project": "frontend",
            "new_issue_count": 2,
            "scan_url": "https://app.corgea.com/scans/def456"
          }
        ]
      }
    }
    ```

    Die äußere Struktur mit `event_id`, `event_type`, `timestamp` und `data` entspricht der [Standard-Payload-Struktur](#payload-structure). Das Objekt `data` enthält:

    | Feld                              | Typ            | Beschreibung                                                                    |
    | --------------------------------- | -------------- | ------------------------------------------------------------------------------- |
    | `title`                           | string         | Anzeigetitel des Berichts                                                       |
    | `company`                         | string         | Unternehmens-ID                                                                 |
    | `company_name`                    | string         | Anzeigename des Unternehmens                                                    |
    | `total_new_issues`                | integer        | Summe der neuen Issues aus allen Scan-Läufen im Payload                         |
    | `message`                         | string         | Lesbare Zusammenfassung für Klartextbenachrichtigungen, beispielsweise in Slack |
    | `scan_runs`                       | array          | Ein Eintrag je Scan-Lauf, in dem mindestens ein neues Finding erkannt wurde     |
    | `scan_runs[].scheduled_scan_name` | string         | Name der Scheduled-Scan-Konfiguration                                           |
    | `scan_runs[].project`             | string \| null | Projektname oder `null`, wenn kein Projekt verknüpft ist                        |
    | `scan_runs[].new_issue_count`     | integer        | Anzahl der in diesem Lauf erkannten neuen Issues                                |
    | `scan_runs[].scan_url`            | string \| null | Direktlink zu den Scan-Ergebnissen in Corgea oder `null`, wenn nicht verfügbar  |
  </Tab>
</Tabs>

***

## FAQ

<AccordionGroup>
  <Accordion title="Kann ich dieselbe Webhook-URL für mehrere Ereignistypen verwenden?">
    Ja. Ihr Endpunkt erhält den Header `X-Corgea-Event` und das Feld `event_type`, anhand derer er das Event identifizieren kann.
  </Accordion>

  <Accordion title="Wie viele Webhooks kann ich erstellen?">
    Es gibt keine feste Obergrenze. Wir empfehlen eine Gliederung nach Zweck, beispielsweise einen Webhook je Team oder Tool.
  </Accordion>

  <Accordion title="Was passiert, wenn mein Endpunkt ausfällt?">
    Corgea unternimmt insgesamt drei Zustellungsversuche mit exponentiellem Backoff. Nach zehn aufeinanderfolgenden Fehlern wird der Webhook automatisch pausiert.
  </Accordion>

  <Accordion title="Kann ich Webhooks testen, ohne echte Ereignisse auszulösen?">
    Ja. Über **Test Webhook** senden Sie einen Beispiel-Payload, ohne auf ein reales Event zu warten. Beim Slack Workflow Builder ist dieser Payload flach und enthält ein nicht leeres Feld `message` sowie die Triage-Schlüssel `pull_request_id`, `scan_url`, `true_positive_count` und `company`. Für ältere Test-Consumer enthält er außerdem `company_id` mit demselben Wert.
  </Accordion>

  <Accordion title="Kann ich nur bei PR-Scan-Fehlern / abgeschlossenen PR-Scans mit Befunden benachrichtigt werden?">
    Ja. Aktivieren Sie unter **Scan Event Filters** die Optionen **Only pull request / merge request scans** und **Only completed scans with true-positive findings**. Abonnieren Sie `scan.failed` und `scan.completed`. Der Findings-Filter gilt nicht für `scan.failed`.
  </Accordion>

  <Accordion title="Unterstützen Webhooks Authentifizierung?">
    Ja. Corgea generiert automatisch einen Secret Key zur HMAC-Signaturprüfung über `X-Corgea-Signature`. Sie können außerdem Custom Header für zielspezifische Authentifizierungs-Tokens hinzufügen.
  </Accordion>

  <Accordion title="Kann ich Webhooks auf bestimmte Branches filtern?">
    Nicht direkt, aber Sie können nach Projekt filtern. Sie können auch die empfangenen Payloads an Ihrem Endpunkt filtern.
  </Accordion>

  <Accordion title="Sind Webhook-Payloads verschlüsselt?">
    Payloads werden über HTTPS (TLS) und damit während der Übertragung verschlüsselt. Verwenden Sie HMAC-Signaturen zur Verifizierung.
  </Accordion>

  <Accordion title="Wie lange werden Webhook-Zustellungsprotokolle aufbewahrt?">
    Zustellungsprotokolle werden für Compliance- und Debugging-Zwecke aufbewahrt. Die konkrete Aufbewahrungsdauer hängt von Ihrem Tarif ab.
  </Accordion>

  <Accordion title="Kann ich einen Webhook manuell erneut auslösen?">
    Ja. Öffnen Sie den Webhook-Zustellungsverlauf und klicken Sie bei der fehlgeschlagenen Zustellung auf **Retry**.
  </Accordion>

  <Accordion title="Von welchen IP-Adressen sendet Corgea Webhooks?">
    Wenden Sie sich an den Support, um die aktuelle Liste der IP-Adressen für die Allowlist Ihrer Firewall zu erhalten.
  </Accordion>
</AccordionGroup>

***

**Fragen oder Probleme?** Kontaktieren Sie [Corgea Support](mailto:support@corgea.com)
