---
title: Webhooks abonnieren
url: https://platform.claude.com/docs/de/managed-agents/webhooks
description: Lass dich benachrichtigen, wenn wichtige Ereignisse eintreten, ohne Polling zu verwenden.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

Sessions sind lang laufende Interaktionen. Während die meisten Echtzeit-Interaktionen über den [SSE-Event-Stream](https://platform.claude.com/docs/de/managed-agents/events-and-streaming) stattfinden, benachrichtigen dich „webhooks" (Webhooks) über wichtige Zustandsänderungen.

Webhook-Events geben den Event-`type` und die `id` zurück, nicht das vollständige Objekt. Wenn du ein Webhook-Event empfängst, musst du das Objekt direkt mit einem `GET`-Aufruf abrufen. Dadurch wird vermieden, dass bei Wiederholungsversuchen veraltete Daten zugestellt werden, und jede Zustellung bleibt klein.

## Unterstützte Event-Typen

<Tabs>
  <Tab title="Session-Events">
    Einige dieser Events sind anders benannt als die entsprechenden Events im [Event-Stream](https://platform.claude.com/docs/de/managed-agents/events-and-streaming) der Session. Zum Beispiel entsprechen `session.status_idle` und `session.status_running` aus dem Stream den Webhook-Events `session.status_idled` und `session.status_run_started`.

    | Event                              | Auslöser                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
    | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `session.status_run_started`       | Die Agent-Ausführung wurde gestartet. Dies wird bei jedem Übergang des Session-Status zu `running` ausgelöst.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
    | `session.status_idled`             | Der Agent wartet auf Eingaben, zum Beispiel auf die Genehmigung einer Tool-Berechtigung oder eine neue Benutzernachricht.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
    | `session.budget_reached`           | Die Session hat ihr [Budget](https://platform.claude.com/docs/de/managed-agents/budgets) erreicht und wurde pausiert. Wird höchstens einmal für jeden von dir festgelegten Budgetwert ausgelöst; eine Änderung des Budgets aktiviert es erneut.                                                                                                                                                                                                                                                                                                                                                                                                                          |
    | `session.status_rescheduled`       | Ein vorübergehender Fehler ist aufgetreten, und die Session wird automatisch erneut versucht.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
    | `session.status_terminated`        | Die Session wurde beendet, entweder aufgrund eines nicht behebbaren Fehlers oder weil sie archiviert wurde.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
    | `session.thread_created`           | Ein neuer [Multiagent-Thread](https://platform.claude.com/docs/de/managed-agents/session-threads) wurde geöffnet: Ein zusätzlicher Agent, der von dem Agent aufgerufen wurde, den die Session ausführt, beginnt mit der Arbeit, oder der [Advisor](https://platform.claude.com/docs/de/managed-agents/multiagent-orchestration#give-the-session-an-advisor) der Session wird konsultiert. Es wird auch für jeden Thread eines [Workflow-Runs](https://platform.claude.com/docs/de/managed-agents/workflow-runs#a-runs-threads) ausgelöst, ebenso wie die anderen beiden Thread-Events in dieser Tabelle.                                                                 |
    | `session.thread_idled`             | Ein Agent in einer [Multiagent-Interaktion](https://platform.claude.com/docs/de/managed-agents/session-threads) wartet auf Eingaben.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
    | `session.thread_terminated`        | Ein [Multiagent-Thread](https://platform.claude.com/docs/de/managed-agents/session-threads) wurde beendet, entweder weil der Thread archiviert wurde oder weil er seine Wiederholungsversuche ausgeschöpft hat. Ein Subagent, der seine Arbeit abschließt, wechselt zu `idle`, nicht zu `terminated` (ein Advisor-Thread wird beendet, sobald seine Konsultation abgeschlossen ist, und die Threads eines Workflow-Runs werden beendet, wenn der Server sie bis zum Ende des Runs archiviert). Wird nur für Child-Threads ausgelöst; das Ende des primären Threads, einschließlich der Archivierung der gesamten Session, erscheint nur als `session.status_terminated`. |
    | `session.outcome_evaluation_ended` | Die [Outcome-Evaluierung](https://platform.claude.com/docs/de/managed-agents/define-outcomes) für eine einzelne Iteration wurde abgeschlossen.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
    | `session.updated`                  | Session-Eigenschaften wurden geändert (zum Beispiel wurde ihr Name oder ihre Konfiguration aktualisiert).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
    | `session.deleted`                  | Die Session wurde dauerhaft gelöscht. Es gibt kein Objekt mehr zum Abrufen, behandle das Event selbst also als endgültig.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
  </Tab>

  <Tab title="Vault-Events">
    | Event                             | Auslöser                                                                                                                                                                                                 |
    | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `vault.created`                   | Vault erstellt.                                                                                                                                                                                          |
    | `vault.archived`                  | Vault archiviert. Für jede zugrunde liegende Credential wird außerdem ein `vault_credential.archived`-Event ausgegeben.                                                                                  |
    | `vault.deleted`                   | Vault gelöscht. Für jede zugrunde liegende Credential wird außerdem ein `vault_credential.deleted`-Event ausgegeben. Es gibt kein Objekt mehr zum Abrufen, behandle das Event selbst also als endgültig. |
    | `vault_credential.created`        | Credential erstellt.                                                                                                                                                                                     |
    | `vault_credential.archived`       | Credential archiviert, entweder direkt oder infolge der Archivierung des Vaults.                                                                                                                         |
    | `vault_credential.deleted`        | Credential gelöscht, entweder direkt oder infolge der Löschung des Vaults. Es gibt kein Objekt mehr zum Abrufen, behandle das Event selbst also als endgültig.                                           |
    | `vault_credential.refresh_failed` | Eine `mcp_oauth`-Credential kann nicht aktualisiert werden (ungültiges Refresh-Token oder nicht behebbarer Fehler vom OAuth-Server).                                                                     |
  </Tab>

  <Tab title="Agent-Events">
    Diese Events verfolgen den Lebenszyklus der Agent-Ressourcen in deinem Workspace und unterscheiden sich von den Agent-Events, die im Event-Stream einer Session zugestellt werden.

    | Event            | Auslöser                                                                                                                                                                                                               |
    | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `agent.created`  | Agent erstellt.                                                                                                                                                                                                        |
    | `agent.updated`  | Eine [neue Version des Agents](https://platform.claude.com/docs/de/managed-agents/agent-setup#update-an-agent) wurde veröffentlicht. Aktualisierungen, die keine neue Version erstellen, lösen dieses Event nicht aus. |
    | `agent.archived` | Agent archiviert.                                                                                                                                                                                                      |
    | `agent.deleted`  | Agent dauerhaft gelöscht. Es gibt kein Objekt mehr zum Abrufen, behandle das Event selbst also als endgültig.                                                                                                          |
  </Tab>

  <Tab title="Deployment-Events">
    | Event                 | Auslöser                                                                                                                                                                                                                                                                                                                                                                                               |
    | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `deployment.created`  | [Geplantes Deployment](https://platform.claude.com/docs/de/managed-agents/scheduled-deployments) erstellt.                                                                                                                                                                                                                                                                                             |
    | `deployment.updated`  | Deployment-Eigenschaften wurden geändert (zum Beispiel wurde sein Zeitplan aktualisiert).                                                                                                                                                                                                                                                                                                              |
    | `deployment.paused`   | Deployment pausiert, entweder auf Anfrage oder automatisch, wenn ein geplanter Run mit einem nicht behebbaren Fehler fehlschlägt, etwa einem archivierten Subagent oder einer archivierten Umgebung. Behebbare Fehler, einschließlich Ratenlimits, pausieren das Deployment nicht. Siehe [Fehlerverhalten](https://platform.claude.com/docs/de/managed-agents/scheduled-deployments#failure-behavior). |
    | `deployment.unpaused` | Deployment fortgesetzt, sein Zeitplan wird wieder aufgenommen.                                                                                                                                                                                                                                                                                                                                         |
    | `deployment.archived` | Deployment archiviert, entweder direkt oder weil sein Agent archiviert wurde. Wird der Agent stattdessen gelöscht, wird ein geplantes Deployment bei seinem nächsten geplanten Run archiviert; ein Deployment ohne Zeitplan wird nicht automatisch archiviert.                                                                                                                                         |
    | `deployment.deleted`  | Deployment dauerhaft gelöscht. Es gibt kein Objekt mehr zum Abrufen, behandle das Event selbst also als endgültig.                                                                                                                                                                                                                                                                                     |
  </Tab>

  <Tab title="Deployment-Run-Events">
    | Event                      | Auslöser                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
    | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `deployment_run.started`   | Ein geplanter Run wurde gestartet. Nur geplante Runs geben `deployment_run`-Events aus; [manuelle Runs](https://platform.claude.com/docs/de/managed-agents/scheduled-deployments#trigger-a-manual-run) nicht.                                                                                                                                                                                                                                                      |
    | `deployment_run.succeeded` | Ein geplanter Run hat seine Session erstellt. Das Event trägt dieselbe `data.id` (die Run-ID) wie das `deployment_run.started`-Event des Runs. Um die Arbeit der Session zu verfolgen, abonniere ihre Session-Events (der Tab „Session-Events") oder rufe den [Deployment-Run](https://platform.claude.com/docs/de/managed-agents/scheduled-deployments#deployment-runs) für seine `session_id` (java: `sessionId`; php: `sessionID`; csharp, go: `SessionID`) ab. |
    | `deployment_run.failed`    | Ein geplanter Run hat keine Session erstellt. Das Event trägt dieselbe `data.id` wie das `deployment_run.started`-Event des Runs. Rufe den [Deployment-Run](https://platform.claude.com/docs/de/managed-agents/scheduled-deployments#deployment-runs) ab, um die Fehlerdetails zu erhalten.                                                                                                                                                                        |
  </Tab>

  <Tab title="Environment-Events">
    | Event                  | Auslöser                                                                                                                                                                |
    | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `environment.created`  | Umgebung erstellt.                                                                                                                                                      |
    | `environment.updated`  | Umgebung mit mindestens einem geänderten Feld aktualisiert. Eine Aktualisierung ohne Änderung gibt nichts aus.                                                          |
    | `environment.archived` | Umgebung archiviert. Das erneute Archivieren einer bereits archivierten Umgebung gibt nichts aus.                                                                       |
    | `environment.deleted`  | Umgebung gelöscht, einschließlich des Löschens einer bereits archivierten Umgebung. Es gibt kein Objekt mehr zum Abrufen, behandle das Event selbst also als endgültig. |

    Die [Work Items](https://platform.claude.com/docs/de/managed-agents/self-hosted-sandboxes) einer Umgebung geben keine Webhook-Events aus.
  </Tab>

  <Tab title="Memory-Store-Events">
    | Event                   | Auslöser                                                                                                                                                                                                                                                                                                                                                             |
    | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `memory_store.created`  | Memory Store erstellt, entweder von dir oder von einem von Anthropic betriebenen Prozess, der einen deiner bestehenden Stores klont.                                                                                                                                                                                                                                 |
    | `memory_store.archived` | Memory Store archiviert. Das erneute Archivieren eines bereits archivierten Stores gibt nichts aus.                                                                                                                                                                                                                                                                  |
    | `memory_store.deleted`  | Memory Store gelöscht, einschließlich des Löschens eines bereits archivierten Stores. Das Löschen eines Stores wirkt sich kaskadierend auf seine Memories und Memory-Versionen aus, ohne Events pro Memory auszugeben; das einzelne `memory_store.deleted`-Event ist das Signal. Es gibt kein Objekt mehr zum Abrufen, behandle das Event selbst also als endgültig. |

    Einzelne [Memories](https://platform.claude.com/docs/de/managed-agents/memory) und Memory-Versionen geben keine Webhook-Events aus.
  </Tab>
</Tabs>

## Einen Endpoint registrieren

Gehe in der Claude Console zur Seite [Webhooks](https://platform.claude.com/settings/workspaces/default/webhooks) (`platform.claude.com/settings/workspaces/default/webhooks`). Jeder Endpoint gehört zu einem Workspace. Wähle den gewünschten Workspace in der Workspace-Auswahl in der Seitenleiste aus.

Ein Webhook-Endpoint besteht aus:

* **URL:** Muss HTTPS auf Port 443 mit einem öffentlich auflösbaren Hostnamen sein.
* **Event-Typen:** Die Liste der `data.type`-Werte, die dieser Endpoint empfängt. Ein Endpoint empfängt nur Events, die er abonniert hat.
* **Signing Secret:** Ein 32-Byte-Secret mit dem Präfix `whsec_`, das bei der Erstellung generiert wird. Es wird nur einmal angezeigt, speichere es also sicher, um Webhook-Zustellungen zu verifizieren.

## Die Signatur verifizieren

Jede Zustellung enthält die Header `webhook-id`, `webhook-timestamp` und `webhook-signature`. Verwende den `unwrap()` (csharp, go: `Unwrap()`)-Helper des SDK, um die Signatur zu verifizieren und das Event in einem Schritt zu parsen. Er wirft einen Fehler, wenn die Signatur ungültig ist oder der Payload älter als 5 Minuten ist.

Setze `ANTHROPIC_WEBHOOK_SIGNING_KEY` auf das Secret mit dem Präfix `whsec_`, das bei der Erstellung des Endpoints angezeigt wurde.

<CodeGroup exclude="shell:cURL, shell:CLI">
  ```python Python
  from flask import Flask, request
  import anthropic

  client = anthropic.Anthropic()  # reads ANTHROPIC_WEBHOOK_SIGNING_KEY from env
  app = Flask(__name__)


  @app.route("/webhook", methods=["POST"])
  def webhook():
      try:
          # unwrap() löst eine Exception aus, wenn die Signatur ungültig oder der Payload veraltet ist
          event = client.beta.webhooks.unwrap(
              request.get_data(as_text=True),
              headers=dict(request.headers),
          )
      except Exception:
          return "invalid signature", 400

      if event.data.type == "session.status_idled":
          print("session idled:", event.data.id)
      # andere Event-Typen behandeln

      return "", 200
  ```

  ```typescript TypeScript
  import express from "express";
  import Anthropic from "@anthropic-ai/sdk";

  const client = new Anthropic(); // reads ANTHROPIC_WEBHOOK_SIGNING_KEY from env
  const app = express();

  // WICHTIG: Verwende express.raw(), nicht express.json(). Die Signatur wird über die Rohbytes berechnet.
  app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
    let event;
    try {
      // unwrap() wirft einen Fehler, wenn die Signatur ungültig oder der Payload veraltet ist
      event = client.beta.webhooks.unwrap(req.body.toString("utf8"), {
        headers: req.headers as Record<string, string>
      });
    } catch {
      return res.status(400).send("invalid signature");
    }

    switch (event.data.type) {
      case "session.status_idled":
        console.log("session idled:", event.data.id);
        break;
      // andere Event-Typen behandeln
    }

    res.sendStatus(200);
  });
  ```

  ```csharp C#
  using Anthropic;

  var client = new AnthropicClient(); // reads ANTHROPIC_WEBHOOK_SIGNING_KEY from env
  var app = WebApplication.Create(args);

  app.MapPost("/webhook", async (HttpRequest request) =>
  {
      using var reader = new StreamReader(request.Body);
      var body = await reader.ReadToEndAsync();
      var headers = request.Headers.ToDictionary(header => header.Key, header => header.Value.ToString());

      UnwrapWebhookEvent webhookEvent;
      try
      {
          // Unwrap() wirft eine Exception, wenn die Signatur ungültig oder der Payload veraltet ist
          webhookEvent = client.Beta.Webhooks.Unwrap(body, headers);
      }
      catch
      {
          return Results.BadRequest("invalid signature");
      }

      if (webhookEvent.Data.TryPickSessionStatusIdled(out var idled))
      {
          Console.WriteLine($"session idled: {idled.ID}");
      }
      // andere Event-Typen behandeln

      return Results.Ok();
  });
  ```

  ```go Go
  package main

  import (
  	"fmt"
  	"io"
  	"net/http"

  	"github.com/anthropics/anthropic-sdk-go"
  )

  var client = anthropic.NewClient() // reads ANTHROPIC_WEBHOOK_SIGNING_KEY from env

  func webhook(w http.ResponseWriter, r *http.Request) {
  	body, err := io.ReadAll(r.Body)
  	if err != nil {
  		http.Error(w, "could not read body", http.StatusBadRequest)
  		return
  	}

  	// Unwrap gibt einen Fehler zurück, wenn die Signatur ungültig oder der Payload veraltet ist
  	event, err := client.Beta.Webhooks.Unwrap(body, r.Header)
  	if err != nil {
  		http.Error(w, "invalid signature", http.StatusBadRequest)
  		return
  	}

  	switch event.Data.Type {
  	case "session.status_idled":
  		fmt.Println("session idled:", event.Data.ID)
  		// andere Event-Typen behandeln
  	}

  	w.WriteHeader(http.StatusOK)
  }

  func main() {
  	http.HandleFunc("/webhook", webhook)
  }
  ```

  ```java Java
  import com.anthropic.client.AnthropicClient;
  import com.anthropic.client.okhttp.AnthropicOkHttpClient;
  import com.anthropic.core.UnwrapWebhookParams;
  import com.anthropic.core.http.Headers;
  import com.sun.net.httpserver.HttpServer;

  // liest ANTHROPIC_WEBHOOK_SIGNING_KEY aus der Umgebung
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  void main() throws Exception {
      var server = HttpServer.create(new InetSocketAddress(8000), 0);
      server.createContext("/webhook", exchange -> {
          var body = new String(exchange.getRequestBody().readAllBytes());
          var headers = Headers.builder();
          exchange.getRequestHeaders().forEach(headers::put);

          try {
              // unwrap() wirft einen Fehler, wenn die Signatur ungültig oder der Payload veraltet ist
              var event = client.beta().webhooks().unwrap(
                  UnwrapWebhookParams.builder()
                      .body(body)
                      .headers(headers.build())
                      .build());

              event.data().sessionStatusIdled().ifPresent(idled ->
                  IO.println("session idled: " + idled.id()));
              // andere Event-Typen behandeln

              exchange.sendResponseHeaders(200, -1);
          } catch (Exception _) {
              exchange.sendResponseHeaders(400, -1);
          }
          exchange.close();
      });
  }
  ```

  ```php PHP
  use Anthropic\Client;
  use Anthropic\Core\Exceptions\WebhookException;

  $client = new Client(); // reads ANTHROPIC_WEBHOOK_SIGNING_KEY from env

  $body = file_get_contents('php://input');
  $headers = getallheaders();

  try {
      // unwrap() wirft einen Fehler, wenn die Signatur ungültig oder der Payload veraltet ist
      $event = $client->beta->webhooks->unwrap($body, headers: $headers);
  } catch (WebhookException) {
      http_response_code(400);
      exit('invalid signature');
  }

  match ($event->data->type) {
      'session.status_idled' => print "session idled: {$event->data->id}\n",
      // Behandle andere Event-Typen
      default => null,
  };

  http_response_code(200);
  ```

  ```ruby Ruby
  require "sinatra"
  require "anthropic"

  client = Anthropic::Client.new # reads ANTHROPIC_WEBHOOK_SIGNING_KEY from env

  post "/webhook" do
    headers = request.env
      .select { |key, _| key.start_with?("HTTP_") }
      .transform_keys { it.delete_prefix("HTTP_").downcase.tr("_", "-") }

    begin
      # unwrap löst einen Fehler aus, wenn die Signatur ungültig oder der Payload veraltet ist
      event = client.beta.webhooks.unwrap(request.body.read, headers: headers)
    rescue StandardError
      halt 400, "invalid signature"
    end

    if event.data.type == :"session.status_idled"
      puts "session idled: #{event.data.id}"
    end
    # andere Event-Typen behandeln

    status 200
  end
  ```
</CodeGroup>

## Ein Event verarbeiten

Parse den Body, verzweige anhand von `data.type` und rufe die Ressource über ihre ID ab. Gib einen beliebigen `2xx`-Status zurück, um den Empfang zu bestätigen. Jede andere Antwort wird dem Endpoint angerechnet: Ein `3xx` deaktiviert ihn sofort (Weiterleitungen werden nie verfolgt), während andere Fehler erneut versucht werden; siehe [Zustellverhalten](https://platform.claude.com/docs/de/managed-agents/webhooks#delivery-behavior) für die Regeln zu Wiederholungsversuchen und automatischer Deaktivierung.

Jeder Event-Payload hat dieselbe Struktur, einschließlich des Event-Typs, der Kennung und des Zeitstempels, zu dem das Event eingetreten ist.

```json
{
  "type": "event",
  "id": "whe_9d5c1f7e...",
  "created_at": "2026-03-18T14:05:22Z",
  "data": {
    "type": "session.status_idled",
    "id": "sesn_01XYZ...",
    "organization_id": "8a3d2f1e-...",
    "workspace_id": "c7b0e4d9-..."
  }
}
```

<CodeGroup exclude="shell:cURL, shell:CLI">
  ```python Python
  if event.data.type == "session.status_idled":
      session = client.beta.sessions.retrieve(event.data.id)
      notify_user(session)
  return "", 204
  ```

  ```typescript TypeScript
  if (event.data.type === "session.status_idled") {
    const session = await client.beta.sessions.retrieve(event.data.id);
    notifyUser(session);
  }
  res.sendStatus(204);
  ```

  ```csharp C#
  if (webhookEvent.Data.TryPickSessionStatusIdled(out var idled))
  {
      var session = await client.Beta.Sessions.Retrieve(idled.ID);
      NotifyUser(session);
  }
  return Results.StatusCode(204);
  ```

  ```go Go
  if event.Data.Type == "session.status_idled" {
  	session, err := client.Beta.Sessions.Get(r.Context(), event.Data.ID, anthropic.BetaSessionGetParams{})
  	if err != nil {
  		panic(err)
  	}
  	notifyUser(session)
  }
  w.WriteHeader(http.StatusNoContent)
  ```

  ```java Java
  event.data().sessionStatusIdled().ifPresent(idled -> {
      var session = client.beta().sessions().retrieve(idled.id());
      notifyUser(session);
  });
  exchange.sendResponseHeaders(204, -1);
  ```

  ```php PHP
  if ($event->data->type === 'session.status_idled') {
      $session = $client->beta->sessions->retrieve($event->data->id);
      notifyUser($session);
  }
  http_response_code(204);
  ```

  ```ruby Ruby
  if event.data.type == :"session.status_idled"
    session = client.beta.sessions.retrieve(event.data.id)
    notify_user(session)
  end
  status 204
  ```
</CodeGroup>

Die `event.id` auf oberster Ebene ist pro Event eindeutig, nicht pro Zustellung. Wenn du dieselbe `event.id` zweimal empfängst, handelt es sich um einen Wiederholungsversuch, und du kannst ihn verwerfen.

## Zustellverhalten

* **Duplikate:** Ein Endpoint kann dasselbe Event mehr als einmal empfangen, und jeder Versuch liefert dieselbe `event.id` auf oberster Ebene (denselben Wert wie der `webhook-id`-Header). Dedupliziere anhand dieser ID.

* **Abonnement-Umfang:** Ein Event wird nur an Endpoints zugestellt, die seinen Typ zum Zeitpunkt der Ausgabe abonniert haben. Ein Event, das ausgegeben wird, während kein Endpoint seinen Typ abonniert hat, wird nie zugestellt, und ein späteres Abonnement liefert es nicht nachträglich aus. Abonniere einen Event-Typ also, bevor du ihn benötigst.

* **Die Reihenfolge ist nicht garantiert.** Events werden nicht in der Reihenfolge zugestellt, in der sie eingetreten sind: `session.status_idled` kann vor `session.outcome_evaluation_ended` eintreffen, selbst wenn das Outcome zuerst erzeugt wurde, und ein `.deleted`-Event kann vor dem `.archived`-Event für dieselbe Ressource eintreffen. Leite deinen Zustand aus der abgerufenen Ressource ab, nicht aus der Reihenfolge, in der Events eintreffen.

* **Wiederholungsversuche:** Für jeden Endpoint und jedes Event unternimmt Anthropic bis zu drei Zustellversuche (eine Antwort, die eine automatische Deaktivierung auslöst, wie weiter unten in diesem Abschnitt beschrieben, wird nie erneut versucht) mit exponentiellem Backoff mit Jitter zwischen 5 und 120 Sekunden. Jeder Versuch liefert dieselbe `event.id`. Nachdem der letzte Versuch fehlgeschlagen ist, wird das Event verworfen: Es wird nicht für eine spätere Zustellung in die Warteschlange gestellt, und es gibt kein Signal, dass es verloren gegangen ist. Webhooks sind kein dauerhaftes Log. Wenn du also jeden Übergang beobachten musst, gleiche den Zustand ab, indem du die Ressource über die API auflistest oder abrufst.

* **Zeitstempel:** Der `webhook-timestamp`-Header wird gesetzt, wenn ein Zustellversuch signiert wird, und bei jedem Wiederholungsversuch neu generiert, sodass Wiederholungsversuche nicht von der Aktualitätsprüfung des SDK abgelehnt werden. Er ist die Uhr für den Zustellversuch, nicht für das Event: Verwende `created_at` (java, php: `createdAt`; csharp, go: `CreatedAt`) aus dem Event-Payload für den Zeitpunkt, zu dem das Event eingetreten ist.

* **Automatische Deaktivierung:** Ein Endpoint wird in drei Fällen automatisch auf `disabled` gesetzt, mit einem maschinenlesbaren `disabled_reason`:

  * Der Endpoint gibt eine `3xx`-Antwort zurück. Weiterleitungen werden nie verfolgt; dies deaktiviert den Endpoint sofort, beim ersten Versuch, mit dem Grund `auto-disabled: endpoint URL returned a redirect (3xx)`. Wenn dein Endpoint umzieht, aktualisiere die URL in der Console und aktiviere den Endpoint erneut.
  * Die URL des Endpoints wird beim Verbindungsaufbau durch Anthropic zu einer nicht öffentlichen IP-Adresse aufgelöst. Dies deaktiviert den Endpoint sofort, mit dem Grund `auto-disabled: endpoint URL resolved to an invalid address`.
  * Zustellungen an den Endpoint schlagen über einen längeren Zeitraum ununterbrochen fehl, mit dem Grund `auto-disabled after sustained delivery failures`. Der Auslöser ist, wie lange der Endpoint ohne Unterbrechung fehlschlägt, nicht eine Anzahl von Zustellungen. Ein einzelnes `2xx` setzt das Zeitfenster zurück, sodass ein einzelnes unzuverlässiges Event den Endpoint nicht deaktivieren kann.

  Alle drei Fälle sind umkehrbar: Aktiviere den Endpoint in der Console erneut, nachdem du das Problem behoben hast. Events, die ausgegeben wurden, während der Endpoint deaktiviert war, werden nicht erneut zugestellt.
