---
title: Migration zur 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` zu `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 SDK 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="Passe deinen Code an die Breaking Changes an">
    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="Teste gegen 2026-10-21">
    Teste deine Integration gegen `2026-10-21`, bevor du sie veröffentlichst.
  </Step>
</Steps>

## Breaking Changes

### 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 Ergebnis des Web-Fetch-Tools, wird weiterhin akzeptiert.

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

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

In `2026-10-21` gibt eine Anfrage, die in einer `user`-Nachricht einen `text`-Block mit einem nicht leeren `citations`-Array sendet, einen 400-Fehler zurück. Entferne `citations` aus diesen Blöcken. Citations an `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 wurden 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 bisher. 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 der [Organisation](https://platform.claude.com/docs/de/api/organization/rate_limits/list) und des [Workspace](https://platform.claude.com/docs/de/api/organization/workspaces/rate_limits/list): auflisten sowie die Antwort auf das Festlegen 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` an den Endpunkten zum Auflisten von Ratenlimits und der Filter `workspace_id` am 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` wurde `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`, einschließlich ihrer Clients für Amazon Bedrock und Google Cloud. 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.

### `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 benennt, etwa `{ role: "user", content: "Hello, Claude" }`, besteht die Typprüfung wie bisher, 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"]` schließt ebenfalls `undefined` ein. 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 Typ-Alias oder benenne stattdessen den Typ einer einzelnen Rolle.

    ```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, benenne die Klasse für ihre Rolle 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` heißt jetzt `MessageContentParam`, und `BetaMessageParamContent` heißt 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 bisher, daher muss Code, der seine Nachrichten damit erstellt, nicht geändert werden.

    Ein Struct-Literal benennt den Typ für seine Rolle. 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 Zeiger 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 bestehen 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()` auf 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 benennt. Benenne stattdessen die drei Klassen:

    ```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 auf 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` heißt jetzt `BetaSystemMessageParam\ClearAt`.
    * `MessageParam\Content` heißt jetzt `MessageContentParam`, und `BetaMessageParam\Content` heißt jetzt `BetaMessageContentParam`. Ihre PHPStan-Typen übernehmen ebenfalls den neuen Namen: `ContentShape` heißt 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 bestehen. 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 einem einzigen Wert sind Konstanten

Dies betrifft die SDKs für C#, Go, Java, PHP und Ruby sowie ein CLI-Flag. In früheren Versionen hatte ein Pflichtfeld, das nur einen Wert enthalten 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, es gibt also nichts zu ä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, 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 sie entgegennimmt, daher funktioniert auch `new BetaManagedAgentsTextBlock("Hello Claude!")`. Eine Klasse, der keine bleibt, wird mit `new BetaManagedAgentsAlwaysAllowPolicy()` erstellt.

    Wenn du eine liest, vergleiche den 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`, wie es `TextBlockParam.Type` bereits tat. Ein optionales Feld, etwa `BetaManagedAgentsBashToolConfigParams.Type`, behält sein Enum.

    Lösche das Feld in einer Anfrage. Es wird als sein einziger Wert gemarshalt, 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 Zeiger auf das leere Struct: `OfAlwaysAllow: &anthropic.BetaManagedAgentsAlwaysAllowPolicyParam{}`.

    Vergleiche in einer Antwort 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, der mit einem der entfernten Typen deklariert wurde, übernimmt den neuen Typ des Felds, etwa `constant.AgentMessage`. `constant.ValueOf[constant.AgentMessage]()` gibt seinen 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, daher sind sie entfallen. Setze das Feld der Union auf einen Zeiger 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 der `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, wie es das von `TextBlockParam` bereits war. Ein optionales Feld, etwa der `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 es entgegennimmt, daher funktioniert auch `BetaManagedAgentsTextBlock.of("Hello Claude!")`. 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 eines 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 der `type` einer Managed-Agents-Klasse unter `Anthropic\Beta`. Diese Properties sind jetzt ein String mit diesem einen Wert als Standardwert, wie es der `type` von `Anthropic\Messages\TextBlockParam` bereits war. Eine optionale Property, etwa der `type` von `Anthropic\Beta\Environments\BetaPackages`, behält ihr Enum.

    `with()` nimmt `type` nicht mehr entgegen. Entferne es: PHP wirft „Unknown named parameter" für ein übrig gebliebenes `type:`, und in einem positionalen Aufruf rücken die Argumente danach um eine Position auf.

    ```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'`, daher kannst du es weglassen.
    * Anfragen, die du als Arrays schreibst, ändern sich nicht und benötigen weiterhin ihren `'type'`.
  </Tab>

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

    Anfragen, die du als Hashes schreibst, ändern sich nicht und benötigen weiterhin ihren `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, daher kannst du es 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üfst, 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 „client-side compaction" (clientseitige Komprimierung) im „tool runner" (Tool-Ausführer) wurde zugunsten der serverseitigen Compaction entfernt, die die Konversation innerhalb der API zusammenfasst statt mit einer zusätzlichen Anfrage 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` gibt es nicht mehr. Die Option funktionierte bereits seit v0.129.0 nicht mehr, wo ihre Übergabe einen `AnthropicError` auslöste. Sie ist nicht im Params-Typ enthalten, daher meldet TypeScript sie als unbekannte Eigenschaft.

    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:` gibt es nicht mehr. Sie funktionierte bereits seit v1.74.0 nicht mehr, wo ihre Übergabe einen `ArgumentError` auslöste.

    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">
    Den Befehl `ant completions create` gibt es nicht mehr.

    ```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` akzeptiert ebenfalls `--stream`, 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` gibt es nicht mehr, ebenso wenig die Ressourcenklasse `Completions` und die Typen `Completion`, `CompletionCreateParams`, `CompletionCreateParamsNonStreaming` und `CompletionCreateParamsStreaming`. `AnthropicBedrock` hat ebenfalls keine Eigenschaft `completions` mehr. Die Konstanten `HUMAN_PROMPT` und `AI_PROMPT`, die nur von Text-Completions-Prompts verwendet wurden, sind ebenfalls entfernt, sowohl als Exporte als auch als statische Eigenschaften 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);
    ```

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

  <Tab title="Go">
    `client.Completions` gibt es nicht mehr, ebenso wenig `CompletionService`, `NewCompletionService`, `CompletionNewParams` und `Completion`. `aws.Client` hat ebenfalls kein Feld `Completions` 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)
    ```

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

  <Tab title="Java">
    `client.completions()` wurde aus `AnthropicClient` und `AnthropicClientAsync` entfernt, ebenso wie `CompletionService`, `CompletionServiceAsync` und das 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()));
    ```

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

  <Tab title="Ruby">
    `client.completions` gibt es nicht mehr, ebenso wenig `Anthropic::Resources::Completions`, `Anthropic::CompletionCreateParams` und `Anthropic::Completion`. `Anthropic::BedrockClient` hat ebenfalls keinen Reader `completions` mehr. Auf `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)
    ```

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

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

Die Nicht-Beta-Models-Methoden akzeptieren `betas` (csharp, go: `Betas`; java: `.addBeta()`) nicht mehr, und die `ant models`-Befehle akzeptieren `--beta` nicht mehr. 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()` akzeptieren `betas` nicht mehr (die Übergabe führt zu einem `TypeError`, und ein Type-Checker markiert sie), und `anthropic.types.ModelListParams` hat keinen Schlüssel `betas` 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 Eigenschaft `betas` 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 Eigenschaft `Betas` mehr. Die Methoden auf `client.Beta.Models` akzeptieren die gleichnamigen Klassen in `Anthropic.Models.Beta.Models`.

    ```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 Feld `Betas` 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()` akzeptieren die gleichnamigen Klassen in `com.anthropic.models.beta.models`.

    ```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()` akzeptieren `betas` nicht mehr (die Übergabe löst `Error: Unknown named parameter $betas` aus), und `Anthropic\Models\ModelRetrieveParams` und `Anthropic\Models\ModelListParams` haben keine Eigenschaft `betas` mehr.

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

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

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

  <Tab title="Ruby">
    `client.models.retrieve` und `client.models.list` akzeptieren `betas:` nicht mehr, und `Anthropic::ModelRetrieveParams` und `Anthropic::ModelListParams` haben kein Feld `betas` 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 Header `anthropic-beta` 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 Header `X-Api-Key`. Ändere daher jeden Proxy oder jedes Gateway, das `X-Api-Key` liest oder setzt, so, dass es `Authorization` verwendet, 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 Anfrageprotokoll 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` hat bereits ein Bearer-Token gesendet.
  </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 Anfrage-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`. In dem `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 Systemeigenschaft `anthropic.apiKey`. `apiKey` auf dem Builder `FoundryBackend` 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` hat bereits ein Bearer-Token gesendet.
  </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` hat bereits ein Bearer-Token gesendet.

    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 es den Key aus `Authorization` liest. `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 jeder Anfrage ausgeführt, die 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` akzeptiert dieselbe Funktion, 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 der Worker erhalten ihren eigenen Key, daher lassen sie die Standard-Header `X-Api-Key` und `Authorization` bei ihren eigenen Anfragen weg.
  </Tab>

  <Tab title="C#">
    Setze den Header selbst mit `ExtraHeaders`. Wenn du `ApiKey` und `AuthToken` auf `null` setzt, wird verhindert, dass Anmeldedaten aus `ANTHROPIC_API_KEY` oder `ANTHROPIC_AUTH_TOKEN` zusätzlich 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 ein Key aus `ANTHROPIC_API_KEY` zusätzlich 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 einen manuell gesetzten `X-Api-Key` bei ihren eigenen Anfragen 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. Eine Anfrage, die eigene `extraHeaders` hat, 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 eine Anfrage unverändert, wenn sie den Key nicht enthält, etwa eine, die zu einem anderen Origin weitergeleitet wurde.

    `Anthropic::AWSClient` akzeptiert kein Argument `middleware:`. Übergib die Middleware stattdessen mit jeder Anfrage, als `request_options: {middleware: send_x_api_key}`.
  </Tab>
</Tabs>

#### Wenn du `X-Api-Key` bei einer Anfrage gesetzt oder entfernt hast

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

Wenn du `X-Api-Key` entfernt hast, damit eine Anfrage 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 enthält genau ein Credential](https://platform.claude.com/docs/de/api/migration-2026-10-21#sdk-one-credential), also stelle sicher, dass es das Token ist: Wenn im Code keines ü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 einer Anfrage fernzuhalten, bewirkt 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 einer Anfrage 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 einer Anfrage ersetzt den Key des Clients nicht mehr: Beide Keys werden gesendet. Um mit einer Anfrage 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 einer Anfrage 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 einer Anfrage 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 einer Anfrage fern. Um eine Anfrage ohne Anmeldedaten zu senden, setze stattdessen `Authorization` auf `null`, oder entferne es in einer Middleware, wenn du dies 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 einer Anfrage 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 einer Anfrage fern. Setze stattdessen `"authorization"` auf `nil`. Um mit einer Anfrage einen anderen Key zu senden, setze `"authorization"` auf `"Bearer #{other_key}"`, nicht `"x-api-key"`.
  </Tab>
</Tabs>

### Ein Client enthält genau ein Credential

Ein API-Key und ein Auth-Token teilen sich jetzt einen Header, daher enthält ein SDK-Client genau ein „credential" (Anmeldeinformation). Wenn im Code keines übergeben wird, folgt er der Reihenfolge der [Credential-Priorität](https://platform.claude.com/docs/de/manage-claude/wif-reference#credential-precedence).

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

    * **Übergib höchstens eines.** 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 nur bei zweien von `credentials`, `config` und `profile`.
    * **Das übergebene ist das einzige.** Wie in v1 sucht der Client nicht nach einem weiteren in der Umgebung oder auf der Festplatte.
    * **Wenn keines übergeben wird, wird nur das erste der folgenden verwendet, das 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 Datei `active_config` existierte; setze `ANTHROPIC_PROFILE`, um es weiterhin zu verwenden.
    * **`copy()` und `with_options()` ersetzen.** Ein übergebenes Credential ersetzt das eigene des Clients, unabhängig davon, welcher Art eines von beiden ist. Eine Basis-URL und Header, die aus der Config oder dem Profil des alten Credentials stammen, entfallen mit ihm, und die des neuen Credentials werden verwendet. Eine von dir übergebene Basis-URL 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 darauf angewiesen warst, 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 ein Credential pro Anfrage.
  </Tab>

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

    * **Übergib höchstens eines.** Zwei oder mehr in `new Anthropic()` oder in einem einzelnen `withOptions()`-Aufruf lösen einen `TypeError` aus. `null` und `undefined` zählen nicht.
    * **Das übergebene ist das einzige.** Der Client sucht nicht nach einem weiteren in der Umgebung oder auf der Festplatte.
    * **Wenn keines übergeben wird, wird das 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 löst die erste Anfrage einen `AnthropicError` aus. `loadConfig()` ohne Argument folgt derselben Reihenfolge und löst denselben Fehler aus.
    * **`withOptions` ersetzt.** Ein übergebenes Credential ersetzt das des kopierten Clients, daher benötigt `client.withOptions({ authToken })` kein `apiKey: null` mehr daneben.
    * **Ein Plattform-Client akzeptiert nur die Credentials seiner Plattform.** Die AWS-, Bedrock- und Foundry-Clients sowie `AnthropicVertex` lösen einen `AnthropicError` für eine Credential-Option aus, mit der sie sich nicht authentifizieren, wie es `AnthropicGoogleCloud` bereits tat. Auf den AWS- und Bedrock-Clients löscht `apiKey: null` jetzt den Key, sodass der Client mit AWS-Credentials 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 darauf angewiesen warst, 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 ein Credential pro Anfrage.
  </Tab>

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

    * **Die Übergabe von zweien ist ein Fehler.** Das Setzen eines zweiten löst eine `ArgumentException` aus. `null` zählt nicht, daher setze, um das Credential in selbst erstellten `ClientOptions` auszutauschen, zuerst das alte auf `null`.
    * **Die Übergabe eines einzigen verwendet dieses und ignoriert die Umgebung.** Es wird keine Credential-Umgebungsvariable und kein Profil auf der Festplatte gelesen. Ebenso gibt `AnthropicCredentials.Resolve(profile: "name")` jetzt die Credentials dieses Profils zurück, wenn `ANTHROPIC_API_KEY` oder `ANTHROPIC_AUTH_TOKEN` gesetzt ist.
    * **Wenn keines übergeben wird, 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 seiner ersten Verwendung, daher löst ein nicht existierendes `ANTHROPIC_PROFILE` jetzt bei der ersten Anfrage statt im Konstruktor einen Fehler aus.
    * **`WithOptions` ersetzt.** Ein im Modifier übergebenes Credential ersetzt das des Clients, unabhängig von dessen Art, daher benötigt `AuthToken = token` kein `ApiKey = null` mehr daneben. Wenn keines übergeben wird, behält die Kopie das Credential, die `BaseUrl` und die `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 Credentials, 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 von ihnen 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 darauf angewiesen warst, 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 ein Credential pro Anfrage.
  </Tab>

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

    * **Zwei davon an `anthropic.NewClient` übergeben sind 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: Das Credential, das es in der Umgebung findet, zählt dann als eines, das du übergeben hast.
    * **Eines davon wird unverändert verwendet.** Es wird kein Credential 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.
    * **Wenn keines davon übergeben wird, wird das erste der folgenden verwendet, das 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.
    * **Eines davon bei einer Anfrage ersetzt das Credential des Clients für diese Anfrage,** daher benötigt `option.WithAuthToken` kein `option.WithHeaderDel("X-Api-Key")` mehr daneben.

    ```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 protokolliert hat, gibt es nicht mehr, 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 darauf angewiesen warst, 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 ein Credential 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 ein Credential enthielt.
  </Tab>

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

    * **Setze höchstens eines.** Bei zweien auf einem Builder löst `build()` eine `IllegalStateException` aus, die sie benennt. `null` oder ein leeres `Optional` zählt nicht.
    * **Das gesetzte ist das einzige.** `fromEnv()`, davor oder danach aufgerufen, übernimmt kein Credential aus der Umgebung oder aus einem Profil auf der Festplatte. In v2 konnte ein Key oder Token, den `fromEnv()` gefunden hatte, zusätzlich oder stattdessen gesendet werden.
    * **Wenn keines gesetzt ist, verwendet `fromEnv()` das erste der folgenden, das 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 darauf angewiesen warst, 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 ein Credential pro Anfrage.
  </Tab>

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

    * Die Übergabe von mehr als einem davon löst `\InvalidArgumentException` aus. Nur `null` gilt als nicht übergeben. Ein leerer String gilt als übergeben, daher sendet `new Client(apiKey: '')` kein Credential.
    * Die Übergabe eines einzigen verwendet dieses, und es wird kein Credential aus der Umgebung oder aus einem Profil auf der Festplatte gelesen. Wenn `ANTHROPIC_API_KEY` gesetzt ist, sendet `new Client(authToken: $token)` das Token. Frühere Versionen sendeten den Key aus der Umgebung mit.
    * Wenn keines übergeben wird, wird das erste der folgenden verwendet, das 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 Datei `active_config` gab. Sie übersprangen außerdem ein `ANTHROPIC_PROFILE`, das ein fehlendes oder ungültiges Profil benannte. In diesem Fall löst `new Client()` jetzt `Anthropic\Core\Exceptions\AnthropicException` aus. 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 mit `error_log()` eine Warnung, 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 darauf angewiesen warst, 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 Aufruf von `withoutHeader`. Lass das Gateway seinen `Authorization`-Header entfernen, bevor es die Anfrage weiterleitet. Die Claude API erwartet ein Credential pro Anfrage.
  </Tab>

  <Tab title="Ruby">
    Die Credential-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:` einen Fehler aus und sendeten andernfalls den Key, falls vorhanden, dann das Token.
    * **Eines übergeben:** Der Client verwendet es und greift nicht auf ein Credential aus der Umgebung oder aus einem Profil auf der Festplatte zurück.
    * **Keines übergeben:** Der Client verwendet das erste der folgenden, das 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 kein Credential übergeben wird und sowohl `ANTHROPIC_API_KEY` als auch `ANTHROPIC_AUTH_TOKEN` gesetzt sind, warnt das SDK außerdem einmal pro Prozess, auf Standard Error ü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 die Warnung zu unterdrücken.

    ```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">
  <Tab title="CLI">
    **`--api-key` und `--auth-token` wurden entfernt.** `ant` nimmt keinen API-Key und kein Auth-Token mehr als Flag-Wert entgegen, da ein Wert in 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               | Verwende stattdessen                                         |
    | ---------------------- | ------------------------------------------------------------ |
    | `--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 Anmeldedaten 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 anhand von `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="Go">
    **`vertex.DefaultVersion` und `bedrock.DefaultVersion` wurden entfernt.**
  </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 Anmeldedaten 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()` hieß
    * `responseValidation()`, `timeout()`, `followRedirects()`, `fallbackState()` und `openTelemetry()` auf `RequestOptions`, die zuvor `getResponseValidation()`, `getTimeout()`, `getFollowRedirects()`, `getFallbackState()` und `getOpenTelemetry()` hießen

    ```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 Requests gesendet werden. Das ist die Basis-URL, die du festgelegt hast, 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, lege seine Basis-URL fest. Ohne eine solche wirft `build()` jetzt eine `IllegalStateException`. In v2 gab es einen Request zurück, dessen `baseUrl()` `null` war. Die Requests, 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">
    **Enum-Cases, die du übergibst, werden als ihre Werte zurückgelesen.** `with()` und Setter wie `withAllowedCallers()` nehmen weiterhin einen Enum-Case oder dessen Wert entgegen. Frühere Versionen behielten einen Case so bei, wie du ihn übergeben hast. v1 behält den Wert des Case, 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, also vergleiche sie mit dem Wert des Case:

    ```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>

  <Tab title="Ruby">
    **`Anthropic::VertexClient::DEFAULT_VERSION` und `Anthropic::BedrockClient::DEFAULT_VERSION` wurden entfernt.**
  </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 Plattformpakete (`@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 betrifft jedes `com.anthropic`-Artefakt.
