---
title: Migration auf API-Version 2026-10-21
url: https://platform.claude.com/docs/de/api/migration-2026-10-21
description: "Aktualisiere eine Claude API-Integration von API-Version 2023-06-01 auf 2026-10-21: die zu installierende SDK-Version und die nötigen Codeänderungen."
---

Dieser Leitfaden listet die Codeänderungen für den Wechsel von API-Version `2023-06-01` auf `2026-10-21` auf. Die [Upgrade-Schritte](https://platform.claude.com/docs/de/api/migration-2026-10-21#migration-checklist) beschreiben der Reihe nach, was zu tun ist.

## Upgrade-Schritte

<Steps>
  <Step title="Auf 2026-10-21 wechseln">
    Wenn du ein SDK verwendest, nutzen deine Anfragen die API-Version, die aktuell war, als die Hauptversion deines SDKs veröffentlicht wurde. Die für deine Sprache angegebenen Versionen sind die ersten, die `2026-10-21` verwenden, also aktualisiere auf diese. Wenn du die API ohne SDK aufrufst, setze den Header `anthropic-version` auf `2026-10-21`.

    <Tabs>
      <Tab title="cURL">
        Setze den Header `anthropic-version` auf `2026-10-21`:

        ```bash
        curl https://api.anthropic.com/v1/messages \
          -H "x-api-key: $ANTHROPIC_API_KEY" \
          -H "anthropic-version: 2026-10-21" \
          -H "content-type: application/json" \
          -d '{
            "model": "claude-opus-5-5",
            "max_tokens": 1024,
            "messages": [{"role": "user", "content": "Hello, Claude"}]
          }'
        ```
      </Tab>

      <Tab title="CLI">
        Aktualisiere die `ant` CLI auf Version 2.0.0. Der Homebrew-Befehl und die Release-Downloads bleiben gleich.

        Go verlangt, dass der Pfad eines Moduls ab Hauptversion 2 auf diese Version endet, daher lautet der Modulpfad der CLI jetzt `github.com/anthropics/anthropic-cli/v2`. Wenn du mit `go install` installierst, füge `/v2` zum Pfad hinzu:

        ```bash
        # Vorher
        go install 'github.com/anthropics/anthropic-cli/cmd/ant@latest'

        # Nachher
        go install 'github.com/anthropics/anthropic-cli/v2/cmd/ant@latest'
        ```

        Der alte Pfad installiert weiterhin das neueste v1-Release, ohne Fehler oder Warnung.
      </Tab>

      <Tab title="Python">
        Aktualisiere das Paket `anthropic` auf Version 2.0.0.
      </Tab>

      <Tab title="TypeScript">
        Aktualisiere das Paket `@anthropic-ai/sdk` auf Version 1.0.0.

        v1 von `@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` und `@anthropic-ai/google-cloud-sdk` benötigt v1 von `@anthropic-ai/sdk`, und ihre früheren Versionen benötigen eine Version unter 1. Wenn du eines davon verwendest, stelle es im selben Upgrade auf v1 um. Andernfalls installiert dein Paketmanager dafür eine zweite, ältere Kopie von `@anthropic-ai/sdk`.
      </Tab>

      <Tab title="C#">
        Aktualisiere das Paket `Anthropic` auf Version 13.0.0.
      </Tab>

      <Tab title="Go">
        Aktualisiere auf Version 2.0.0 des Go SDK, dessen Modulpfad `github.com/anthropics/anthropic-sdk-go/v2` ist. Eine neue Hauptversion eines Go-Moduls hat einen neuen Importpfad, also ändere jeden Import von `github.com/anthropics/anthropic-sdk-go` und seiner Pakete wie `github.com/anthropics/anthropic-sdk-go/option` so, dass er mit `github.com/anthropics/anthropic-sdk-go/v2` beginnt. Führe dann `go get github.com/anthropics/anthropic-sdk-go/v2` aus.
      </Tab>

      <Tab title="Java">
        Aktualisiere das Artefakt `com.anthropic:anthropic-java` auf Version 3.0.0.
      </Tab>

      <Tab title="PHP">
        Führe `composer require "anthropic-ai/sdk"` aus, um das Paket auf Version 1.0.0 zu aktualisieren. `composer update` allein bleibt innerhalb deiner aktuellen Versionsbeschränkung.
      </Tab>

      <Tab title="Ruby">
        Aktualisiere das Gem `anthropic` auf Version 2.0.0.
      </Tab>
    </Tabs>

    <Warning>
      Auf Amazon Bedrock ist `2026-10-21` nur für Claude 4.7 und neuere Modelle verfügbar. Wenn du auf Bedrock ein älteres Modell aufrufst, das in [Claude auf Amazon Bedrock (Opus 4.6 und früher)](https://platform.claude.com/docs/de/build-with-claude/claude-on-amazon-bedrock-legacy) aufgeführt ist, bleib bei der SDK-Version, die du heute verwendest, oder sende, falls du die API-Version selbst setzt, weiterhin die Version, die du heute sendest. Um diese Aufrufe auf `2026-10-21` umzustellen, stelle sie zuerst auf ein Modell ab Claude 4.7 um.
    </Warning>

    Veröffentliche das Upgrade zusammen mit deinen Korrekturen aus dem nächsten Schritt.
  </Step>

  <Step title="Deinen Code an die Breaking Changes anpassen">
    Geh die [Breaking Changes](https://platform.claude.com/docs/de/api/migration-2026-10-21#breaking-changes) durch und passe deinen Code für jede an, die dich betrifft. Nimm außerdem die [Codeänderungen vor, die die neue SDK- oder CLI-Version erfordert](https://platform.claude.com/docs/de/api/migration-2026-10-21#sdk-changes).
  </Step>

  <Step title="Gegen 2026-10-21 testen">
    Teste deine Integration gegen `2026-10-21`, bevor du sie veröffentlichst.
  </Step>
</Steps>

## Breaking Changes

„Breaking changes" (inkompatible Änderungen) sind Änderungen, die bestehenden Code brechen können.

### Messages API

Diese Änderungen gelten für Anfragen an die Messages API (`POST /v1/messages`), für das [Token-Zählen](https://platform.claude.com/docs/de/build-with-claude/token-counting) und für jede Anfrage in einem [Message Batch](https://platform.claude.com/docs/de/build-with-claude/batch-processing), der mit `2026-10-21` erstellt wurde.

#### Document-Blöcke in Assistant-Nachrichten geben einen Fehler zurück

Betrifft dich, wenn du `document`-Blöcke direkt in `assistant`-Nachrichten sendest.

In `2026-10-21` gibt eine Anfrage, die einen `document`-Block direkt in eine `assistant`-Nachricht setzt, einen 400-Fehler zurück. Sende Dokumente stattdessen in `user`-Nachrichten. Ein Dokument, das in einem anderen Block verschachtelt ist, etwa in einem von Claude zurückgegebenen Web-Fetch-Tool-Ergebnis, wird weiterhin akzeptiert.

#### Zitate in User-Nachrichten geben einen Fehler zurück

Betrifft dich, wenn du `citations` in `text`-Blöcken in `user`-Nachrichten sendest, auch innerhalb von `search_result`-Blöcken.

In `2026-10-21` gibt eine Anfrage, die einen `text`-Block mit einem nicht leeren `citations`-Array in einer `user`-Nachricht sendet, einen 400-Fehler zurück. Entferne `citations` aus diesen Blöcken. Zitate in `text`-Blöcken in `assistant`-Nachrichten, etwa in früheren Antworten von Claude, die du zurücksendest, werden weiterhin akzeptiert, ebenso die Einstellung `"citations": {"enabled": true}` bei Dokumenten und Suchergebnissen.

#### Sampling-Parameter werden entfernt

Betrifft dich, wenn du `temperature`, `top_p` oder `top_k` in Messages-Anfragen oder Message-Batch-Anfragen sendest.

In `2026-10-21` gibt eine Anfrage, die `temperature`, `top_p` oder `top_k` sendet, einen 400-Fehler zurück, selbst beim Standardwert des Parameters.

Entferne die drei Parameter aus deinen Anfragen.

Ab den neuesten Hauptversionen haben das SDK und die CLI die drei Parameter nicht mehr.

Ohne diese Parameter sampelt eine Anfrage mit deren Standardwerten, einschließlich einer `temperature` von 1.0, genau wie eine `2023-06-01`-Anfrage, die sie weglässt. Modelle, die bereits nur die Standardwerte akzeptieren, wie Claude 4.7 und neuere Modelle, sampeln wie zuvor. Bei Modellen, die andere Werte akzeptieren, wie Claude Sonnet 4.6, verliert eine Anfrage, die `temperature` für konsistentere Ausgaben gesenkt hat, diesen Effekt. Keine andere Einstellung ersetzt ihn. Wenn eine Anfrage auf einen vom Standard abweichenden Wert angewiesen ist, sende den Parameter entweder nicht mehr oder belasse diese Anfrage auf `2023-06-01`.

### Admin API und Claude Enterprise Analytics API

Betrifft dich, wenn dein Code die Antwortfelder der Admin API oder der Claude Enterprise Analytics API aus den folgenden Tabellen liest.

In `2026-10-21` enthalten Antworten der Admin API und der [Claude Enterprise Analytics API](https://platform.claude.com/docs/de/manage-claude/analytics-api) nicht mehr die alten Namen umbenannter Felder. Verwende stattdessen die neuen Namen.

Admin API:

| Endpunkte                                                                                                                                                                                                                                                                           | Alter Name     | Neuer Name                                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| [RBAC-Gruppen](https://platform.claude.com/docs/de/api/beta/organization/rbac_groups/list): erstellen, auflisten, abrufen und aktualisieren                                                                                                                                         | `roles`        | `role_ids`                                                                                                                                     |
| [RBAC-Gruppenmitglieder](https://platform.claude.com/docs/de/api/beta/organization/rbac_groups/members/list): auflisten und hinzufügen sowie die Antwort auf das [Entfernen eines Mitglieds](https://platform.claude.com/docs/de/api/beta/organization/rbac_groups/members/remove)  | `group_id`     | `rbac_group_id`                                                                                                                                |
| [RBAC-Rollen](https://platform.claude.com/docs/de/api/beta/organization/rbac_roles/list): auflisten und abrufen                                                                                                                                                                     | `name`         | `display_name`                                                                                                                                 |
| Ratenlimits für [Organisation](https://platform.claude.com/docs/de/api/organization/rate_limits/list) und [Workspace](https://platform.claude.com/docs/de/api/organization/workspaces/rate_limits/list): auflisten sowie die Antwort auf das Setzen der Ratenlimits eines Workspace | `group_type`   | `group.type`                                                                                                                                   |
| [API-Keys](https://platform.claude.com/docs/de/api/organization/api_keys/list): auflisten, abrufen und aktualisieren                                                                                                                                                                | `workspace_id` | `scope` (andere Werte; siehe [`workspace_id` bei API-Keys](https://platform.claude.com/docs/de/api/migration-2026-10-21#api-key-workspace-id)) |

Claude Enterprise Analytics API:

| Endpunkte                                                                                                                                                                                                                              | Alter Name    | Neuer Name            |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------- |
| Berichte zu [Nutzung](https://platform.claude.com/docs/de/api/beta/organization/analytics/user_usage_report/list) und [Kosten](https://platform.claude.com/docs/de/api/beta/organization/analytics/user_cost_report/list) pro Benutzer | `actor.email` | `actor.email_address` |
| [Aktivitätszusammenfassungen](https://platform.claude.com/docs/de/api/beta/organization/analytics/summaries/list)                                                                                                                      | `summaries`   | `data`                |

Der Query-Parameter `group_type` bei den Endpunkten zum Auflisten von Ratenlimits und der Filter `workspace_id` beim Endpunkt zum Auflisten von API-Keys bleiben unverändert.

#### `workspace_id` bei API-Keys

Betrifft dich, wenn dein Code `workspace_id` bei API-Keys liest.

In `2023-06-01` ist die `workspace_id` eines API-Keys die ID des Workspace, an den der Key gebunden ist, oder `null` für einen Key, der an den Default Workspace gebunden ist, und für einen Key, der nicht an einen einzelnen Workspace gebunden ist (ein Key für alle Workspaces).

In `2026-10-21` wird `workspace_id` entfernt. Lies stattdessen `scope`: Für einen an einen Workspace gebundenen Key, einschließlich des Default Workspace, ist `scope.workspace_id` die tatsächliche ID dieses Workspace, und ein Key für alle Workspaces hat einen `scope` von `{"type": "organization"}`, ohne `workspace_id`.

Wenn dein Code eine `workspace_id` mit dem Wert `null` als Default Workspace behandelt hat, vergleiche stattdessen `scope.workspace_id` mit der ID deines Default Workspace. Um diese ID zu finden, rufe [List Workspaces](https://platform.claude.com/docs/de/api/organization/workspaces/list) mit `include_default=true` auf und nimm den Workspace mit dem Namen `"Default"`.

## SDK- und CLI-Änderungen

Frühere SDK- und CLI-Versionen haben bei jeder Anfrage `anthropic-version: 2023-06-01` gesendet. Die Versionen unter [Auf 2026-10-21 wechseln](https://platform.claude.com/docs/de/api/migration-2026-10-21#upgrade) senden `2026-10-21`. Die Änderungen unter [Breaking Changes](https://platform.claude.com/docs/de/api/migration-2026-10-21#breaking-changes) gelten auch für sie: Die entfernten Parameter und die alten Feldnamen sind auch aus den Typen des SDK sowie aus den Flags und der Ausgabe der CLI verschwunden.

### API-Version auf Amazon Bedrock und Google Cloud

Der Client des SDK für Google Cloud's Agent Platform gibt die Version im Request-Body statt in einem Header an. Er sendet `anthropic_version: 2026-10-21`, wo frühere Versionen `vertex-2023-10-16` gesendet haben, und keinen `anthropic-version`-Header.

Der Amazon Bedrock-Client macht dasselbe. Er sendet `anthropic_version: 2026-10-21`, wo frühere Versionen `bedrock-2023-05-31` gesendet haben, und keinen `anthropic-version`-Header. Modelle, die älter als Claude Opus 4.7 sind, unterstützen API-Version `2026-10-21` auf Bedrock noch nicht, und eine Anfrage, die sie angibt, kann einen 400-Fehler erhalten. Wenn du eines davon verwendest, bleib vorerst bei der früheren SDK-Version oder aktualisiere und sende `bedrock-2023-05-31` selbst.

<Tabs>
  <Tab title="Python">
    Dies gilt für `AnthropicVertex`, `AsyncAnthropicVertex`, `AnthropicBedrock` und `AsyncAnthropicBedrock`.

    Um `bedrock-2023-05-31` zu senden, übergib bei jeder Anfrage `extra_body={"anthropic_version": "bedrock-2023-05-31"}`.
  </Tab>

  <Tab title="TypeScript">
    Dies gilt für `AnthropicVertex` und `AnthropicBedrock`. Wenn du den Header `anthropic-version` am Client oder bei einer Anfrage setzt, landet sein Wert im Body.

    Um `bedrock-2023-05-31` zu senden, setze den Header `anthropic-version` am Client oder bei einer Anfrage auf `"bedrock-2023-05-31"`.
  </Tab>

  <Tab title="C#">
    Dies gilt für `AnthropicVertexClient` und `AnthropicBedrockClient`. Wenn du den Header `anthropic-version` über `ClientOptions.ExtraHeaders` setzt, landet sein Wert im Body.

    Um `bedrock-2023-05-31` zu senden, rufe `WithOptions` am Client auf und setze `anthropic-version` in `ClientOptions.ExtraHeaders` auf `bedrock-2023-05-31`.
  </Tab>

  <Tab title="Go">
    Dies gilt für die Pakete `vertex` und `bedrock`. Wenn du den Header `anthropic-version` mit `option.WithHeader` setzt, landet sein Wert im Body. `vertex.DefaultVersion` und `bedrock.DefaultVersion` wurden entfernt.

    Um `bedrock-2023-05-31` zu senden, übergib `option.WithHeader("anthropic-version", "bedrock-2023-05-31")` an den Client oder an eine Anfrage.
  </Tab>

  <Tab title="Java">
    Dies gilt für `VertexBackend` und `BedrockBackend`. Wenn du den Header `anthropic-version` am Client oder bei einer Anfrage setzt, landet sein Wert im Body.

    Um `bedrock-2023-05-31` zu senden, setze den Header `anthropic-version` am Client oder bei einer Anfrage auf `bedrock-2023-05-31`.
  </Tab>

  <Tab title="PHP">
    Dies gilt für `Anthropic\Vertex\Client` und `Anthropic\Bedrock\Client`.

    Um `bedrock-2023-05-31` zu senden, übergib `'extraBodyParams' => ['anthropic_version' => 'bedrock-2023-05-31']` in `requestOptions`.
  </Tab>

  <Tab title="Ruby">
    Dies gilt für `Anthropic::VertexClient` und `Anthropic::BedrockClient`. Wenn du den Header `anthropic-version` über `extra_headers` setzt, landet sein Wert im Body. `Anthropic::VertexClient::DEFAULT_VERSION` und `Anthropic::BedrockClient::DEFAULT_VERSION` wurden entfernt.

    Um `bedrock-2023-05-31` zu senden, übergib `extra_headers: {"anthropic-version" => "bedrock-2023-05-31"}` in `request_options`.
  </Tab>
</Tabs>

### `MessageParam` ist eine Union mit einem Typ pro Rolle

In früheren Versionen war `MessageParam` ein einziger Typ für jede Rolle. Jede Rolle hat jetzt einen eigenen Typ: `UserMessageParam`, `AssistantMessageParam` und `SystemMessageParam`. `BetaMessageParam` ist auf dieselbe Weise aufgeteilt, in `BetaUserMessageParam`, `BetaAssistantMessageParam` und `BetaSystemMessageParam`. Die Anfragen, die das SDK sendet, haben dieselben Felder und Werte wie zuvor.

<Tabs exclude="shell">
  <Tab title="Python">
    Eine als Dict-Literal geschriebene Nachricht, etwa `{"role": "user", "content": "Hello"}`, muss nicht geändert werden.

    In v1 war `anthropic.types.MessageParam` ein einzelnes `TypedDict`. In v2 ist es eine Union der drei Typen, und `anthropic.types.beta.BetaMessageParam` ist eine Union seiner drei Typen. Beide Namen funktionieren weiterhin in Annotationen, etwa `list[MessageParam]`.

    Der Aufruf eines der beiden Namen löst jetzt einen `TypeError` aus, und ein Type-Checker markiert ihn. Schreibe die Nachricht als Dict:

    ```python
    # Vorher
    message = MessageParam(role="user", content="Hello")

    # Nachher
    message: MessageParam = {"role": "user", "content": "Hello"}
    ```

    Das Ableiten einer Unterklasse von einem der beiden Namen löst ebenfalls einen `TypeError` aus. Leite stattdessen vom Typ für die Rolle ab, etwa `UserMessageParam`.

    Die übrigen Änderungen betreffen nur die Typprüfung. Ein Dict, dessen `role` eine Variable ist, die mehr als eine Rolle enthalten kann, passt zu keinem Typ in der Union, also baue das Dict jeweils für eine Rolle:

    ```python
    # Vorher
    def to_message(role: Literal["user", "assistant"], text: str) -> MessageParam:
        return {"role": role, "content": text}


    # Nachher
    def to_message(role: Literal["user", "assistant"], text: str) -> MessageParam:
        if role == "user":
            return {"role": "user", "content": text}
        return {"role": "assistant", "content": text}
    ```

    Zwei weitere gelten nur für `BetaMessageParam`:

    * `clear_at` und `output_config` sind Schlüssel von `BetaSystemMessageParam`, daher kann eine User- oder Assistant-Nachricht sie nicht haben.
    * `content` ist in `BetaSystemMessageParam` optional, daher meldet pyright `message["content"]`. Lies es mit `message.get("content")` oder prüfe zuerst, dass `message["role"]` nicht `"system"` ist.
  </Tab>

  <Tab title="TypeScript">
    `MessageParam` war ein einzelnes Interface. Es ist jetzt `UserMessageParam | AssistantMessageParam | SystemMessageParam`, und `BetaMessageParam` ist dieselbe Union seiner drei Typen. Nur die Typen haben sich geändert. Ein Nachrichten-Literal, das seine Rolle angibt, etwa `{ role: "user", content: "Hello, Claude" }`, besteht die Typprüfung wie zuvor, daher muss der meiste Code nicht geändert werden.

    Der System-Typ unterscheidet sich von den anderen beiden. Sein `content` ist ein String oder Text-Blöcke, in `beta` zusätzlich `tool_addition`- und `tool_removal`-Blöcke, daher kompiliert ein Image-Block dort nicht mehr. In `beta` hat nur er `clear_at` und `output_config`, und sein `content` ist optional.

    Code, der eine Nachricht beliebiger Rolle verarbeitet, muss `role` prüfen, bevor er Content-Blöcke ersetzt oder hinzufügt und bevor er `clear_at` oder `output_config` liest:

    ```typescript
    // Vorher
    const copy: Anthropic.MessageParam = { ...message, content: blocks };

    // Nachher
    const copy: Anthropic.MessageParam =
      message.role === "system" ? message : { ...message, content: blocks };
    ```

    Der `content` eines `BetaMessageParam` kann `undefined` sein:

    ```typescript
    // Vorher
    const types =
      typeof message.content === "string" ? [] : message.content.map((block) => block.type);

    // Nachher
    const types = Array.isArray(message.content) ? message.content.map((block) => block.type) : [];
    ```

    Der Typ `BetaMessageParam["content"]` enthält ebenfalls `undefined`. Verwende für den Content einer User- oder Assistant-Nachricht `BetaMessageContentParam`.

    Ein Interface kann keine Union erweitern, und eine Klasse kann keine implementieren. Verwende einen Type-Alias oder gib stattdessen den Typ einer Rolle an.

    ```typescript
    // Vorher
    interface StoredMessage extends Anthropic.MessageParam {
      id: string;
    }

    // Nachher
    type StoredMessage = Anthropic.MessageParam & { id: string };
    ```
  </Tab>

  <Tab title="C#">
    In v12 waren `MessageParam` und `BetaMessageParam` Klassen, deren `Role` und `Content` du gesetzt hast. In v13 ist jede eine Union der drei Klassen für ihre Rollen, und die `Role`-Enums in `Anthropic.Models.Messages` und `Anthropic.Models.Beta.Messages` sind entfallen.

    Wenn du eine Nachricht erstellst, gib die Klasse für ihre Rolle an und lösche `Role`. Jede Klasse wird implizit in die Union konvertiert:

    ```csharp
    // Vorher
    Messages = [new() { Role = Role.User, Content = "Hello, Claude" }],

    // Nachher
    Messages = [new UserMessageParam { Content = "Hello, Claude" }],
    ```

    `new UserMessageParam("Hello, Claude")` funktioniert ebenfalls.

    Auch die Klassen, die `Content` enthalten, ändern sich:

    * `MessageParamContent` ist jetzt `MessageContentParam`, und `BetaMessageParamContent` ist jetzt `BetaMessageContentParam`.
    * Eine System-Nachricht hat eine eigene Content-Klasse. Ein `SystemMessageParamContent` enthält einen String oder eine Liste von `TextBlockParam`, und ein `BetaSystemMessageParamContent` enthält einen String oder eine Liste von `SystemMessageContentBlock`. Eine `List<ContentBlockParam>` oder eine `List<BetaContentBlockParam>` wird nicht mehr in sie konvertiert.
    * `ClearAt` und `OutputConfig` gibt es nur bei `BetaSystemMessageParam`.

    Wenn du eine Nachricht liest, hat die Union weiterhin `Role` und `Content`, aber du kannst sie nicht setzen, daher gehört ein `with`-Ausdruck an die Klasse für die Rolle. `Role` enthält jetzt eine `MessageParamRole` oder eine `BetaMessageParamRole`. `BetaMessageParam.Content` kann `null` sein, weil `Content` bei `BetaSystemMessageParam` optional ist.

    ```csharp
    // Vorher
    if (message.Role.Value() == Role.Assistant) { }

    // Nachher
    if (message.Role.Value() == MessageParamRole.Assistant) { }
    ```

    `TryPickUser`, `TryPickAssistant`, `TryPickSystem`, `Switch` und `Match` liefern dir die Klasse für die Rolle.
  </Tab>

  <Tab title="Go">
    In v1 war `MessageParam` ein einzelnes Struct mit einem `Role`- und einem `Content`-Feld. In v2 ist es eine Union: `OfUser` enthält einen `*UserMessageParam`, `OfAssistant` einen `*AssistantMessageParam` und `OfSystem` einen `*SystemMessageParam`. `BetaMessageParam` ändert sich auf dieselbe Weise. Das SDK sendet dasselbe JSON wie zuvor, abgesehen von der Reihenfolge der Schlüssel in einer Beta-System-Nachricht.

    `NewUserMessage`, `NewAssistantMessage`, `NewBetaUserMessage` und die `ToParam`-Methoden von `Message` und `BetaMessage` funktionieren wie zuvor, daher muss Code, der seine Nachrichten damit erstellt, nicht geändert werden.

    Ein Struct-Literal gibt den Typ für seine Rolle an. Lass `Role` weg, weil jeder Typ seine eigene marshalt:

    ```go
    // Vorher
    anthropic.MessageParam{
    	Role:    anthropic.MessageParamRoleAssistant,
    	Content: blocks,
    }

    // Nachher
    anthropic.MessageParam{OfAssistant: &anthropic.AssistantMessageParam{
    	Content: blocks,
    }}
    ```

    Code, der eine Nachricht liest, prüft, welches Feld gesetzt ist:

    ```go
    // Vorher
    if message.Role == anthropic.MessageParamRoleUser {
    	blocks = message.Content
    }

    // Nachher
    if message.OfUser != nil {
    	blocks = message.OfUser.Content
    }
    ```

    * Die Typen `MessageParamRole` und `BetaMessageParamRole` und ihre Konstanten sind entfallen. `message.GetRole()` gibt einen Pointer auf die Rolle als `string` zurück oder `nil`, wenn kein Feld gesetzt ist.
    * `ClearAt` und `OutputConfig` wurden von `BetaMessageParam` nach `BetaSystemMessageParam` verschoben. Die Namen des Typs `BetaMessageParamClearAt` und seiner Konstanten beginnen jetzt mit `BetaSystemMessageParamClearAt`.
    * `SystemMessageParam.Content` ist ein `[]TextBlockParam`. `BetaSystemMessageParam.Content` ist ein `[]BetaSystemMessageParamContentUnion`, das `text`-, `tool_addition`- und `tool_removal`-Blöcke enthält. `NewBetaSystemMessage` nimmt Blöcke dieses Typs entgegen, daher wird `anthropic.NewBetaTextBlock("Be brief.")` zu `anthropic.BetaSystemMessageParamContentUnion{OfText: &anthropic.BetaTextBlockParam{Text: "Be brief."}}`.
    * Eine Kopie eines `MessageParam` zeigt auf dieselbe Nachricht wie das Original. Das Setzen von `duplicate.OfUser.Content` ändert beide, während das Setzen von `duplicate.Content` in v1 nur die Kopie geändert hat.
    * `mcp.ToMessage` gibt für eine andere Rolle als `user` oder `assistant` einen `*mcp.UnsupportedValueError` zurück. v1 hat jede Rolle in die Nachricht kopiert.
  </Tab>

  <Tab title="Java">
    In v2 war `MessageParam` eine einzelne Klasse mit einer `role` und einem `content`. In v3 ist es eine Union der drei Klassen, und `MessageParam.Content` ist jetzt das Top-Level-`MessageContentParam`. `BetaMessageParam` ändert sich auf dieselbe Weise, und seine Klassen haben dieselben Namen mit einem `Beta`-Präfix. Das JSON, das das SDK sendet, ist dasselbe, außer dass eine Beta-System-Nachricht jetzt `role` vor `content` hat.

    `addUserMessage`, `addAssistantMessage` und `addSystemMessage` mit einem `String`, `addMessage` mit einer `Message` oder einem `MessageParam` sowie `Message.toParam()` ändern sich nicht.

    `MessageParam.builder()` und `toBuilder()` sind entfallen. Rufe die Factory-Methode für die Rolle auf, also `ofUser`, `ofAssistant` oder `ofSystem`:

    ```java
    // Vorher
    MessageParam message = MessageParam.builder()
        .role(MessageParam.Role.USER)
        .content("Hello, Claude")
        .build();

    // Nachher
    MessageParam message = MessageParam.ofUser("Hello, Claude");
    ```

    Die Methoden, die eine Liste von Content-Blöcken entgegennehmen, haben neue Namen in den Buildern von `MessageCreateParams`, `StructuredMessageCreateParams`, `MessageCountTokensParams` und `BatchCreateParams.Request.Params`:

    | v2                                 | v2 beta                                       | v3                                        |
    | ---------------------------------- | --------------------------------------------- | ----------------------------------------- |
    | `addUserMessageOfBlockParams`      | `addUserMessageOfBetaContentBlockParams`      | `addUserMessageOfContentBlockParams`      |
    | `addAssistantMessageOfBlockParams` | `addAssistantMessageOfBetaContentBlockParams` | `addAssistantMessageOfContentBlockParams` |
    | `addSystemMessageOfBlockParams`    | `addSystemMessageOfBetaContentBlockParams`    | `addSystemMessageOfBlocks`                |

    In der Content-Klasse wird `BlockParams` (`BetaContentBlockParams` in Beta) zu `ContentBlockParams` in `ofBlockParams`, `blockParams()`, `isBlockParams()`, `asBlockParams()` und im `visitBlockParams` des Visitors.

    Eine System-Nachricht hat ihre eigene Content-Klasse, `SystemMessageParam.Content`, die `addSystemMessage` jetzt entgegennimmt. Ihre Blöcke sind `TextBlockParam`, nicht `ContentBlockParam`. In Beta sind sie `BetaSystemMessageParam.Content.SystemMessageContentBlock`, das `ofText`, `ofToolAddition` und `ofToolRemoval` hat.

    ```java
    // Vorher
    builder.addSystemMessageOfBlockParams(List.of(ContentBlockParam.ofText(textBlock)));

    // Nachher
    builder.addSystemMessageOfBlocks(List.of(textBlock));
    ```

    Wenn du eine Nachricht liest, ändert sich `role()` nicht. `content()` gibt ein `MessageContentParam` zurück, oder in Beta ein `Optional<BetaMessageContentParam>`, wo eine System-Nachricht keinen Content haben kann. `_role()`, `_content()` und `_additionalProperties()` befinden sich jetzt in der Klasse für die Rolle, die `asUser()`, `asAssistant()` oder `asSystem()` zurückgibt.
  </Tab>

  <Tab title="PHP">
    Die Klassen befinden sich in `Anthropic\Messages` und die Beta-Klassen in `Anthropic\Beta\Messages`. Nachrichten, die du als Arrays schreibst, ändern sich nicht und benötigen weiterhin ihre `'role'`.

    `MessageParam::with()` und `BetaMessageParam::with()` bleiben erhalten und geben die Klasse zurück, die zu `role` gehört. Ein Aufruf mit benannten Argumenten muss nicht geändert werden. `role` ist jetzt der erste Parameter, also vertausche in einem positionalen Aufruf `content` und `role` oder rufe `with()` an der Klasse der Rolle auf, die kein `role` entgegennimmt. Bei Argumenten in der alten Reihenfolge wirft PHP einen `UnhandledMatchError`, vor dem PHPStan nicht warnt, oder einen `TypeError`, wenn `content` eine Liste oder `role` ein Enum-Case ist.

    ```php
    // Vorher
    MessageParam::with('Hello, Claude', 'user');

    // Nachher
    UserMessageParam::with('Hello, Claude');
    ```

    Kein Objekt ist mehr ein `MessageParam`: `instanceof MessageParam` ist false, und PHP wirft einen `TypeError`, wo ein Parameter- oder Rückgabetyp ihn angibt. Gib stattdessen die drei Klassen an:

    ```php
    // Vorher
    function send(MessageParam $message): void {}

    // Nachher
    function send(UserMessageParam|AssistantMessageParam|SystemMessageParam $message): void {}
    ```

    * `MessageParam::fromArray()` und `(new MessageParam)->withContent()` werfen „Call to undefined method". Rufe sie an der Klasse der Rolle auf, die `role` selbst setzt.
    * `withRole()` nimmt jetzt nur noch den String entgegen: PHP wirft einen `TypeError` für einen `Role`-Case. Um einer Nachricht eine andere Rolle zu geben, erstelle die Klasse dieser Rolle.
    * `clearAt` und `outputConfig` existieren nur bei `BetaSystemMessageParam`, und `BetaMessageParam::with()` verwirft sie für die anderen beiden Rollen. Das Enum `BetaMessageParam\ClearAt` ist jetzt `BetaSystemMessageParam\ClearAt`.
    * `MessageParam\Content` ist jetzt `MessageContentParam`, und `BetaMessageParam\Content` ist jetzt `BetaMessageContentParam`. Ihre PHPStan-Typen übernehmen ebenfalls den neuen Namen: `ContentShape` ist jetzt `MessageContentParamShape`.
    * Ein Array, dessen `'role'` ein `Role`-Case ist, funktioniert weiterhin, aber PHPStan meldet es jetzt. Schreibe den String.
  </Tab>

  <Tab title="Ruby">
    Nachrichten, die du als Hashes schreibst, ändern sich nicht.

    In v2 ist `Anthropic::MessageParam` eine Union aus `Anthropic::UserMessageParam`, `Anthropic::AssistantMessageParam` und `Anthropic::SystemMessageParam`. Auf dieselbe Weise ist `Anthropic::Beta::BetaMessageParam` eine Union seiner drei Klassen.

    `Anthropic::MessageParam.new(role: :user, content: "Hello, Claude")` funktioniert weiterhin und gibt eine Instanz der Klasse für diese Rolle zurück. Du kannst diese Klasse auch selbst erstellen, ohne `role:`, als `Anthropic::UserMessageParam.new(content: "Hello, Claude")`. Vier Dinge ändern sich für Code, der diese Instanzen erstellt oder untersucht:

    * `MessageParam.new` nimmt nur Keywords entgegen, also übergib einen Hash als `MessageParam.new(**hash)`. Es löst einen `ArgumentError` aus, wenn `role:` fehlt oder keine der drei Rollen ist.
    * `message.is_a?(Anthropic::MessageParam)` ist `false`. Ein `when Anthropic::MessageParam`-Zweig und `messages.grep(Anthropic::MessageParam)` passen weiterhin.
    * Eine mit `.new` erstellte Instanz hat kein `:role` in ihrem `to_h`, und `message[:role]` ist `nil`. `message.role` gibt weiterhin die Rolle zurück.
    * Nur `BetaSystemMessageParam` hat `clear_at` und `output_config`. Bei einer User- oder Assistant-Nachricht gaben sie `nil` zurück und lösen jetzt einen `NoMethodError` aus.

    ```ruby
    # Vorher
    typed = messages.select { _1.is_a?(Anthropic::MessageParam) }
    roles = typed.map { _1[:role] }

    # Nachher
    typed = messages.grep(Anthropic::MessageParam)
    roles = typed.map(&:role)
    ```

    Die `Role`-Enum-Module bleiben. Diese Konstanten wurden verschoben. Die Namen, die mit `Beta` beginnen, befinden sich unter `Anthropic::Beta`, die anderen unter `Anthropic`:

    | Entfernt                    | Stattdessen verwenden                                                                      |
    | --------------------------- | ------------------------------------------------------------------------------------------ |
    | `MessageParam::Content`     | `MessageContentParam` oder `SystemMessageParam::Content` für eine System-Nachricht         |
    | `BetaMessageParam::Content` | `BetaMessageContentParam` oder `BetaSystemMessageParam::Content` für eine System-Nachricht |
    | `BetaMessageParam::ClearAt` | `BetaSystemMessageParam::ClearAt`                                                          |

    Wenn du mit Sorbet typprüfst, ist `MessageParam::OrHash` entfallen, und `Anthropic::MessageParam` als Typ akzeptiert keine Instanz mehr. Verwende `Anthropic::MessageParam::Variants` für die drei Klassen, von denen jede ihr eigenes `OrHash` hat. In RBS hat ein als `Anthropic::MessageParam` typisierter Wert kein `role` oder `content`. Verwende den Alias `Anthropic::Models::message_param`, der die Hash-Form einer Nachricht war und jetzt die Union der drei Klassen ist. Die Beta-Namen sind `BetaMessageParam::Variants` und `Anthropic::Models::Beta::beta_message_param`.
  </Tab>
</Tabs>

### Enums mit nur einem Wert sind Konstanten

Dies betrifft die C#-, Go-, Java-, PHP- und Ruby-SDKs sowie ein CLI-Flag. In früheren Versionen hatte ein Pflichtfeld, das nur einen einzigen Wert annehmen kann, einen eigenen Enum-Typ mit einem einzigen Member. Diese Felder sind jetzt Konstanten, und die Enum-Typen sind entfallen. Das JSON, das das SDK sendet und liest, ist dasselbe.

<Tabs exclude="shell:cURL, python, typescript">
  <Tab title="CLI">
    `--type` ist bei `ant beta:sessions:resources add` optional. `file` ist der einzige Wert, den `--type` dort annehmen kann, daher sendet v2 ihn für dich. Befehle, die weiterhin `--type file` übergeben, funktionieren weiter, du musst also nichts ändern.
  </Tab>

  <Tab title="C#">
    In v12 hatte eine solche `required`-Property ein Enum mit einem einzigen Member, etwa `BetaManagedAgentsTextBlockType.Text`. Fast alle davon sind die `Type`-Property einer Klasse unter `Anthropic.Models.Beta`: `Agents`, `DeploymentRuns`, `Deployments`, `Dreams`, `Environments`, `MemoryStores`, `Sessions`, `UserProfiles` und `Vaults`. In v13 sind diese Properties ein `JsonElement`, das der Konstruktor befüllt, so wie es `TextBlockParam.Type` bereits war.

    Eine optionale Property, etwa `BetaManagedAgentsGlobToolConfigParams.Type`, behält ihr Enum. Zwei dieser Enums haben einen neuen Namen:

    | v12                                         | v13                                       |
    | ------------------------------------------- | ----------------------------------------- |
    | `BetaManagedAgentsBashToolConfigParamsType` | `Anthropic.Models.Beta.Agents.Type`       |
    | `BetaPackagesType`                          | `Anthropic.Models.Beta.Environments.Type` |

    Wenn du ein Objekt erstellst, lösche die Property:

    ```csharp
    // Vorher
    new BetaManagedAgentsTextBlock
    {
        Type = BetaManagedAgentsTextBlockType.Text,
        Text = "Hello Claude!",
    };

    // Nachher
    new BetaManagedAgentsTextBlock { Text = "Hello Claude!" };
    ```

    Eine Klasse, der eine einzige Pflicht-Property bleibt, erhält außerdem einen Konstruktor, der diese entgegennimmt, sodass auch `new BetaManagedAgentsTextBlock("Hello Claude!")` funktioniert. Eine Klasse, der keine bleibt, wird mit `new BetaManagedAgentsAlwaysAllowPolicy()` erstellt.

    Wenn du eine solche Property liest, vergleiche mit dem String:

    ```csharp
    // Vorher
    if (message.Type.Value() == BetaManagedAgentsAgentMessageEventType.AgentMessage) { }

    // Nachher
    if (message.Type.GetString() == "agent.message") { }
    ```

    Um die Varianten einer Union zu unterscheiden, verwende weiterhin ihre Methoden `TryPick*`, `Switch` und `Match`, die sich nicht ändern.
  </Tab>

  <Tab title="Go">
    Ein Beispiel für einen solchen Enum-Typ und seine Konstante ist `BetaManagedAgentsTextBlockType` und `BetaManagedAgentsTextBlockTypeText`. Fast alle davon sind das `Type`-Feld eines Structs unter `client.Beta`: Agents, Deployments, Deployment Runs, Dreams, Environments, Memory Stores, Sessions, User Profiles und Vaults. In v2 verwenden diese Felder einen Typ aus dem Paket `shared/constant`, so wie es `TextBlockParam.Type` bereits tat. Ein optionales Feld, etwa `BetaManagedAgentsBashToolConfigParams.Type`, behält sein Enum.

    Lösche das Feld in einem Request. Es wird als sein einziger Wert gemarshallt, wenn du es weglässt:

    ```go
    // Vorher
    anthropic.BetaManagedAgentsTextBlockParam{
    	Type: anthropic.BetaManagedAgentsTextBlockTypeText,
    	Text: "Hello Claude!",
    }

    // Nachher
    anthropic.BetaManagedAgentsTextBlockParam{
    	Text: "Hello Claude!",
    }
    ```

    Ein Struct, dessen einziges Feld dieses `Type` war, hat jetzt einen Konstruktor, etwa `NewBetaManagedAgentsAlwaysAllowPolicyParam()`. Als Union-Member funktioniert auch ein Pointer auf das leere Struct: `OfAlwaysAllow: &anthropic.BetaManagedAgentsAlwaysAllowPolicyParam{}`.

    Vergleiche in einer Response mit dem String:

    ```go
    // Vorher
    switch event.Type {
    case string(anthropic.BetaManagedAgentsAgentMessageEventTypeAgentMessage):
    }

    // Nachher
    switch event.Type {
    case "agent.message":
    }
    ```

    Eine eigene Variable, ein eigenes Feld oder ein eigener Parameter, die mit einem der entfernten Typen deklariert wurden, übernehmen den neuen Typ des Feldes, etwa `constant.AgentMessage`. `constant.ValueOf[constant.AgentMessage]()` gibt dessen Wert zurück.

    Die Union-Konstruktoren ändern sich mit den Feldern. Diese fünf verlieren ihr `type_`-Argument:

    * `BetaManagedAgentsEventParamsOfUserToolConfirmation`
    * `BetaManagedAgentsEventParamsOfUserDefineOutcome`
    * `BetaManagedAgentsDeploymentInitialEventParamsOfUserDefineOutcome`
    * `BetaManagedAgentsMultiagentRosterEntryParamsOfBetaManagedAgentsAgents`
    * `BetaManagedAgentsMultiagentRosterEntryParamsOfBetaManagedAgentsAdvisors`

    Diese vier nahmen kein anderes Argument entgegen und sind daher entfallen. Setze das Feld der Union auf einen Pointer auf das leere Struct, etwa `BetaManagedAgentsEventParamsUnion{OfUserInterrupt: &anthropic.BetaManagedAgentsUserInterruptEventParams{}}`:

    * `BetaManagedAgentsEventParamsOfUserInterrupt`
    * `BetaManagedAgentsMultiagentRosterEntryParamsOfBetaManagedAgentsMultiagentSelfs`
    * `BetaManagedAgentsCredentialNetworkingParamsOfUnrestricted`
    * `BetaOutputBehaviorParamOfCreateNew`
  </Tab>

  <Tab title="Java">
    Ein Beispiel für ein solches Enum ist die verschachtelte Klasse `BetaManagedAgentsTextBlock.Type` mit ihrem einzigen Member `TEXT`. Fast alle davon sind das `type` einer Klasse unter `com.anthropic.models.beta`: `agents`, `deploymentruns`, `deployments`, `dreams`, `environments`, `memorystores`, `sessions`, `userprofiles` und `vaults`. In v3 sind diese Felder ein `JsonValue`, das der Builder befüllt, so wie es das von `TextBlockParam` bereits war. Ein optionales Feld, etwa das `type` von `BetaManagedAgentsBashToolConfigParams`, behält sein Enum.

    Wenn du ein Objekt erstellst, lösche den Aufruf:

    ```java
    // Vorher
    BetaManagedAgentsTextBlock block = BetaManagedAgentsTextBlock.builder()
        .type(BetaManagedAgentsTextBlock.Type.TEXT)
        .text("Hello Claude!")
        .build();

    // Nachher
    BetaManagedAgentsTextBlock block = BetaManagedAgentsTextBlock.builder()
        .text("Hello Claude!")
        .build();
    ```

    Eine Klasse, der ein einziges Pflichtfeld bleibt, erhält außerdem eine Factory-Methode, die dieses entgegennimmt, sodass auch `BetaManagedAgentsTextBlock.of("Hello Claude!")` funktioniert. Eine Klasse, der keines bleibt, verliert `of(type)`, und ihre Unions verlieren die Überladung, die das Enum entgegennahm, etwa `ofAlwaysAllow(type)`. Erstelle sie mit `BetaManagedAgentsAlwaysAllowPolicy.builder().build()`.

    Wenn du ein solches Feld liest, ist `type()` entfallen, und `_type()` gibt den `com.anthropic.core.JsonValue` zurück:

    ```java
    // Vorher
    if (message.type().equals(BetaManagedAgentsAgentMessageEvent.Type.AGENT_MESSAGE)) {}

    // Nachher
    if (message._type().equals(JsonValue.from("agent.message"))) {}
    ```

    Um die Varianten einer Union zu unterscheiden, verwende weiterhin ihre Methoden `is*()` und `as*()` sowie ihren Visitor, die sich nicht ändern.
  </Tab>

  <Tab title="PHP">
    Ein Beispiel für einen solchen Enum-Case ist `Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock\Type::TEXT`. Fast alle davon sind das `type` einer Managed-Agents-Klasse unter `Anthropic\Beta`. Diese Properties sind jetzt ein String mit diesem einen Wert als Standardwert, so wie es das `type` von `Anthropic\Messages\TextBlockParam` bereits war. Eine optionale Property, etwa das `type` von `Anthropic\Beta\Environments\BetaPackages`, behält ihr Enum.

    `with()` nimmt kein `type` mehr entgegen. Entferne es: PHP wirft „Unknown named parameter" für ein übrig gebliebenes `type:`, und bei einem positionalen Aufruf rücken die nachfolgenden Argumente um eine Stelle nach vorne.

    ```php
    // Vorher
    ManagedAgentsTextBlock::with(text: 'Hello Claude!', type: Type::TEXT);

    // Nachher
    ManagedAgentsTextBlock::with(text: 'Hello Claude!');
    ```

    Wo du mit einem Enum-Case verglichen hast, vergleiche mit dem String:

    ```php
    // Vorher
    $event->type === Type::AGENT_MESSAGE->value;

    // Nachher
    $event->type === 'agent.message';
    ```

    * `withType()` und das `type`-Argument von `$client->beta->sessions->resources->add()` nehmen jetzt nur noch den String entgegen. In `add()` ist der Standardwert `'file'`, du kannst es also weglassen.
    * Requests, die du als Arrays schreibst, ändern sich nicht und benötigen weiterhin ihr `'type'`.
  </Tab>

  <Tab title="Ruby">
    Ein Beispiel für eine solche Enum-Konstante ist `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock::Type::TEXT`. Fast alle davon sind das `type` einer Managed-Agents-Klasse unter `Anthropic::Beta`. In v2 sind diese Felder als Konstante deklariert, so wie es das `type` von `Anthropic::TextBlockParam` bereits war. Ein optionales Feld, etwa das `type` von `Anthropic::Beta::BetaManagedAgentsGlobToolConfigParams`, behält sein Enum.

    Ersetze eine entfernte Konstante durch ihr Symbol:

    ```ruby
    # Vorher
    event.type == Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent::Type::AGENT_MESSAGE

    # Nachher
    event.type == :"agent.message"
    ```

    Requests, die du als Hashes schreibst, ändern sich nicht und benötigen weiterhin ihr `type`:

    ```ruby
    client.beta.sessions.events.send_(
      session.id,
      events: [{type: "user.message", content: [{type: "text", text: "Hello Claude!"}]}]
    )
    ```

    Wenn du eine Modellinstanz erstellst, hat `type:` jetzt einen Standardwert, du kannst es also weglassen: `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock.new(text: "Hello Claude!")`. Dasselbe gilt für das Keyword `type:` von `client.beta.sessions.resources.add`.

    Wenn du mit Sorbet Typprüfungen durchführst, sind die Aliase `Type::OrSymbol` und `Type::TaggedSymbol` dieser Module mit ihnen entfallen, und die Felder sind ein `Symbol`. `OrSymbol` erlaubte auch einen `String`, daher besteht `.new(type: "text")` die Typprüfung nicht mehr. Lass das Keyword weg oder übergib `:text`. In RBS ist der Alias `type_` jeder Klasse entfallen, und das Feld ist das Literal, etwa `:text`.
  </Tab>
</Tabs>

### Clientseitige Compaction wurde aus dem Tool-Runner entfernt

Dies betrifft die TypeScript- und Ruby-SDKs. Die clientseitige „compaction" (Komprimierung) im Tool-Runner wurde zugunsten der serverseitigen Compaction entfernt, die die Konversation innerhalb der API zusammenfasst statt mit einem zusätzlichen Request vom Client.

<Tabs exclude="shell, python, csharp, go, java, php">
  <Tab title="TypeScript">
    Die Option `compactionControl` und das Modul `@anthropic-ai/sdk/lib/tools/CompactionControl` sind entfallen. Die Option funktionierte seit v0.129.0 nicht mehr; dort warf ihre Übergabe einen `AnthropicError`. Sie ist nicht im Params-Typ enthalten, daher meldet TypeScript sie als unbekannte Property.

    Um weiterhin automatisch bei einem Token-Schwellenwert zu komprimieren:

    ```typescript
    // Vorher
    const runner = client.beta.messages.toolRunner({
      // ...
      compactionControl: { enabled: true, contextTokenThreshold: 100_000 }
    });

    // Nachher
    const runner = client.beta.messages.toolRunner({
      // ...
      betas: ["compact-2026-01-12"],
      context_management: {
        edits: [{ type: "compact_20260112", trigger: { type: "input_tokens", value: 100_000 } }]
      }
    });
    ```

    Um selbst zu entscheiden, wann die Konversation komprimiert wird, rufe [`runner.compactBeforeNextTurn()`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/helpers.md#compaction) auf.
  </Tab>

  <Tab title="Ruby">
    Die Option `compaction_control:` ist entfallen. Sie funktionierte seit v1.74.0 nicht mehr; dort löste ihre Übergabe einen `ArgumentError` aus.

    Um weiterhin automatisch bei einem Token-Schwellenwert zu komprimieren:

    ```ruby
    # Vorher
    runner = client.beta.messages.tool_runner(
      # ...
      compaction_control: {enabled: true, context_token_threshold: 100_000}
    )

    # Nachher
    runner = client.beta.messages.tool_runner(
      # ...
      betas: ["compact-2026-01-12"],
      context_management: {
        edits: [{type: :compact_20260112, trigger: {type: :input_tokens, value: 100_000}}]
      }
    )
    ```

    Um selbst zu entscheiden, wann die Konversation komprimiert wird, rufe [`#compact_before_next_turn`](https://github.com/anthropics/anthropic-sdk-ruby/blob/main/helpers.md#compact_before_next_turn---compact-the-conversation) auf dem Runner auf.
  </Tab>
</Tabs>

Der Auslöse-Schwellenwert muss mindestens 50.000 Token betragen. Siehe [Compaction](https://platform.claude.com/docs/de/build-with-claude/compaction-threshold) für die weiteren Optionen (`pause_after_compaction`, benutzerdefinierte `instructions`).

### Text Completions wurde entfernt

Die veraltete Text Completions API wurde aus den TypeScript-, Go-, Java- und Ruby-SDKs sowie aus der CLI entfernt. Neuere Modelle und Funktionen unterstützen sie nicht. Verwende stattdessen die [Messages API](https://platform.claude.com/docs/de/api/messages).

<Tabs exclude="shell:cURL, python, csharp, php">
  <Tab title="CLI">
    Der Befehl `ant completions create` ist entfallen.

    ```bash
    # Vorher
    ant completions create \
      --model "$MODEL" \
      --max-tokens-to-sample 1024 \
      --prompt $'\n\nHuman: Hello, Claude\n\nAssistant:'

    # Nachher
    ant messages create \
      --model "$MODEL" \
      --max-tokens 1024 \
      --message '{role: user, content: "Hello, Claude"}'
    ```

    Der Antworttext wandert vom Feld `completion` nach `content.0.text`, daher übergibt ein Skript, das `--transform completion` übergeben hat, stattdessen `--transform content.0.text`.

    `ant messages create` nimmt ebenfalls `--stream` entgegen, aber seine Events haben eine andere Form: Der Text kommt in `delta.text` von `content_block_delta`-Events an, daher gilt `--transform content.0.text` nicht für einen Stream.
  </Tab>

  <Tab title="TypeScript">
    `client.completions` ist entfallen, zusammen mit der Ressourcenklasse `Completions` und den Typen `Completion`, `CompletionCreateParams`, `CompletionCreateParamsNonStreaming` und `CompletionCreateParamsStreaming`. `AnthropicBedrock` hat ebenfalls keine `completions`-Property mehr. Die Konstanten `HUMAN_PROMPT` und `AI_PROMPT`, die nur von Text-Completions-Prompts verwendet wurden, sind ebenfalls entfallen, sowohl als Exporte als auch als statische Properties des Clients.

    ```typescript
    // Vorher
    const completion = await client.completions.create({
      model,
      max_tokens_to_sample: 1024,
      prompt: "\n\nHuman: Hello, Claude\n\nAssistant:"
    });
    console.log(completion.completion);

    // Nachher
    const message = await client.messages.create({
      model,
      max_tokens: 1024,
      messages: [{ role: "user", content: "Hello, Claude" }]
    });
    console.log(message.content);
    ```

    `client.completions.create({ ..., stream: true })` wird zu `client.messages.create({ ..., stream: true })` oder `client.messages.stream({ ... })`.
  </Tab>

  <Tab title="Go">
    `client.Completions` ist entfallen, zusammen mit `CompletionService`, `NewCompletionService`, `CompletionNewParams` und `Completion`. `aws.Client` hat ebenfalls kein `Completions`-Feld mehr. `bedrock.DefaultEndpoints` listet `/v1/complete` nicht mehr auf.

    ```go
    // Vorher
    completion, err := client.Completions.New(ctx, anthropic.CompletionNewParams{
    	Model:             model,
    	MaxTokensToSample: 1024,
    	Prompt:            "\n\nHuman: Hello, Claude\n\nAssistant:",
    })
    fmt.Println(completion.Completion)

    // Nachher
    message, err := client.Messages.New(ctx, anthropic.MessageNewParams{
    	Model:     model,
    	MaxTokens: 1024,
    	Messages: []anthropic.MessageParam{
    		anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Claude")),
    	},
    })
    fmt.Println(message.Content[0].Text)
    ```

    `client.Completions.NewStreaming` wird zu `client.Messages.NewStreaming`.
  </Tab>

  <Tab title="Java">
    `client.completions()` ist aus `AnthropicClient` und `AnthropicClientAsync` entfallen, zusammen mit `CompletionService`, `CompletionServiceAsync` und dem Paket `com.anthropic.models.completions` (`CompletionCreateParams` und `Completion`).

    ```java
    // Vorher
    CompletionCreateParams params = CompletionCreateParams.builder()
        .model(model)
        .maxTokensToSample(1024)
        .prompt("\n\nHuman: Hello, Claude\n\nAssistant:")
        .build();

    System.out.println(client.completions().create(params).completion());

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

    client.messages().create(params).content().stream()
        .flatMap(contentBlock -> contentBlock.text().stream())
        .forEach(textBlock -> System.out.println(textBlock.text()));
    ```

    `client.completions().createStreaming` wird zu `client.messages().createStreaming`.
  </Tab>

  <Tab title="Ruby">
    `client.completions` ist entfallen, zusammen mit `Anthropic::Resources::Completions`, `Anthropic::CompletionCreateParams` und `Anthropic::Completion`. `Anthropic::BedrockClient` hat ebenfalls keinen `completions`-Reader mehr. Bei `Anthropic::BedrockMantleClient` und `Anthropic::GoogleCloudClient`, wo `completions` einen `NotImplementedError` auslöste, existiert die Methode nicht mehr.

    ```ruby
    # Vorher
    completion = client.completions.create(
      model: model,
      max_tokens_to_sample: 1024,
      prompt: "\n\nHuman: Hello, Claude\n\nAssistant:"
    )
    puts(completion.completion)

    # Nachher
    message = client.messages.create(
      model: model,
      max_tokens: 1024,
      messages: [{role: "user", content: "Hello, Claude"}]
    )
    puts(message.content)
    ```

    `client.completions.create_streaming` wird zu `client.messages.stream`.
  </Tab>
</Tabs>

### `betas` wurde aus den Nicht-Beta-Models-Methoden entfernt

Die Nicht-Beta-Models-Methoden nehmen kein `betas` (csharp, go: `Betas`; java: `.addBeta()`) mehr entgegen, und die `ant models`-Befehle nehmen kein `--beta` mehr entgegen. Um Beta-Header zu senden, rufe dieselben Methoden auf `client.beta.models` (csharp, go: `client.Beta.Models`; java: `client.beta().models()`; php: `$client->beta->models`) auf, oder `ant beta:models` in der CLI. Im SDK geben diese Methoden `BetaModelInfo` (ruby: `Anthropic::Beta::BetaModelInfo`) zurück, wo die Nicht-Beta-Methoden `ModelInfo` (ruby: `Anthropic::ModelInfo`) zurückgeben.

<Tabs exclude="shell:cURL">
  <Tab title="CLI">
    ```bash
    # Vorher
    ant models list --beta "$BETA"

    # Nachher
    ant beta:models list --beta "$BETA"
    ```
  </Tab>

  <Tab title="Python">
    `client.models.retrieve()` und `client.models.list()` nehmen kein `betas` mehr entgegen (die Übergabe führt zu einem `TypeError`, und ein Type-Checker markiert sie), und `anthropic.types.ModelListParams` hat keinen `betas`-Schlüssel mehr.

    ```python
    # Vorher
    page = client.models.list(betas=[beta])

    # Nachher
    page = client.beta.models.list(betas=[beta])
    ```
  </Tab>

  <Tab title="TypeScript">
    `Anthropic.ModelRetrieveParams` und `Anthropic.ModelListParams` haben keine `betas`-Property mehr.

    ```typescript
    // Vorher
    const page = await client.models.list({ betas: [beta] });

    // Nachher
    const page = await client.beta.models.list({ betas: [beta] });
    ```
  </Tab>

  <Tab title="C#">
    `ModelRetrieveParams` und `ModelListParams` in `Anthropic.Models.Models` haben keine `Betas`-Property mehr. Die Methoden auf `client.Beta.Models` nehmen die gleichnamigen Klassen in `Anthropic.Models.Beta.Models` entgegen.

    ```csharp
    // Vorher
    using Anthropic.Models.Models;

    var page = await client.Models.List(new ModelListParams { Betas = [beta] });

    // Nachher
    using Anthropic.Models.Beta.Models;

    var page = await client.Beta.Models.List(new ModelListParams { Betas = [beta] });
    ```
  </Tab>

  <Tab title="Go">
    `ModelGetParams` und `ModelListParams` haben kein `Betas`-Feld mehr.

    ```go
    // Vorher
    page, err := client.Models.List(ctx, anthropic.ModelListParams{
    	Betas: []anthropic.AnthropicBeta{beta},
    })

    // Nachher
    page, err := client.Beta.Models.List(ctx, anthropic.BetaModelListParams{
    	Betas: []anthropic.AnthropicBeta{beta},
    })
    ```
  </Tab>

  <Tab title="Java">
    `ModelRetrieveParams` und `ModelListParams` in `com.anthropic.models.models` haben kein `betas()` mehr, und ihre Builder haben kein `betas` und `addBeta` mehr. Die Methoden auf `client.beta().models()` nehmen die gleichnamigen Klassen in `com.anthropic.models.beta.models` entgegen.

    ```java
    // Vorher
    import com.anthropic.models.models.ModelListPage;
    import com.anthropic.models.models.ModelListParams;

    ModelListPage page = client.models().list(ModelListParams.builder().addBeta(beta).build());

    // Nachher
    import com.anthropic.models.beta.models.ModelListPage;
    import com.anthropic.models.beta.models.ModelListParams;

    ModelListPage page = client.beta().models().list(ModelListParams.builder().addBeta(beta).build());
    ```
  </Tab>

  <Tab title="PHP">
    `$client->models->retrieve()` und `$client->models->list()` nehmen kein `betas` mehr entgegen (die Übergabe wirft `Error: Unknown named parameter $betas`), und `Anthropic\Models\ModelRetrieveParams` und `Anthropic\Models\ModelListParams` haben keine `betas`-Property mehr.

    ```php
    // Vorher
    $page = $client->models->list(betas: [$beta]);

    // Nachher
    $page = $client->beta->models->list(betas: [$beta]);
    ```

    Wenn du Argumente positional übergibst, rücken `workspaceID` und `requestOptions` in beiden Methoden jeweils um eine Stelle nach vorne.
  </Tab>

  <Tab title="Ruby">
    `client.models.retrieve` und `client.models.list` nehmen kein `betas:` mehr entgegen, und `Anthropic::ModelRetrieveParams` und `Anthropic::ModelListParams` haben kein `betas`-Feld mehr.

    ```ruby
    # Vorher
    page = client.models.list(betas: [beta])

    # Nachher
    page = client.beta.models.list(betas: [beta])
    ```

    Die Übergabe von `betas:` an `client.models` löst keinen Fehler aus, setzt aber den `anthropic-beta`-Header nicht mehr.
  </Tab>
</Tabs>

### API-Keys werden als `Authorization: Bearer` gesendet

Das SDK und die CLI senden deinen API-Key als `Authorization: Bearer <key>` statt im `X-Api-Key`-Header. Ändere daher jeden Proxy oder jedes Gateway, das `X-Api-Key` liest oder setzt, so, dass `Authorization` verwendet wird, oder [sende den Key selbst in `X-Api-Key`](https://platform.claude.com/docs/de/api/migration-2026-10-21#sdk-proxy-x-api-key). Die Claude API akzeptiert einen Key in beiden Headern, daher benötigt ein Programm, das direkt mit der API kommuniziert, keine Änderung.

```text wrap
# Before
X-Api-Key: <key>

# After
Authorization: Bearer <key>
```

<Tabs>
  <Tab title="CLI">
    Dies gilt für einen Key in `ANTHROPIC_API_KEY` und für einen, der per Pipe an `--api-key-stdin` übergeben wird.

    Mit `--debug` zeigt das Request-Log jetzt `Authorization: Bearer <REDACTED>`, wo es zuvor `X-Api-Key: <REDACTED>` zeigte.
  </Tab>

  <Tab title="Python">
    `Authorization` ist der Header, den `auth_token` bereits verwendet.

    Dies gilt für das Argument `api_key` und die Umgebungsvariable `ANTHROPIC_API_KEY` von `Anthropic` und `AsyncAnthropic` sowie für `api_key` und `ANTHROPIC_AWS_API_KEY` von `AnthropicAWS`. `AnthropicFoundry` sendet seinen Key weiterhin als `x-api-key`, und `AnthropicBedrockMantle` sendete bereits ein Bearer-Token.
  </Tab>

  <Tab title="TypeScript">
    `Authorization` ist der Header, den die Option `authToken` bereits verwendet.

    Dies gilt für die Option `apiKey`, die Umgebungsvariable `ANTHROPIC_API_KEY` sowie `apiKey` und `ANTHROPIC_AWS_API_KEY` in `@anthropic-ai/aws-sdk`. `apiKey` in `@anthropic-ai/foundry-sdk` wird weiterhin als `X-Api-Key` gesendet, und `apiKey` in `@anthropic-ai/bedrock-sdk` war bereits ein Bearer-Token.

    Middleware oder ein benutzerdefiniertes `fetch`, das den Key aus dem Request-Header `x-api-key` liest, muss stattdessen `authorization` lesen, wo der Key auf `Bearer `folgt.
  </Tab>

  <Tab title="C#">
    `Authorization` ist der Header, den `AuthToken` bereits verwendet.

    Dies gilt für `ApiKey` auf `AnthropicClient` und `ClientOptions` sowie für die Umgebungsvariable `ANTHROPIC_API_KEY`. Im `Anthropic.Aws`-Release, das von v13 abhängt, gilt es auch für `ApiKey` in `AwsClientOptions` und für `ANTHROPIC_AWS_API_KEY`. `AnthropicFoundryApiKeyCredentials` sendet seinen Key weiterhin als `x-api-key`, und `ApiKey` in `MantleAwsClientOptions` war bereits ein Bearer-Token.
  </Tab>

  <Tab title="Go">
    Dies gilt für `option.WithAPIKey`, die Umgebungsvariable `ANTHROPIC_API_KEY` und `APIKey` in `aws.ClientConfig` (oder `ANTHROPIC_AWS_API_KEY`). `APIKey` in `foundry.ClientConfig` (oder `ANTHROPIC_FOUNDRY_API_KEY`) wird weiterhin als `X-Api-Key` gesendet, und `APIKey` in `bedrock.MantleClientConfig` war bereits ein Bearer-Token.
  </Tab>

  <Tab title="Java">
    `Authorization` ist der Header, den `authToken` bereits verwendet.

    Dies gilt für `apiKey` auf den Buildern `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` und `AnthropicBackend`, die Umgebungsvariable `ANTHROPIC_API_KEY` und die System-Property `anthropic.apiKey`. `apiKey` auf dem `FoundryBackend`-Builder wird weiterhin als `x-api-key` gesendet. `apiKey` auf den Buildern `AwsBackend`, `BedrockBackend` und `BedrockMantleBackend` war bereits ein Bearer-Token.

    Ein Interceptor sieht den Key jetzt in `Authorization` statt in `X-Api-Key`.
  </Tab>

  <Tab title="PHP">
    `Authorization` ist der Header, den `authToken` bereits verwendet.

    Dies gilt für das Argument `apiKey` und die Umgebungsvariable `ANTHROPIC_API_KEY` von `Anthropic\Client` sowie für `apiKey` und `ANTHROPIC_AWS_API_KEY` von `Anthropic\Aws\Client`. `Anthropic\Foundry\Client` sendet seinen Key weiterhin als `x-api-key`, und `Anthropic\Bedrock\MantleClient` sendete bereits ein Bearer-Token.
  </Tab>

  <Tab title="Ruby">
    `Authorization` ist der Header, den `auth_token:` bereits verwendet.

    Dies gilt für das Argument `api_key:` und die Umgebungsvariable `ANTHROPIC_API_KEY` von `Anthropic::Client` sowie für `api_key:` und `ANTHROPIC_AWS_API_KEY` von `Anthropic::AWSClient`. `Anthropic::BedrockMantleClient` sendete bereits ein Bearer-Token.

    Das SDK entfernt `Authorization`, wenn es einer Weiterleitung zu einem anderen Origin folgt, was eine Weiterleitung von `http` zu `https` auf demselben Host einschließt. Der Key wird jetzt auch dort entfernt.
  </Tab>
</Tabs>

#### Wenn ein Proxy oder Gateway `X-Api-Key` liest

<Tabs exclude="shell:cURL">
  <Tab title="CLI">
    Wenn `--base-url` oder `ANTHROPIC_BASE_URL` `ant` auf einen Proxy oder ein Gateway verweist, das `X-Api-Key` liest, ändere es so, dass der Key aus `Authorization` gelesen wird. `ant` hat kein Flag und keine Umgebungsvariable, um einen eigenen Header hinzuzufügen, daher kann es `X-Api-Key` nicht senden.
  </Tab>

  <Tab title="Python">
    Verschiebe den Key mit einer `auth`-Funktion auf dem HTTP-Client zurück. Sie wird bei jedem Request ausgeführt, den der Client sendet, einschließlich Wiederholungen:

    ```python
    import httpx2
    from anthropic import Anthropic, DefaultHttpxClient


    def send_x_api_key(request: httpx2.Request) -> httpx2.Request:
        if request.headers.get("Authorization") == f"Bearer {api_key}":
            del request.headers["Authorization"]
            request.headers["X-Api-Key"] = api_key
        return request


    client = Anthropic(api_key=api_key, http_client=DefaultHttpxClient(auth=send_x_api_key))
    ```

    `AsyncAnthropic` nimmt dieselbe Funktion entgegen, in `http_client=DefaultAsyncHttpxClient(auth=send_x_api_key)`.
  </Tab>

  <Tab title="TypeScript">
    Setze den Header selbst. `Authorization: null` verhindert, dass der Key zusätzlich dort gesendet wird:

    ```typescript
    const client = new Anthropic({
      apiKey,
      defaultHeaders: { "X-Api-Key": apiKey, Authorization: null }
    });
    ```

    Wenn der Proxy die Anmeldedaten hinzufügt und dein Client keine hat, konntest du das in v0 entweder mit `"X-Api-Key": null` oder mit `Authorization: null` in `defaultHeaders` angeben. v1 akzeptiert nur `Authorization: null`.

    Der Environment-Work-Poller und -Worker erhalten ihren eigenen Key, daher lassen sie `X-Api-Key`- und `Authorization`-Standard-Header bei ihren eigenen Requests weg.
  </Tab>

  <Tab title="C#">
    Setze den Header selbst mit `ExtraHeaders`. Wenn du `ApiKey` und `AuthToken` auf `null` setzt, verhinderst du, dass zusätzlich Anmeldedaten aus `ANTHROPIC_API_KEY` oder `ANTHROPIC_AUTH_TOKEN` gesendet werden:

    ```csharp
    AnthropicClient client = new(
        new ClientOptions
        {
            ApiKey = null,
            AuthToken = null,
            ExtraHeaders = new Dictionary<string, string> { ["X-Api-Key"] = apiKey },
        }
    );
    ```
  </Tab>

  <Tab title="Go">
    Setze den Header selbst. `option.WithHeaderDel` verhindert, dass zusätzlich ein Key aus `ANTHROPIC_API_KEY` gesendet wird:

    ```go
    client := anthropic.NewClient(
    	option.WithHeader("X-Api-Key", apiKey),
    	option.WithHeaderDel("Authorization"),
    )
    ```

    `environments.WorkPoller` und `environments.EnvironmentWorker` erhalten ihren eigenen Key, daher lassen sie ein manuell gesetztes `X-Api-Key` bei ihren eigenen Requests weg.
  </Tab>

  <Tab title="Java">
    Setze den Header selbst, statt `apiKey` aufzurufen:

    ```java
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .putHeader("X-Api-Key", apiKey)
        .build();
    ```
  </Tab>

  <Tab title="PHP">
    Verschiebe den Key mit einer Middleware zurück:

    ```php
    use Anthropic\Client;
    use Psr\Http\Message\RequestInterface;
    use Psr\Http\Message\ResponseInterface;

    $sendXApiKey = fn (RequestInterface $request, callable $next): ResponseInterface => $next(
        $request->withoutHeader('Authorization')->withHeader('X-Api-Key', $apiKey)
    );

    $client = new Client(apiKey: $apiKey, requestOptions: ['middleware' => [$sendXApiKey]]);
    ```

    Verwende dafür nicht die `extraHeaders` des Clients. Ein Request mit eigenen `extraHeaders` ersetzt die des Clients, und jeder Endpunkt unter `$client->beta`, der einen Beta-Header benötigt, hat solche.
  </Tab>

  <Tab title="Ruby">
    Verschiebe den Key mit einer Middleware zurück:

    ```ruby
    send_x_api_key = lambda do |req, nxt|
      next nxt.call(req) unless req.headers["authorization"] == "Bearer #{api_key}"
      nxt.call(req.with(headers: {**req.headers.except("authorization"), "x-api-key" => api_key}))
    end

    client = Anthropic::Client.new(api_key: api_key, middleware: send_x_api_key)
    ```

    Die erste Zeile lässt einen Request unverändert, wenn er den Key nicht enthält, etwa einen, der zu einem anderen Origin weitergeleitet wurde.

    `Anthropic::AWSClient` nimmt kein `middleware:`-Argument entgegen. Übergib die Middleware stattdessen mit jedem Request, als `request_options: {middleware: send_x_api_key}`.
  </Tab>
</Tabs>

#### Wenn du `X-Api-Key` bei einem Request gesetzt oder entfernt hast

Dies betrifft die Python-, TypeScript-, Go-, PHP- und Ruby-SDKs.

Wenn du `X-Api-Key` entfernt hast, damit ein Request nur ein Auth-Token sendet, lösche diesen Code, statt ihn zu ändern, denn das Entfernen von `Authorization` würde das Token entfernen. [Ein Client hält genau eine Anmeldeinformation](https://platform.claude.com/docs/de/api/migration-2026-10-21#sdk-one-credential), stelle also sicher, dass es das Token ist: Wenn im Code keine übergeben wird und sowohl `ANTHROPIC_API_KEY` als auch `ANTHROPIC_AUTH_TOKEN` gesetzt sind, verwendet der Client den Key.

<Tabs exclude="shell, csharp, java">
  <Tab title="Python">
    Code, der `extra_headers={"X-Api-Key": omit}` übergibt, um den Key von einem Request fernzuhalten, tut das nicht mehr. Übergib stattdessen `extra_headers={"Authorization": omit}`.

    `extra_headers={"X-Api-Key": other_key}` ersetzt den Key des Clients nicht mehr: Beide Keys werden gesendet. Um mit einem einzelnen Request einen anderen Key zu senden, übergib `extra_headers={"Authorization": f"Bearer {other_key}"}`.
  </Tab>

  <Tab title="TypeScript">
    `headers: { "X-Api-Key": otherKey }` in den Optionen eines Requests ersetzt den Key des Clients nicht mehr: Beide Keys werden gesendet. Um mit einem einzelnen Request einen anderen Key zu senden, übergib ``headers: { Authorization: `Bearer $\{otherKey}` }``.
  </Tab>

  <Tab title="Go">
    `option.WithHeaderDel("X-Api-Key")` hält den Key nicht mehr von einem Request fern. Lösche stattdessen `Authorization`:

    ```go
    // Vorher
    client.Messages.New(ctx, params, option.WithHeaderDel("X-Api-Key"))

    // Nachher
    client.Messages.New(ctx, params, option.WithHeaderDel("Authorization"))
    ```

    `option.WithHeader("X-Api-Key", otherKey)` ersetzt den Key des Clients nicht mehr: Beide Keys werden gesendet. Um mit einem einzelnen Request einen anderen Key zu senden, übergib `option.WithAPIKey(otherKey)`.
  </Tab>

  <Tab title="PHP">
    `'extraHeaders' => ['X-Api-Key' => null]` hält den Key nicht mehr von einem Request fern. Um einen Request ohne Anmeldedaten zu senden, setze stattdessen `Authorization` auf `null`, oder entferne es in einer Middleware, wenn du das für den gesamten Client getan hast.

    `'extraHeaders' => ['X-Api-Key' => $otherKey]` ersetzt den Key des Clients nicht mehr: Beide Keys werden gesendet. Um mit einem einzelnen Request einen anderen Key zu senden, setze `Authorization` auf `"Bearer {$otherKey}"`.
  </Tab>

  <Tab title="Ruby">
    `extra_headers: {"x-api-key" => nil}` hält den Key nicht mehr von einem Request fern. Setze stattdessen `"authorization"` auf `nil`. Um mit einem einzelnen Request einen anderen Key zu senden, setze `"authorization"` auf `"Bearer #{other_key}"`, nicht `"x-api-key"`.
  </Tab>
</Tabs>

### Ein Client hält eine Anmeldeinformation

Ein API-Key und ein Auth-Token teilen sich jetzt einen Header, daher hält ein SDK-Client eine einzige Anmeldeinformation. Wird im Code keine übergeben, folgt er der Reihenfolge der [Vorrangregeln für Anmeldeinformationen](https://platform.claude.com/docs/de/manage-claude/wif-reference#credential-precedence).

<Tabs exclude="shell">
  <Tab title="Python">
    v1 sendete sowohl einen API-Key als auch ein Auth-Token, wenn der Client beides hatte, jeweils in einem eigenen Header. Die Anmeldeinformation ist eines von `api_key`, `auth_token`, `credentials`, `config` oder `profile`.

    * **Übergib höchstens eine.** Zwei oder mehr im Konstruktor oder in einem einzelnen `copy()`- oder `with_options()`-Aufruf lösen `ValueError` aus. `None` zählt nicht. v1 löste `TypeError` aus, und zwar nur bei zwei von `credentials`, `config` und `profile`.
    * **Die übergebene ist die einzige.** Wie in v1 sucht der Client nicht nach einer weiteren in der Umgebung oder auf der Festplatte.
    * **Wird keine übergeben, wird nur die erste der folgenden verwendet, die gesetzt ist:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, das Profil, das `ANTHROPIC_PROFILE` benennt, die Variablen für Workload Identity Federation, das aktive Profil auf der Festplatte (das, das die Datei `active_config` benennt, andernfalls `default`). Wenn die ersten beiden gesetzt sind, protokolliert der Client einmalig eine Warnung. v1 verwendete das aktive Profil vor den Federation-Variablen, wenn `ANTHROPIC_CONFIG_DIR` gesetzt war oder eine `active_config`-Datei existierte; setze `ANTHROPIC_PROFILE`, um es weiterhin zu verwenden.
    * **`copy()` und `with_options()` ersetzen.** Eine übergebene Anmeldeinformation ersetzt die des Clients, unabhängig davon, welcher Art die eine oder andere ist. Eine Basis-URL und Header, die aus der Konfiguration oder dem Profil der alten Anmeldeinformation stammen, entfallen mit ihr, und die der neuen Anmeldeinformation werden verwendet. Eine Basis-URL, die du übergeben hast, bleibt erhalten.

    ```python
    client = Anthropic(api_key=key, auth_token=token)

    # Vorher: sendete `X-Api-Key: <key>` und `Authorization: Bearer <token>`
    # Nachher: löst `ValueError` aus
    ```

    Die Plattform-Clients behalten ihre eigenen Regeln. `AnthropicAWS` akzeptiert `auth_token` neben `api_key` ohne Fehler und sendet den Key.

    Die Docstrings von `Anthropic.__init__` und `Anthropic.copy` in [`_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) enthalten die Details.

    Wenn du dich darauf verlassen hast, beides zu senden, zum Beispiel ein Token für ein Gateway und einen Key für die API dahinter, übergib das Token als `auth_token` und setze `X-Api-Key` in `default_headers`. Lass das Gateway seinen `Authorization`-Header entfernen, bevor es die Anfrage weiterleitet. Die Claude API erwartet eine Anmeldeinformation pro Anfrage.
  </Tab>

  <Tab title="TypeScript">
    In v0 sendete ein Client, der sowohl einen API-Key als auch ein Auth-Token hatte, beides, jeweils in einem eigenen Header. Die Anmeldeinformation ist eines von `apiKey`, `authToken`, `credentials`, `config` oder `profile`.

    * **Übergib höchstens eine.** Zwei oder mehr in `new Anthropic()` oder in einem einzelnen `withOptions()`-Aufruf werfen einen `TypeError`. `null` und `undefined` zählen nicht.
    * **Die übergebene ist die einzige.** Der Client sucht nicht nach einer weiteren in der Umgebung oder auf der Festplatte.
    * **Wird keine übergeben, wird die erste der folgenden verwendet:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, das Profil, das `ANTHROPIC_PROFILE` benennt, die Variablen für Workload Identity Federation, das aktive Profil auf der Festplatte (das, das die Datei `active_config` benennt, andernfalls `default`). Wenn die ersten beiden gesetzt sind, protokolliert der Client einmalig eine Warnung. In v0 kam das aktive Profil vor den Federation-Variablen. Ein `ANTHROPIC_PROFILE`, das ein fehlendes Profil benennt, wurde in v0 übersprungen, und jetzt wirft die erste Anfrage einen `AnthropicError`. `loadConfig()` ohne Argument folgt derselben Reihenfolge und wirft denselben Fehler.
    * **`withOptions` ersetzt.** Eine übergebene Anmeldeinformation ersetzt die des kopierten Clients, sodass `client.withOptions({ authToken })` kein `apiKey: null` mehr daneben benötigt.
    * **Ein Plattform-Client akzeptiert nur die Anmeldeinformationen seiner Plattform.** Die AWS-, Bedrock- und Foundry-Clients sowie `AnthropicVertex` werfen einen `AnthropicError` für eine Anmeldeinformations-Option, mit der sie sich nicht authentifizieren, wie es `AnthropicGoogleCloud` bereits tat. Bei den AWS- und Bedrock-Clients löscht `apiKey: null` jetzt den Key, sodass der Client mit AWS-Anmeldeinformationen signiert. `AnthropicBedrock` speichert seinen Key in `client.apiKey`, wo v0 ihn in `client.authToken` speicherte.

    ```typescript
    // Vorher: hat den API-Key gesendet und `credentials` ignoriert
    const client = new Anthropic({ apiKey, credentials });

    // Nachher: die Zeile oben wirft einen TypeError
    const client = new Anthropic({ credentials });
    ```

    Die Doc-Kommentare zu [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/src/client.ts) beschreiben, wie sich jede Option verhält, und der Doc-Kommentar zum Konstruktor jedes dieser Plattform-Clients listet die Optionen auf, die er ablehnt.

    Wenn du dich darauf verlassen hast, beides zu senden, zum Beispiel ein Token für ein Gateway und einen Key für die API dahinter, setze `X-Api-Key` in `defaultHeaders` und behalte `authToken` bei. Lass das Gateway seinen `Authorization`-Header entfernen, bevor es die Anfrage weiterleitet. Die Claude API erwartet eine Anmeldeinformation pro Anfrage.
  </Tab>

  <Tab title="C#">
    In v12 sendete ein Client, der sowohl einen API-Key als auch ein Auth-Token hatte, beides, jeweils in einem eigenen Header. Die Anmeldeinformation ist eines von `ApiKey`, `AuthToken` oder `ClientOptions.Credentials`.

    * **Zwei zu übergeben ist ein Fehler.** Das Setzen einer zweiten wirft eine `ArgumentException`. `null` zählt nicht; um also die Anmeldeinformation in selbst erstellten `ClientOptions` auszutauschen, setze die alte zuerst auf `null`.
    * **Wird eine übergeben, wird sie verwendet und die Umgebung ignoriert.** Es wird keine Umgebungsvariable für Anmeldeinformationen und kein Profil auf der Festplatte gelesen. Ebenso gibt `AnthropicCredentials.Resolve(profile: "name")` jetzt die Anmeldeinformationen dieses Profils zurück, wenn `ANTHROPIC_API_KEY` oder `ANTHROPIC_AUTH_TOKEN` gesetzt ist.
    * **Wird keine übergeben, wird der erste Treffer in der Umgebung verwendet:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, die Variablen für Workload Identity Federation, dann das aktive Profil auf der Festplatte. Ein leeres `ANTHROPIC_API_KEY` oder `ANTHROPIC_AUTH_TOKEN` gilt als nicht gesetzt. Wenn die ersten beiden gesetzt sind, wird einmalig eine Warnung nach stderr ausgegeben. Der Client sucht bei der ersten Verwendung, daher wirft ein nicht existierendes `ANTHROPIC_PROFILE` jetzt bei der ersten Anfrage statt im Konstruktor.
    * **`WithOptions` ersetzt.** Eine im Modifier übergebene Anmeldeinformation ersetzt die des Clients, unabhängig von deren Art, sodass `AuthToken = token` kein `ApiKey = null` mehr daneben benötigt. Wird keine übergeben, behält die Kopie die Anmeldeinformation, `BaseUrl` und `ExtraHeaders` des Clients, selbst wenn der Modifier neue `ClientOptions` zurückgibt.

    ```csharp
    // Vorher: beide gesendet, jeweils in einem eigenen Header
    AnthropicClient client = new() { ApiKey = apiKey, AuthToken = token };

    // Nachher: die Zeile oben wirft eine ArgumentException
    AnthropicClient client = new() { AuthToken = token };
    ```

    Die XML-Dokumentation zu diesen drei Eigenschaften von [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-csharp/blob/main/src/Anthropic/Core/ClientOptions.cs) enthält die Details.

    Cloud-Plattform-Clients behalten die Anmeldeinformationen, mit denen sie erstellt wurden. Die Bedrock-, Bedrock-Mantle-, Foundry-, Google-Cloud- und AWS-Clients sowie `AnthropicVertexClient` entscheiden bei ihrer Erstellung, wie sie sich authentifizieren, und die meisten verwenden dafür den `Authorization`-Header. Die Releases dieser Pakete, die von v13 abhängen, ignorieren ein `ApiKey` oder `AuthToken`, das du über `WithOptions` setzt. Um einen anderen Key mit `AnthropicAwsClient` zu verwenden, erstelle einen neuen Client mit `ApiKey` in `AwsClientOptions`.

    Wenn du dich darauf verlassen hast, beides zu senden, zum Beispiel ein Token für ein Gateway und einen Key für die API dahinter, setze `X-Api-Key` mit `ExtraHeaders` und behalte `AuthToken` bei. Lass das Gateway seinen `Authorization`-Header entfernen, bevor es die Anfrage weiterleitet. Die Claude API erwartet eine Anmeldeinformation pro Anfrage.
  </Tab>

  <Tab title="Go">
    In v1 sendete ein Client, der sowohl einen API-Key als auch ein Auth-Token hatte, beides, jeweils in einem eigenen Header. Die Anmeldeinformation stammt aus `option.WithAPIKey`, `option.WithAuthToken`, `option.WithConfig`, `option.WithProfile` oder `option.WithFederationTokenProvider`.

    * **Zwei davon an `anthropic.NewClient` zu übergeben ist ein Fehler.** `NewClient` gibt keinen Fehler zurück, daher schlägt jede Anfrage des Clients mit diesem Fehler fehl. `NewClient` wendet bereits `anthropic.DefaultClientOptions()` an, übergib dessen Ergebnis also nicht zusätzlich: Die Anmeldeinformation, die es in der Umgebung findet, zählt dann als eine von dir übergebene.
    * **Eine davon wird unverändert verwendet.** Es wird keine Anmeldeinformation aus der Umgebung oder aus einem Profil auf der Festplatte gelesen. In v1 hatten `ANTHROPIC_API_KEY` und `ANTHROPIC_AUTH_TOKEN` Vorrang vor den letzten drei.
    * **Ohne eine davon wird die erste der folgenden verwendet, die gesetzt ist,** in derselben Reihenfolge wie in v1: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, die Variablen für Workload Identity Federation, das aktive Profil auf der Festplatte. Wenn die ersten beiden gesetzt sind, protokolliert das SDK einmalig eine Warnung.
    * **Eine davon bei einer Anfrage ersetzt die Anmeldeinformation des Clients für diese Anfrage,** sodass `option.WithAuthToken` kein `option.WithHeaderDel("X-Api-Key")` mehr daneben benötigt.

    ```go
    // Vorher: Der API-Key wurde gesendet und eine Warnung wurde protokolliert
    client := anthropic.NewClient(
    	option.WithAPIKey(apiKey),
    	option.WithProfile("work"),
    )

    // Nachher: Jede Anfrage des obigen Clients schlägt fehl, also übergib den gewünschten
    client := anthropic.NewClient(option.WithAPIKey(apiKey))
    ```

    Die Warnung, die v1 protokollierte, entfällt, daher tut `option.WithConfigQuiet`, das sie unterdrückte, jetzt dasselbe wie `option.WithConfig` und ist abgekündigt.

    Die Doc-Kommentare zu `anthropic.NewClient` und `anthropic.DefaultClientOptions` in [`client.go`](https://github.com/anthropics/anthropic-sdk-go/blob/main/client.go) enthalten die Details.

    Wenn du dich darauf verlassen hast, beides zu senden, zum Beispiel ein Token für ein Gateway und einen Key für die API dahinter, setze `X-Api-Key` mit `option.WithHeader` und behalte `option.WithAuthToken` bei. Lass das Gateway seinen `Authorization`-Header entfernen, bevor es die Anfrage weiterleitet. Die Claude API erwartet eine Anmeldeinformation pro Anfrage.

    `ANTHROPIC_CUSTOM_HEADERS` und `ANTHROPIC_WEBHOOK_SIGNING_KEY` gelten jetzt für jeden Client, den `anthropic.NewClient` erstellt. In v1 wurden sie nur gelesen, wenn weder die Umgebung noch ein Profil auf der Festplatte eine Anmeldeinformation enthielt.
  </Tab>

  <Tab title="Java">
    In v2 sendete ein Client, der sowohl einen API-Key als auch ein Auth-Token hatte, beides, jeweils in einem eigenen Header. Die Anmeldeinformation ist eines von `apiKey`, `authToken` oder `configurationProvider` auf den Buildern `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` und `AnthropicBackend`.

    * **Setze höchstens eine.** Mit zwei auf einem Builder wirft `build()` eine `IllegalStateException`, die sie benennt. `null` oder ein leeres `Optional` zählt nicht.
    * **Die gesetzte ist die einzige.** `fromEnv()`, davor oder danach aufgerufen, übernimmt keine Anmeldeinformation aus der Umgebung oder aus einem Profil auf der Festplatte. In v2 konnte ein Key oder Token, den `fromEnv()` fand, zusätzlich oder stattdessen gesendet werden.
    * **Ist keine gesetzt, verwendet `fromEnv()` die erste der folgenden, die es findet:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, die Variablen für Workload Identity Federation, das aktive Profil auf der Festplatte. Wenn die ersten beiden gesetzt sind, wird einmalig eine Warnung nach `System.err` ausgegeben. Die Systemeigenschaften `anthropic.apiKey` und `anthropic.authToken` zählen als Umgebung. Ein leerer Key oder ein leeres Token, in einer Variable oder einer Systemeigenschaft, gilt als nicht gesetzt. In v2 verwendete `fromEnv()` den leeren Wert als Key oder Token.

    ```java
    // Vorher: Beide wurden gesendet. In v3 wirft build() eine IllegalStateException
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .apiKey(apiKey)
        .authToken(authToken)
        .build();

    // Nachher
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .apiKey(apiKey)
        .build();
    ```

    Die Dokumentation von `fromEnv()` auf diesen Buildern enthält die Details.

    Wenn du dich darauf verlassen hast, beides zu senden, zum Beispiel ein Token für ein Gateway und einen Key für die API dahinter, setze beide Header selbst:

    ```java
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .putHeader("Authorization", "Bearer " + gatewayToken)
        .putHeader("X-Api-Key", apiKey)
        .build();
    ```

    Lass das Gateway seinen `Authorization`-Header entfernen, bevor es die Anfrage weiterleitet. Die Claude API erwartet eine Anmeldeinformation pro Anfrage.
  </Tab>

  <Tab title="PHP">
    Frühere Versionen sendeten sowohl einen API-Key als auch ein Auth-Token, wenn der Client beides hatte, jeweils in einem eigenen Header. `Anthropic\Client` akzeptiert eine Anmeldeinformation, aus `apiKey`, `authToken` oder `credentials`:

    * Wird mehr als eine davon übergeben, wird `\InvalidArgumentException` geworfen. Nur `null` gilt als nicht übergeben. Ein leerer String gilt als übergeben, daher sendet `new Client(apiKey: '')` keine Anmeldeinformation.
    * Wird eine übergeben, wird sie verwendet, und es wird keine Anmeldeinformation aus der Umgebung oder aus einem Profil auf der Festplatte gelesen. Mit gesetztem `ANTHROPIC_API_KEY` sendet `new Client(authToken: $token)` das Token. Frühere Versionen sendeten den Key aus der Umgebung mit.
    * Wird keine übergeben, wird die erste der folgenden verwendet, die gesetzt ist: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, das von `ANTHROPIC_PROFILE` benannte Profil, die Variablen für Workload Identity Federation, das aktive Profil auf der Festplatte (das, das die Datei `active_config` benennt, andernfalls `default`). Frühere Versionen verwendeten das aktive Profil vor den Federation-Variablen und verwendeten kein Profil, wenn es keine `active_config`-Datei gab. Sie übersprangen außerdem ein `ANTHROPIC_PROFILE`, das ein fehlendes oder ungültiges Profil benannte. In diesem Fall wirft `new Client()` jetzt `Anthropic\Core\Exceptions\AnthropicException`. Wenn sowohl `ANTHROPIC_API_KEY` als auch `ANTHROPIC_AUTH_TOKEN` gesetzt sind, sendet der Client den Key, und seine Eigenschaft `authToken` ist leer. Der erste so erstellte Client schreibt außerdem eine Warnung mit `error_log()`, einmal pro Prozess, was auf einem Webserver einmal pro Anfrage bedeutet: `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Um sie zu unterbinden, entferne die Variable, die du nicht verwendest.

    ```php
    // Vorher: Key wurde als X-Api-Key und das Token als Authorization gesendet.
    // Nachher: wirft "Pass at most one of `apiKey`, `authToken`, or `credentials`. Received `apiKey`, `authToken`."
    $client = new Client(apiKey: $key, authToken: $token);
    ```

    Wenn du dich darauf verlassen hast, beides zu senden, zum Beispiel ein Token für ein Gateway und einen Key für die API dahinter, übergib das Token als `authToken` und füge `X-Api-Key` in einer Middleware wie der unter [Wenn ein Proxy oder Gateway `X-Api-Key` liest](https://platform.claude.com/docs/de/api/migration-2026-10-21#sdk-proxy-x-api-key) hinzu, ohne den `withoutHeader`-Aufruf. Lass das Gateway seinen `Authorization`-Header entfernen, bevor es die Anfrage weiterleitet. Die Claude API erwartet eine Anmeldeinformation pro Anfrage.
  </Tab>

  <Tab title="Ruby">
    Die Anmeldeinformations-Argumente von `Anthropic::Client.new` sind `api_key:`, `auth_token:`, `credentials:` und `config:`. Ein `nil`-Argument gilt als nicht übergeben. Die Plattform-Clients behalten ihre eigenen Regeln.

    * **Zwei oder mehr übergeben:** `Anthropic::Client.new` löst `ArgumentError` aus. Frühere Versionen lösten nur bei `credentials:` zusammen mit `config:` aus und sendeten ansonsten den Key, falls vorhanden, dann das Token.
    * **Eine übergeben:** Der Client verwendet sie und greift nicht auf eine Anmeldeinformation aus der Umgebung oder aus einem Profil auf der Festplatte zurück.
    * **Keine übergeben:** Der Client verwendet die erste der folgenden, die er findet: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, die Variablen für Workload Identity Federation, das aktive Profil auf der Festplatte. Die Reihenfolge hat sich nicht geändert, aber wenn sowohl `ANTHROPIC_API_KEY` als auch `ANTHROPIC_AUTH_TOKEN` gesetzt sind, ist `client.auth_token` jetzt `nil`. Ein leeres `ANTHROPIC_API_KEY` oder `ANTHROPIC_AUTH_TOKEN` gilt jetzt als nicht gesetzt, während frühere Versionen ein leeres `ANTHROPIC_API_KEY` das Token und alles danach verdecken ließen.

    Wenn keine Anmeldeinformation übergeben wird und sowohl `ANTHROPIC_API_KEY` als auch `ANTHROPIC_AUTH_TOKEN` gesetzt sind, warnt das SDK außerdem einmal pro Prozess auf der Standardfehlerausgabe über `Kernel#warn`: `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Entferne die Variable, die du nicht verwendest, um sie zum Schweigen zu bringen.

    ```ruby
    # Vorher: Der Key wurde gesendet und das Token ignoriert.
    # Nachher: ArgumentError, "Pass at most one of `api_key:`, `auth_token:`, `credentials:`, or `config:`. Received `api_key:`, `auth_token:`."
    Anthropic::Client.new(api_key: api_key, auth_token: auth_token)

    # Übergib nur den Wert, der gesendet werden soll.
    Anthropic::Client.new(api_key: api_key)
    ```
  </Tab>
</Tabs>

### Änderungen in einem SDK oder der CLI

Diese Änderungen betreffen jeweils ein SDK oder die CLI.

<Tabs exclude="shell:cURL, python, typescript, go, ruby">
  <Tab title="CLI">
    **`--api-key` und `--auth-token` wurden entfernt.** `ant` akzeptiert keinen API-Key und kein Auth-Token mehr als Flag-Wert, da ein Wert auf der Befehlszeile im Shell-Verlauf und in Prozesslisten sichtbar ist. Beide Flags geben seit v1.27.0 eine Abkündigungswarnung aus. Ein Befehl, der noch eines davon übergibt, bricht mit `flag provided but not defined` ab.

    | Entfernt               | Stattdessen verwenden                                        |
    | ---------------------- | ------------------------------------------------------------ |
    | `--api-key <key>`      | `ANTHROPIC_API_KEY`, `--api-key-stdin` oder `ant auth login` |
    | `--auth-token <token>` | `ANTHROPIC_AUTH_TOKEN` oder `--auth-token-stdin`             |

    ```bash
    # Vorher
    ant --api-key "$KEY" models list

    # Nachher, aus der Umgebung
    export ANTHROPIC_API_KEY="$KEY"
    ant models list

    # Nachher, aus einem Secret-Manager
    op read op://vault/anthropic/api-key | ant --api-key-stdin models list
    ```

    `--api-key-stdin` und `--auth-token-stdin` lesen die gesamte Standardeingabe, daher bezieht ein Befehl, der eines davon verwendet, seinen Request-Body aus Flags.

    `ant auth status`, die Eingabeaufforderung beim ersten Ausführen von `ant apply` und der Hinweis zu mehreren Authentifizierungsquellen bezeichnen diese Anmeldeinformationen jetzt als `ANTHROPIC_API_KEY` und `ANTHROPIC_AUTH_TOKEN`, wo sie zuvor `--api-key / ANTHROPIC_API_KEY` und `--auth-token / ANTHROPIC_AUTH_TOKEN` ausgaben.
  </Tab>

  <Tab title="C#">
    **Der `Type` einer Union ist ein Enum.** In v12 war die Eigenschaft `Type` einer Union-Klasse, wie `ContentBlock.Type` oder `RawMessageStreamEvent.Type`, ein `JsonElement`. In v13 ist sie ein `ApiEnum<string, T>`, wobei `T` ein neues Enum mit einem Member für jede Variante ist, wie `ContentBlockType`. Einige Unions werden stattdessen über `Name` oder `Command` unterschieden, wie `BetaMemoryTool20250818Command.Command`, und diese Eigenschaften ändern sich auf dieselbe Weise. Der `Type` einer Variantenklasse, wie `TextBlock.Type`, ist weiterhin ein `JsonElement`.

    ```csharp
    // Vorher
    if (block.Type.GetString() == "tool_use") { }

    // Nachher
    if (block.Type.Value() == ContentBlockType.ToolUse) { }
    ```

    `block.Type.Raw()` gibt den String zurück, auch einen, für den diese Version des SDK kein Enum-Member hat.

    **`IChatClient` ignoriert Sampling-Optionen.** Die `IChatClient`-Adapter (`AsIChatClient()`) ignorieren jetzt `ChatOptions.Temperature`, `ChatOptions.TopK` und `ChatOptions.TopP`. Siehe [Sampling-Parameter wurden entfernt](https://platform.claude.com/docs/de/api/migration-2026-10-21#sampling-parameters).
  </Tab>

  <Tab title="Java">
    **Getter, die jetzt ein `Optional` zurückgeben.** `apiKey()` und `authToken()` auf `AnthropicBackend` geben jetzt ein `Optional<String>` zurück, wie es `apiKey()` auf `AwsBackend` und `BedrockMantleBackend` bereits tat. In v2 gab jeder einen `String` zurück, der `null` war, wenn das Backend keine Anmeldeinformation dieser Art hatte.

    ```java
    // Vorher
    String apiKey = backend.apiKey();
    if (apiKey != null) {}

    // Nachher
    Optional<String> apiKey = backend.apiKey();
    if (apiKey.isPresent()) {}
    ```

    Diese Getter geben jetzt ebenfalls ein `Optional` zurück. In v2 gab jeder den Wert selbst zurück, der `null` war, wenn keiner vorhanden war:

    * `apiKey()` und `awsCredentialsProvider()` auf `BedrockBackend`
    * `filename()` und `mimeType()` auf `McpResourceFile`
    * `detail()` auf `CredentialSource`
    * `body()` auf `HttpRequest`
    * `resource()` auf `FoundryBackend`, das zuvor `getResource()` war
    * `responseValidation()`, `timeout()`, `followRedirects()`, `fallbackState()` und `openTelemetry()` auf `RequestOptions`, die zuvor `getResponseValidation()`, `getTimeout()`, `getFollowRedirects()`, `getFallbackState()` und `getOpenTelemetry()` waren

    ```java
    // Vorher
    String filename = file.filename();
    if (filename != null) {}
    String resource = backend.getResource();

    // Nachher
    Optional<String> filename = file.filename();
    if (filename.isPresent()) {}
    Optional<String> resource = backend.resource();
    ```

    `getBaseUrl()` auf `FoundryBackend` wurde entfernt. Rufe `baseUrl()` auf, das die URL zurückgibt, an die Anfragen gehen. Das ist die von dir gesetzte Basis-URL oder die aus der Ressource erstellte, und sie endet auf `/anthropic`.

    `getBaseUrl()` auf `AnthropicBackend` wurde ebenfalls entfernt. Rufe `baseUrl()` auf, das denselben Wert zurückgibt.

    **`HttpRequest` erfordert eine Basis-URL.** Wenn du selbst einen `HttpRequest` erstellst, etwa in einem Test eines Interceptors, setze seine Basis-URL. Ohne sie wirft `build()` jetzt eine `IllegalStateException`. In v2 gab es eine Anfrage zurück, deren `baseUrl()` `null` war. Die Anfragen, die das SDK erstellt, hatten bereits eine.

    ```java
    // Vorher
    HttpRequest request = HttpRequest.builder()
        .method(HttpMethod.GET)
        .build();

    // Nachher
    HttpRequest request = HttpRequest.builder()
        .method(HttpMethod.GET)
        .baseUrl("https://api.anthropic.com")
        .build();
    ```

    `baseUrl()` gibt weiterhin einen `String` zurück, der jetzt nie `null` ist. Auf dem Builder wurde `baseUrl(Optional<String>)` entfernt, und `baseUrl(String)` akzeptiert kein `null` mehr.

    **Interceptors sehen `anthropic-version`.** Der Client fügt den Standard-Header `anthropic-version` jetzt hinzu, bevor Interceptors ausgeführt werden. In v2 fügte das Backend ihn danach hinzu. Wenn dein Interceptor eine eigene Version setzt, rufe `replaceHeaders` auf, da `putHeader` jetzt einen zweiten Wert hinzufügt:

    ```java
    // Vorher
    request.toBuilder().putHeader("anthropic-version", version).build();

    // Nachher
    request.toBuilder().replaceHeaders("anthropic-version", version).build();
    ```
  </Tab>

  <Tab title="PHP">
    **Übergebene Enum-Cases werden als ihre Werte zurückgelesen.** `with()` und Setter wie `withAllowedCallers()` akzeptieren weiterhin einen Enum-Case oder dessen Wert. Frühere Versionen behielten einen Case so bei, wie du ihn übergeben hast. v1 behält den Wert des Cases, was die Eigenschaftstypen bereits deklarieren. Objekte, die das SDK aus einer Antwort erstellt, ändern sich nicht, und das JSON, das das SDK sendet, ist dasselbe. Wenn du eine Eigenschaft zurückliest und mit einem Case vergleichst, ist der Vergleich jetzt false und es wird nichts geworfen, vergleiche sie also mit dem Wert des Cases:

    ```php
    $tool = CodeExecutionTool20250825::with(allowedCallers: [AllowedCaller::DIRECT]);

    // Vorher
    in_array(AllowedCaller::DIRECT, $tool->allowedCallers, true);

    // Nachher
    in_array(AllowedCaller::DIRECT->value, $tool->allowedCallers, true);
    ```
  </Tab>
</Tabs>

### Die Lizenz ist Apache 2.0

Ab diesen Versionen stehen das SDK und die CLI unter der Apache License, Version 2.0. Frühere Versionen bleiben unter der MIT License. Es sind keine Codeänderungen erforderlich. Wenn du die Lizenzen deiner Abhängigkeiten nachverfolgst, aktualisiere deren Einträge.

* **TypeScript:** Die Plattform-Pakete (`@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` und `@anthropic-ai/google-cloud-sdk`) wechseln die Lizenz in ihren eigenen 1.0.0-Releases.
* **C#:** Die anderen Pakete (`Anthropic.Bedrock`, `Anthropic.Vertex`, `Anthropic.Foundry`, `Anthropic.Aws`, `Anthropic.GoogleCloud` und `Anthropic.Mcp`) wechseln die Lizenz in ihren eigenen 1.0.0-Releases.
* **Java:** Die Änderung umfasst jedes `com.anthropic`-Artefakt.
