---
title: Ablehnungen und Fallback
url: https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback
description: Wie Claude Fable-Modelle, Claude Opus-Modelle, Claude Sonnet 5.5 und Claude Haiku 5.5 Klassifikator-Ablehnungen zurückgeben und wie du abgelehnte Anfragen auf einem Fallback-Modell wiederholst.
---

Claude Fable 5.1, Claude Fable 5, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5 und Claude Haiku 5.5 enthalten „safety classifiers" (Sicherheitsklassifikatoren), die eine Anfrage ablehnen können. Wenn das passiert, erhältst du eine normale Antwort, keinen Fehler, mit `stop_reason: "refusal"`. Ihr `stop_details.category` benennt den Richtlinienbereich (siehe [Wie eine Ablehnung aussieht](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#refusal-response)). In der Regel kannst du trotzdem eine Antwort erhalten, indem du dieselbe Anfrage an ein anderes Claude-Modell sendest. Diese Seite zeigt dir, wie du eine „refusal" (Ablehnung) erkennst und wie du diese Wiederholung einrichtest.

Lies diese Seite, wenn du auf einem dieser Modelle aufbaust und möchtest, dass abgelehnte Anfragen automatisch an ein anderes Modell weitergereicht werden. Sie gilt auch, wenn du `"refusal"` in einer Antwort gesehen hast und wissen möchtest, was als Nächstes zu tun ist.

Verwandte Seiten:

* [Stop-Reasons und Fallback](https://platform.claude.com/docs/de/build-with-claude/handling-stop-reasons): die vollständige Liste der `stop_reason`-Werte.
* [Fallback-Guthaben](https://platform.claude.com/docs/de/build-with-claude/fallback-credit): wie du vermeidest, die Prompt-Cache-Kosten doppelt zu zahlen, wenn du den erneuten Versuch selbst baust.
* [SDK-Middleware](https://platform.claude.com/docs/de/cli-sdks-libraries/middleware): der SDK-Helfer, der all dies kapselt.
* [Cookbook zu Fallback und Abrechnung](https://platform.claude.com/cookbook/fable-5-fallback-billing-guide): ein durchgearbeitetes End-to-End-Beispiel.

Die einfachste Einrichtung, in der Beta auf der Claude API: Setze `fallbacks` auf `"default"`, und die API versucht eine abgelehnte Anfrage erneut auf dem „fallback model" (Fallback-Modell), das Anthropic für die jeweilige Ablehnungskategorie empfiehlt. Für Kategorien ohne empfohlenes Fallback-Modell bleibt die Ablehnung bestehen. Claude Haiku 5.5 hat keinen serverseitigen Fallback, verwende dafür also [clientseitigen Fallback mit der SDK-Middleware](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#client-side-fallback) oder [schreibe den erneuten Versuch selbst](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#manual-retry).

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: server-side-fallback-2026-07-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-fable-5",
      "max_tokens": 1024,
      "fallbacks": "default",
      "messages": [{"role": "user", "content": "Hello, Claude"}]
    }'
  ```

  ```bash CLI
  ant beta:messages create \
    --model claude-fable-5 \
    --max-tokens 1024 \
    --message '{"role":"user","content":"Hello, Claude"}' \
    --fallbacks default \
    --beta server-side-fallback-2026-07-01
  ```

  ```python Python
  client = Anthropic()

  response = client.beta.messages.create(
      model="claude-fable-5",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello, Claude"}],
      fallbacks="default",
      betas=["server-side-fallback-2026-07-01"],
  )
  print(response.model)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const response = await client.beta.messages.create({
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello, Claude" }],
    fallbacks: "default",
    betas: ["server-side-fallback-2026-07-01"]
  });
  console.log(response.model);
  ```

  ```csharp C#
  AnthropicClient client = new();

  BetaMessage response = await client.Beta.Messages.Create(
      new()
      {
          Model = Messages::Model.ClaudeFable5,
          MaxTokens = 1024,
          Messages = [new() { Content = "Hello, Claude", Role = Role.User }],
          Fallbacks = new Default(),
          Betas = [AnthropicBeta.ServerSideFallback2026_07_01],
      }
  );

  Console.WriteLine(response.Model.Raw());
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Beta.Messages.New(context.Background(), anthropic.BetaMessageNewParams{
  	Model:     anthropic.ModelClaudeFable5,
  	MaxTokens: 1024,
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello, Claude")),
  	},
  	Fallbacks: anthropic.BetaFallbacksParamOfDefault(),
  	Betas:     []anthropic.AnthropicBeta{anthropic.AnthropicBetaServerSideFallback2026_07_01},
  })
  if err != nil {
  	panic(err)
  }

  fmt.Println(response.Model)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  BetaMessage response = client.beta().messages().create(MessageCreateParams.builder()
      .model(Model.CLAUDE_FABLE_5)
      .maxTokens(1024L)
      .addUserMessage("Hello, Claude")
      .fallbacksDefault()
      .addBeta(AnthropicBeta.SERVER_SIDE_FALLBACK_2026_07_01)
      .build());

  IO.println(response.model().asString());
  ```

  ```php PHP
  $client = new Client();

  $response = $client->beta->messages->create(
      model: 'claude-fable-5',
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello, Claude']],
      fallbacks: 'default',
      betas: ['server-side-fallback-2026-07-01'],
  );

  echo $response->model, PHP_EOL;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  response = client.beta.messages.create(
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello, Claude"}],
    fallbacks: :default,
    betas: ["server-side-fallback-2026-07-01"]
  )

  puts response.model
  ```
</CodeGroup>

Die folgenden Abschnitte behandeln, was eine Ablehnungsantwort enthält, wann du serverseitigen oder clientseitigen Fallback verwenden solltest und wie jeweils abgerechnet wird.

## Wie eine Ablehnung aussieht

Eine Ablehnung ist eine erfolgreiche HTTP-200-Antwort mit `stop_reason: "refusal"`:

```json
{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-fable-5",
  "content": [],
  "stop_reason": "refusal",
  "stop_details": {
    "type": "refusal",
    "category": "cyber",
    "explanation": "This request was declined because it could enable cyber harm."
  },
  "usage": {
    "input_tokens": 412,
    "output_tokens": 0
  }
}
```

Das `stop_details`-Objekt erklärt die Ablehnung:

* **`category`:** benennt den Richtlinienbereich, der den Klassifikator ausgelöst hat.
* **`explanation`:** eine menschenlesbare Beschreibung. Der Text ist nicht stabil, zeige ihn also an, statt ihn zu parsen.
* **`recommended_model`:** nur bei Anfragen vorhanden, die `fallbacks` setzen ([serverseitiger Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#server-side-fallback), Beta). Es benennt ein Modell, auf dem du direkt erneut versuchen kannst, wenn die API den Fallback-Versuch übersprungen hat (zum Beispiel, weil das Fallback-Modell durch ein Ratenlimit begrenzt war), und ist andernfalls `null`. Es ist ein Hinweis, keine Garantie.
* `category` und `explanation` sind beide `null`, wenn die Ablehnung keiner benannten Kategorie zugeordnet ist. Dieses `null` ist ein normaler, dauerhafter Wert, kein Platzhalter.
* `stop_details` selbst ist für jeden anderen Stop-Reason als `refusal` `null`.

| `category`               | Bedeutung                                                                                                                                                                                                                                                                                                                                                                                                                  | Vor jeglicher Ausgabe abgerechnet |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `"cyber"`                | Die Anfrage könnte Cyber-Schaden ermöglichen, etwa die Entwicklung von Malware oder Exploits. Auch harmlose Cybersicherheitsarbeit kann diese Kategorie auslösen.                                                                                                                                                                                                                                                          | Nein                              |
| `"bio"`                  | Die Anfrage könnte biologischen Schaden ermöglichen, etwa gefährliche Labormethoden. Auch nützliche Arbeit in den Lebenswissenschaften kann diese Kategorie auslösen.                                                                                                                                                                                                                                                      | Ja                                |
| `"frontier_llm"`         | Die Anfrage könnte die Entwicklung konkurrierender KI-Modelle unterstützen, was gemäß [Anthropics kommerziellen Bedingungen](https://www.anthropic.com/legal/commercial-terms) eingeschränkt ist. Auch harmlose Arbeit im Bereich maschinelles Lernen kann diese Kategorie auslösen.                                                                                                                                       | Ja                                |
| `"reasoning_extraction"` | Die Anfrage fordert das Modell auf, sein internes Reasoning im Antworttext wiederzugeben. Um das Reasoning stattdessen in strukturierter Form zu erhalten, verwende [adaptives Nachdenken](https://platform.claude.com/docs/de/build-with-claude/thinking). Siehe [Reasoning in Thinking-Blöcken belassen](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#keep-reasoning-in-thinking-blocks). | Ja                                |
| `"general_harms"`        | Die Anfrage fällt in einen Bereich der Nutzungsrichtlinien außerhalb der vier benannten Kategorien. Auch harmlose Arbeit kann diese Kategorie auslösen.                                                                                                                                                                                                                                                                    | Nein                              |

Eine Ablehnung kann vor jeglicher Ausgabe eintreffen oder mitten im Stream nach teilweiser Ausgabe. Behandle in beiden Fällen jede teilweise Ausgabe als unvollständig und verwirf sie.

### Reasoning in Thinking-Blöcken belassen

Eine `reasoning_extraction`-Ablehnung entsteht meist durch einen Prompt, der das Modell auffordert, sein Nachdenken oder Reasoning in die Ausgabe zu schreiben, entweder wörtlich oder in einem festen Format. Häufige Beispiele:

* Ein `<thinking>`-, `<reasoning>`- oder Scratchpad-Abschnitt, den das Modell ausfüllt, bevor es antwortet
* Ein `reasoning`-, `thinking`- oder `trace`-Feld in einer JSON-Ausgabe oder in einer Tool-Eingabe
* Die privaten Notizen des Modells oder ein fortlaufendes Protokoll seines Reasonings
* Reasoning, das wörtlich oder vollständig angefordert wird

Die Formulierung kann in einem System-Prompt, einem Skill oder einer Tool-Beschreibung stehen, also prüfe auch diese.

Du kannst Claude weiterhin bitten, seine Antwort zu erklären. Bitte um eine kurze Erklärung, die Belege hinter einem Ergebnis oder eine Zusammenfassung der durchgeführten Aktionen. Um zu sehen, wie das Modell nachgedacht hat, setze `display: "summarized"` und lies die [`thinking`-Blöcke](https://platform.claude.com/docs/de/build-with-claude/thinking#summarized-thinking). Diese Kategorie hat kein empfohlenes Fallback-Modell, also ändere den Prompt, statt die Anfrage zu wiederholen. Wenn eine umformulierte Anfrage weiterhin abgelehnt wird, [kontaktiere den Support](https://support.claude.com/en/articles/9015913-how-to-get-support) und gib die [Request-ID](https://platform.claude.com/docs/de/api/errors#request-id) an.

## Wie Ablehnungen berechnet werden

Diese Abrechnungsregeln gelten auf jeder Plattform: der Claude API, Amazon Bedrock, Claude Platform on AWS, Google Cloud und Microsoft Foundry.

**Ablehnungen vor jeglicher Ausgabe:** Um Versuche zu erschweren, die Schutzmaßnahmen von Anthropic in großem Umfang zu umgehen, wird eine Ablehnung, die vor jeglicher Ausgabe eintrifft, abgerechnet, wenn ihre `stop_details.category` den Wert `"bio"`, `"frontier_llm"` oder `"reasoning_extraction"` hat. Dies sind die Kategorien, in denen Anthropic, Stand September 2026, wenige Fehlalarme misst. Diese Ablehnungen werden wie jede andere Anfrage abgerechnet, zu den Tarifen des Modells, das sie ausgeführt hat. Eine Ablehnung vor jeglicher Ausgabe in einer anderen Kategorie oder mit der Kategorie `null` wird nicht abgerechnet. In beiden Fällen ist `content` leer, und Token-Zählungen erscheinen in `usage`. Die Anfrage zählt dennoch gegen deine Ratenlimits.

**Ablehnungen mitten im Stream:** Eine Ablehnung mitten im Stream berechnet die Input-Token und die bereits gestreamte Ausgabe zu normalen Tarifen.

**Fallback:** Wenn du Fallback verwendest, wird die Ablehnung, die ihn ausgelöst hat, zusätzlich zur Fallback-Anfrage abgerechnet, wenn sie mitten im Stream eintraf oder zu einer der abgerechneten Kategorien gehört. Die [Fallback-Gutschrift](https://platform.claude.com/docs/de/build-with-claude/fallback-credit) gleicht den Prompt-Cache-Miss der Fallback-Anfrage aus, sodass du nicht zweimal für das Caching der Konversation bezahlst. Eine Ablehnung durch Claude Haiku 5.5 enthält keine Fallback-Gutschrift, daher zahlt ein Fallback danach die vollen Kosten für das Schreiben des Prompt-Caches des Fallback-Modells. Wie der serverseitige Fallback jeden Versuch meldet, erfährst du unter [Abrechnung und Ratenlimits](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#billing-and-rate-limits).

Die abgerechneten Kategorien können sich ändern, während Anthropic die Fehlalarmraten seiner Schutzmaßnahmen weiter misst und verfeinert. Die Spalte **Vor jeglicher Ausgabe abgerechnet** in der [Tabelle der Ablehnungskategorien](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#refusal-response) listet die abgerechneten Kategorien auf.

## Einen Fallback-Ansatz wählen

Es gibt drei Möglichkeiten, eine abgelehnte Anfrage auf einem anderen Modell erneut zu versuchen. Die richtige hängt davon ab, wo du läufst und wie viel Kontrolle du brauchst.

| Deine Situation                              | Verwende                                                                                                                                                                                                                  | Warum                                                                       |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Claude API, einfachste Einrichtung           | [Serverseitiger Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#server-side-fallback)                                                                                               | Eine Anfrage, eine Antwort. Die API übernimmt den erneuten Versuch.         |
| Beliebige Plattform, mit einem Anthropic SDK | [Die SDK-Middleware](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#client-side-fallback)                                                                                                    | Einmal auf dem Client konfigurieren. Erneute Versuche erfolgen automatisch. |
| Rohes HTTP oder eigene Retry-Logik           | [Ein manueller erneuter Versuch](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#manual-retry) mit [Fallback-Guthaben](https://platform.claude.com/docs/de/build-with-claude/fallback-credit) | Volle Kontrolle. Fallback-Guthaben hält die Kosten niedrig.                 |

Serverseitiger Fallback und die SDK-Middleware wenden die Fallback-Gutschrift für dich an. Die Seite [Fallback-Gutschrift](https://platform.claude.com/docs/de/build-with-claude/fallback-credit) brauchst du nur, wenn du den erneuten Versuch selbst baust. Claude Haiku 5.5 hat weder serverseitigen Fallback noch Fallback-Gutschrift, verwende also die SDK-Middleware oder einen manuellen erneuten Versuch.

## Serverseitiger Fallback

Serverseitiger Fallback versucht eine abgelehnte Anfrage innerhalb eines einzigen API-Aufrufs erneut. Im Standardmodus führt die API, wenn das primäre Modell ablehnt und die Ablehnungskategorie einen empfohlenen Fallback hat, dieselbe Anfrage auf dem Modell aus, das Anthropic für diese Kategorie empfiehlt. Du kannst stattdessen [bis zu drei eigene Fallback-Modelle benennen](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#naming-your-own-fallback-models). In beiden Fällen erhältst du eine Antwort zurück, die das Modell benennt, das geantwortet hat, sodass dein Nutzer in einem einzigen Roundtrip eine Antwort erhält.

<Note>
  Serverseitiger Fallback befindet sich auf der Claude API in der Beta. Der Parameter `fallbacks` wird von der [Message Batches API](https://platform.claude.com/docs/de/build-with-claude/batch-processing) nicht unterstützt (ein Batch-Element, das ihn enthält, kommt als fehlerhaftes Ergebnis zurück) und ist auf Amazon Bedrock, Google Cloud oder Microsoft Foundry nicht verfügbar. Verwende auf diesen Plattformen stattdessen [clientseitigen Fallback mit der SDK-Middleware](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#client-side-fallback). Claude Haiku 5.5 hat keinen serverseitigen Fallback: Mit `fallbacks: "default"` bleibt eine abgelehnte Anfrage abgelehnt, und eine Liste von Fallback-Modellen gibt einen 400-Fehler zurück.
</Note>

### Die Anfrage stellen

Setze den `fallbacks`-Parameter auf den String `"default"` und sende den Beta-Header `server-side-fallback-2026-07-01`. Die API wendet dann das serverseitig definierte Standard-Routing des angefragten Modells an, das basierend auf der vom Klassifikator gemeldeten Ablehnungskategorie ein empfohlenes Fallback-Modell auswählt, sodass abgelehnte Anfragen bedient werden, ohne dass du eine Modellliste pflegen musst, wenn sich Empfehlungen ändern.

Das Standard-Routing löst niemals die vorab erfolgende [Ablehnung übergroßer Bilder](https://platform.claude.com/docs/de/build-with-claude/vision-coordinates#oversized-image-error) für Modelle aus, die du nicht gewählt hast: Ein geroutetes Modell, das ein mit `"oversized_image": "error"` markiertes Bild verkleinern würde, wird stattdessen aus dem Routing entfernt, sodass ein markiertes Bild niemals verkleinert ausgeliefert wird.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: server-side-fallback-2026-07-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-fable-5",
      "max_tokens": 1024,
      "fallbacks": "default",
      "messages": [{"role": "user", "content": "Hello, Claude"}]
    }' |
    jq -c '{
      stop_reason,
      model,
      # Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
      # kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort geliefert hat.
      served_by_fallback: (
        any(.usage.iterations[]?; .type == "fallback_message")
        and .stop_reason != "refusal"
      )
    }'
  ```

  ```bash CLI
  ant beta:messages create \
    --model claude-fable-5 \
    --max-tokens 1024 \
    --message '{"role":"user","content":"Hello, Claude"}' \
    --fallbacks default \
    --beta server-side-fallback-2026-07-01 \
    --format json |
    jq -c '{
      stop_reason,
      model,
      # Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
      # kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort geliefert hat.
      served_by_fallback: (
        any(.usage.iterations[]?; .type == "fallback_message")
        and .stop_reason != "refusal"
      )
    }'
  ```

  ```python Python
  client = Anthropic()

  response = client.beta.messages.create(
      model="claude-fable-5",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello, Claude"}],
      fallbacks="default",
      betas=["server-side-fallback-2026-07-01"],
  )

  # Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
  # kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort lieferte.
  fallback_ran = any(
      iteration.type == "fallback_message"
      for iteration in response.usage.iterations or []
  )
  served_by_fallback = fallback_ran and response.stop_reason != "refusal"

  print(
      json.dumps(
          {
              "stop_reason": response.stop_reason,
              "model": response.model,
              "served_by_fallback": served_by_fallback,
          }
      )
  )
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const response = await client.beta.messages.create({
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello, Claude" }],
    fallbacks: "default",
    betas: ["server-side-fallback-2026-07-01"]
  });

  // Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
  // kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort lieferte.
  const { stop_reason, model, usage } = response;
  const servedByFallback =
    (usage.iterations ?? []).some((entry) => entry.type === "fallback_message") &&
    stop_reason !== "refusal";

  console.log(
    JSON.stringify({
      stop_reason,
      model,
      served_by_fallback: servedByFallback
    })
  );
  ```

  ```csharp C#
  AnthropicClient client = new();

  var response = await client.Beta.Messages.Create(
      new()
      {
          Model = Messages::Model.ClaudeFable5,
          MaxTokens = 1024,
          Messages =
          [
              new() { Content = "Hello, Claude", Role = Role.User },
          ],
          Fallbacks = new Default(),
          Betas = [AnthropicBeta.ServerSideFallback2026_07_01],
      }
  );

  // Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
  // kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort lieferte.
  bool fallbackRan = (response.Usage.Iterations ?? []).Any(iteration =>
      iteration.TryPickBetaFallbackMessageIterationUsage(out _)
  );
  bool servedByFallback =
      fallbackRan && response.StopReason?.Value() != BetaStopReason.Refusal;

  Console.WriteLine(
      JsonSerializer.Serialize(
          new
          {
              stop_reason = response.StopReason?.Raw(),
              model = response.Model.Raw(),
              served_by_fallback = servedByFallback,
          }
      )
  );
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Beta.Messages.New(context.Background(), anthropic.BetaMessageNewParams{
  	Model:     anthropic.ModelClaudeFable5,
  	MaxTokens: 1024,
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello, Claude")),
  	},
  	Fallbacks: anthropic.BetaFallbacksParamOfDefault(),
  	Betas:     []anthropic.AnthropicBeta{anthropic.AnthropicBetaServerSideFallback2026_07_01},
  })
  if err != nil {
  	panic(err)
  }

  // Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
  // kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort geliefert hat.
  fallbackRan := slices.ContainsFunc(
  	response.Usage.Iterations,
  	func(iteration anthropic.BetaIterationsUsageItemUnion) bool {
  		_, isFallback := iteration.AsAny().(anthropic.BetaFallbackMessageIterationUsage)
  		return isFallback
  	},
  )
  servedByFallback := fallbackRan && response.StopReason != anthropic.BetaStopReasonRefusal

  summary, err := json.Marshal(struct {
  	StopReason       anthropic.BetaStopReason `json:"stop_reason"`
  	Model            anthropic.Model          `json:"model"`
  	ServedByFallback bool                     `json:"served_by_fallback"`
  }{response.StopReason, response.Model, servedByFallback})
  if err != nil {
  	panic(err)
  }
  fmt.Println(string(summary))
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  BetaMessage response = client.beta().messages().create(
      MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5)
          .maxTokens(1024L)
          .addUserMessage("Hello, Claude")
          .fallbacksDefault()
          .addBeta(AnthropicBeta.SERVER_SIDE_FALLBACK_2026_07_01)
          .build()
  );

  // Ein fallback_message-Usage-Eintrag bedeutet, dass ein Fallback-Modell die
  // Antwort erzeugt hat; ein refusal-Stop-Grund bedeutet, dass kein Modell sie bedient hat.
  List<BetaUsage.Iteration> iterations =
      response.usage().iterations().orElse(List.of());
  boolean servedByFallback =
      iterations.stream().anyMatch(BetaUsage.Iteration::isFallbackMessage)
          && response.stopReason().filter(BetaStopReason.REFUSAL::equals).isEmpty();

  IO.println("""
      {"stop_reason":"%s","model":"%s","served_by_fallback":%b}\
      """.formatted(
          response.stopReason().map(BetaStopReason::asString).orElse("null"),
          response.model().asString(),
          servedByFallback));
  ```

  ```php PHP
  $client = new Client();

  $response = $client->beta->messages->create(
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello, Claude']],
      model: 'claude-fable-5',
      fallbacks: 'default',
      betas: ['server-side-fallback-2026-07-01'],
  );

  // Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
  // kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort geliefert hat.
  $iterations = $response->usage->iterations ?? [];
  $servedByFallback = array_any($iterations, fn($entry) => $entry->type === 'fallback_message')
      && $response->stopReason !== 'refusal';

  echo json_encode([
      'stop_reason' => $response->stopReason,
      'model' => $response->model,
      'served_by_fallback' => $servedByFallback,
  ]), PHP_EOL;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  response = client.beta.messages.create(
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello, Claude"}],
    fallbacks: :default,
    betas: ["server-side-fallback-2026-07-01"]
  )

  # Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
  # kombiniere ihn mit stop_reason, um zu bestätigen, dass das Fallback die Antwort geliefert hat.
  iterations = response.usage.iterations || []
  served_by_fallback = iterations.any? { it.type == :fallback_message } &&
    response.stop_reason != :refusal

  stop_reason = response.stop_reason
  model = response.model
  puts JSON.generate({stop_reason:, model:, served_by_fallback:})
  ```
</CodeGroup>

Anthropic legt Schutzmaßnahmen für jedes Modell einzeln und für jede Richtlinienkategorie fest, entsprechend der Fähigkeit des Modells: Je nach Kategorie kann eine markierte Anfrage auf ein weniger leistungsfähiges Modell zurückfallen oder abgelehnt werden. Der Modus `"default"` kodiert diese modell- und kategoriespezifischen Empfehlungen für dich, sodass eine abgelehnte Anfrage auf dem Modell erneut versucht wird, das Anthropic für diese Kategorie empfiehlt. Fallbacks sind in beiden Fällen sichtbar: Die Antwort benennt das Modell, das sie bedient hat, und der `fallback`-Content-Block markiert die Übergabe.

Das Routing wird serverseitig angewendet und nicht pro Modell in der [Models API](https://platform.claude.com/docs/de/api/models/list) veröffentlicht. Um zu sehen, welches Modell eine abgelehnte Anfrage bedient hat, prüfe das `model`-Feld auf oberster Ebene der Antwort und suche nach einem `fallback_message`-Eintrag in `usage.iterations`, wie es die Beispiele auf dieser Seite tun.

Nur eine Ablehnung durch einen Sicherheitsklassifikator löst den Fallback aus. Ein Ratenlimit, eine Überlastung oder ein Serverfehler beim angefragten Modell wird dir unverändert zurückgegeben.

<Note>
  Der Beta-Header muss genau das Datum `2026-07-01` tragen, das sowohl `"default"` als auch die Form mit expliziter Liste unterstützt, oder `2026-06-01`, das nur die Form mit expliziter Liste akzeptiert. Bei jedem anderen `server-side-fallback-*`-Wert wird der `fallbacks`-Parameter mit einem 400-Fehler abgelehnt. Wenn du gegen eine frühere Vorschau dieser Funktion gebaut hast, aktualisiere den Beta-Header sowie die Anfrage- und Antwortformen gemeinsam auf die auf dieser Seite beschriebenen.
</Note>

### Eigene Fallback-Modelle benennen

Anstelle des Standard-Routings kannst du `fallbacks` auf eine Liste von bis zu drei Modellen setzen. Wenn das angefragte Modell ablehnt, führt die API das nächste Modell in der Kette mit derselben Anfrage aus. Verwende diese Form, wenn du genau steuern möchtest, welche Modelle abgelehnte Anfragen bedienen, etwa um ein Modell festzulegen, das deine Anwendung qualifiziert hat.

Benannte Fallback-Modelle zählen für die [Prüfung auf übergroße Bilder](https://platform.claude.com/docs/de/build-with-claude/vision-coordinates#oversized-image-error): Eine Anfrage, deren Bild-Block `"oversized_image": "error"` setzt, wird vorab gegen das angefragte Modell und jeden benannten Fallback geprüft, wird abgelehnt, wenn eines davon dieses Bild verkleinern würde, und das in der Ablehnung gemeldete Skalierungsziel passt für alle.

Die hervorgehobenen Zeilen sind der einzige Unterschied zur Anfrage mit Standard-Routing.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: server-side-fallback-2026-07-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-fable-5",
      "max_tokens": 1024,
      "fallbacks": [{"model": "claude-opus-4-8"}],
      "messages": [{"role": "user", "content": "Hello, Claude"}]
    }'
  ```

  ```bash CLI
  ant beta:messages create \
    --model claude-fable-5 \
    --max-tokens 1024 \
    --message '{"role":"user","content":"Hello, Claude"}' \
    --fallbacks '[{"model":"claude-opus-4-8"}]' \
    --beta server-side-fallback-2026-07-01
  ```

  ```python Python
  client = Anthropic()

  response = client.beta.messages.create(
      model="claude-fable-5",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello, Claude"}],
      fallbacks=[{"model": "claude-opus-4-8"}],
      betas=["server-side-fallback-2026-07-01"],
  )
  print(response.model)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const response = await client.beta.messages.create({
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello, Claude" }],
    fallbacks: [{ model: "claude-opus-4-8" }],
    betas: ["server-side-fallback-2026-07-01"]
  });
  console.log(response.model);
  ```

  ```csharp C#
  AnthropicClient client = new();

  BetaMessage response = await client.Beta.Messages.Create(
      new()
      {
          Model = Messages::Model.ClaudeFable5,
          MaxTokens = 1024,
          Messages = [new() { Content = "Hello, Claude", Role = Role.User }],
          Fallbacks = new([new(Messages::Model.ClaudeOpus4_8)]),
          Betas = [AnthropicBeta.ServerSideFallback2026_07_01],
      }
  );

  Console.WriteLine(response.Model.Raw());
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Beta.Messages.New(context.Background(), anthropic.BetaMessageNewParams{
  	Model:     anthropic.ModelClaudeFable5,
  	MaxTokens: 1024,
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello, Claude")),
  	},
  	Fallbacks: anthropic.BetaFallbacksParamUnion{
  		OfBetaFallbackArray: []anthropic.BetaFallbackParam{{Model: anthropic.ModelClaudeOpus4_8}},
  	},
  	Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaServerSideFallback2026_07_01},
  })
  if err != nil {
  	panic(err)
  }

  fmt.Println(response.Model)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  BetaMessage response = client.beta().messages().create(MessageCreateParams.builder()
      .model(Model.CLAUDE_FABLE_5)
      .maxTokens(1024L)
      .addUserMessage("Hello, Claude")
      .fallbacksOfFallbackParams(List.of(BetaFallbackParam.builder()
          .model(Model.CLAUDE_OPUS_4_8)
          .build()))
      .addBeta(AnthropicBeta.SERVER_SIDE_FALLBACK_2026_07_01)
      .build());

  IO.println(response.model().asString());
  ```

  ```php PHP
  $client = new Client();

  $response = $client->beta->messages->create(
      model: 'claude-fable-5',
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello, Claude']],
      fallbacks: [['model' => 'claude-opus-4-8']],
      betas: ['server-side-fallback-2026-07-01'],
  );

  echo $response->model, PHP_EOL;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  response = client.beta.messages.create(
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello, Claude"}],
    fallbacks: [{model: "claude-opus-4-8"}],
    betas: ["server-side-fallback-2026-07-01"]
  )

  puts response.model
  ```
</CodeGroup>

Für die `fallbacks`-Liste gelten einige Regeln:

* Einträge werden der Reihe nach versucht. Jeder muss sich von den anderen Einträgen und vom angefragten Modell unterscheiden.
* Jeder Eintrag muss eines der zulässigen Ziele des angefragten Modells sein. Bei gesetztem Beta-Header wird diese Liste als `allowed_fallback_models` im Eintrag des Modells in der [Models API](https://platform.claude.com/docs/de/api/models/list) veröffentlicht.
* Jeder Eintrag benennt ein `model` und kann `max_tokens`, `thinking`, `output_config` und `speed` nur für diesen Versuch überschreiben.
* Die Anfrage muss als direkte Anfrage an jedes benannte Modell gültig sein. Wenn ein Fallback-Modell eine Funktion, die die Anfrage verwendet, nicht unterstützt, lehnt die API die Anfrage vorab ab. Unter dem Header `2026-07-01` ist `thinking: {"type": "between_tools"}` die Ausnahme: Wenn eine Claude Sonnet 5.5-Anfrage auf Claude Sonnet 5 zurückfällt, läuft der Fallback-Versuch mit `thinking: {"type": "disabled"}` und `display: "omitted"`. Unter `2026-06-01` setze `thinking` im Claude Sonnet 5-Eintrag, sonst wird die Anfrage vorab abgelehnt.
* Wie im Standardmodus löst nur eine Ablehnung durch einen Sicherheitsklassifikator den Fallback aus. Ein Ratenlimit, eine Überlastung oder ein Serverfehler beim angefragten Modell wird unverändert an dich zurückgegeben.
* Wenn ein Fallback-Modell ratenlimitiert oder überlastet ist, wird der Fallback-Versuch nicht unternommen und stattdessen die vorherige Ablehnung zurückgegeben. `stop_details.recommended_model` der Ablehnung benennt dann ein Modell, das du direkt erneut versuchen kannst. Dimensioniere die Ratenlimits des Fallback-Modells für das erwartete Ablehnungsvolumen, sonst werden Fallbacks unter Last zu Ablehnungen.

Die Antwort hat in beiden Modi dieselbe Form: Das Modell, das den Turn bedient hat, erscheint im `model`-Feld auf oberster Ebene, ein `fallback`-Content-Block markiert die Übergabe, und `usage.iterations` zeichnet jeden Versuch auf.

### Was die Antwort enthält

Die Antwort sieht aus wie jede andere Nachricht, mit zwei Ergänzungen:

* Das `model`-Feld auf oberster Ebene meldet das Modell, das die zurückgegebene Nachricht erzeugt hat, ob das nun das angefragte Modell oder ein Fallback ist.

* Ein `fallback`-Content-Block markiert jede Stelle in `content`, an der die Ausgabe eines Modells der des nächsten weicht: `{"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}`.

  * `from.model` gibt den Modell-String wieder, den du gesendet hast, wenn der ablehnende Hop das angefragte Modell ist.
  * `to.model` ist immer die aufgelöste ID des Modells, das fortsetzt.

Bei einer Ablehnung vor jeglicher Ausgabe ist der `fallback`-Block der erste Content-Block. Zum Beispiel, wenn das Standard-Routing Claude Opus 4.8 für die Kategorie der Ablehnung auswählt:

```json
{
  "id": "msg_01XFUDYJgAACzvnptvVoYEL",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-4-8",
  "content": [
    {
      "type": "fallback",
      "from": { "model": "claude-fable-5" },
      "to": { "model": "claude-opus-4-8" }
    },
    { "type": "text", "text": "Hi! How can I help you today?" }
  ],
  "stop_reason": "end_turn",
  "stop_details": null,
  "usage": {
    "input_tokens": 412,
    "output_tokens": 264,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0,
    "iterations": [
      {
        "type": "message",
        "model": "claude-fable-5",
        "input_tokens": 535,
        "output_tokens": 0,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      },
      {
        "type": "fallback_message",
        "model": "claude-opus-4-8",
        "input_tokens": 412,
        "output_tokens": 264,
        "cache_read_input_tokens": 0,
        "cache_creation_input_tokens": 0
      }
    ]
  }
}
```

Das Array `usage.iterations` zeichnet jeden Versuch auf. Ein Modell, das abgelehnt hat, erscheint als gewöhnlicher `message`-Eintrag, und das Modell, das den Turn bedient hat, erscheint als `fallback_message`-Eintrag. Wenn jedes Modell in der Kette ablehnt, ist die Antwort die Ablehnung des letzten Modells, mit einem `message`-Eintrag für jeden früheren Hop und einem `fallback_message`-Eintrag für den letzten.

[Sticky Routing](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#sticky-routing) kann einen späteren Turn direkt an das Fallback-Modell senden. Ein solcher Turn trägt keinen `fallback`-Content-Block, weil kein Modell diesen Turn abgelehnt hat. Erkenne ihn am `fallback_message`-Eintrag in `usage.iterations`, am Fehlen eines `message`-Eintrags für das angefragte Modell und am `model`-Feld der Antwort.

### Das Gespräch fortsetzen

Sende im nächsten Turn den Assistant-Inhalt so zurück, wie du ihn erhalten hast. Nach einem Fallback mitten in der Ausgabe kann `content` Block-Typen enthalten, die das ablehnende Modell vor der Übergabe erzeugt hat. Die folgende Tabelle zeigt, welche du behältst und welche du weglässt, wenn du den Turn zurücksendest.

| Block-Typ                                                                              | Im nächsten Turn                                                                                                                                                                                                                                                                  |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fallback`                                                                             | Behalte ihn genau dort, wo er erschien. Die API verwendet seine Position, um die Thinking-Blöcke um ihn herum zu validieren, sodass eine Anfrage, die Thinking-Blöcke von beiden Seiten der Grenze zurücksendet, abgelehnt wird, wenn der Block weggelassen oder verschoben wird. |
| `text`                                                                                 | Behalten.                                                                                                                                                                                                                                                                         |
| Jeder Block nach dem letzten `fallback`-Block                                          | Behalten.                                                                                                                                                                                                                                                                         |
| `thinking`, `redacted_thinking` oder `connector_text` vor dem letzten `fallback`-Block | Weglassen.                                                                                                                                                                                                                                                                        |
| Clientseitiges `tool_use` vor dem letzten `fallback`-Block                             | Weglassen.                                                                                                                                                                                                                                                                        |
| `server_tool_use` vor dem letzten `fallback`-Block                                     | Behalten, wenn mit seinem Ergebnis gepaart. Weglassen, wenn es kein passendes Ergebnis hat.                                                                                                                                                                                       |

<Note>
  Ein `connector_text`-Block trägt Erzähltext, den manche Tool-nutzenden Antworten zwischen Tool-Aufrufen enthalten.
</Note>

### Streaming

Bei einer Streaming-Anfrage erfolgt der erneute Versuch auf demselben Stream, und nichts, was du bereits erhalten hast, wird ungültig. Was du siehst, hängt davon ab, wann die Ablehnung erfolgt.

**Wenn die Ablehnung vor jeglicher Ausgabe erfolgt:**

* `message_start` benennt das Fallback-Modell, und der `fallback`-Block ist der erste Content-Block.
* Da `message_start` auf den Start des Fallback-Versuchs wartet, umfasst die Zeit bis zum ersten Byte den abgelehnten Versuch.

**Wenn die Ablehnung mitten in der Ausgabe erfolgt:**

* Der offene Content-Block wird geschlossen, und der `fallback`-Block (ein gewöhnliches Paar aus `content_block_start` und `content_block_stop` ohne Deltas) markiert die Grenze.
* Das Fallback-Modell setzt ab der teilweisen Ausgabe fort. Nur die `text`-Blöcke der teilweisen Ausgabe werden dem Fallback-Modell als Kontext übergeben. Andere Block-Typen verbleiben in `content`.
* `message_start` hat bereits das angefragte Modell benannt, lies das bedienende Modell also aus dem `to.model` des `fallback`-Blocks und aus dem `fallback_message`-Eintrag in `usage.iterations` des letzten `message_delta`.

### Nicht-Streaming-Antworten

Bei einer Nicht-Streaming-Anfrage verhält sich eine Ablehnung mitten in der Ausgabe anders: Die Antwort lässt die teilweise Ausgabe des abgelehnten Modells weg, und das Fallback-Modell antwortet von Grund auf neu. Das Ergebnis sieht aus wie eine Ablehnung vor jeglicher Ausgabe, mit dem `fallback`-Block an erster Stelle. Der abgelehnte Versuch und seine Output-Token erscheinen dennoch in `usage.iterations`.

<Note>
  **Ablehnungen während der Tool-Nutzung:** Abgeschlossene Tool-Arbeit blockiert den Fallback nicht. Wenn eine Ablehnung ausgelöst wird, nachdem Server-Tools (zum Beispiel Websuche oder Code-Ausführung) innerhalb einer Anfrage fertig ausgeführt wurden, wird der Fallback-Versuch fortgesetzt: Die abgeschlossenen Tool-Ergebnisse werden übernommen, und das Fallback-Modell kann weiterhin Server-Tools aufrufen. Der eine Fall, der nicht erneut versucht wird, ist eine Streaming-Ablehnung, die ausgelöst wird, während ein Tool-Use-Block beliebigen Typs (ein Client-Tool, ein Server-Tool oder ein MCP-Tool-Aufruf) auf dem Stream noch offen ist: Diese Ablehnung wird direkt zurückgegeben, und wenn der Header `fallback-credit-2026-07-01` gesetzt ist, trägt sie dennoch ein Guthaben-Token, das durch Fortsetzen der teilweisen Antwort eingelöst werden kann. Nicht-Streaming-Anfragen sind nicht betroffen; die API verwirft die teilweise Arbeit und versucht erneut, bevor sie antwortet.
</Note>

### Abrechnung und Ratenlimits

Für jeden Versuch gelten die Regeln unter [Wie Ablehnungen berechnet werden](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#how-refusals-are-billed), und zwar zu den Tarifen des Modells, das ihn ausgeführt hat. Ein Versuch, der abgelehnt hat, bevor er irgendeine Ausgabe erzeugt hat, wird nur abgerechnet, wenn seine Ablehnungskategorie abgerechnet wird, und seine Token werden in jedem Fall in seinem `usage.iterations`-Eintrag gemeldet. Jeder Versuch, der Ausgabe erzeugt hat, einschließlich eines, der mitten in seiner Antwort abgelehnt hat, wird separat berechnet. Das Array `usage.iterations` ist die Aufzeichnung pro Versuch dessen, was dir berechnet wird. Die `usage`-Zählungen auf oberster Ebene beschreiben nur den Versuch, der die zurückgegebene Nachricht erzeugt hat. Token verschiedener Modelle werden niemals in einem Feld summiert.

Jeder Versuch, der läuft, einschließlich eines abgelehnten, zählt gegen die Ratenlimits seines eigenen Modells.

### Sticky Routing

Nachdem ein Gespräch zurückgefallen ist, zeichnet die API auf, welches Modell es bedient hat. Spätere Anfragen für dieses Gespräch, die `fallbacks` enthalten, gehen direkt an dieses Fallback-Modell, ohne das angefragte Modell auszuführen. Das vermeidet, bei jedem Turn für einen Versuch zu zahlen, der vorhersehbar erneut abgelehnt würde.

Einige Eigenschaften der Routing-Entscheidung:

* Sie wird etwa 1 Stunde lang aufbewahrt und ist auf deine Organisation beschränkt.
* Sie wird als Content-Hash des Gesprächspräfixes plus dem Modell, das es bedient hat, gespeichert. Der Nachrichteninhalt selbst wird nicht gespeichert.
* Sie erfolgt nach bestem Bemühen, daher muss dein Code damit umgehen können, dass das angefragte Modell jederzeit erneut versucht wird.

Sticky Routing gilt sowohl für Streaming- als auch für Nicht-Streaming-Anfragen. Bei einer Streaming-Anfrage wird die Routing-Entscheidung getroffen, bevor der Stream geöffnet wird, sodass das `model`-Feld des `message_start`-Events bereits die ID des Fallback-Modells trägt.

## Clientseitiger Fallback mit der SDK-Middleware

Das SDK enthält eine Refusal-Fallback-Middleware. Du konfigurierst sie einmal auf dem Client mit deiner Liste von Fallback-Modellen. Aufrufe über `client.beta.messages` (csharp, go: `client.Beta.Messages`; java: `client.beta().messages()`; php: `$client->beta->messages`) versuchen abgelehnte Anfragen dann automatisch erneut, auf jeder Plattform. Die Middleware sendet außerdem bei jeder von ihr verarbeiteten Anfrage den Beta-Header `fallback-credit-2026-07-01`, sodass erneute Versuche ohne Einrichtung pro Anfrage neu bepreist werden. Eine Ablehnung durch Claude Haiku 5.5 enthält keine Fallback-Gutschrift, daher zahlt ein erneuter Versuch danach die vollen Kosten für das Schreiben des Prompt-Caches des Fallback-Modells.

### Einrichtung

Übergib `BetaRefusalFallbackMiddleware` (typescript: `betaRefusalFallbackMiddleware`; go: `betafallback.BetaRefusalFallbackMiddleware`; csharp: `BetaRefusalFallbackHandler`; java: `BetaRefusalFallbackInterceptor`; php: `RefusalFallbackMiddleware`) an den Client-Konstruktor und teile eine `BetaFallbackState`-Instanz über die Anfragen eines Gesprächs hinweg.

<CodeGroup exclude="shell">
  <CodeGroupItem language="cURL">
    Die Refusal-Fallback-Middleware ist Teil des Claude SDK, daher kann eine cURL-Anfrage sie nicht verwenden. Um innerhalb einer einzigen Anfrage auf einen Fallback zurückzugreifen, verwende den [serverseitigen Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#server-side-fallback). Um den erneuten Versuch selbst zu schreiben, siehe [Fallback-Gutschrift](https://platform.claude.com/docs/de/build-with-claude/fallback-credit).
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Die `ant` CLI enthält die Refusal-Fallback-Middleware nicht. Um innerhalb einer einzigen Anfrage auf einen Fallback zurückzugreifen, verwende den [serverseitigen Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#server-side-fallback). Um den erneuten Versuch selbst zu schreiben, siehe [Fallback-Gutschrift](https://platform.claude.com/docs/de/build-with-claude/fallback-credit).
  </CodeGroupItem>

  ```python Python
  from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware

  # Bei einer Ablehnung wiederholt die Middleware die Anfrage mit dem aufgeführten Fallback-Modell und
  # sendet automatisch den Fallback-Credit-Beta-Header bei jeder Anfrage, die sie verarbeitet.
  client = Anthropic(
      middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
  )

  state = BetaFallbackState()  # pins follow-ups to the model that accepted

  # Streaming: Bei einer Ablehnung wiederholt die Middleware die Anfrage mit dem Fallback-Modell und
  # fügt dessen Events in den offenen Stream ein.
  with (
      state,
      client.beta.messages.stream(
          max_tokens=1024,
          model="claude-fable-5",
          messages=[{"role": "user", "content": "Hello, Claude"}],
      ) as stream,
  ):
      for text in stream.text_stream:
          print(text, end="", flush=True)
      final_message = stream.get_final_message()
  print(f"\nserved by: {final_message.model}")

  # Nicht-Streaming: Die Wiederverwendung des Zustands hält die Konversation fixiert.
  with state:
      message = client.beta.messages.create(
          max_tokens=1024,
          model="claude-fable-5",
          messages=[{"role": "user", "content": "Hello, Claude"}],
      )
  print(f"served by: {message.model}")
  ```

  ```typescript TypeScript
  import { BetaFallbackState, betaRefusalFallbackMiddleware } from "@anthropic-ai/sdk";

  // Bei einer Ablehnung wiederholt die Middleware die Anfrage mit dem angegebenen Fallback-Modell und
  // sendet automatisch den Fallback-Credit-Beta-Header bei jeder Anfrage, die sie verarbeitet.
  const client = new Anthropic({
    middleware: [betaRefusalFallbackMiddleware([{ model: "claude-opus-4-8" }])]
  });

  // Teile einen Zustand über die gesamte Konversation, damit Folgeanfragen
  // an das Modell gebunden bleiben, das akzeptiert hat.
  const fallbackState = new BetaFallbackState();

  // Streaming: Bei einer Ablehnung wiederholt die Middleware die Anfrage mit dem Fallback-Modell und
  // fügt dessen Events in den offenen Stream ein.
  const stream = client.beta.messages
    .stream(
      {
        max_tokens: 1024,
        model: "claude-fable-5",
        messages: [{ role: "user", content: "Hello, Claude" }]
      },
      { fallbackState }
    )
    .on("text", (text) => process.stdout.write(text));

  const finalMessage = await stream.finalMessage();
  console.log("\nserved by:", finalMessage.model);

  // Ohne Streaming: Die Wiederverwendung des Zustands hält die Konversation gebunden.
  const message = await client.beta.messages.create(
    {
      max_tokens: 1024,
      model: "claude-fable-5",
      messages: [{ role: "user", content: "Hello, Claude" }]
    },
    { fallbackState }
  );
  console.log("served by:", message.model);
  ```

  ```csharp C#
  using Anthropic;
  using Anthropic.Helpers;
  using Anthropic.Models.Beta.Messages;
  using Messages = Anthropic.Models.Messages;

  // Bei einer Ablehnung wiederholt der Handler die Anfrage mit dem aufgeführten Fallback-Modell und
  // sendet automatisch den Fallback-Credit-Beta-Header bei jeder Anfrage, die er verarbeitet.
  AnthropicClient client = new()
  {
      Handlers =
      [
          new BetaRefusalFallbackHandler { Fallbacks = [new(Messages::Model.ClaudeOpus4_8)] },
      ],
  };

  // Bindet Folgeanfragen, die diesen Zustand teilen, an das Modell, das akzeptiert hat.
  BetaFallbackState fallbackState = BetaFallbackState.Create();

  MessageCreateParams parameters = new()
  {
      Model = Messages::Model.ClaudeFable5,
      MaxTokens = 1024,
      Messages = [new() { Content = "Hello, Claude", Role = Role.User }],
  };

  // Streaming: Endet der Stream mit einer Ablehnung, fügt der Handler die Events des
  // Fallback-Modells in den noch offenen Stream ein.
  BetaMessageContentAggregator aggregator = new();
  using (fallbackState.Use())
  {
      var responseUpdates = client.Beta.Messages.CreateStreaming(parameters);
      await foreach (BetaRawMessageStreamEvent rawEvent in responseUpdates.CollectAsync(aggregator))
      {
          if (
              rawEvent.TryPickContentBlockDelta(out var deltaEvent)
              && deltaEvent.Delta.TryPickText(out var textDelta)
          )
          {
              Console.Write(textDelta.Text);
          }
      }
  }
  BetaMessage streamedMessage = aggregator.Message();
  Console.WriteLine($"\nserved by: {streamedMessage.Model.Raw()}");

  // Nicht-Streaming: Die Wiederverwendung des Zustands hält die Konversation an das Modell gebunden, das akzeptiert hat.
  using (fallbackState.Use())
  {
      BetaMessage message = await client.Beta.Messages.Create(parameters);
      Console.WriteLine($"served by: {message.Model.Raw()}");
  }
  ```

  ```go Go
  import (
  // ...
  	"github.com/anthropics/anthropic-sdk-go/lib/betafallback"
  // ...
  )

  func main() {
  	ctx := context.Background()

  	// Die Middleware wiederholt eine abgelehnte Anfrage nacheinander auf jedem
  	// Fallback-Modell und meldet Anfragen automatisch für die Fallback-Credit-Beta an.
  	client := anthropic.NewClient(
  		option.WithMiddleware(betafallback.BetaRefusalFallbackMiddleware(
  			[]anthropic.BetaFallbackParam{{Model: anthropic.ModelClaudeOpus4_8}},
  		)),
  	)

  	// Ein Zustand pro Konversation: Anfragen, die ihn teilen, bleiben an das Modell
  	// gebunden, das akzeptiert hat; ein Follow-up fragt nie erneut ein ablehnendes Modell.
  	state := &betafallback.BetaFallbackState{}
  	conversation := betafallback.WithBetaFallbackState(state)

  	params := anthropic.BetaMessageNewParams{
  		MaxTokens: 1024,
  		Model:     anthropic.ModelClaudeFable5,
  		Messages: []anthropic.BetaMessageParam{
  			anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Hello, Claude")),
  		},
  	}

  	// Streaming: Bei einer Ablehnung wiederholt die Middleware direkt und fügt die Events
  	// des Fallback-Modells als eine durchgehende Nachricht in den offenen Stream ein.
  	stream := client.Beta.Messages.NewStreaming(ctx, params, conversation)
  	defer stream.Close()
  	var streamed anthropic.BetaMessage
  	for stream.Next() {
  		event := stream.Current()
  		if err := streamed.Accumulate(event); err != nil {
  			panic(err)
  		}
  		switch eventVariant := event.AsAny().(type) {
  		case anthropic.BetaRawContentBlockDeltaEvent:
  			if textDelta, ok := eventVariant.Delta.AsAny().(anthropic.BetaTextDelta); ok {
  				fmt.Print(textDelta.Text)
  			}
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  	fmt.Println("\nserved by:", streamed.Model)

  	// Nicht-Streaming: Der geteilte Zustand bindet dieses Follow-up an das Modell,
  	// das den gestreamten Turn bedient hat.
  	message, err := client.Beta.Messages.New(ctx, params, conversation)
  	if err != nil {
  		panic(err)
  	}
  	fmt.Println("served by:", message.Model)
  }
  ```

  ```java Java
  import com.anthropic.client.AnthropicClient;
  import com.anthropic.client.okhttp.AnthropicOkHttpClient;
  import com.anthropic.core.RequestOptions;
  import com.anthropic.core.http.StreamResponse;
  import com.anthropic.helpers.BetaFallbackState;
  import com.anthropic.helpers.BetaMessageAccumulator;
  import com.anthropic.helpers.BetaRefusalFallbackInterceptor;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaRawMessageStreamEvent;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      // Der Interceptor wiederholt abgelehnte Anfragen auf dem Fallback-Modell. Er fügt automatisch
      // den Fallback-Credit-Beta-Header zu jeder Anfrage hinzu, die er verarbeitet.
      AnthropicClient client = AnthropicOkHttpClient.builder()
          .fromEnv()
          .addInterceptor(BetaRefusalFallbackInterceptor.builder()
              .addFallback(Model.CLAUDE_OPUS_4_8)
              .build())
          .build();

      // Teile einen State über Anfragen hinweg, damit Folgeanfragen an das akzeptierende Modell gebunden bleiben.
      BetaFallbackState state = BetaFallbackState.create();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5)
          .maxTokens(1024)
          .addUserMessage("Hello, Claude")
          .build();

      // Streaming: Bei einer Ablehnung werden die Events des Fallback-Modells in den offenen Stream eingefügt.
      BetaMessageAccumulator accumulator = BetaMessageAccumulator.create();
      try (StreamResponse<BetaRawMessageStreamEvent> streamResponse = client.beta()
              .messages()
              .createStreaming(params, RequestOptions.builder().fallbackState(state).build())) {
          streamResponse.stream()
              .peek(accumulator::accumulate)
              .forEach(event -> event.contentBlockDelta()
                  .flatMap(deltaEvent -> deltaEvent.delta().text())
                  .ifPresent(textDelta -> IO.print(textDelta.text())));
      }
      IO.println("\nserved by: " + accumulator.message().model().asString());

      // Nicht-Streaming: Die Wiederverwendung desselben States hält die Konversation gebunden.
      BetaMessage message = client.beta()
          .messages()
          .create(params, RequestOptions.builder().fallbackState(state).build());
      IO.println("served by: " + message.model().asString());
  }
  ```

  ```php PHP
  use Anthropic\Beta\Messages\BetaRawContentBlockDeltaEvent;
  use Anthropic\Beta\Messages\BetaTextDelta;
  use Anthropic\Client;
  use Anthropic\Lib\Middleware\BetaFallbackState;
  use Anthropic\Lib\Middleware\RefusalFallbackMiddleware;
  use Anthropic\Lib\Streaming\MessageAccumulator;

  // Konfiguriere die Fallback-Kette einmal. Bei einer Ablehnung wiederholt die Middleware die
  // Anfrage entlang der Kette und sendet den Fallback-Credit-Beta-Header für dich.
  $client = new Client(
      requestOptions: [
          'middleware' => [new RefusalFallbackMiddleware([['model' => 'claude-opus-4-8']])],
      ],
  );

  // Teile einen State über die Konversation hinweg, damit Folgeanfragen an das Modell
  // gebunden bleiben, das akzeptiert hat.
  $state = new BetaFallbackState();

  // Streaming: Bei einer Ablehnung fügt die Middleware die Events des Fallback-Modells
  // in den noch offenen Stream ein. Das Modell des Accumulators ist das ausliefernde Modell.
  $stream = $client->beta->messages->createStream(
      model: 'claude-fable-5',
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello, Claude']],
      requestOptions: ['fallbackState' => $state],
  );
  $accumulator = MessageAccumulator::forBetaMessages();
  foreach ($stream as $event) {
      $accumulator->accumulate($event);
      if ($event instanceof BetaRawContentBlockDeltaEvent
          && $event->delta instanceof BetaTextDelta) {
          echo $event->delta->text;
      }
  }
  echo "\nserved by: {$accumulator->message()->model}\n";

  // Nicht-Streaming: dieselbe Middleware. Die Wiederverwendung des States hält die Konversation
  // an das Modell gebunden, das akzeptiert hat.
  $message = $client->beta->messages->create(
      model: 'claude-fable-5',
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello, Claude']],
      requestOptions: ['fallbackState' => $state],
  );
  echo "served by: {$message->model}\n";
  ```

  ```ruby Ruby
  # Bei einer Ablehnung wiederholt die Middleware die Anfrage entlang der Fallback-Kette.
  # Sie sendet den Fallback-Credit-Beta-Header bei jeder Anfrage, die sie verarbeitet.
  client = Anthropic::Client.new(
    middleware: [Anthropic::BetaRefusalFallbackMiddleware.new([{model: "claude-opus-4-8"}])]
  )

  # Teile einen Zustand über die Konversation hinweg, damit Folgeanfragen
  # an das Modell gebunden bleiben, das akzeptiert hat.
  state = Anthropic::BetaFallbackState.new

  # Streaming: Bei einer Ablehnung fügt die Middleware die Events des Fallback-Modells
  # in den noch offenen Stream ein.
  stream = client.beta.messages.stream(
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello, Claude"}],
    request_options: {fallback_state: state}
  )
  stream.text.each { print it }
  puts "\nserved by: #{stream.accumulated_message.model}"

  # Nicht-Streaming: Die Wiederverwendung des Zustands hält die Konversation an das Modell gebunden, das akzeptiert hat.
  message = client.beta.messages.create(
    model: "claude-fable-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello, Claude"}],
    request_options: {fallback_state: state}
  )
  puts "served by: #{message.model}"
  ```
</CodeGroup>

### Verhalten

* Retries durchlaufen deine Fallback-Liste der Reihe nach. Ein Fallback-Modell, das selbst ablehnt, gibt die Anfrage an den nächsten Eintrag weiter.
* Wenn jedes Modell in der Liste abgelehnt hat, gibt die Middleware die letzte Ablehnung (die Ablehnungsantwort des letzten Modells) zurück, statt einen Fehler auszulösen.
* Thinking-Blöcke von Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, Claude Haiku 5.5 oder Claude Fable 5 werden unverändert durchgereicht. Jeder erneute Versuch sendet deinen ursprünglichen Anfrage-Body erneut, und die einzigen Blöcke, die die Middleware bei späteren Anfragen aus dem Konversationsverlauf entfernt, sind die `fallback`-Grenzblöcke, die sie selbst hinzugefügt hat. Das Fallback-Modell kann Claude Fable 5.1-Blöcke nicht lesen, die nur [Claude Fable 5.1 und Claude Mythos 5.1 lesen](https://platform.claude.com/docs/de/build-with-claude/thinking#preserved-for-model), daher verwirft die API sie. Die API verwirft außerdem Claude Opus 5.5-Blöcke für jedes Fallback-Modell außer Claude Fable 5.1 und Claude Mythos 5.1 (siehe [Modellwechsel mitten im Gespräch](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#switching-models)). Sie verwirft auch Claude Sonnet 5.5-Blöcke, für jedes Fallback-Modell außer Claude Opus 5.5 auf der Claude API und Google Cloud. Claude Opus 5.5 und Claude Sonnet 5.5 lesen Claude Haiku 5.5-Blöcke auf der Claude API und Google Cloud, und die API verwirft sie für ein Fallback-Modell, das sie nicht lesen kann.
* Über die Middleware bediente Antworten enthalten an jeder Modellgrenze einen `fallback`-Content-Block, genau wie Antworten des serverseitigen Fallbacks. Die Middleware verwaltet diese Blöcke bei späteren Anfragen für dich.
* Das Modell, das akzeptiert hat, wird in `BetaFallbackState` aufgezeichnet, sodass Folgeanfragen, die den State teilen, an dieses Modell gebunden bleiben, statt erneut ein Modell zu fragen, das abgelehnt hat.

<Note>
  Die Middleware und der serverseitige `fallbacks`-Parameter erledigen dieselbe Aufgabe. Konfiguriere das eine oder das andere, niemals beide bei derselben Anfrage. Um eine serverseitige `fallbacks`-Anfrage aus einer Anwendung zu senden, die die Middleware installiert, verwende eine separate Client-Instanz ohne sie.
</Note>

## Den erneuten Versuch selbst schreiben

Über rohes HTTP oder mit eigener Retry-Logik implementierst du das Muster, das die Middleware kapselt:

<Steps>
  <Step title="Die Ablehnung erkennen">
    Prüfe die Antwort auf `stop_reason: "refusal"`.
  </Step>

  <Step title="Auf einem Fallback-Modell erneut senden">
    Sende dieselbe Anfrage mit `model` auf ein Fallback-Modell gesetzt, etwa Claude Opus 4.8. Wenn die abgelehnte Anfrage `thinking: {"type": "between_tools"}` gesendet hat, ändere zuerst `thinking`: Nur Claude Sonnet 5.5 akzeptiert diesen Wert, also lass `thinking` weg oder setze einen Wert, den das Fallback-Modell akzeptiert. [Serverseitiger Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#server-side-fallback) unter dem Header `2026-07-01` nimmt diese Änderung für dich vor, wenn er auf Claude Sonnet 5 zurückfällt. Ein anderes Modell kann normalerweise eine Anfrage bedienen, die Claude Fable 5.1 oder Claude Fable 5 ablehnt. Wie du mit dem Konversationsverlauf umgehst, hängt davon ab, ob du eine [Fallback-Gutschrift](https://platform.claude.com/docs/de/build-with-claude/fallback-credit) einlöst:

    * **Ohne Einlösung einer Gutschrift:** Du kannst die früheren `thinking`- und `redacted_thinking`-Blöcke an Ort und Stelle lassen oder sie entfernen, um Eingabe-Token zu sparen. Das Fallback-Modell kann sie in beiden Fällen normalerweise nicht nutzen: Nur Claude Fable 5.1 und Claude Mythos 5.1 [lesen Claude Fable 5.1-Blöcke](https://platform.claude.com/docs/de/build-with-claude/thinking#preserved-for-model), und nur diese beiden Modelle, Claude Fable 5 und Claude Mythos 5 lesen Claude Fable 5-Blöcke, daher verwirft die API sie für jedes andere Fallback-Modell. Die API verwirft außerdem Claude Opus 5.5-Blöcke für jedes Fallback-Modell außer Claude Fable 5.1 und Claude Mythos 5.1 (siehe [Modellwechsel mitten im Gespräch](https://platform.claude.com/docs/de/build-with-claude/preserved-thinking#switching-models)). Sie verwirft auch Claude Sonnet 5.5-Blöcke, für jedes Fallback-Modell außer Claude Opus 5.5 auf der Claude API und Google Cloud. Ein erneuter Versuch nach einer Ablehnung durch Claude Haiku 5.5 fällt immer unter diesen Fall. Claude Opus 5.5 und Claude Sonnet 5.5 lesen Claude Haiku 5.5-Blöcke auf der Claude API und Google Cloud, lass diese Blöcke also an Ort und Stelle, wenn du dort auf eines dieser Modelle zurückfällst. Für ein Fallback-Modell, das sie nicht lesen kann, verwirft die API sie, ohne sie abzurechnen.
    * **Mit Einlösung einer Gutschrift:** Sende den Body unverändert, da die Einlösung eine exakte Übereinstimmung erfordert. Der Server behandelt die Thinking-Blöcke des früheren Modells bei einer Einlösung selbst, also entferne sie nicht (siehe [Felder, die mit der abgelehnten Anfrage übereinstimmen müssen](https://platform.claude.com/docs/de/build-with-claude/fallback-credit#reference)).
  </Step>

  <Step title="Beim Fallback-Modell bleiben">
    Verwende bei Multi-Turn-Konversationen das Fallback-Modell auch für nachfolgende Turns, statt zurückzuwechseln.
  </Step>
</Steps>

Ein manueller erneuter Versuch schreibt den Prompt-Cache des Fallback-Modells von Grund auf neu, was mehr kostet als das Lesen eines vorhandenen Caches. Die [Fallback-Gutschrift](https://platform.claude.com/docs/de/build-with-claude/fallback-credit) erstattet diese Kosten; löse sie bei jedem erneuten Versuch ein, den du selbst baust. Eine Ablehnung durch Claude Haiku 5.5 enthält keine Fallback-Gutschrift, daher zahlt ein erneuter Versuch danach die vollen Kosten für das Schreiben des Prompt-Caches des Fallback-Modells.

## Ablehnungen in Message Batches

Eine abgelehnte Anfrage in einem [Message Batch](https://platform.claude.com/docs/de/build-with-claude/batch-processing) kommt als `result.type: "succeeded"` mit `stop_reason: "refusal"` zurück. Batch-Ergebnisse tragen dasselbe `stop_details`-Objekt wie synchrone Antworten, sodass du Ablehnungen entweder über `stop_reason` oder `stop_details.type` erkennen kannst. Ein Unterschied: Batch-Ablehnungen erzeugen keine Fallback-Guthaben, daher enthält `stop_details` bei einem Batch-Ergebnis niemals ein `fallback_credit_token`.

Serverseitiger Fallback ist für Batches nicht verfügbar (eine Batch-Anfrage, die `fallbacks` enthält, erzeugt ein fehlerhaftes Ergebnis pro Element). Um abgelehnte Batch-Elemente erneut zu versuchen:

1. Sammle die abgelehnten Elemente aus den Ergebnissen.
2. Lass die Thinking-Blöcke in Verläufen mit mehreren Turns an Ort und Stelle oder entferne sie, um Eingabe-Token zu sparen. Für ein Fallback-Modell, das sie nicht lesen kann, verwirft die API sie, ohne sie abzurechnen, wie bei [einem manuellen erneuten Versuch](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#manual-retry).
3. Wenn ein abgelehntes Element `thinking: {"type": "between_tools"}` gesendet hat, lass `thinking` weg oder setze einen Wert, den das Fallback-Modell akzeptiert. Nur Claude Sonnet 5.5 akzeptiert `between_tools`.
4. Reiche sie auf einem Fallback-Modell als neuen Batch oder als direkte Anfragen erneut ein.

## Häufige Fallstricke

* **Versuche auf einem anderen Modell erneut.** Eine abgelehnte Anfrage erneut an dasselbe Modell zu senden, bringt meist eine weitere Ablehnung. Richte den erneuten Versuch auf das Fallback-Modell.
* **Budgetiere erneute Versuche pro Anfrage, nicht pro Turn oder pro Sitzung.** Ein einzelner Turn kann mehrere Ablehnungen erzeugen, zum Beispiel ein Agent plus seine Sub-Agenten.
* **Konfiguriere Fallback auf jedem Anfragepfad.** Retry-Handler, Fehlerbehandlungszweige und Hintergrund-Worker brauchen ihn alle. Ein Handler, der eine Anfrage ohne Fallback erneut ausgibt, verliert den Schutz genau bei den Anfragen, die ihn am wahrscheinlichsten brauchen.
* **Gib Sub-Agent-Aufrufen ihren eigenen Fallback.** Der `fallbacks`-Parameter wird nicht in Modellaufrufe weitergegeben, die aus der Tool-Ausführung heraus erfolgen.
* **Mache Fallback zu einer Eigenschaft der Anfrage, nicht des umgebenden Zustands.** Ein geteiltes Flag, ein gecachter Konfigurationswert oder ein globaler Schalter kann aus dem Takt geraten und eine Anfrage stillschweigend ungeschützt lassen. Wenn du nicht bestätigen kannst, dass Fallback aktiv ist, konfiguriere ihn, statt anzunehmen, dass er eingeschaltet ist.
* **Instrumentiere Ablehnungen als eigenes Signal.** Eine Ablehnung ist ein HTTP 200, daher sieht Monitoring, das auf Fehlerraten oder 5xx-Antworten aufbaut, sie nie. Emittiere ein Event pro Ablehnung und eines pro per Fallback bedienter Antwort (der `fallback_message`-Eintrag in `usage.iterations` markiert Letztere), und alarmiere dann bei der Lücke zwischen den beiden Zählungen.
* **Verzweige auf `stop_reason` oder `stop_details.type`, nicht auf `content` oder die inneren `stop_details`-Felder.** Das `stop_details`-Objekt ist bei einer Ablehnung immer vorhanden, aber seine Felder `category` und `explanation` können `null` sein. Prüfe direkt, ob `stop_reason` gleich `"refusal"` ist.

## Nächste Schritte

<CardGroup>
  <Card title="Fallback-Guthaben" icon="scales" href="https://platform.claude.com/docs/de/build-with-claude/fallback-credit">
    Vermeide, die Prompt-Cache-Kosten doppelt zu zahlen, wenn du den erneuten Versuch selbst baust.
  </Card>

  <Card title="Stop-Reasons und Fallback" icon="code" href="https://platform.claude.com/docs/de/build-with-claude/handling-stop-reasons">
    Jeder `stop_reason`-Wert und wie du damit umgehst.
  </Card>

  <Card title="SDK-Middleware" icon="settings" href="https://platform.claude.com/docs/de/cli-sdks-libraries/middleware">
    Wie SDK-Middleware funktioniert, einschließlich des Refusal-Fallback-Helfers.
  </Card>

  <Card title="Migrationsleitfaden" icon="arrow-right" href="https://platform.claude.com/docs/de/models/fable-5-1/migration-guide">
    Migriere eine bestehende Anwendung zu Claude Fable 5.1.
  </Card>
</CardGroup>
