---
title: Migrer vers la version d'API 2026-10-21
url: https://platform.claude.com/docs/fr/api/migration-2026-10-21
description: "Mettez à niveau une intégration de l'API Claude de la version d'API 2023-06-01 vers 2026-10-21 : la version du SDK à installer et les modifications de code à effectuer."
---

Ce guide répertorie les modifications de code nécessaires pour passer de la version d'API `2023-06-01` à `2026-10-21`. Les [étapes de mise à niveau](https://platform.claude.com/docs/fr/api/migration-2026-10-21#migration-checklist) indiquent ce qu'il faut faire, dans l'ordre.

## Étapes de mise à niveau

<Steps>
  <Step title="Passer à 2026-10-21">
    Si vous utilisez un SDK, vos requêtes utilisent la version d'API qui était en vigueur lors de la publication de la version majeure de votre SDK. Les versions indiquées pour votre langage sont les premières à utiliser `2026-10-21` ; mettez donc à niveau vers celles-ci. Si vous appelez l'API sans SDK, définissez l'en-tête `anthropic-version` sur `2026-10-21`.

    <Tabs>
      <Tab title="cURL">
        Définissez l'en-tête `anthropic-version` sur `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">
        Mettez à niveau la CLI `ant` vers la version 2.0.0. La commande Homebrew et les téléchargements des versions restent les mêmes.

        Go exige que le chemin d'un module en version majeure 2 ou ultérieure se termine par cette version ; le chemin de module de la CLI est donc désormais `github.com/anthropics/anthropic-cli/v2`. Si vous installez avec `go install`, ajoutez `/v2` au chemin :

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

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

        L'ancien chemin continue d'installer la dernière version v1, sans erreur ni avertissement.
      </Tab>

      <Tab title="Python">
        Mettez à niveau le paquet `anthropic` vers la version 2.0.0.
      </Tab>

      <Tab title="TypeScript">
        Mettez à niveau le paquet `@anthropic-ai/sdk` vers la version 1.0.0.

        La v1 de `@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` et `@anthropic-ai/google-cloud-sdk` nécessite la v1 de `@anthropic-ai/sdk`, et leurs versions antérieures nécessitent une version inférieure à 1. Si vous utilisez l'un d'eux, passez-le en v1 lors de la même mise à niveau. Sinon, votre gestionnaire de paquets installe pour lui une seconde copie, plus ancienne, de `@anthropic-ai/sdk`.
      </Tab>

      <Tab title="C#">
        Mettez à niveau le paquet `Anthropic` vers la version 13.0.0.
      </Tab>

      <Tab title="Go">
        Mettez à niveau vers la version 2.0.0 du SDK Go, dont le chemin de module est `github.com/anthropics/anthropic-sdk-go/v2`. Une nouvelle version majeure d'un module Go a un nouveau chemin d'importation ; modifiez donc chaque importation de `github.com/anthropics/anthropic-sdk-go`, et de ses paquets tels que `github.com/anthropics/anthropic-sdk-go/option`, pour qu'elle commence par `github.com/anthropics/anthropic-sdk-go/v2`. Exécutez ensuite `go get github.com/anthropics/anthropic-sdk-go/v2`.
      </Tab>

      <Tab title="Java">
        Mettez à niveau l'artefact `com.anthropic:anthropic-java` vers la version 3.0.0.
      </Tab>

      <Tab title="PHP">
        Exécutez `composer require "anthropic-ai/sdk"` pour mettre à niveau le paquet vers la version 1.0.0. `composer update` seul reste dans les limites de votre contrainte de version actuelle.
      </Tab>

      <Tab title="Ruby">
        Mettez à niveau la gem `anthropic` vers la version 2.0.0.
      </Tab>
    </Tabs>

    <Warning>
      Sur Amazon Bedrock, `2026-10-21` n'est disponible que pour les modèles Claude 4.7 et ultérieurs. Si vous appelez sur Bedrock un modèle plus ancien, répertorié dans [Claude sur Amazon Bedrock (Opus 4.6 et antérieurs)](https://platform.claude.com/docs/fr/build-with-claude/claude-on-amazon-bedrock-legacy), restez sur la version du SDK que vous utilisez aujourd'hui ou, si vous définissez vous-même la version d'API, continuez d'envoyer la version que vous envoyez aujourd'hui. Pour faire passer ces appels à `2026-10-21`, basculez-les d'abord vers un modèle Claude 4.7 ou ultérieur.
    </Warning>

    Publiez la mise à niveau en même temps que vos corrections de l'étape suivante.
  </Step>

  <Step title="Mettre à jour votre code pour les changements incompatibles">
    Parcourez les [changements incompatibles](https://platform.claude.com/docs/fr/api/migration-2026-10-21#breaking-changes) et mettez à jour votre code pour chacun de ceux qui vous concernent. Effectuez également les [modifications de code requises par la nouvelle version du SDK ou de la CLI](https://platform.claude.com/docs/fr/api/migration-2026-10-21#sdk-changes).
  </Step>

  <Step title="Tester avec 2026-10-21">
    Testez votre intégration avec `2026-10-21` avant de la publier.
  </Step>
</Steps>

## Changements incompatibles

### API Messages

Ces changements s'appliquent aux requêtes vers l'API Messages (`POST /v1/messages`), au [comptage des tokens](https://platform.claude.com/docs/fr/build-with-claude/token-counting) et à chaque requête d'un [Message Batch](https://platform.claude.com/docs/fr/build-with-claude/batch-processing) créé avec `2026-10-21`.

#### Les blocs de document dans les messages de l'assistant renvoient une erreur

Vous concerne si vous envoyez des blocs `document` directement dans des messages `assistant`.

Dans `2026-10-21`, une requête qui place un bloc `document` directement dans un message `assistant` renvoie une erreur 400. Envoyez plutôt les documents dans des messages `user`. Un document imbriqué dans un autre bloc, comme un résultat de l'outil de récupération web renvoyé par Claude, est toujours accepté.

#### Les citations dans les messages de l'utilisateur renvoient une erreur

Vous concerne si vous envoyez des `citations` sur des blocs `text` dans des messages `user`, y compris à l'intérieur de blocs `search_result`.

Dans `2026-10-21`, une requête qui envoie un bloc `text` avec un tableau `citations` non vide dans un message `user` renvoie une erreur 400. Supprimez `citations` de ces blocs. Les citations sur les blocs `text` dans les messages `assistant`, comme les réponses précédentes de Claude que vous renvoyez, sont toujours acceptées, de même que le paramètre `"citations": {"enabled": true}` sur les documents et les résultats de recherche.

#### Les paramètres d'échantillonnage sont supprimés

Vous concerne si vous envoyez `temperature`, `top_p` ou `top_k` dans des requêtes Messages ou des requêtes Message Batch.

Dans `2026-10-21`, une requête qui envoie `temperature`, `top_p` ou `top_k` renvoie une erreur 400, même avec la valeur par défaut du paramètre.

Supprimez ces trois paramètres de vos requêtes.

Depuis les dernières versions majeures, le SDK et la CLI ne comportent plus ces trois paramètres.

Sans ces paramètres, une requête échantillonne avec leurs valeurs par défaut, y compris une `temperature` de 1.0, comme une requête `2023-06-01` qui les omet. Les modèles qui n'acceptent déjà que les valeurs par défaut, comme les modèles Claude 4.7 et ultérieurs, échantillonnent comme auparavant. Sur les modèles qui acceptent d'autres valeurs, comme Claude Sonnet 4.6, une requête qui abaissait `temperature` pour obtenir une sortie plus cohérente perd cet effet. Aucun autre paramètre ne le remplace. Si une requête dépend d'une valeur autre que celle par défaut, cessez d'envoyer le paramètre ou conservez cette requête sur `2023-06-01`.

### Admin API et Claude Enterprise Analytics API

Vous concerne si votre code lit les champs de réponse de l'Admin API ou de la Claude Enterprise Analytics API figurant dans les tableaux suivants.

Dans `2026-10-21`, les réponses de l'Admin API et de la [Claude Enterprise Analytics API](https://platform.claude.com/docs/fr/manage-claude/analytics-api) n'incluent plus les anciens noms des champs renommés. Utilisez plutôt les nouveaux noms.

Admin API :

| Endpoints                                                                                                                                                                                                                                                                                                           | Ancien nom     | Nouveau nom                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Groupes RBAC](https://platform.claude.com/docs/fr/api/beta/organization/rbac_groups/list) : création, liste, récupération et mise à jour                                                                                                                                                                           | `roles`        | `role_ids`                                                                                                                                                |
| [Membres des groupes RBAC](https://platform.claude.com/docs/fr/api/beta/organization/rbac_groups/members/list) : liste et ajout, ainsi que la réponse à la [suppression d'un membre](https://platform.claude.com/docs/fr/api/beta/organization/rbac_groups/members/remove)                                          | `group_id`     | `rbac_group_id`                                                                                                                                           |
| [Rôles RBAC](https://platform.claude.com/docs/fr/api/beta/organization/rbac_roles/list) : liste et récupération                                                                                                                                                                                                     | `name`         | `display_name`                                                                                                                                            |
| Limites de débit de l'[organisation](https://platform.claude.com/docs/fr/api/organization/rate_limits/list) et de l'[espace de travail](https://platform.claude.com/docs/fr/api/organization/workspaces/rate_limits/list) : liste, ainsi que la réponse à la définition des limites de débit d'un espace de travail | `group_type`   | `group.type`                                                                                                                                              |
| [Clés API](https://platform.claude.com/docs/fr/api/organization/api_keys/list) : liste, récupération et mise à jour                                                                                                                                                                                                 | `workspace_id` | `scope` (valeurs différentes ; voir [`workspace_id` sur les clés API](https://platform.claude.com/docs/fr/api/migration-2026-10-21#api-key-workspace-id)) |

Claude Enterprise Analytics API :

| Endpoints                                                                                                                                                                                                                                    | Ancien nom    | Nouveau nom           |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------- |
| Rapports d'[utilisation](https://platform.claude.com/docs/fr/api/beta/organization/analytics/user_usage_report/list) et de [coût](https://platform.claude.com/docs/fr/api/beta/organization/analytics/user_cost_report/list) par utilisateur | `actor.email` | `actor.email_address` |
| [Résumés d'activité](https://platform.claude.com/docs/fr/api/beta/organization/analytics/summaries/list)                                                                                                                                     | `summaries`   | `data`                |

Le paramètre de requête `group_type` sur les endpoints de liste des limites de débit et le filtre `workspace_id` sur l'endpoint de liste des clés API sont inchangés.

#### `workspace_id` sur les clés API

Vous concerne si votre code lit `workspace_id` sur les clés API.

Dans `2023-06-01`, le `workspace_id` d'une clé API est l'ID de l'espace de travail auquel la clé est liée, ou `null` pour une clé liée au Default Workspace et pour une clé qui n'est pas liée à un seul espace de travail (une clé pour tous les espaces de travail).

Dans `2026-10-21`, `workspace_id` est supprimé. Lisez plutôt `scope` : pour une clé liée à un espace de travail, y compris le Default Workspace, `scope.workspace_id` est l'ID réel de cet espace de travail, et une clé pour tous les espaces de travail a un `scope` de `{"type": "organization"}`, sans `workspace_id`.

Si votre code traitait un `workspace_id` `null` comme le Default Workspace, comparez plutôt `scope.workspace_id` avec l'ID de votre Default Workspace. Pour trouver cet ID, appelez [List Workspaces](https://platform.claude.com/docs/fr/api/organization/workspaces/list) avec `include_default=true` et prenez l'espace de travail nommé `"Default"`.

## Modifications du SDK et de la CLI

Les versions antérieures du SDK et de la CLI envoyaient `anthropic-version: 2023-06-01` avec chaque requête. Les versions indiquées sous [Passer à 2026-10-21](https://platform.claude.com/docs/fr/api/migration-2026-10-21#upgrade) envoient `2026-10-21`, y compris leurs clients Amazon Bedrock et Google Cloud. Les modifications décrites dans [Changements incompatibles](https://platform.claude.com/docs/fr/api/migration-2026-10-21#breaking-changes) s'appliquent également à elles : les paramètres supprimés et les anciens noms de champs ont aussi disparu des types du SDK ainsi que des options et de la sortie de la CLI.

### `MessageParam` est une union avec un type par rôle

Dans les versions antérieures, `MessageParam` était un seul type pour tous les rôles. Chaque rôle a désormais son propre type : `UserMessageParam`, `AssistantMessageParam` et `SystemMessageParam`. `BetaMessageParam` est divisé de la même manière, en `BetaUserMessageParam`, `BetaAssistantMessageParam` et `BetaSystemMessageParam`. Les requêtes envoyées par le SDK ont les mêmes champs et valeurs qu'auparavant.

<Tabs exclude="shell">
  <Tab title="Python">
    Un message écrit sous forme de littéral dict, comme `{"role": "user", "content": "Hello"}`, ne nécessite aucune modification.

    Dans la v1, `anthropic.types.MessageParam` était un seul `TypedDict`. Dans la v2, c'est une union des trois types, et `anthropic.types.beta.BetaMessageParam` est une union de ses trois types. Les deux noms fonctionnent toujours dans les annotations, comme `list[MessageParam]`.

    Appeler l'un ou l'autre de ces noms lève désormais une `TypeError`, et un vérificateur de types le signale. Écrivez le message sous forme de dict :

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

    # Après
    message: MessageParam = {"role": "user", "content": "Hello"}
    ```

    Hériter de l'un ou l'autre de ces noms lève également une `TypeError`. Héritez du type correspondant au rôle, comme `UserMessageParam`.

    Les autres modifications n'affectent que la vérification des types. Un dict dont le `role` est une variable pouvant contenir plus d'un rôle ne correspond à aucun type de l'union ; construisez donc le dict pour un rôle à la fois :

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


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

    Deux autres s'appliquent uniquement à `BetaMessageParam` :

    * `clear_at` et `output_config` sont des clés de `BetaSystemMessageParam` ; un message utilisateur ou assistant ne peut donc pas les avoir.
    * `content` est facultatif dans `BetaSystemMessageParam` ; pyright signale donc `message["content"]`. Lisez-le avec `message.get("content")`, ou vérifiez d'abord que `message["role"]` n'est pas `"system"`.
  </Tab>

  <Tab title="TypeScript">
    `MessageParam` était une seule interface. C'est désormais `UserMessageParam | AssistantMessageParam | SystemMessageParam`, et `BetaMessageParam` est la même union de ses trois types. Seuls les types ont changé. Un littéral de message qui nomme son rôle, comme `{ role: "user", content: "Hello, Claude" }`, passe la vérification des types comme auparavant ; la plupart du code ne nécessite donc aucune modification.

    Le type système diffère des deux autres. Son `content` est une chaîne ou des blocs de texte, plus des blocs `tool_addition` et `tool_removal` en `beta` ; un bloc d'image à cet endroit ne compile donc plus. En `beta`, lui seul possède `clear_at` et `output_config`, et son `content` est facultatif.

    Le code qui traite un message de n'importe quel rôle doit vérifier `role` avant de remplacer ou d'ajouter des blocs de contenu, et avant de lire `clear_at` ou `output_config` :

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

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

    Le `content` d'un `BetaMessageParam` peut être `undefined` :

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

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

    Le type `BetaMessageParam["content"]` inclut également `undefined`. Pour le contenu d'un message utilisateur ou assistant, utilisez `BetaMessageContentParam`.

    Une interface ne peut pas étendre une union, et une classe ne peut pas en implémenter une. Utilisez un alias de type, ou nommez plutôt le type d'un seul rôle.

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

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

  <Tab title="C#">
    Dans la v12, `MessageParam` et `BetaMessageParam` étaient des classes dont vous définissiez `Role` et `Content`. Dans la v13, chacune est une union des trois classes correspondant à ses rôles, et les enums `Role` dans `Anthropic.Models.Messages` et `Anthropic.Models.Beta.Messages` ont disparu.

    Lorsque vous construisez un message, nommez la classe correspondant à son rôle et supprimez `Role`. Chaque classe se convertit implicitement en l'union :

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

    // Après
    Messages = [new UserMessageParam { Content = "Hello, Claude" }],
    ```

    `new UserMessageParam("Hello, Claude")` fonctionne également.

    Les classes qui contiennent `Content` changent aussi :

    * `MessageParamContent` est désormais `MessageContentParam`, et `BetaMessageParamContent` est désormais `BetaMessageContentParam`.
    * Un message système a sa propre classe de contenu. Un `SystemMessageParamContent` contient une chaîne ou une liste de `TextBlockParam`, et un `BetaSystemMessageParamContent` contient une chaîne ou une liste de `SystemMessageContentBlock`. Une `List<ContentBlockParam>` ou une `List<BetaContentBlockParam>` ne s'y convertit plus.
    * `ClearAt` et `OutputConfig` se trouvent uniquement sur `BetaSystemMessageParam`.

    Lorsque vous lisez un message, l'union possède toujours `Role` et `Content`, mais vous ne pouvez pas les définir ; une expression `with` s'applique donc à la classe correspondant au rôle. `Role` contient désormais un `MessageParamRole` ou un `BetaMessageParamRole`. `BetaMessageParam.Content` peut être `null`, car `Content` est facultatif sur `BetaSystemMessageParam`.

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

    // Après
    if (message.Role.Value() == MessageParamRole.Assistant) { }
    ```

    `TryPickUser`, `TryPickAssistant`, `TryPickSystem`, `Switch` et `Match` vous donnent la classe correspondant au rôle.
  </Tab>

  <Tab title="Go">
    Dans la v1, `MessageParam` était une seule struct avec un champ `Role` et un champ `Content`. Dans la v2, c'est une union : `OfUser` contient un `*UserMessageParam`, `OfAssistant` un `*AssistantMessageParam` et `OfSystem` un `*SystemMessageParam`. `BetaMessageParam` change de la même manière. Le SDK envoie le même JSON qu'auparavant, à l'exception de l'ordre des clés dans un message système beta.

    `NewUserMessage`, `NewAssistantMessage`, `NewBetaUserMessage` et les méthodes `ToParam` de `Message` et `BetaMessage` fonctionnent comme auparavant ; le code qui construit ses messages avec elles ne nécessite donc aucune modification.

    Un littéral de struct nomme le type correspondant à son rôle. Omettez `Role`, car chaque type sérialise le sien :

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

    // Après
    anthropic.MessageParam{OfAssistant: &anthropic.AssistantMessageParam{
    	Content: blocks,
    }}
    ```

    Le code qui lit un message vérifie quel champ est défini :

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

    // Après
    if message.OfUser != nil {
    	blocks = message.OfUser.Content
    }
    ```

    * Les types `MessageParamRole` et `BetaMessageParamRole` et leurs constantes ont disparu. `message.GetRole()` renvoie un pointeur vers le rôle sous forme de `string`, ou `nil` lorsqu'aucun champ n'est défini.
    * `ClearAt` et `OutputConfig` ont été déplacés de `BetaMessageParam` vers `BetaSystemMessageParam`. Les noms du type `BetaMessageParamClearAt` et de ses constantes commencent désormais par `BetaSystemMessageParamClearAt`.
    * `SystemMessageParam.Content` est un `[]TextBlockParam`. `BetaSystemMessageParam.Content` est un `[]BetaSystemMessageParamContentUnion`, qui contient des blocs `text`, `tool_addition` et `tool_removal`. `NewBetaSystemMessage` prend des blocs de ce type ; `anthropic.NewBetaTextBlock("Be brief.")` devient donc `anthropic.BetaSystemMessageParamContentUnion{OfText: &anthropic.BetaTextBlockParam{Text: "Be brief."}}`.
    * Une copie d'un `MessageParam` pointe vers le même message que l'original. Définir `duplicate.OfUser.Content` modifie les deux, alors que définir `duplicate.Content` dans la v1 ne modifiait que la copie.
    * `mcp.ToMessage` renvoie une `*mcp.UnsupportedValueError` pour un rôle autre que `user` ou `assistant`. La v1 copiait n'importe quel rôle dans le message.
  </Tab>

  <Tab title="Java">
    Dans la v2, `MessageParam` était une seule classe avec un `role` et un `content`. Dans la v3, c'est une union des trois classes, et `MessageParam.Content` est désormais le `MessageContentParam` de premier niveau. `BetaMessageParam` change de la même manière, et ses classes portent les mêmes noms avec un préfixe `Beta`. Le JSON envoyé par le SDK est le même, sauf qu'un message système beta a désormais `role` avant `content`.

    `addUserMessage`, `addAssistantMessage` et `addSystemMessage` avec un `String`, `addMessage` avec un `Message` ou un `MessageParam`, ainsi que `Message.toParam()` ne changent pas.

    `MessageParam.builder()` et `toBuilder()` ont disparu. Appelez la méthode de fabrique correspondant au rôle, à savoir `ofUser`, `ofAssistant` ou `ofSystem` :

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

    // Après
    MessageParam message = MessageParam.ofUser("Hello, Claude");
    ```

    Les méthodes qui prennent une liste de blocs de contenu ont de nouveaux noms sur les builders de `MessageCreateParams`, `StructuredMessageCreateParams`, `MessageCountTokensParams` et `BatchCreateParams.Request.Params` :

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

    Sur la classe de contenu, `BlockParams` (`BetaContentBlockParams` en beta) devient `ContentBlockParams` dans `ofBlockParams`, `blockParams()`, `isBlockParams()`, `asBlockParams()` et le `visitBlockParams` du visiteur.

    Un message système a sa propre classe de contenu, `SystemMessageParam.Content`, que `addSystemMessage` prend désormais. Ses blocs sont des `TextBlockParam`, et non des `ContentBlockParam`. En beta, ce sont des `BetaSystemMessageParam.Content.SystemMessageContentBlock`, qui possède `ofText`, `ofToolAddition` et `ofToolRemoval`.

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

    // Après
    builder.addSystemMessageOfBlocks(List.of(textBlock));
    ```

    Lorsque vous lisez un message, `role()` ne change pas. `content()` renvoie un `MessageContentParam`, ou un `Optional<BetaMessageContentParam>` en beta, où un message système peut ne pas avoir de contenu. `_role()`, `_content()` et `_additionalProperties()` se trouvent désormais sur la classe correspondant au rôle, que renvoie `asUser()`, `asAssistant()` ou `asSystem()`.
  </Tab>

  <Tab title="PHP">
    Les classes se trouvent dans `Anthropic\Messages`, et les classes beta dans `Anthropic\Beta\Messages`. Les messages que vous écrivez sous forme de tableaux ne changent pas et nécessitent toujours leur `'role'`.

    `MessageParam::with()` et `BetaMessageParam::with()` sont conservées et renvoient la classe correspondant à `role`. Un appel avec des arguments nommés ne nécessite aucune modification. `role` est désormais le premier paramètre ; dans un appel positionnel, inversez donc `content` et `role`, ou appelez `with()` sur la classe du rôle, qui ne prend pas de `role`. Pour des arguments dans l'ancien ordre, PHP lève une `UnhandledMatchError`, dont PHPStan n'avertit pas, ou une `TypeError` si `content` est une liste ou si `role` est un cas d'enum.

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

    // Après
    UserMessageParam::with('Hello, Claude');
    ```

    Aucun objet n'est plus un `MessageParam` : `instanceof MessageParam` est faux, et PHP lève une `TypeError` là où un type de paramètre ou de retour le nomme. Nommez plutôt les trois classes :

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

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

    * `MessageParam::fromArray()` et `(new MessageParam)->withContent()` lèvent « Call to undefined method ». Appelez-les sur la classe du rôle, qui définit elle-même `role`.
    * `withRole()` ne prend désormais que la chaîne : PHP lève une `TypeError` pour un cas de `Role`. Pour donner un autre rôle à un message, construisez la classe de ce rôle.
    * `clearAt` et `outputConfig` n'existent que sur `BetaSystemMessageParam`, et `BetaMessageParam::with()` les ignore pour les deux autres rôles. L'enum `BetaMessageParam\ClearAt` est désormais `BetaSystemMessageParam\ClearAt`.
    * `MessageParam\Content` est désormais `MessageContentParam`, et `BetaMessageParam\Content` est désormais `BetaMessageContentParam`. Leurs types PHPStan prennent également le nouveau nom : `ContentShape` est désormais `MessageContentParamShape`.
    * Un tableau dont le `'role'` est un cas de `Role` fonctionne toujours, mais PHPStan le signale désormais. Écrivez la chaîne.
  </Tab>

  <Tab title="Ruby">
    Les messages que vous écrivez sous forme de hashes ne changent pas.

    Dans la v2, `Anthropic::MessageParam` est une union de `Anthropic::UserMessageParam`, `Anthropic::AssistantMessageParam` et `Anthropic::SystemMessageParam`. De la même manière, `Anthropic::Beta::BetaMessageParam` est une union de ses trois classes.

    `Anthropic::MessageParam.new(role: :user, content: "Hello, Claude")` fonctionne toujours et renvoie une instance de la classe correspondant à ce rôle. Vous pouvez également construire cette classe vous-même, sans `role:`, sous la forme `Anthropic::UserMessageParam.new(content: "Hello, Claude")`. Quatre choses changent pour le code qui construit ou inspecte ces instances :

    * `MessageParam.new` ne prend que des mots-clés ; passez donc un hash sous la forme `MessageParam.new(**hash)`. Il lève une `ArgumentError` lorsque `role:` est absent ou n'est pas l'un des trois rôles.
    * `message.is_a?(Anthropic::MessageParam)` vaut `false`. Une branche `when Anthropic::MessageParam` et `messages.grep(Anthropic::MessageParam)` correspondent toujours.
    * Une instance construite avec `.new` n'a pas de `:role` dans son `to_h`, et `message[:role]` vaut `nil`. `message.role` renvoie toujours le rôle.
    * Seul `BetaSystemMessageParam` possède `clear_at` et `output_config`. Sur un message utilisateur ou assistant, ils renvoyaient `nil` et lèvent désormais une `NoMethodError`.

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

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

    Les modules d'enum `Role` sont conservés. Ces constantes ont été déplacées. Les noms qui commencent par `Beta` se trouvent sous `Anthropic::Beta`, et les autres sous `Anthropic` :

    | Supprimé                    | À utiliser à la place                                                                   |
    | --------------------------- | --------------------------------------------------------------------------------------- |
    | `MessageParam::Content`     | `MessageContentParam`, ou `SystemMessageParam::Content` pour un message système         |
    | `BetaMessageParam::Content` | `BetaMessageContentParam`, ou `BetaSystemMessageParam::Content` pour un message système |
    | `BetaMessageParam::ClearAt` | `BetaSystemMessageParam::ClearAt`                                                       |

    Si vous vérifiez les types avec Sorbet, `MessageParam::OrHash` a disparu, et `Anthropic::MessageParam` en tant que type n'accepte plus d'instance. Utilisez `Anthropic::MessageParam::Variants` pour les trois classes, chacune ayant son propre `OrHash`. En RBS, une valeur typée `Anthropic::MessageParam` n'a ni `role` ni `content`. Utilisez l'alias `Anthropic::Models::message_param`, qui était la forme hash d'un message et qui est désormais l'union des trois classes. Les noms beta sont `BetaMessageParam::Variants` et `Anthropic::Models::Beta::beta_message_param`.
  </Tab>
</Tabs>

### Les enums à une seule valeur sont des constantes

Ceci concerne les SDK C#, Go, Java, PHP et Ruby ainsi qu'une option de la CLI. Dans les versions antérieures, un champ obligatoire ne pouvant contenir qu'une seule valeur avait son propre type enum avec un seul membre. Ces champs sont désormais des constantes, et les types enum ont disparu. Le JSON que le SDK envoie et lit est le même.

<Tabs exclude="shell:cURL, python, typescript">
  <Tab title="CLI">
    `--type` est facultatif sur `ant beta:sessions:resources add`. `file` est la seule valeur que `--type` peut prendre à cet endroit ; la v2 l'envoie donc pour vous. Les commandes qui passent encore `--type file` continuent de fonctionner ; il n'y a donc rien à modifier.
  </Tab>

  <Tab title="C#">
    Dans la v12, une telle propriété `required` avait un enum avec un seul membre, comme `BetaManagedAgentsTextBlockType.Text`. Presque toutes sont la propriété `Type` d'une classe sous `Anthropic.Models.Beta` : `Agents`, `DeploymentRuns`, `Deployments`, `Dreams`, `Environments`, `MemoryStores`, `Sessions`, `UserProfiles` et `Vaults`. Dans la v13, ces propriétés sont un `JsonElement` que le constructeur renseigne, comme l'était déjà `TextBlockParam.Type`.

    Une propriété facultative, comme `BetaManagedAgentsGlobToolConfigParams.Type`, conserve son enum. Deux de ces enums ont un nouveau nom :

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

    Lorsque vous construisez un objet, supprimez la propriété :

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

    // Après
    new BetaManagedAgentsTextBlock { Text = "Hello Claude!" };
    ```

    Une classe à laquelle il reste une seule propriété obligatoire gagne également un constructeur qui la prend ; `new BetaManagedAgentsTextBlock("Hello Claude!")` fonctionne donc aussi. Une classe à laquelle il n'en reste aucune se construit avec `new BetaManagedAgentsAlwaysAllowPolicy()`.

    Lorsque vous en lisez une, comparez la chaîne :

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

    // Après
    if (message.Type.GetString() == "agent.message") { }
    ```

    Pour distinguer les variantes d'une union, continuez d'utiliser ses méthodes `TryPick*`, `Switch` et `Match`, qui ne changent pas.
  </Tab>

  <Tab title="Go">
    Un exemple d'un tel type enum et de sa constante est `BetaManagedAgentsTextBlockType` et `BetaManagedAgentsTextBlockTypeText`. Presque tous sont le champ `Type` d'une struct sous `client.Beta` : Agents, Deployments, Deployment Runs, Dreams, Environments, Memory Stores, Sessions, User Profiles et Vaults. Dans la v2, ces champs utilisent un type du paquet `shared/constant`, comme le faisait déjà `TextBlockParam.Type`. Un champ facultatif, comme `BetaManagedAgentsBashToolConfigParams.Type`, conserve son enum.

    Dans une requête, supprimez le champ. Il est sérialisé avec son unique valeur lorsque vous l'omettez :

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

    // Après
    anthropic.BetaManagedAgentsTextBlockParam{
    	Text: "Hello Claude!",
    }
    ```

    Une struct dont le seul champ était ce `Type` a désormais un constructeur, comme `NewBetaManagedAgentsAlwaysAllowPolicyParam()`. En tant que membre d'union, un pointeur vers la struct vide fonctionne également : `OfAlwaysAllow: &anthropic.BetaManagedAgentsAlwaysAllowPolicyParam{}`.

    Dans une réponse, comparez avec la chaîne :

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

    // Après
    switch event.Type {
    case "agent.message":
    }
    ```

    Une variable, un champ ou un paramètre de votre code qui était déclaré avec l'un des types supprimés prend le nouveau type du champ, comme `constant.AgentMessage`. `constant.ValueOf[constant.AgentMessage]()` renvoie sa valeur.

    Les constructeurs d'union changent avec les champs. Ces cinq-là perdent leur argument `type_` :

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

    Ces quatre-là ne prenaient aucun autre argument ; ils ont donc disparu. Définissez le champ de l'union sur un pointeur vers la struct vide, comme `BetaManagedAgentsEventParamsUnion{OfUserInterrupt: &anthropic.BetaManagedAgentsUserInterruptEventParams{}}` :

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

  <Tab title="Java">
    Un exemple d'un tel enum est la classe imbriquée `BetaManagedAgentsTextBlock.Type`, avec son unique membre `TEXT`. Presque tous sont le `type` d'une classe sous `com.anthropic.models.beta` : `agents`, `deploymentruns`, `deployments`, `dreams`, `environments`, `memorystores`, `sessions`, `userprofiles` et `vaults`. Dans la v3, ces champs sont un `JsonValue` que le builder renseigne, comme l'était déjà celui de `TextBlockParam`. Un champ facultatif, comme le `type` de `BetaManagedAgentsBashToolConfigParams`, conserve son enum.

    Lorsque vous construisez un objet, supprimez l'appel :

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

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

    Une classe à laquelle il reste un seul champ obligatoire gagne également une méthode de fabrique qui le prend ; `BetaManagedAgentsTextBlock.of("Hello Claude!")` fonctionne donc aussi. Une classe à laquelle il n'en reste aucun perd `of(type)`, et ses unions perdent la surcharge qui prenait l'enum, comme `ofAlwaysAllow(type)`. Construisez-la avec `BetaManagedAgentsAlwaysAllowPolicy.builder().build()`.

    Lorsque vous en lisez un, `type()` a disparu et `_type()` renvoie le `com.anthropic.core.JsonValue` :

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

    // Après
    if (message._type().equals(JsonValue.from("agent.message"))) {}
    ```

    Pour distinguer les variantes d'une union, continuez d'utiliser ses méthodes `is*()` et `as*()` ainsi que son visiteur, qui ne changent pas.
  </Tab>

  <Tab title="PHP">
    Un exemple d'un tel cas d'enum est `Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock\Type::TEXT`. Presque tous sont le `type` d'une classe Managed Agents sous `Anthropic\Beta`. Ces propriétés sont désormais une chaîne ayant cette unique valeur comme valeur par défaut, comme l'était déjà le `type` de `Anthropic\Messages\TextBlockParam`. Une propriété facultative, comme le `type` de `Anthropic\Beta\Environments\BetaPackages`, conserve son enum.

    `with()` ne prend plus `type`. Supprimez-le : PHP lève « Unknown named parameter » pour un `type:` restant, et dans un appel positionnel, les arguments qui le suivent remontent d'une position.

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

    // Après
    ManagedAgentsTextBlock::with(text: 'Hello Claude!');
    ```

    Là où vous compariez avec un cas d'enum, comparez avec la chaîne :

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

    // Après
    $event->type === 'agent.message';
    ```

    * `withType()` et l'argument `type` de `$client->beta->sessions->resources->add()` ne prennent désormais que la chaîne. Dans `add()`, il vaut `'file'` par défaut ; vous pouvez donc l'omettre.
    * Les requêtes que vous écrivez sous forme de tableaux ne changent pas et nécessitent toujours leur `'type'`.
  </Tab>

  <Tab title="Ruby">
    Un exemple d'une telle constante d'enum est `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock::Type::TEXT`. Presque toutes sont le `type` d'une classe Managed Agents sous `Anthropic::Beta`. Dans la v2, ces champs sont déclarés comme une constante, comme l'était déjà le `type` de `Anthropic::TextBlockParam`. Un champ facultatif, comme le `type` de `Anthropic::Beta::BetaManagedAgentsGlobToolConfigParams`, conserve son enum.

    Remplacez une constante supprimée par son symbole :

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

    # Après
    event.type == :"agent.message"
    ```

    Les requêtes que vous écrivez sous forme de hashes ne changent pas et nécessitent toujours leur `type` :

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

    Lorsque vous construisez une instance de modèle, `type:` a désormais une valeur par défaut ; vous pouvez donc l'omettre : `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock.new(text: "Hello Claude!")`. Il en va de même pour le mot-clé `type:` de `client.beta.sessions.resources.add`.

    Si vous vérifiez les types avec Sorbet, les alias `Type::OrSymbol` et `Type::TaggedSymbol` de ces modules ont disparu avec eux, et les champs sont un `Symbol`. `OrSymbol` autorisait également un `String` ; `.new(type: "text")` ne passe donc plus la vérification des types. Supprimez le mot-clé ou passez `:text`. En RBS, l'alias `type_` de chaque classe a disparu, et le champ est le littéral, comme `:text`.
  </Tab>
</Tabs>

### La compaction côté client est supprimée du tool runner

Cela concerne les SDK TypeScript et Ruby. La « client-side compaction » (compaction côté client) dans le « tool runner » (exécuteur d'outils) a été supprimée au profit de la compaction côté serveur, qui résume la conversation au sein de l'API plutôt qu'au moyen d'une requête supplémentaire du client.

<Tabs exclude="shell, python, csharp, go, java, php">
  <Tab title="TypeScript">
    L'option `compactionControl` et le module `@anthropic-ai/sdk/lib/tools/CompactionControl` ont disparu. L'option a cessé de fonctionner dans la v0.129.0, où la transmettre levait une `AnthropicError`. Elle ne figure pas dans le type des paramètres, donc TypeScript la signale comme une propriété inconnue.

    Pour continuer à compacter automatiquement à partir d'un seuil de tokens :

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

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

    Pour décider vous-même du moment où la conversation est compactée, appelez [`runner.compactBeforeNextTurn()`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/helpers.md#compaction).
  </Tab>

  <Tab title="Ruby">
    L'option `compaction_control:` a disparu. Elle a cessé de fonctionner dans la v1.74.0, où la transmettre levait une `ArgumentError`.

    Pour continuer à compacter automatiquement à partir d'un seuil de tokens :

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

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

    Pour décider vous-même du moment où la conversation est compactée, appelez [`#compact_before_next_turn`](https://github.com/anthropics/anthropic-sdk-ruby/blob/main/helpers.md#compact_before_next_turn---compact-the-conversation) sur le runner.
  </Tab>
</Tabs>

Le seuil de déclenchement doit être d'au moins 50 000 tokens. Consultez [compaction](https://platform.claude.com/docs/fr/build-with-claude/compaction-threshold) pour les autres options (`pause_after_compaction`, `instructions` personnalisées).

### Text Completions est supprimé

L'ancienne API Text Completions est supprimée des SDK TypeScript, Go, Java et Ruby ainsi que de la CLI. Les modèles et fonctionnalités plus récents ne la prennent pas en charge. Utilisez plutôt l'[API Messages](https://platform.claude.com/docs/fr/api/messages).

<Tabs exclude="shell:cURL, python, csharp, php">
  <Tab title="CLI">
    La commande `ant completions create` a disparu.

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

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

    Le texte de la réponse passe du champ `completion` à `content.0.text`, donc un script qui transmettait `--transform completion` transmet désormais `--transform content.0.text`.

    `ant messages create` accepte également `--stream`, mais ses événements ont une autre forme : le texte arrive dans `delta.text` des événements `content_block_delta`, donc `--transform content.0.text` ne s'applique pas à un stream.
  </Tab>

  <Tab title="TypeScript">
    `client.completions` a disparu, ainsi que la classe de ressource `Completions` et les types `Completion`, `CompletionCreateParams`, `CompletionCreateParamsNonStreaming` et `CompletionCreateParamsStreaming`. `AnthropicBedrock` n'a plus non plus de propriété `completions`. Les constantes `HUMAN_PROMPT` et `AI_PROMPT`, que seuls les prompts Text Completions utilisaient, ont également disparu, à la fois en tant qu'exports et en tant que propriétés statiques du client.

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

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

    `client.completions.create({ ..., stream: true })` devient `client.messages.create({ ..., stream: true })` ou `client.messages.stream({ ... })`.
  </Tab>

  <Tab title="Go">
    `client.Completions` a disparu, ainsi que `CompletionService`, `NewCompletionService`, `CompletionNewParams` et `Completion`. `aws.Client` n'a plus non plus de champ `Completions`. `bedrock.DefaultEndpoints` ne répertorie plus `/v1/complete`.

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

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

    `client.Completions.NewStreaming` devient `client.Messages.NewStreaming`.
  </Tab>

  <Tab title="Java">
    `client.completions()` a disparu de `AnthropicClient` et `AnthropicClientAsync`, ainsi que `CompletionService`, `CompletionServiceAsync` et le package `com.anthropic.models.completions` (`CompletionCreateParams` et `Completion`).

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

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

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

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

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

  <Tab title="Ruby">
    `client.completions` a disparu, ainsi que `Anthropic::Resources::Completions`, `Anthropic::CompletionCreateParams` et `Anthropic::Completion`. `Anthropic::BedrockClient` n'a plus non plus de lecteur `completions`. Sur `Anthropic::BedrockMantleClient` et `Anthropic::GoogleCloudClient`, où `completions` levait `NotImplementedError`, la méthode n'existe plus.

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

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

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

### `betas` est supprimé des méthodes Models non bêta

Les méthodes Models non bêta n'acceptent plus `betas` (csharp, go: `Betas`; java: `.addBeta()`), et les commandes `ant models` n'acceptent plus `--beta`. Pour envoyer des en-têtes bêta, appelez les mêmes méthodes sur `client.beta.models` (csharp, go: `client.Beta.Models`; java: `client.beta().models()`; php: `$client->beta->models`), ou `ant beta:models` dans la CLI. Dans le SDK, ces méthodes renvoient `BetaModelInfo` (ruby: `Anthropic::Beta::BetaModelInfo`) là où les méthodes non bêta renvoient `ModelInfo` (ruby: `Anthropic::ModelInfo`).

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

    # Après
    ant beta:models list --beta "$BETA"
    ```
  </Tab>

  <Tab title="Python">
    `client.models.retrieve()` et `client.models.list()` n'acceptent plus `betas` (le transmettre provoque une `TypeError`, et un vérificateur de types le signale), et `anthropic.types.ModelListParams` n'a plus de clé `betas`.

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

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

  <Tab title="TypeScript">
    `Anthropic.ModelRetrieveParams` et `Anthropic.ModelListParams` n'ont plus de propriété `betas`.

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

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

  <Tab title="C#">
    `ModelRetrieveParams` et `ModelListParams` dans `Anthropic.Models.Models` n'ont plus de propriété `Betas`. Les méthodes de `client.Beta.Models` acceptent les classes de mêmes noms dans `Anthropic.Models.Beta.Models`.

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

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

    // Après
    using Anthropic.Models.Beta.Models;

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

  <Tab title="Go">
    `ModelGetParams` et `ModelListParams` n'ont plus de champ `Betas`.

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

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

  <Tab title="Java">
    `ModelRetrieveParams` et `ModelListParams` dans `com.anthropic.models.models` n'ont plus `betas()`, et leurs builders n'ont plus `betas` ni `addBeta`. Les méthodes de `client.beta().models()` acceptent les classes de mêmes noms dans `com.anthropic.models.beta.models`.

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

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

    // Après
    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()` et `$client->models->list()` n'acceptent plus `betas` (le transmettre lève `Error: Unknown named parameter $betas`), et `Anthropic\Models\ModelRetrieveParams` et `Anthropic\Models\ModelListParams` n'ont plus de propriété `betas`.

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

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

    Si vous transmettez les arguments par position, `workspaceID` et `requestOptions` remontent chacun d'une place dans les deux méthodes.
  </Tab>

  <Tab title="Ruby">
    `client.models.retrieve` et `client.models.list` n'acceptent plus `betas:`, et `Anthropic::ModelRetrieveParams` et `Anthropic::ModelListParams` n'ont plus de champ `betas`.

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

    # Après
    page = client.beta.models.list(betas: [beta])
    ```

    Transmettre `betas:` à `client.models` ne lève pas d'erreur, mais ne définit plus l'en-tête `anthropic-beta`.
  </Tab>
</Tabs>

### Les clés API sont envoyées sous la forme `Authorization: Bearer`

Le SDK et la CLI envoient votre clé API sous la forme `Authorization: Bearer <key>` au lieu de l'en-tête `X-Api-Key`. Modifiez donc tout proxy ou passerelle qui lit ou définit `X-Api-Key` pour qu'il utilise `Authorization`, ou [envoyez vous-même la clé dans `X-Api-Key`](https://platform.claude.com/docs/fr/api/migration-2026-10-21#sdk-proxy-x-api-key). L'API Claude accepte une clé dans l'un ou l'autre en-tête, donc un programme qui communique directement avec l'API ne nécessite aucune modification.

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

# After
Authorization: Bearer <key>
```

<Tabs>
  <Tab title="CLI">
    Cela s'applique à une clé dans `ANTHROPIC_API_KEY` et à une clé transmise via un pipe à `--api-key-stdin`.

    Avec `--debug`, le journal des requêtes affiche désormais `Authorization: Bearer <REDACTED>` là où il affichait `X-Api-Key: <REDACTED>`.
  </Tab>

  <Tab title="Python">
    `Authorization` est l'en-tête que `auth_token` utilise déjà.

    Cela s'applique à l'argument `api_key` et à la variable d'environnement `ANTHROPIC_API_KEY` de `Anthropic` et `AsyncAnthropic`, ainsi qu'à `api_key` et `ANTHROPIC_AWS_API_KEY` de `AnthropicAWS`. `AnthropicFoundry` envoie toujours sa clé sous la forme `x-api-key`, et `AnthropicBedrockMantle` envoyait déjà un jeton bearer.
  </Tab>

  <Tab title="TypeScript">
    `Authorization` est l'en-tête que l'option `authToken` utilise déjà.

    Cela s'applique à l'option `apiKey`, à la variable d'environnement `ANTHROPIC_API_KEY`, ainsi qu'à `apiKey` et `ANTHROPIC_AWS_API_KEY` dans `@anthropic-ai/aws-sdk`. `apiKey` dans `@anthropic-ai/foundry-sdk` est toujours envoyé sous la forme `X-Api-Key`, et `apiKey` dans `@anthropic-ai/bedrock-sdk` était déjà un jeton bearer.

    Un « middleware » (intergiciel) ou un `fetch` personnalisé qui lit la clé dans l'en-tête de requête `x-api-key` doit désormais lire `authorization`, où la clé suit `Bearer `.
  </Tab>

  <Tab title="C#">
    `Authorization` est l'en-tête que `AuthToken` utilise déjà.

    Cela s'applique à `ApiKey` sur `AnthropicClient` et `ClientOptions` ainsi qu'à la variable d'environnement `ANTHROPIC_API_KEY`. Dans la version de `Anthropic.Aws` qui dépend de la v13, cela s'applique également à `ApiKey` dans `AwsClientOptions` et à `ANTHROPIC_AWS_API_KEY`. `AnthropicFoundryApiKeyCredentials` envoie toujours sa clé sous la forme `x-api-key`, et `ApiKey` dans `MantleAwsClientOptions` était déjà un jeton bearer.
  </Tab>

  <Tab title="Go">
    Cela s'applique à `option.WithAPIKey`, à la variable d'environnement `ANTHROPIC_API_KEY` et à `APIKey` dans `aws.ClientConfig` (ou `ANTHROPIC_AWS_API_KEY`). `APIKey` dans `foundry.ClientConfig` (ou `ANTHROPIC_FOUNDRY_API_KEY`) est toujours envoyé sous la forme `X-Api-Key`, et `APIKey` dans `bedrock.MantleClientConfig` était déjà un jeton bearer.
  </Tab>

  <Tab title="Java">
    `Authorization` est l'en-tête que `authToken` utilise déjà.

    Cela s'applique à `apiKey` sur les builders `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` et `AnthropicBackend`, à la variable d'environnement `ANTHROPIC_API_KEY` et à la propriété système `anthropic.apiKey`. `apiKey` sur le builder `FoundryBackend` est toujours envoyé sous la forme `x-api-key`. `apiKey` sur les builders `AwsBackend`, `BedrockBackend` et `BedrockMantleBackend` était déjà un jeton bearer.

    Un intercepteur voit désormais la clé dans `Authorization` au lieu de `X-Api-Key`.
  </Tab>

  <Tab title="PHP">
    `Authorization` est l'en-tête que `authToken` utilise déjà.

    Cela s'applique à l'argument `apiKey` et à la variable d'environnement `ANTHROPIC_API_KEY` de `Anthropic\Client`, ainsi qu'à `apiKey` et `ANTHROPIC_AWS_API_KEY` de `Anthropic\Aws\Client`. `Anthropic\Foundry\Client` envoie toujours sa clé sous la forme `x-api-key`, et `Anthropic\Bedrock\MantleClient` envoyait déjà un jeton bearer.
  </Tab>

  <Tab title="Ruby">
    `Authorization` est l'en-tête que `auth_token:` utilise déjà.

    Cela s'applique à l'argument `api_key:` et à la variable d'environnement `ANTHROPIC_API_KEY` de `Anthropic::Client`, ainsi qu'à `api_key:` et `ANTHROPIC_AWS_API_KEY` de `Anthropic::AWSClient`. `Anthropic::BedrockMantleClient` envoyait déjà un jeton bearer.

    Le SDK supprime `Authorization` lorsqu'il suit une redirection vers une autre origine, ce qui inclut une redirection de `http` vers `https` sur le même hôte. La clé y est désormais également supprimée.
  </Tab>
</Tabs>

#### Si un proxy ou une passerelle lit `X-Api-Key`

<Tabs exclude="shell:cURL">
  <Tab title="CLI">
    Si `--base-url` ou `ANTHROPIC_BASE_URL` dirige `ant` vers un proxy ou une passerelle qui lit `X-Api-Key`, modifiez-le pour qu'il lise la clé dans `Authorization`. `ant` n'a aucun flag ni aucune variable d'environnement permettant d'ajouter votre propre en-tête, il ne peut donc pas envoyer `X-Api-Key`.
  </Tab>

  <Tab title="Python">
    Replacez la clé dans son ancien en-tête avec une fonction `auth` sur le client HTTP. Elle s'exécute à chaque requête envoyée par le client, y compris les nouvelles tentatives :

    ```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` accepte la même fonction, dans `http_client=DefaultAsyncHttpxClient(auth=send_x_api_key)`.
  </Tab>

  <Tab title="TypeScript">
    Définissez l'en-tête vous-même. `Authorization: null` empêche également la clé d'y être envoyée :

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

    Si le proxy ajoute l'identifiant et que votre client n'en a aucun, la v0 vous permettait de l'indiquer avec `"X-Api-Key": null` ou `Authorization: null` dans `defaultHeaders`. La v1 n'accepte que `Authorization: null`.

    Le poller et le worker de travail d'environnement reçoivent leur propre clé, ils excluent donc les en-têtes par défaut `X-Api-Key` et `Authorization` de leurs propres requêtes.
  </Tab>

  <Tab title="C#">
    Définissez l'en-tête vous-même avec `ExtraHeaders`. Définir `ApiKey` et `AuthToken` sur `null` empêche également l'envoi d'un identifiant trouvé dans `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` :

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

  <Tab title="Go">
    Définissez l'en-tête vous-même. `option.WithHeaderDel` empêche également l'envoi d'une clé trouvée dans `ANTHROPIC_API_KEY` :

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

    `environments.WorkPoller` et `environments.EnvironmentWorker` reçoivent leur propre clé, ils excluent donc un `X-Api-Key` défini manuellement de leurs propres requêtes.
  </Tab>

  <Tab title="Java">
    Définissez l'en-tête vous-même au lieu d'appeler `apiKey` :

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

  <Tab title="PHP">
    Replacez la clé dans son ancien en-tête avec un middleware :

    ```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]]);
    ```

    N'utilisez pas les `extraHeaders` du client pour cela. Une requête qui possède ses propres `extraHeaders` remplace ceux du client, et chaque endpoint sous `$client->beta` qui nécessite un en-tête bêta en possède.
  </Tab>

  <Tab title="Ruby">
    Replacez la clé dans son ancien en-tête avec un middleware :

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

    La première ligne laisse une requête inchangée lorsqu'elle ne contient pas la clé, par exemple une requête redirigée vers une autre origine.

    `Anthropic::AWSClient` n'accepte pas d'argument `middleware:`. Transmettez plutôt le middleware avec chaque requête, sous la forme `request_options: {middleware: send_x_api_key}`.
  </Tab>
</Tabs>

#### Si vous définissiez ou supprimiez `X-Api-Key` sur une requête

Cela concerne les SDK Python, TypeScript, Go, PHP et Ruby.

Si vous supprimiez `X-Api-Key` pour qu'une requête n'envoie qu'un « auth token » (jeton d'authentification), supprimez ce code au lieu de le modifier, car supprimer `Authorization` supprimerait le jeton. [Un client détient un seul identifiant](https://platform.claude.com/docs/fr/api/migration-2026-10-21#sdk-one-credential), assurez-vous donc qu'il s'agit bien du jeton : si aucun n'est transmis dans le code et que `ANTHROPIC_API_KEY` et `ANTHROPIC_AUTH_TOKEN` sont tous deux définis, le client utilise la clé.

<Tabs exclude="shell, csharp, java">
  <Tab title="Python">
    Le code qui transmet `extra_headers={"X-Api-Key": omit}` pour exclure la clé d'une requête ne le fait plus. Transmettez plutôt `extra_headers={"Authorization": omit}`.

    `extra_headers={"X-Api-Key": other_key}` ne remplace plus la clé du client : les deux clés sont envoyées. Pour envoyer une autre clé avec une requête, transmettez `extra_headers={"Authorization": f"Bearer {other_key}"}`.
  </Tab>

  <Tab title="TypeScript">
    `headers: { "X-Api-Key": otherKey }` dans les options d'une requête ne remplace plus la clé du client : les deux clés sont envoyées. Pour envoyer une autre clé avec une requête, transmettez ``headers: { Authorization: `Bearer $\{otherKey}` }``.
  </Tab>

  <Tab title="Go">
    `option.WithHeaderDel("X-Api-Key")` n'exclut plus la clé d'une requête. Supprimez plutôt `Authorization` :

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

    // Après
    client.Messages.New(ctx, params, option.WithHeaderDel("Authorization"))
    ```

    `option.WithHeader("X-Api-Key", otherKey)` ne remplace plus la clé du client : les deux clés sont envoyées. Pour envoyer une autre clé avec une requête, transmettez `option.WithAPIKey(otherKey)`.
  </Tab>

  <Tab title="PHP">
    `'extraHeaders' => ['X-Api-Key' => null]` n'exclut plus la clé d'une requête. Pour envoyer une requête sans identifiant, définissez plutôt `Authorization` sur `null`, ou supprimez-le dans un middleware si vous faisiez cela pour l'ensemble du client.

    `'extraHeaders' => ['X-Api-Key' => $otherKey]` ne remplace plus la clé du client : les deux clés sont envoyées. Pour envoyer une autre clé avec une requête, définissez `Authorization` sur `"Bearer {$otherKey}"`.
  </Tab>

  <Tab title="Ruby">
    `extra_headers: {"x-api-key" => nil}` n'exclut plus la clé d'une requête. Définissez plutôt `"authorization"` sur `nil`. Pour envoyer une autre clé avec une requête, définissez `"authorization"` sur `"Bearer #{other_key}"`, et non `"x-api-key"`.
  </Tab>
</Tabs>

### Un client détient un seul identifiant

Une clé API et un jeton d'authentification partagent désormais un en-tête, donc un client SDK détient un seul identifiant. Si aucun n'est transmis dans le code, il suit l'ordre de [priorité des identifiants](https://platform.claude.com/docs/fr/manage-claude/wif-reference#credential-precedence).

<Tabs exclude="shell">
  <Tab title="Python">
    La v1 envoyait à la fois une clé API et un jeton d'authentification lorsque le client possédait les deux, chacun dans son propre en-tête. L'identifiant est l'un des éléments suivants : `api_key`, `auth_token`, `credentials`, `config` ou `profile`.

    * **Transmettez-en au plus un.** Deux ou plus dans le constructeur, ou dans un même appel à `copy()` ou `with_options()`, lèvent `ValueError`. `None` ne compte pas. La v1 levait `TypeError`, et uniquement pour deux éléments parmi `credentials`, `config` et `profile`.
    * **Celui que vous transmettez est le seul.** Comme dans la v1, le client n'en cherche pas d'autre dans l'environnement ou sur le disque.
    * **Si aucun n'est transmis, seul le premier des éléments suivants qui est défini est utilisé :** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, le profil nommé par `ANTHROPIC_PROFILE`, les variables de fédération d'identité de charge de travail, le profil actif sur le disque (celui nommé par le fichier `active_config`, sinon `default`). Lorsque les deux premiers sont définis, le client journalise un avertissement une seule fois. La v1 utilisait le profil actif avant les variables de fédération lorsque `ANTHROPIC_CONFIG_DIR` était défini ou qu'un fichier `active_config` existait ; définissez `ANTHROPIC_PROFILE` pour continuer à l'utiliser.
    * **`copy()` et `with_options()` remplacent.** Un identifiant que vous transmettez remplace celui du client, quel que soit le type de l'un ou de l'autre. Une URL de base et des en-têtes provenant de la configuration ou du profil de l'ancien identifiant disparaissent avec lui, et ceux du nouvel identifiant sont utilisés. Une URL de base que vous avez transmise est conservée.

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

    # Avant : envoyait `X-Api-Key: <key>` et `Authorization: Bearer <token>`.
    # Après : lève `ValueError`.
    ```

    Les clients de plateforme conservent leurs propres règles. `AnthropicAWS` accepte `auth_token` à côté de `api_key` sans erreur, et envoie la clé.

    Les docstrings de `Anthropic.__init__` et `Anthropic.copy` dans [`_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) contiennent les détails.

    Si vous comptiez sur l'envoi des deux, par exemple un jeton pour une passerelle et une clé pour l'API située derrière, transmettez le jeton en tant que `auth_token` et définissez `X-Api-Key` dans `default_headers`. Faites en sorte que la passerelle supprime son en-tête `Authorization` avant de transférer la requête. L'API Claude attend un seul identifiant par requête.
  </Tab>

  <Tab title="TypeScript">
    Dans la v0, un client qui possédait à la fois une clé API et un jeton d'authentification envoyait les deux, chacun dans son propre en-tête. L'identifiant est l'un des éléments suivants : `apiKey`, `authToken`, `credentials`, `config` ou `profile`.

    * **Transmettez-en au plus un.** Deux ou plus dans `new Anthropic()`, ou dans un même appel à `withOptions()`, lèvent une `TypeError`. `null` et `undefined` ne comptent pas.
    * **Celui que vous transmettez est le seul.** Le client n'en cherche pas d'autre dans l'environnement ou sur le disque.
    * **Si aucun n'est transmis, le premier des éléments suivants est utilisé :** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, le profil nommé par `ANTHROPIC_PROFILE`, les variables de fédération d'identité de charge de travail, le profil actif sur le disque (celui nommé par le fichier `active_config`, sinon `default`). Lorsque les deux premiers sont définis, le client journalise un avertissement une seule fois. Dans la v0, le profil actif passait avant les variables de fédération. Un `ANTHROPIC_PROFILE` qui nomme un profil inexistant était ignoré dans la v0 ; désormais, la première requête lève une `AnthropicError`. `loadConfig()` sans argument suit le même ordre et lève la même erreur.
    * **`withOptions` remplace.** Un identifiant que vous transmettez remplace celui du client que vous copiez, donc `client.withOptions({ authToken })` n'a plus besoin de `apiKey: null` à côté.
    * **Un client de plateforme n'accepte que les identifiants de sa plateforme.** Les clients AWS, Bedrock et Foundry ainsi que `AnthropicVertex` lèvent une `AnthropicError` pour une option d'identifiant avec laquelle ils ne s'authentifient pas, comme le faisait déjà `AnthropicGoogleCloud`. Sur les clients AWS et Bedrock, `apiKey: null` efface désormais la clé, de sorte que le client signe avec les identifiants AWS. `AnthropicBedrock` conserve sa clé dans `client.apiKey`, là où la v0 la conservait dans `client.authToken`.

    ```typescript
    // Avant : envoyait la clé API et ignorait `credentials`.
    const client = new Anthropic({ apiKey, credentials });

    // Après : la ligne ci-dessus lève une TypeError.
    const client = new Anthropic({ credentials });
    ```

    Les commentaires de documentation de [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/src/client.ts) indiquent le comportement de chaque option, et le commentaire de documentation du constructeur de chacun de ces clients de plateforme répertorie les options qu'il rejette.

    Si vous comptiez sur l'envoi des deux, par exemple un jeton pour une passerelle et une clé pour l'API située derrière, définissez `X-Api-Key` dans `defaultHeaders` et conservez `authToken`. Faites en sorte que la passerelle supprime son en-tête `Authorization` avant de transférer la requête. L'API Claude attend un seul identifiant par requête.
  </Tab>

  <Tab title="C#">
    Dans la v12, un client qui possédait à la fois une clé API et un jeton d'authentification envoyait les deux, chacun dans son propre en-tête. L'identifiant est l'un des éléments suivants : `ApiKey`, `AuthToken` ou `ClientOptions.Credentials`.

    * **En transmettre deux est une erreur.** Définir un second identifiant lève une `ArgumentException`. `null` ne compte pas, donc pour changer l'identifiant dans des `ClientOptions` que vous avez construites vous-même, définissez d'abord l'ancien sur `null`.
    * **En transmettre un l'utilise et ignore l'environnement.** Aucune variable d'environnement d'identifiant ni aucun profil sur le disque n'est lu. De la même manière, `AnthropicCredentials.Resolve(profile: "name")` renvoie désormais les identifiants de ce profil lorsque `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` est défini.
    * **N'en transmettre aucun utilise la première correspondance dans l'environnement :** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, les variables de fédération d'identité de charge de travail, puis le profil actif sur le disque. Un `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` vide est considéré comme non défini. Lorsque les deux premiers sont définis, un avertissement est envoyé sur stderr une seule fois. Le client effectue la recherche lors de sa première utilisation, donc un `ANTHROPIC_PROFILE` inexistant lève désormais une exception à la première requête plutôt que dans le constructeur.
    * **`WithOptions` remplace.** Un identifiant que vous transmettez dans le modificateur remplace celui du client, quel qu'en soit le type, donc `AuthToken = token` n'a plus besoin de `ApiKey = null` à côté. Si aucun n'est transmis, la copie conserve l'identifiant, la `BaseUrl` et les `ExtraHeaders` du client, même lorsque le modificateur renvoie de nouvelles `ClientOptions`.

    ```csharp
    // Avant : les deux étaient envoyés, chacun dans son propre en-tête.
    AnthropicClient client = new() { ApiKey = apiKey, AuthToken = token };

    // Après : la ligne ci-dessus lève une ArgumentException.
    AnthropicClient client = new() { AuthToken = token };
    ```

    La documentation XML de ces trois propriétés de [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-csharp/blob/main/src/Anthropic/Core/ClientOptions.cs) contient les détails.

    Les clients de plateforme cloud conservent les identifiants avec lesquels ils ont été construits. Les clients Bedrock, Bedrock Mantle, Foundry, Google Cloud et AWS ainsi que `AnthropicVertexClient` décident de leur mode d'authentification lors de leur construction, et la plupart d'entre eux utilisent l'en-tête `Authorization` pour cela. Les versions de ces packages qui dépendent de la v13 ignorent un `ApiKey` ou un `AuthToken` que vous définissez via `WithOptions`. Pour utiliser une autre clé avec `AnthropicAwsClient`, construisez un nouveau client avec `ApiKey` dans `AwsClientOptions`.

    Si vous comptiez sur l'envoi des deux, par exemple un jeton pour une passerelle et une clé pour l'API située derrière, définissez `X-Api-Key` avec `ExtraHeaders` et conservez `AuthToken`. Faites en sorte que la passerelle supprime son en-tête `Authorization` avant de transférer la requête. L'API Claude attend un seul identifiant par requête.
  </Tab>

  <Tab title="Go">
    Dans la v1, un client qui possédait à la fois une clé API et un jeton d'authentification envoyait les deux, chacun dans son propre en-tête. L'identifiant provient de `option.WithAPIKey`, `option.WithAuthToken`, `option.WithConfig`, `option.WithProfile` ou `option.WithFederationTokenProvider`.

    * **En transmettre deux à `anthropic.NewClient` est une erreur.** `NewClient` ne renvoie pas d'erreur, donc chaque requête effectuée par le client échoue avec celle-ci. `NewClient` applique déjà `anthropic.DefaultClientOptions()`, ne transmettez donc pas également son résultat : l'identifiant qu'il trouve dans l'environnement compterait alors comme un identifiant que vous avez transmis.
    * **Un seul d'entre eux est utilisé tel quel.** Aucun identifiant n'est lu depuis l'environnement ou depuis un profil sur le disque. Dans la v1, `ANTHROPIC_API_KEY` et `ANTHROPIC_AUTH_TOKEN` l'emportaient sur les trois derniers.
    * **Si aucun n'est transmis, le premier des éléments suivants qui est défini est utilisé,** dans le même ordre que dans la v1 : `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, les variables de fédération d'identité de charge de travail, le profil actif sur le disque. Lorsque les deux premiers sont définis, le SDK journalise un avertissement une seule fois.
    * **L'un d'entre eux sur une requête remplace l'identifiant du client pour cette requête,** donc `option.WithAuthToken` n'a plus besoin de `option.WithHeaderDel("X-Api-Key")` à côté.

    ```go
    // Avant : la clé API était envoyée et un avertissement était journalisé.
    client := anthropic.NewClient(
    	option.WithAPIKey(apiKey),
    	option.WithProfile("work"),
    )

    // Après : chaque requête du client ci-dessus échoue, passez donc celle que vous souhaitez.
    client := anthropic.NewClient(option.WithAPIKey(apiKey))
    ```

    L'avertissement que la v1 journalisait a disparu, donc `option.WithConfigQuiet`, qui le supprimait, fait désormais la même chose que `option.WithConfig` et est déprécié.

    Les commentaires de documentation de `anthropic.NewClient` et `anthropic.DefaultClientOptions` dans [`client.go`](https://github.com/anthropics/anthropic-sdk-go/blob/main/client.go) contiennent les détails.

    Si vous comptiez sur l'envoi des deux, par exemple un jeton pour une passerelle et une clé pour l'API située derrière, définissez `X-Api-Key` avec `option.WithHeader` et conservez `option.WithAuthToken`. Faites en sorte que la passerelle supprime son en-tête `Authorization` avant de transférer la requête. L'API Claude attend un seul identifiant par requête.

    `ANTHROPIC_CUSTOM_HEADERS` et `ANTHROPIC_WEBHOOK_SIGNING_KEY` s'appliquent désormais à chaque client construit par `anthropic.NewClient`. Dans la v1, ils n'étaient lus que lorsque ni l'environnement ni un profil sur le disque ne contenait d'identifiant.
  </Tab>

  <Tab title="Java">
    Dans la v2, un client qui possédait à la fois une clé API et un jeton d'authentification envoyait les deux, chacun dans son propre en-tête. L'identifiant est l'un des éléments suivants : `apiKey`, `authToken` ou `configurationProvider` sur les builders `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` et `AnthropicBackend`.

    * **Définissez-en au plus un.** Avec deux sur un même builder, `build()` lève une `IllegalStateException` qui les nomme. `null` ou un `Optional` vide ne compte pas.
    * **Celui que vous définissez est le seul.** `fromEnv()`, appelé avant ou après, ne prend aucun identifiant dans l'environnement ou dans un profil sur le disque. Dans la v2, une clé ou un jeton trouvé par `fromEnv()` pouvait être envoyé en plus, ou à la place.
    * **Si aucun n'est défini, `fromEnv()` utilise le premier des éléments suivants qu'il trouve :** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, les variables de fédération d'identité de charge de travail, le profil actif sur le disque. Lorsque les deux premiers sont définis, un avertissement est envoyé sur `System.err` une seule fois. Les propriétés système `anthropic.apiKey` et `anthropic.authToken` comptent comme faisant partie de l'environnement. Une clé ou un jeton vide, dans une variable ou une propriété système, est considéré comme non défini. Dans la v2, `fromEnv()` utilisait la valeur vide comme clé ou jeton.

    ```java
    // Avant : les deux étaient envoyés. En v3, build() lève une IllegalStateException.
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .apiKey(apiKey)
        .authToken(authToken)
        .build();

    // Après
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .apiKey(apiKey)
        .build();
    ```

    La documentation de `fromEnv()` sur ces builders contient les détails.

    Si vous comptiez sur l'envoi des deux, par exemple un jeton pour une passerelle et une clé pour l'API située derrière, définissez vous-même les deux en-têtes :

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

    Faites en sorte que la passerelle supprime son en-tête `Authorization` avant de transférer la requête. L'API Claude attend un seul identifiant par requête.
  </Tab>

  <Tab title="PHP">
    Les versions antérieures envoyaient à la fois une clé API et un jeton d'authentification lorsque le client possédait les deux, chacun dans son propre en-tête. `Anthropic\Client` accepte un seul identifiant, parmi `apiKey`, `authToken` ou `credentials` :

    * En transmettre plus d'un lève `\InvalidArgumentException`. Seul `null` compte comme non transmis. Une chaîne vide compte comme transmise, donc `new Client(apiKey: '')` n'envoie aucun identifiant.
    * En transmettre un l'utilise, et aucun identifiant n'est lu depuis l'environnement ou depuis un profil sur le disque. Avec `ANTHROPIC_API_KEY` défini, `new Client(authToken: $token)` envoie le jeton. Les versions antérieures envoyaient la clé de l'environnement en plus.
    * N'en transmettre aucun utilise le premier des éléments suivants qui est défini : `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, le profil nommé par `ANTHROPIC_PROFILE`, les variables de fédération d'identité de charge de travail, le profil actif sur le disque (celui nommé par le fichier `active_config`, sinon `default`). Les versions antérieures utilisaient le profil actif avant les variables de fédération, et n'utilisaient aucun profil en l'absence de fichier `active_config`. Elles ignoraient également un `ANTHROPIC_PROFILE` qui nommait un profil inexistant ou invalide. Dans ce cas, `new Client()` lève désormais `Anthropic\Core\Exceptions\AnthropicException`. Avec `ANTHROPIC_API_KEY` et `ANTHROPIC_AUTH_TOKEN` tous deux définis, le client envoie la clé et sa propriété `authToken` est vide. Le premier client construit de cette manière écrit également un avertissement avec `error_log()`, une fois par processus, ce qui sur un serveur web signifie une fois par requête : `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Pour l'arrêter, supprimez la variable que vous n'utilisez pas.

    ```php
    // Avant : envoyait la clé en tant que X-Api-Key et le jeton en tant qu'Authorization.
    // Après : lève l'erreur "Pass at most one of `apiKey`, `authToken`, or `credentials`. Received `apiKey`, `authToken`."
    $client = new Client(apiKey: $key, authToken: $token);
    ```

    Si vous comptiez sur l'envoi des deux, par exemple un jeton pour une passerelle et une clé pour l'API située derrière, transmettez le jeton en tant que `authToken` et ajoutez `X-Api-Key` dans un middleware comme celui de la section [Si un proxy ou une passerelle lit `X-Api-Key`](https://platform.claude.com/docs/fr/api/migration-2026-10-21#sdk-proxy-x-api-key), sans l'appel à `withoutHeader`. Faites en sorte que la passerelle supprime son en-tête `Authorization` avant de transférer la requête. L'API Claude attend un seul identifiant par requête.
  </Tab>

  <Tab title="Ruby">
    Les arguments d'identifiant de `Anthropic::Client.new` sont `api_key:`, `auth_token:`, `credentials:` et `config:`. Un argument `nil` compte comme non transmis. Les clients de plateforme conservent leurs propres règles.

    * **Deux ou plus transmis :** `Anthropic::Client.new` lève `ArgumentError`. Les versions antérieures ne levaient une erreur que pour `credentials:` avec `config:`, et sinon envoyaient la clé s'il y en avait une, puis le jeton.
    * **Un seul transmis :** le client l'utilise, et ne se rabat pas sur un identifiant provenant de l'environnement ou d'un profil sur le disque.
    * **Aucun transmis :** le client utilise le premier des éléments suivants qu'il trouve : `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, les variables de fédération d'identité de charge de travail, le profil actif sur le disque. L'ordre n'a pas changé, mais avec `ANTHROPIC_API_KEY` et `ANTHROPIC_AUTH_TOKEN` tous deux définis, `client.auth_token` vaut désormais `nil`. Un `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` vide est désormais considéré comme non défini, alors que les versions antérieures laissaient un `ANTHROPIC_API_KEY` vide masquer le jeton et tout ce qui suivait.

    Lorsqu'aucun identifiant n'est transmis et que `ANTHROPIC_API_KEY` et `ANTHROPIC_AUTH_TOKEN` sont tous deux définis, le SDK émet également un avertissement une fois par processus, sur la sortie d'erreur standard via `Kernel#warn` : `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Supprimez la variable que vous n'utilisez pas pour le faire taire.

    ```ruby
    # Avant : envoyait la clé et ignorait le jeton.
    # Après : 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)

    # Transmettez uniquement celui que vous souhaitez envoyer.
    Anthropic::Client.new(api_key: api_key)
    ```
  </Tab>
</Tabs>

### Modifications dans un seul SDK ou dans la CLI

Chacune de ces modifications concerne un seul SDK ou la CLI.

<Tabs exclude="shell:cURL, python, typescript">
  <Tab title="CLI">
    **`--api-key` et `--auth-token` sont supprimés.** `ant` n'accepte plus de clé API ni de jeton d'authentification comme valeur d'option, car une valeur passée sur la ligne de commande est visible dans l'historique du shell et dans les listes de processus. Les deux options affichent un avertissement de dépréciation depuis la v1.27.0. Une commande qui en passe encore une s'arrête avec `flag provided but not defined`.

    | Supprimé               | Utilisez à la place                                        |
    | ---------------------- | ---------------------------------------------------------- |
    | `--api-key <key>`      | `ANTHROPIC_API_KEY`, `--api-key-stdin` ou `ant auth login` |
    | `--auth-token <token>` | `ANTHROPIC_AUTH_TOKEN` ou `--auth-token-stdin`             |

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

    # Après, depuis l'environnement
    export ANTHROPIC_API_KEY="$KEY"
    ant models list

    # Après, depuis un gestionnaire de secrets
    op read op://vault/anthropic/api-key | ant --api-key-stdin models list
    ```

    `--api-key-stdin` et `--auth-token-stdin` lisent l'intégralité de l'entrée standard, de sorte qu'une commande qui utilise l'une d'elles prend le corps de sa requête à partir des options.

    `ant auth status`, l'invite de première exécution de `ant apply` et la note concernant les sources d'authentification multiples désignent désormais ces identifiants par `ANTHROPIC_API_KEY` et `ANTHROPIC_AUTH_TOKEN`, là où ils affichaient `--api-key / ANTHROPIC_API_KEY` et `--auth-token / ANTHROPIC_AUTH_TOKEN`.
  </Tab>

  <Tab title="C#">
    **Le `Type` d'une union est une énumération.** Dans la v12, la propriété `Type` d'une classe d'union, telle que `ContentBlock.Type` ou `RawMessageStreamEvent.Type`, était un `JsonElement`. Dans la v13, c'est un `ApiEnum<string, T>`, où `T` est une nouvelle énumération comportant un membre pour chaque variante, telle que `ContentBlockType`. Quelques unions se distinguent plutôt par `Name` ou `Command`, comme `BetaMemoryTool20250818Command.Command`, et ces propriétés changent de la même manière. Le `Type` d'une classe de variante, telle que `TextBlock.Type`, reste un `JsonElement`.

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

    // Après
    if (block.Type.Value() == ContentBlockType.ToolUse) { }
    ```

    `block.Type.Raw()` renvoie la chaîne, y compris une chaîne pour laquelle cette version du SDK n'a pas de membre d'énumération.

    **`IChatClient` ignore les options d'échantillonnage.** Les adaptateurs `IChatClient` (`AsIChatClient()`) ignorent désormais `ChatOptions.Temperature`, `ChatOptions.TopK` et `ChatOptions.TopP`. Consultez [Les paramètres d'échantillonnage sont supprimés](https://platform.claude.com/docs/fr/api/migration-2026-10-21#sampling-parameters).
  </Tab>

  <Tab title="Go">
    **`vertex.DefaultVersion` et `bedrock.DefaultVersion` sont supprimés.**
  </Tab>

  <Tab title="Java">
    **Accesseurs qui renvoient désormais un `Optional`.** `apiKey()` et `authToken()` sur `AnthropicBackend` renvoient désormais un `Optional<String>`, comme le faisait déjà `apiKey()` sur `AwsBackend` et `BedrockMantleBackend`. Dans la v2, chacun renvoyait un `String`, qui valait `null` lorsque le backend n'avait pas d'identifiant de ce type.

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

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

    Ces accesseurs renvoient désormais eux aussi un `Optional`. Dans la v2, chacun renvoyait la valeur elle-même, qui valait `null` en son absence :

    * `apiKey()` et `awsCredentialsProvider()` sur `BedrockBackend`
    * `filename()` et `mimeType()` sur `McpResourceFile`
    * `detail()` sur `CredentialSource`
    * `body()` sur `HttpRequest`
    * `resource()` sur `FoundryBackend`, qui était `getResource()`
    * `responseValidation()`, `timeout()`, `followRedirects()`, `fallbackState()` et `openTelemetry()` sur `RequestOptions`, qui étaient `getResponseValidation()`, `getTimeout()`, `getFollowRedirects()`, `getFallbackState()` et `getOpenTelemetry()`

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

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

    `getBaseUrl()` sur `FoundryBackend` est supprimé. Appelez `baseUrl()`, qui renvoie l'URL vers laquelle les requêtes sont envoyées. Il s'agit de l'URL de base que vous avez définie, ou de celle construite à partir de la ressource, et elle se termine par `/anthropic`.

    `getBaseUrl()` sur `AnthropicBackend` est également supprimé. Appelez `baseUrl()`, qui renvoie la même valeur.

    **`HttpRequest` exige une URL de base.** Si vous construisez vous-même un `HttpRequest`, par exemple dans un test d'intercepteur, définissez son URL de base. Sans elle, `build()` lève désormais une `IllegalStateException`. Dans la v2, il renvoyait une requête dont `baseUrl()` valait `null`. Les requêtes construites par le SDK en avaient déjà une.

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

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

    `baseUrl()` renvoie toujours un `String`, qui n'est désormais jamais `null`. Sur le builder, `baseUrl(Optional<String>)` est supprimé et `baseUrl(String)` n'accepte plus `null`.

    **Les intercepteurs voient `anthropic-version`.** Le client ajoute désormais l'en-tête `anthropic-version` par défaut avant l'exécution des intercepteurs. Dans la v2, le backend l'ajoutait après eux. Si votre intercepteur définit sa propre version, appelez `replaceHeaders`, car `putHeader` ajoute désormais une seconde valeur :

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

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

  <Tab title="PHP">
    **Les cas d'énumération que vous passez sont relus sous forme de leurs valeurs.** `with()` et les setters tels que `withAllowedCallers()` acceptent toujours un cas d'énumération ou sa valeur. Les versions antérieures conservaient un cas tel que vous l'aviez passé. La v1 conserve la valeur du cas, ce que déclarent déjà les types des propriétés. Les objets que le SDK construit à partir d'une réponse ne changent pas, et le JSON envoyé par le SDK est identique. Si vous relisez une propriété et la comparez à un cas, la comparaison est désormais fausse et aucune exception n'est levée ; comparez-la donc à la valeur du cas :

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

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

    // Après
    in_array(AllowedCaller::DIRECT->value, $tool->allowedCallers, true);
    ```
  </Tab>

  <Tab title="Ruby">
    **`Anthropic::VertexClient::DEFAULT_VERSION` et `Anthropic::BedrockClient::DEFAULT_VERSION` sont supprimés.**
  </Tab>
</Tabs>

### La licence est Apache 2.0

À partir de ces versions, le SDK et la CLI sont distribués sous la licence Apache, version 2.0. Les versions antérieures restent sous licence MIT. Aucune modification de code n'est nécessaire. Si vous suivez les licences de vos dépendances, mettez à jour leurs entrées.

* **TypeScript :** Les paquets de plateforme (`@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` et `@anthropic-ai/google-cloud-sdk`) changent de licence dans leurs propres versions 1.0.0.
* **C# :** Les autres paquets (`Anthropic.Bedrock`, `Anthropic.Vertex`, `Anthropic.Foundry`, `Anthropic.Aws`, `Anthropic.GoogleCloud` et `Anthropic.Mcp`) changent de licence dans leurs propres versions 1.0.0.
* **Java :** Le changement concerne tous les artefacts `com.anthropic`.
