---
title: Migrazione alla versione API 2026-10-21
url: https://platform.claude.com/docs/it/api/migration-2026-10-21
description: "Aggiorna un'integrazione con la Claude API dalla versione API 2023-06-01 alla 2026-10-21: la versione dell'SDK da installare e le modifiche al codice da apportare."
---

Questa guida elenca le modifiche al codice necessarie per passare dalla versione API `2023-06-01` alla `2026-10-21`. I [passaggi di aggiornamento](https://platform.claude.com/docs/it/api/migration-2026-10-21#migration-checklist) indicano cosa fare, in ordine.

## Passaggi di aggiornamento

<Steps>
  <Step title="Passa alla 2026-10-21">
    Se usi un SDK, le tue richieste usano la versione API che era corrente quando è stata rilasciata la versione major del tuo SDK. Le versioni indicate per il tuo linguaggio sono le prime a usare `2026-10-21`, quindi aggiorna a quelle. Se chiami l'API senza un SDK, imposta l'header `anthropic-version` su `2026-10-21`.

    <Tabs>
      <Tab title="cURL">
        Imposta l'header `anthropic-version` su `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">
        Aggiorna la CLI `ant` alla versione 2.0.0. Il comando Homebrew e i download delle release restano invariati.

        Go richiede che il percorso di un modulo con versione major 2 o successiva termini con quella versione, quindi il percorso del modulo della CLI è ora `github.com/anthropics/anthropic-cli/v2`. Se installi con `go install`, aggiungi `/v2` al percorso:

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

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

        Il vecchio percorso continua a installare l'ultima release v1, senza errori né avvisi.
      </Tab>

      <Tab title="Python">
        Aggiorna il pacchetto `anthropic` alla versione 2.0.0.
      </Tab>

      <Tab title="TypeScript">
        Aggiorna il pacchetto `@anthropic-ai/sdk` alla versione 1.0.0.

        La v1 di `@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` e `@anthropic-ai/google-cloud-sdk` richiede la v1 di `@anthropic-ai/sdk`, e le loro versioni precedenti richiedono una versione inferiore alla 1. Se ne usi uno, portalo alla v1 nello stesso aggiornamento. Altrimenti il tuo gestore di pacchetti installa per esso una seconda copia, più vecchia, di `@anthropic-ai/sdk`.
      </Tab>

      <Tab title="C#">
        Aggiorna il pacchetto `Anthropic` alla versione 13.0.0.
      </Tab>

      <Tab title="Go">
        Aggiorna alla versione 2.0.0 dell'SDK Go, il cui percorso del modulo è `github.com/anthropics/anthropic-sdk-go/v2`. Una nuova versione major di un modulo Go ha un nuovo percorso di importazione, quindi modifica ogni importazione di `github.com/anthropics/anthropic-sdk-go`, e dei suoi pacchetti come `github.com/anthropics/anthropic-sdk-go/option`, in modo che inizi con `github.com/anthropics/anthropic-sdk-go/v2`. Poi esegui `go get github.com/anthropics/anthropic-sdk-go/v2`.
      </Tab>

      <Tab title="Java">
        Aggiorna l'artefatto `com.anthropic:anthropic-java` alla versione 3.0.0.
      </Tab>

      <Tab title="PHP">
        Esegui `composer require "anthropic-ai/sdk"` per aggiornare il pacchetto alla versione 1.0.0. `composer update` da solo resta entro il tuo vincolo di versione attuale.
      </Tab>

      <Tab title="Ruby">
        Aggiorna la gem `anthropic` alla versione 2.0.0.
      </Tab>
    </Tabs>

    <Warning>
      Su Amazon Bedrock, `2026-10-21` è disponibile solo per i modelli Claude 4.7 e successivi. Se chiami un modello più vecchio su Bedrock, elencato in [Claude su Amazon Bedrock (Opus 4.6 e precedenti)](https://platform.claude.com/docs/it/build-with-claude/claude-on-amazon-bedrock-legacy), resta sulla versione dell'SDK che usi oggi oppure, se imposti tu stesso la versione API, continua a inviare la versione che invii oggi. Per spostare quelle chiamate a `2026-10-21`, passale prima a un modello Claude 4.7 o successivo.
    </Warning>

    Rilascia l'aggiornamento insieme alle correzioni del passaggio successivo.
  </Step>

  <Step title="Aggiorna il tuo codice per le modifiche incompatibili">
    Esamina le [modifiche incompatibili](https://platform.claude.com/docs/it/api/migration-2026-10-21#breaking-changes) e aggiorna il tuo codice per ciascuna che ti riguarda. Apporta anche le [modifiche al codice richieste dalla nuova versione dell'SDK o della CLI](https://platform.claude.com/docs/it/api/migration-2026-10-21#sdk-changes).
  </Step>

  <Step title="Testa con la 2026-10-21">
    Testa la tua integrazione con `2026-10-21` prima del rilascio.
  </Step>
</Steps>

## Modifiche incompatibili

### Messages API

Queste modifiche si applicano alle richieste alla Messages API (`POST /v1/messages`), al [conteggio dei token](https://platform.claude.com/docs/it/build-with-claude/token-counting) e a ogni richiesta in un [Message Batch](https://platform.claude.com/docs/it/build-with-claude/batch-processing) creato con `2026-10-21`.

#### I blocchi document nei messaggi assistant restituiscono un errore

Ti riguarda se invii blocchi `document` direttamente nei messaggi `assistant`.

In `2026-10-21`, una richiesta che inserisce un blocco `document` direttamente in un messaggio `assistant` restituisce un errore 400. Invia invece i documenti nei messaggi `user`. Un documento annidato all'interno di un altro blocco, come il risultato di uno strumento web fetch restituito da Claude, è ancora accettato.

#### Le citazioni nei messaggi user restituiscono un errore

Ti riguarda se invii `citations` su blocchi `text` nei messaggi `user`, anche all'interno di blocchi `search_result`.

In `2026-10-21`, una richiesta che invia un blocco `text` con un array `citations` non vuoto in un messaggio `user` restituisce un errore 400. Rimuovi `citations` da quei blocchi. Le citazioni sui blocchi `text` nei messaggi `assistant`, come le risposte precedenti di Claude che rimandi indietro, sono ancora accettate, così come l'impostazione `"citations": {"enabled": true}` su documenti e risultati di ricerca.

#### I parametri di campionamento sono stati rimossi

Ti riguarda se invii `temperature`, `top_p` o `top_k` nelle richieste Messages o nelle richieste Message Batch.

In `2026-10-21`, una richiesta che invia `temperature`, `top_p` o `top_k` restituisce un errore 400, anche con il valore predefinito del parametro.

Rimuovi i tre parametri dalle tue richieste.

A partire dalle ultime versioni major, l'SDK e la CLI non hanno più i tre parametri.

Senza questi parametri, una richiesta esegue il campionamento con i loro valori predefiniti, inclusa una `temperature` di 1.0, come una richiesta `2023-06-01` che li omette. I modelli che già accettano solo i valori predefiniti, come i modelli Claude 4.7 e successivi, eseguono il campionamento come prima. Sui modelli che accettano altri valori, come Claude Sonnet 4.6, una richiesta che abbassava `temperature` per ottenere un output più coerente perde quell'effetto. Nessun'altra impostazione lo sostituisce. Se una richiesta si basa su un valore non predefinito, smetti di inviare il parametro oppure mantieni quella richiesta su `2023-06-01`.

### Admin API e Claude Enterprise Analytics API

Ti riguarda se il tuo codice legge i campi di risposta dell'Admin API o della Claude Enterprise Analytics API riportati nelle tabelle seguenti.

In `2026-10-21`, le risposte dell'Admin API e della [Claude Enterprise Analytics API](https://platform.claude.com/docs/it/manage-claude/analytics-api) non includono più i vecchi nomi dei campi rinominati. Usa invece i nuovi nomi.

Admin API:

| Endpoint                                                                                                                                                                                                                                                                                           | Vecchio nome   | Nuovo nome                                                                                                                                          |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Gruppi RBAC](https://platform.claude.com/docs/it/api/beta/organization/rbac_groups/list): creazione, elenco, recupero e aggiornamento                                                                                                                                                             | `roles`        | `role_ids`                                                                                                                                          |
| [Membri dei gruppi RBAC](https://platform.claude.com/docs/it/api/beta/organization/rbac_groups/members/list): elenco e aggiunta, e la risposta alla [rimozione di un membro](https://platform.claude.com/docs/it/api/beta/organization/rbac_groups/members/remove)                                 | `group_id`     | `rbac_group_id`                                                                                                                                     |
| [Ruoli RBAC](https://platform.claude.com/docs/it/api/beta/organization/rbac_roles/list): elenco e recupero                                                                                                                                                                                         | `name`         | `display_name`                                                                                                                                      |
| Limiti di velocità dell'[organizzazione](https://platform.claude.com/docs/it/api/organization/rate_limits/list) e del [workspace](https://platform.claude.com/docs/it/api/organization/workspaces/rate_limits/list): elenco, e la risposta all'impostazione dei limiti di velocità di un workspace | `group_type`   | `group.type`                                                                                                                                        |
| [Chiavi API](https://platform.claude.com/docs/it/api/organization/api_keys/list): elenco, recupero e aggiornamento                                                                                                                                                                                 | `workspace_id` | `scope` (valori diversi; vedi [`workspace_id` sulle chiavi API](https://platform.claude.com/docs/it/api/migration-2026-10-21#api-key-workspace-id)) |

Claude Enterprise Analytics API:

| Endpoint                                                                                                                                                                                                                         | Vecchio nome  | Nuovo nome            |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------- |
| Report per utente di [utilizzo](https://platform.claude.com/docs/it/api/beta/organization/analytics/user_usage_report/list) e [costi](https://platform.claude.com/docs/it/api/beta/organization/analytics/user_cost_report/list) | `actor.email` | `actor.email_address` |
| [Riepiloghi delle attività](https://platform.claude.com/docs/it/api/beta/organization/analytics/summaries/list)                                                                                                                  | `summaries`   | `data`                |

Il parametro di query `group_type` sugli endpoint di elenco dei limiti di velocità e il filtro `workspace_id` sull'endpoint di elenco delle chiavi API restano invariati.

#### `workspace_id` sulle chiavi API

Ti riguarda se il tuo codice legge `workspace_id` sulle chiavi API.

In `2023-06-01`, il `workspace_id` di una chiave API è l'ID del workspace a cui la chiave è associata, oppure `null` per una chiave associata al Default Workspace e per una chiave non associata a un singolo workspace (una chiave per tutti i workspace).

In `2026-10-21`, `workspace_id` è stato rimosso. Leggi invece `scope`: per una chiave associata a un workspace, incluso il Default Workspace, `scope.workspace_id` è l'ID reale di quel workspace, e una chiave per tutti i workspace ha uno `scope` pari a `{"type": "organization"}`, senza `workspace_id`.

Se il tuo codice trattava un `workspace_id` `null` come il Default Workspace, confronta invece `scope.workspace_id` con l'ID del tuo Default Workspace. Per trovare quell'ID, chiama [List Workspaces](https://platform.claude.com/docs/it/api/organization/workspaces/list) con `include_default=true` e prendi il workspace denominato `"Default"`.

## Modifiche all'SDK e alla CLI

Le versioni precedenti dell'SDK e della CLI inviavano `anthropic-version: 2023-06-01` con ogni richiesta. Le versioni indicate in [Passa alla 2026-10-21](https://platform.claude.com/docs/it/api/migration-2026-10-21#upgrade) inviano `2026-10-21`. Anche a loro si applicano le modifiche descritte in [Modifiche incompatibili](https://platform.claude.com/docs/it/api/migration-2026-10-21#breaking-changes): i parametri rimossi e i vecchi nomi dei campi sono spariti anche dai tipi dell'SDK e dai flag e dall'output della CLI.

### Versione API su Amazon Bedrock e Google Cloud

Il client dell'SDK per Google Cloud's Agent Platform indica la versione nel corpo della richiesta anziché in un header. Invia `anthropic_version: 2026-10-21`, dove le versioni precedenti inviavano `vertex-2023-10-16`, e nessun header `anthropic-version`.

Il client Amazon Bedrock fa lo stesso. Invia `anthropic_version: 2026-10-21`, dove le versioni precedenti inviavano `bedrock-2023-05-31`, e nessun header `anthropic-version`. I modelli precedenti a Claude Opus 4.7 non supportano ancora la versione API `2026-10-21` su Bedrock, e una richiesta che la indica potrebbe ricevere un errore 400. Se ne usi uno, resta per ora sulla versione precedente dell'SDK, oppure aggiorna e invia tu stesso `bedrock-2023-05-31`.

<Tabs>
  <Tab title="Python">
    Questo si applica a `AnthropicVertex`, `AsyncAnthropicVertex`, `AnthropicBedrock` e `AsyncAnthropicBedrock`.

    Per inviare `bedrock-2023-05-31`, passa `extra_body={"anthropic_version": "bedrock-2023-05-31"}` con ogni richiesta.
  </Tab>

  <Tab title="TypeScript">
    Questo si applica a `AnthropicVertex` e `AnthropicBedrock`. Se imposti l'header `anthropic-version` sul client o su una richiesta, il suo valore finisce nel corpo.

    Per inviare `bedrock-2023-05-31`, imposta l'header `anthropic-version` su `"bedrock-2023-05-31"` sul client o su una richiesta.
  </Tab>

  <Tab title="C#">
    Questo si applica a `AnthropicVertexClient` e `AnthropicBedrockClient`. Se imposti l'header `anthropic-version` tramite `ClientOptions.ExtraHeaders`, il suo valore finisce nel corpo.

    Per inviare `bedrock-2023-05-31`, chiama `WithOptions` sul client e imposta `anthropic-version` su `bedrock-2023-05-31` in `ClientOptions.ExtraHeaders`.
  </Tab>

  <Tab title="Go">
    Questo si applica ai pacchetti `vertex` e `bedrock`. Se imposti l'header `anthropic-version` con `option.WithHeader`, il suo valore finisce nel corpo. `vertex.DefaultVersion` e `bedrock.DefaultVersion` sono stati rimossi.

    Per inviare `bedrock-2023-05-31`, passa `option.WithHeader("anthropic-version", "bedrock-2023-05-31")` al client o a una richiesta.
  </Tab>

  <Tab title="Java">
    Questo si applica a `VertexBackend` e `BedrockBackend`. Se imposti l'header `anthropic-version` sul client o su una richiesta, il suo valore finisce nel corpo.

    Per inviare `bedrock-2023-05-31`, imposta l'header `anthropic-version` su `bedrock-2023-05-31` sul client o su una richiesta.
  </Tab>

  <Tab title="PHP">
    Questo si applica a `Anthropic\Vertex\Client` e `Anthropic\Bedrock\Client`.

    Per inviare `bedrock-2023-05-31`, passa `'extraBodyParams' => ['anthropic_version' => 'bedrock-2023-05-31']` in `requestOptions`.
  </Tab>

  <Tab title="Ruby">
    Questo si applica a `Anthropic::VertexClient` e `Anthropic::BedrockClient`. Se imposti l'header `anthropic-version` tramite `extra_headers`, il suo valore finisce nel corpo. `Anthropic::VertexClient::DEFAULT_VERSION` e `Anthropic::BedrockClient::DEFAULT_VERSION` sono stati rimossi.

    Per inviare `bedrock-2023-05-31`, passa `extra_headers: {"anthropic-version" => "bedrock-2023-05-31"}` in `request_options`.
  </Tab>
</Tabs>

### `MessageParam` è un'unione con un tipo per ruolo

Nelle versioni precedenti, `MessageParam` era un unico tipo per ogni ruolo. Ora ogni ruolo ha un proprio tipo: `UserMessageParam`, `AssistantMessageParam` e `SystemMessageParam`. `BetaMessageParam` è suddiviso allo stesso modo, in `BetaUserMessageParam`, `BetaAssistantMessageParam` e `BetaSystemMessageParam`. Le richieste inviate dall'SDK hanno gli stessi campi e valori di prima.

<Tabs exclude="shell">
  <Tab title="Python">
    Un messaggio scritto come letterale dict, come `{"role": "user", "content": "Hello"}`, non richiede modifiche.

    Nella v1, `anthropic.types.MessageParam` era un unico `TypedDict`. Nella v2 è un'unione dei tre tipi, e `anthropic.types.beta.BetaMessageParam` è un'unione dei suoi tre. Entrambi i nomi funzionano ancora nelle annotazioni, come `list[MessageParam]`.

    Chiamare uno dei due nomi ora solleva un `TypeError`, e un type checker lo segnala. Scrivi il messaggio come dict:

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

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

    Anche creare una sottoclasse di uno dei due nomi solleva un `TypeError`. Crea una sottoclasse del tipo per il ruolo, come `UserMessageParam`.

    Le modifiche rimanenti riguardano solo il controllo dei tipi. Un dict il cui `role` è una variabile che può contenere più di un ruolo non corrisponde a nessun tipo dell'unione, quindi costruisci il dict per un ruolo alla volta:

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


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

    Altre due si applicano solo a `BetaMessageParam`:

    * `clear_at` e `output_config` sono chiavi di `BetaSystemMessageParam`, quindi un messaggio user o assistant non può averle.
    * `content` è facoltativo in `BetaSystemMessageParam`, quindi pyright segnala `message["content"]`. Leggilo con `message.get("content")`, oppure verifica prima che `message["role"]` non sia `"system"`.
  </Tab>

  <Tab title="TypeScript">
    `MessageParam` era un'unica interfaccia. Ora è `UserMessageParam | AssistantMessageParam | SystemMessageParam`, e `BetaMessageParam` è la stessa unione dei suoi tre tipi. Sono cambiati solo i tipi. Un letterale di messaggio che indica il proprio ruolo, come `{ role: "user", content: "Hello, Claude" }`, supera il controllo dei tipi come prima, quindi la maggior parte del codice non richiede modifiche.

    Il tipo system differisce dagli altri due. Il suo `content` è una stringa o blocchi di testo, più i blocchi `tool_addition` e `tool_removal` in `beta`, quindi un blocco immagine lì non compila più. In `beta`, solo esso ha `clear_at` e `output_config`, e il suo `content` è facoltativo.

    Il codice che gestisce un messaggio di qualsiasi ruolo deve controllare `role` prima di sostituire o aggiungere blocchi di contenuto, e prima di leggere `clear_at` o `output_config`:

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

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

    Il `content` di un `BetaMessageParam` può essere `undefined`:

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

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

    Anche il tipo `BetaMessageParam["content"]` include `undefined`. Per il contenuto di un messaggio user o assistant, usa `BetaMessageContentParam`.

    Un'interfaccia non può estendere un'unione, e una classe non può implementarne una. Usa un alias di tipo, oppure indica invece il tipo di un singolo ruolo.

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

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

  <Tab title="C#">
    Nella v12, `MessageParam` e `BetaMessageParam` erano classi di cui impostavi `Role` e `Content`. Nella v13 ciascuna è un'unione delle tre classi per i suoi ruoli, e gli enum `Role` in `Anthropic.Models.Messages` e `Anthropic.Models.Beta.Messages` non esistono più.

    Quando costruisci un messaggio, indica la classe per il suo ruolo ed elimina `Role`. Ogni classe si converte implicitamente nell'unione:

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

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

    Funziona anche `new UserMessageParam("Hello, Claude")`.

    Cambiano anche le classi che contengono `Content`:

    * `MessageParamContent` è ora `MessageContentParam`, e `BetaMessageParamContent` è ora `BetaMessageContentParam`.
    * Un messaggio system ha una propria classe di contenuto. Un `SystemMessageParamContent` contiene una stringa o una lista di `TextBlockParam`, e un `BetaSystemMessageParamContent` contiene una stringa o una lista di `SystemMessageContentBlock`. Una `List<ContentBlockParam>` o una `List<BetaContentBlockParam>` non si converte più in essa.
    * `ClearAt` e `OutputConfig` si trovano solo su `BetaSystemMessageParam`.

    Quando leggi un messaggio, l'unione ha ancora `Role` e `Content`, ma non puoi impostarli, quindi un'espressione `with` va applicata alla classe per il ruolo. `Role` ora contiene un `MessageParamRole` o un `BetaMessageParamRole`. `BetaMessageParam.Content` può essere `null`, perché `Content` è facoltativo su `BetaSystemMessageParam`.

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

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

    `TryPickUser`, `TryPickAssistant`, `TryPickSystem`, `Switch` e `Match` ti forniscono la classe per il ruolo.
  </Tab>

  <Tab title="Go">
    Nella v1, `MessageParam` era un'unica struct con un campo `Role` e un campo `Content`. Nella v2 è un'unione: `OfUser` contiene un `*UserMessageParam`, `OfAssistant` un `*AssistantMessageParam` e `OfSystem` un `*SystemMessageParam`. `BetaMessageParam` cambia allo stesso modo. L'SDK invia lo stesso JSON di prima, a parte l'ordine delle chiavi in un messaggio system beta.

    `NewUserMessage`, `NewAssistantMessage`, `NewBetaUserMessage` e i metodi `ToParam` di `Message` e `BetaMessage` funzionano come prima, quindi il codice che costruisce i propri messaggi con essi non richiede modifiche.

    Un letterale struct indica il tipo per il suo ruolo. Ometti `Role`, perché ogni tipo serializza il proprio:

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

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

    Il codice che legge un messaggio controlla quale campo è impostato:

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

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

    * I tipi `MessageParamRole` e `BetaMessageParamRole` e le loro costanti non esistono più. `message.GetRole()` restituisce un puntatore al ruolo come `string`, oppure `nil` quando nessun campo è impostato.
    * `ClearAt` e `OutputConfig` sono stati spostati da `BetaMessageParam` a `BetaSystemMessageParam`. I nomi del tipo `BetaMessageParamClearAt` e delle sue costanti ora iniziano con `BetaSystemMessageParamClearAt`.
    * `SystemMessageParam.Content` è un `[]TextBlockParam`. `BetaSystemMessageParam.Content` è un `[]BetaSystemMessageParamContentUnion`, che contiene blocchi `text`, `tool_addition` e `tool_removal`. `NewBetaSystemMessage` accetta blocchi di quel tipo, quindi `anthropic.NewBetaTextBlock("Be brief.")` diventa `anthropic.BetaSystemMessageParamContentUnion{OfText: &anthropic.BetaTextBlockParam{Text: "Be brief."}}`.
    * Una copia di un `MessageParam` punta allo stesso messaggio dell'originale. Impostare `duplicate.OfUser.Content` modifica entrambi, mentre nella v1 impostare `duplicate.Content` modificava solo la copia.
    * `mcp.ToMessage` restituisce un `*mcp.UnsupportedValueError` per un ruolo diverso da `user` o `assistant`. La v1 copiava qualsiasi ruolo nel messaggio.
  </Tab>

  <Tab title="Java">
    Nella v2, `MessageParam` era una singola classe con un `role` e un `content`. Nella v3 è un'unione delle tre classi, e `MessageParam.Content` è ora il `MessageContentParam` di primo livello. `BetaMessageParam` cambia allo stesso modo, e le sue classi hanno gli stessi nomi con un prefisso `Beta`. Il JSON inviato dall'SDK è lo stesso, tranne per il fatto che un messaggio system beta ora ha `role` prima di `content`.

    `addUserMessage`, `addAssistantMessage` e `addSystemMessage` con una `String`, `addMessage` con un `Message` o un `MessageParam`, e `Message.toParam()` non cambiano.

    `MessageParam.builder()` e `toBuilder()` non esistono più. Chiama il metodo factory per il ruolo, ovvero `ofUser`, `ofAssistant` o `ofSystem`:

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

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

    I metodi che accettano una lista di blocchi di contenuto hanno nuovi nomi sui builder di `MessageCreateParams`, `StructuredMessageCreateParams`, `MessageCountTokensParams` e `BatchCreateParams.Request.Params`:

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

    Sulla classe di contenuto, `BlockParams` (`BetaContentBlockParams` in beta) diventa `ContentBlockParams` in `ofBlockParams`, `blockParams()`, `isBlockParams()`, `asBlockParams()` e nel `visitBlockParams` del visitor.

    Un messaggio system ha una propria classe di contenuto, `SystemMessageParam.Content`, che ora `addSystemMessage` accetta. I suoi blocchi sono `TextBlockParam`, non `ContentBlockParam`. In beta sono `BetaSystemMessageParam.Content.SystemMessageContentBlock`, che ha `ofText`, `ofToolAddition` e `ofToolRemoval`.

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

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

    Quando leggi un messaggio, `role()` non cambia. `content()` restituisce un `MessageContentParam`, oppure un `Optional<BetaMessageContentParam>` in beta, dove un messaggio system può non avere contenuto. `_role()`, `_content()` e `_additionalProperties()` si trovano ora sulla classe per il ruolo, restituita da `asUser()`, `asAssistant()` o `asSystem()`.
  </Tab>

  <Tab title="PHP">
    Le classi si trovano in `Anthropic\Messages`, e le classi beta in `Anthropic\Beta\Messages`. I messaggi che scrivi come array non cambiano, e richiedono ancora il loro `'role'`.

    `MessageParam::with()` e `BetaMessageParam::with()` restano, e restituiscono la classe corrispondente a `role`. Una chiamata con argomenti nominati non richiede modifiche. `role` è ora il primo parametro, quindi in una chiamata posizionale scambia `content` e `role`, oppure chiama `with()` sulla classe del ruolo, che non accetta `role`. Per argomenti nel vecchio ordine PHP lancia `UnhandledMatchError`, di cui PHPStan non avvisa, oppure un `TypeError` se `content` è una lista o `role` è un caso di enum.

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

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

    Nessun oggetto è più un `MessageParam`: `instanceof MessageParam` è false, e PHP lancia un `TypeError` dove un tipo di parametro o di ritorno lo indica. Indica invece le tre classi:

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

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

    * `MessageParam::fromArray()` e `(new MessageParam)->withContent()` lanciano "Call to undefined method". Chiamali sulla classe del ruolo, che imposta `role` da sola.
    * `withRole()` ora accetta solo la stringa: PHP lancia un `TypeError` per un caso di `Role`. Per assegnare a un messaggio un altro ruolo, costruisci la classe di quel ruolo.
    * `clearAt` e `outputConfig` esistono solo su `BetaSystemMessageParam`, e `BetaMessageParam::with()` li scarta per gli altri due ruoli. L'enum `BetaMessageParam\ClearAt` è ora `BetaSystemMessageParam\ClearAt`.
    * `MessageParam\Content` è ora `MessageContentParam`, e `BetaMessageParam\Content` è ora `BetaMessageContentParam`. Anche i loro tipi PHPStan adottano il nuovo nome: `ContentShape` è ora `MessageContentParamShape`.
    * Un array il cui `'role'` è un caso di `Role` funziona ancora, ma PHPStan ora lo segnala. Scrivi la stringa.
  </Tab>

  <Tab title="Ruby">
    I messaggi che scrivi come hash non cambiano.

    Nella v2, `Anthropic::MessageParam` è un'unione di `Anthropic::UserMessageParam`, `Anthropic::AssistantMessageParam` e `Anthropic::SystemMessageParam`. Allo stesso modo, `Anthropic::Beta::BetaMessageParam` è un'unione delle sue tre classi.

    `Anthropic::MessageParam.new(role: :user, content: "Hello, Claude")` funziona ancora, e restituisce un'istanza della classe per quel ruolo. Puoi anche costruire tu stesso quella classe, senza `role:`, come `Anthropic::UserMessageParam.new(content: "Hello, Claude")`. Quattro cose cambiano per il codice che costruisce o ispeziona queste istanze:

    * `MessageParam.new` accetta solo keyword, quindi passa un hash come `MessageParam.new(**hash)`. Solleva un `ArgumentError` quando `role:` manca o non è uno dei tre ruoli.
    * `message.is_a?(Anthropic::MessageParam)` è `false`. Un ramo `when Anthropic::MessageParam` e `messages.grep(Anthropic::MessageParam)` corrispondono ancora.
    * Un'istanza costruita con `.new` non ha `:role` nel suo `to_h`, e `message[:role]` è `nil`. `message.role` restituisce ancora il ruolo.
    * Solo `BetaSystemMessageParam` ha `clear_at` e `output_config`. Su un messaggio user o assistant restituivano `nil`, e ora sollevano un `NoMethodError`.

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

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

    I moduli enum `Role` restano. Queste costanti sono state spostate. I nomi che iniziano con `Beta` si trovano sotto `Anthropic::Beta`, e gli altri sotto `Anthropic`:

    | Rimosso                     | Usa invece                                                                                  |
    | --------------------------- | ------------------------------------------------------------------------------------------- |
    | `MessageParam::Content`     | `MessageContentParam`, oppure `SystemMessageParam::Content` per un messaggio system         |
    | `BetaMessageParam::Content` | `BetaMessageContentParam`, oppure `BetaSystemMessageParam::Content` per un messaggio system |
    | `BetaMessageParam::ClearAt` | `BetaSystemMessageParam::ClearAt`                                                           |

    Se esegui il controllo dei tipi con Sorbet, `MessageParam::OrHash` non esiste più, e `Anthropic::MessageParam` come tipo non accetta più un'istanza. Usa `Anthropic::MessageParam::Variants` per le tre classi, ciascuna delle quali ha il proprio `OrHash`. In RBS, un valore di tipo `Anthropic::MessageParam` non ha `role` né `content`. Usa l'alias `Anthropic::Models::message_param`, che era la forma hash di un messaggio ed è ora l'unione delle tre classi. I nomi beta sono `BetaMessageParam::Variants` e `Anthropic::Models::Beta::beta_message_param`.
  </Tab>
</Tabs>

### Gli enum a un solo valore sono costanti

Questa modifica riguarda gli SDK C#, Go, Java, PHP e Ruby e un flag della CLI. Nelle versioni precedenti, un campo obbligatorio che può contenere un solo valore aveva un proprio tipo enum con un unico membro. Questi campi ora sono costanti e i tipi enum non esistono più. Il JSON che l'SDK invia e legge è lo stesso.

<Tabs exclude="shell:cURL, python, typescript">
  <Tab title="CLI">
    `--type` è facoltativo in `ant beta:sessions:resources add`. `file` è l'unico valore che `--type` può assumere lì, quindi la v2 lo invia per te. I comandi che passano ancora `--type file` continuano a funzionare, quindi non c'è nulla da modificare.
  </Tab>

  <Tab title="C#">
    Nella v12, una proprietà `required` di questo tipo aveva un enum con un unico membro, come `BetaManagedAgentsTextBlockType.Text`. Quasi tutte sono la proprietà `Type` di una classe sotto `Anthropic.Models.Beta`: `Agents`, `DeploymentRuns`, `Deployments`, `Dreams`, `Environments`, `MemoryStores`, `Sessions`, `UserProfiles` e `Vaults`. Nella v13 queste proprietà sono un `JsonElement` che il costruttore compila, come già era `TextBlockParam.Type`.

    Una proprietà facoltativa, come `BetaManagedAgentsGlobToolConfigParams.Type`, mantiene il proprio enum. Due di questi enum hanno un nuovo nome:

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

    Quando costruisci un oggetto, elimina la proprietà:

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

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

    Una classe a cui resta una sola proprietà obbligatoria ottiene anche un costruttore che la accetta, quindi funziona anche `new BetaManagedAgentsTextBlock("Hello Claude!")`. Una classe a cui non ne resta nessuna si costruisce con `new BetaManagedAgentsAlwaysAllowPolicy()`.

    Quando ne leggi una, confronta la stringa:

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

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

    Per distinguere le varianti di una union, continua a usare i suoi metodi `TryPick*`, `Switch` e `Match`, che non cambiano.
  </Tab>

  <Tab title="Go">
    Un esempio di tale tipo enum e della sua costante è `BetaManagedAgentsTextBlockType` e `BetaManagedAgentsTextBlockTypeText`. Quasi tutti sono il campo `Type` di una struct sotto `client.Beta`: Agents, Deployments, Deployment Runs, Dreams, Environments, Memory Stores, Sessions, User Profiles e Vaults. Nella v2 questi campi usano un tipo del pacchetto `shared/constant`, come già faceva `TextBlockParam.Type`. Un campo facoltativo, come `BetaManagedAgentsBashToolConfigParams.Type`, mantiene il proprio enum.

    In una richiesta, elimina il campo. Viene serializzato con il suo unico valore quando lo ometti:

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

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

    Una struct il cui unico campo era quel `Type` ora ha un costruttore, come `NewBetaManagedAgentsAlwaysAllowPolicyParam()`. Come membro di una union, funziona anche un puntatore alla struct vuota: `OfAlwaysAllow: &anthropic.BetaManagedAgentsAlwaysAllowPolicyParam{}`.

    In una risposta, confronta con la stringa:

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

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

    Una tua variabile, campo o parametro dichiarato con uno dei tipi rimossi assume il nuovo tipo del campo, come `constant.AgentMessage`. `constant.ValueOf[constant.AgentMessage]()` restituisce il suo valore.

    I costruttori delle union cambiano insieme ai campi. Questi cinque perdono il loro argomento `type_`:

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

    Questi quattro non accettavano altri argomenti, quindi non esistono più. Imposta il campo della union su un puntatore alla struct vuota, come `BetaManagedAgentsEventParamsUnion{OfUserInterrupt: &anthropic.BetaManagedAgentsUserInterruptEventParams{}}`:

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

  <Tab title="Java">
    Un esempio di tale enum è la classe annidata `BetaManagedAgentsTextBlock.Type`, con il suo unico membro `TEXT`. Quasi tutti sono il `type` di una classe sotto `com.anthropic.models.beta`: `agents`, `deploymentruns`, `deployments`, `dreams`, `environments`, `memorystores`, `sessions`, `userprofiles` e `vaults`. Nella v3 questi campi sono un `JsonValue` che il builder compila, come già era quello di `TextBlockParam`. Un campo facoltativo, come il `type` di `BetaManagedAgentsBashToolConfigParams`, mantiene il proprio enum.

    Quando costruisci un oggetto, elimina la chiamata:

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

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

    Una classe a cui resta un solo campo obbligatorio ottiene anche un metodo factory che lo accetta, quindi funziona anche `BetaManagedAgentsTextBlock.of("Hello Claude!")`. Una classe a cui non ne resta nessuno perde `of(type)`, e le sue union perdono l'overload che accettava l'enum, come `ofAlwaysAllow(type)`. Costruiscila con `BetaManagedAgentsAlwaysAllowPolicy.builder().build()`.

    Quando ne leggi uno, `type()` non esiste più e `_type()` restituisce il `com.anthropic.core.JsonValue`:

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

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

    Per distinguere le varianti di una union, continua a usare i suoi metodi `is*()` e `as*()` e il suo visitor, che non cambiano.
  </Tab>

  <Tab title="PHP">
    Un esempio di tale caso enum è `Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock\Type::TEXT`. Quasi tutti sono il `type` di una classe Managed Agents sotto `Anthropic\Beta`. Queste proprietà ora sono una stringa con quell'unico valore come predefinito, come già era il `type` di `Anthropic\Messages\TextBlockParam`. Una proprietà facoltativa, come il `type` di `Anthropic\Beta\Environments\BetaPackages`, mantiene il proprio enum.

    `with()` non accetta più `type`. Rimuovilo: PHP genera "Unknown named parameter" per un `type:` rimasto, e in una chiamata posizionale gli argomenti successivi avanzano di una posizione.

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

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

    Dove confrontavi con un caso enum, confronta con la stringa:

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

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

    * `withType()` e l'argomento `type` di `$client->beta->sessions->resources->add()` ora accettano solo la stringa. In `add()` il valore predefinito è `'file'`, quindi puoi ometterlo.
    * Le richieste che scrivi come array non cambiano e necessitano ancora del loro `'type'`.
  </Tab>

  <Tab title="Ruby">
    Un esempio di tale costante enum è `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock::Type::TEXT`. Quasi tutte sono il `type` di una classe Managed Agents sotto `Anthropic::Beta`. Nella v2 questi campi sono dichiarati come costante, come già era il `type` di `Anthropic::TextBlockParam`. Un campo facoltativo, come il `type` di `Anthropic::Beta::BetaManagedAgentsGlobToolConfigParams`, mantiene il proprio enum.

    Sostituisci una costante rimossa con il suo simbolo:

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

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

    Le richieste che scrivi come hash non cambiano e necessitano ancora del loro `type`:

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

    Quando costruisci un'istanza di modello, `type:` ora ha un valore predefinito, quindi puoi ometterlo: `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock.new(text: "Hello Claude!")`. Lo stesso vale per la keyword `type:` di `client.beta.sessions.resources.add`.

    Se esegui il controllo dei tipi con Sorbet, gli alias `Type::OrSymbol` e `Type::TaggedSymbol` di questi moduli sono stati rimossi insieme a essi, e i campi sono un `Symbol`. `OrSymbol` consentiva anche una `String`, quindi `.new(type: "text")` non supera più il controllo dei tipi. Rimuovi la keyword o passa `:text`. In RBS, l'alias `type_` di ogni classe non esiste più e il campo è il letterale, come `:text`.
  </Tab>
</Tabs>

### La compattazione lato client è stata rimossa dal tool runner

Questa modifica riguarda gli SDK TypeScript e Ruby. La compattazione lato client nel tool runner è stata rimossa a favore della compattazione lato server, che riassume la conversazione all'interno dell'API anziché con una richiesta aggiuntiva dal client.

<Tabs exclude="shell, python, csharp, go, java, php">
  <Tab title="TypeScript">
    L'opzione `compactionControl` e il modulo `@anthropic-ai/sdk/lib/tools/CompactionControl` non esistono più. L'opzione ha smesso di funzionare nella v0.129.0, dove passarla generava un `AnthropicError`. Non è presente nel tipo dei parametri, quindi TypeScript la segnala come proprietà sconosciuta.

    Per continuare a compattare automaticamente a una soglia di token:

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

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

    Per decidere tu quando compattare la conversazione, chiama [`runner.compactBeforeNextTurn()`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/helpers.md#compaction).
  </Tab>

  <Tab title="Ruby">
    L'opzione `compaction_control:` non esiste più. Ha smesso di funzionare nella v1.74.0, dove passarla sollevava un `ArgumentError`.

    Per continuare a compattare automaticamente a una soglia di token:

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

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

    Per decidere tu quando compattare la conversazione, chiama [`#compact_before_next_turn`](https://github.com/anthropics/anthropic-sdk-ruby/blob/main/helpers.md#compact_before_next_turn---compact-the-conversation) sul runner.
  </Tab>
</Tabs>

La soglia di attivazione deve essere di almeno 50.000 token. Consulta [compattazione](https://platform.claude.com/docs/it/build-with-claude/compaction-threshold) per le altre opzioni (`pause_after_compaction`, `instructions` personalizzate).

### Text Completions è stata rimossa

La API legacy Text Completions è stata rimossa dagli SDK TypeScript, Go, Java e Ruby e dalla CLI. I modelli e le funzionalità più recenti non la supportano. Usa invece la [Messages API](https://platform.claude.com/docs/it/api/messages).

<Tabs exclude="shell:cURL, python, csharp, php">
  <Tab title="CLI">
    Il comando `ant completions create` non esiste più.

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

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

    Il testo della risposta si sposta dal campo `completion` a `content.0.text`, quindi uno script che passava `--transform completion` passa invece `--transform content.0.text`.

    Anche `ant messages create` accetta `--stream`, ma i suoi eventi hanno un'altra forma: il testo arriva in `delta.text` degli eventi `content_block_delta`, quindi `--transform content.0.text` non si applica a uno stream.
  </Tab>

  <Tab title="TypeScript">
    `client.completions` non esiste più, insieme alla classe di risorsa `Completions` e ai tipi `Completion`, `CompletionCreateParams`, `CompletionCreateParamsNonStreaming` e `CompletionCreateParamsStreaming`. Anche `AnthropicBedrock` non ha più una proprietà `completions`. Anche le costanti `HUMAN_PROMPT` e `AI_PROMPT`, usate solo dai prompt di Text Completions, non esistono più, sia come export sia come proprietà statiche del client.

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

    // Dopo
    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 })` diventa `client.messages.create({ ..., stream: true })` o `client.messages.stream({ ... })`.
  </Tab>

  <Tab title="Go">
    `client.Completions` non esiste più, insieme a `CompletionService`, `NewCompletionService`, `CompletionNewParams` e `Completion`. Anche `aws.Client` non ha più un campo `Completions`. `bedrock.DefaultEndpoints` non elenca più `/v1/complete`.

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

    // Dopo
    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` diventa `client.Messages.NewStreaming`.
  </Tab>

  <Tab title="Java">
    `client.completions()` è stato rimosso da `AnthropicClient` e `AnthropicClientAsync`, insieme a `CompletionService`, `CompletionServiceAsync` e al pacchetto `com.anthropic.models.completions` (`CompletionCreateParams` e `Completion`).

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

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

    // Dopo
    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` diventa `client.messages().createStreaming`.
  </Tab>

  <Tab title="Ruby">
    `client.completions` non esiste più, insieme a `Anthropic::Resources::Completions`, `Anthropic::CompletionCreateParams` e `Anthropic::Completion`. Anche `Anthropic::BedrockClient` non ha più un reader `completions`. Su `Anthropic::BedrockMantleClient` e `Anthropic::GoogleCloudClient`, dove `completions` sollevava `NotImplementedError`, il metodo non esiste più.

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

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

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

### `betas` è stato rimosso dai metodi Models non beta

I metodi Models non beta non accettano più `betas` (csharp, go: `Betas`; java: `.addBeta()`), e i comandi `ant models` non accettano più `--beta`. Per inviare header beta, chiama gli stessi metodi su `client.beta.models` (csharp, go: `client.Beta.Models`; java: `client.beta().models()`; php: `$client->beta->models`), oppure `ant beta:models` nella CLI. Nell'SDK, questi metodi restituiscono `BetaModelInfo` (ruby: `Anthropic::Beta::BetaModelInfo`) dove quelli non beta restituiscono `ModelInfo` (ruby: `Anthropic::ModelInfo`).

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

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

  <Tab title="Python">
    `client.models.retrieve()` e `client.models.list()` non accettano più `betas` (passarlo genera un `TypeError`, e un type checker lo segnala), e `anthropic.types.ModelListParams` non ha più una chiave `betas`.

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

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

  <Tab title="TypeScript">
    `Anthropic.ModelRetrieveParams` e `Anthropic.ModelListParams` non hanno più una proprietà `betas`.

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

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

  <Tab title="C#">
    `ModelRetrieveParams` e `ModelListParams` in `Anthropic.Models.Models` non hanno più una proprietà `Betas`. I metodi su `client.Beta.Models` accettano le classi con gli stessi nomi in `Anthropic.Models.Beta.Models`.

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

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

    // Dopo
    using Anthropic.Models.Beta.Models;

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

  <Tab title="Go">
    `ModelGetParams` e `ModelListParams` non hanno più un campo `Betas`.

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

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

  <Tab title="Java">
    `ModelRetrieveParams` e `ModelListParams` in `com.anthropic.models.models` non hanno più `betas()`, e i loro builder non hanno più `betas` e `addBeta`. I metodi su `client.beta().models()` accettano le classi con gli stessi nomi in `com.anthropic.models.beta.models`.

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

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

    // Dopo
    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()` e `$client->models->list()` non accettano più `betas` (passarlo genera `Error: Unknown named parameter $betas`), e `Anthropic\Models\ModelRetrieveParams` e `Anthropic\Models\ModelListParams` non hanno più una proprietà `betas`.

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

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

    Se passi gli argomenti per posizione, `workspaceID` e `requestOptions` avanzano ciascuno di una posizione in entrambi i metodi.
  </Tab>

  <Tab title="Ruby">
    `client.models.retrieve` e `client.models.list` non accettano più `betas:`, e `Anthropic::ModelRetrieveParams` e `Anthropic::ModelListParams` non hanno più un campo `betas`.

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

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

    Passare `betas:` a `client.models` non solleva errori, ma non imposta più l'header `anthropic-beta`.
  </Tab>
</Tabs>

### Le chiavi API vengono inviate come `Authorization: Bearer`

L'SDK e la CLI inviano la tua chiave API come `Authorization: Bearer <key>` anziché nell'header `X-Api-Key`, quindi modifica qualsiasi proxy o gateway che legge o imposta `X-Api-Key` affinché usi `Authorization`, oppure [invia tu stesso la chiave in `X-Api-Key`](https://platform.claude.com/docs/it/api/migration-2026-10-21#sdk-proxy-x-api-key). La Claude API accetta una chiave in entrambi gli header, quindi un programma che comunica direttamente con l'API non richiede modifiche.

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

# After
Authorization: Bearer <key>
```

<Tabs>
  <Tab title="CLI">
    Questo vale per una chiave in `ANTHROPIC_API_KEY` e per una passata tramite pipe a `--api-key-stdin`.

    Con `--debug`, il log delle richieste ora mostra `Authorization: Bearer <REDACTED>` dove mostrava `X-Api-Key: <REDACTED>`.
  </Tab>

  <Tab title="Python">
    `Authorization` è l'header che `auth_token` usa già.

    Questo vale per l'argomento `api_key` e la variabile d'ambiente `ANTHROPIC_API_KEY` di `Anthropic` e `AsyncAnthropic`, e per `api_key` e `ANTHROPIC_AWS_API_KEY` di `AnthropicAWS`. `AnthropicFoundry` invia ancora la sua chiave come `x-api-key`, e `AnthropicBedrockMantle` inviava già un bearer token.
  </Tab>

  <Tab title="TypeScript">
    `Authorization` è l'header che l'opzione `authToken` usa già.

    Questo vale per l'opzione `apiKey`, la variabile d'ambiente `ANTHROPIC_API_KEY`, e `apiKey` e `ANTHROPIC_AWS_API_KEY` in `@anthropic-ai/aws-sdk`. `apiKey` in `@anthropic-ai/foundry-sdk` viene ancora inviata come `X-Api-Key`, e `apiKey` in `@anthropic-ai/bedrock-sdk` era già un bearer token.

    Un middleware o un `fetch` personalizzato che legge la chiave dall'header di richiesta `x-api-key` deve invece leggere `authorization`, dove la chiave segue `Bearer `.
  </Tab>

  <Tab title="C#">
    `Authorization` è l'header che `AuthToken` usa già.

    Questo vale per `ApiKey` su `AnthropicClient` e `ClientOptions` e per la variabile d'ambiente `ANTHROPIC_API_KEY`. Nella release di `Anthropic.Aws` che dipende dalla v13, vale anche per `ApiKey` in `AwsClientOptions` e per `ANTHROPIC_AWS_API_KEY`. `AnthropicFoundryApiKeyCredentials` invia ancora la sua chiave come `x-api-key`, e `ApiKey` in `MantleAwsClientOptions` era già un bearer token.
  </Tab>

  <Tab title="Go">
    Questo vale per `option.WithAPIKey`, la variabile d'ambiente `ANTHROPIC_API_KEY` e `APIKey` in `aws.ClientConfig` (o `ANTHROPIC_AWS_API_KEY`). `APIKey` in `foundry.ClientConfig` (o `ANTHROPIC_FOUNDRY_API_KEY`) viene ancora inviata come `X-Api-Key`, e `APIKey` in `bedrock.MantleClientConfig` era già un bearer token.
  </Tab>

  <Tab title="Java">
    `Authorization` è l'header che `authToken` usa già.

    Questo vale per `apiKey` sui builder `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` e `AnthropicBackend`, la variabile d'ambiente `ANTHROPIC_API_KEY` e la proprietà di sistema `anthropic.apiKey`. `apiKey` sul builder `FoundryBackend` viene ancora inviata come `x-api-key`. `apiKey` sui builder `AwsBackend`, `BedrockBackend` e `BedrockMantleBackend` era già un bearer token.

    Un interceptor ora vede la chiave in `Authorization` anziché in `X-Api-Key`.
  </Tab>

  <Tab title="PHP">
    `Authorization` è l'header che `authToken` usa già.

    Questo vale per l'argomento `apiKey` e la variabile d'ambiente `ANTHROPIC_API_KEY` di `Anthropic\Client`, e per `apiKey` e `ANTHROPIC_AWS_API_KEY` di `Anthropic\Aws\Client`. `Anthropic\Foundry\Client` invia ancora la sua chiave come `x-api-key`, e `Anthropic\Bedrock\MantleClient` inviava già un bearer token.
  </Tab>

  <Tab title="Ruby">
    `Authorization` è l'header che `auth_token:` usa già.

    Questo vale per l'argomento `api_key:` e la variabile d'ambiente `ANTHROPIC_API_KEY` di `Anthropic::Client`, e per `api_key:` e `ANTHROPIC_AWS_API_KEY` di `Anthropic::AWSClient`. `Anthropic::BedrockMantleClient` inviava già un bearer token.

    L'SDK rimuove `Authorization` quando segue un reindirizzamento verso un'altra origine, il che include un reindirizzamento da `http` a `https` sullo stesso host. Ora anche la chiave viene rimossa in quel caso.
  </Tab>
</Tabs>

#### Se un proxy o gateway legge `X-Api-Key`

<Tabs exclude="shell:cURL">
  <Tab title="CLI">
    Se `--base-url` o `ANTHROPIC_BASE_URL` indirizza `ant` verso un proxy o gateway che legge `X-Api-Key`, modificalo affinché legga la chiave da `Authorization`. `ant` non ha alcun flag o variabile d'ambiente per aggiungere un header personalizzato, quindi non può inviare `X-Api-Key`.
  </Tab>

  <Tab title="Python">
    Riporta la chiave nell'header originale con una funzione `auth` sul client HTTP. Viene eseguita su ogni richiesta inviata dal client, inclusi i tentativi ripetuti:

    ```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` accetta la stessa funzione, in `http_client=DefaultAsyncHttpxClient(auth=send_x_api_key)`.
  </Tab>

  <Tab title="TypeScript">
    Imposta tu stesso l'header. `Authorization: null` impedisce anche che la chiave venga inviata lì:

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

    Se il proxy aggiunge la credenziale e il tuo client non ne ha, la v0 ti permetteva di indicarlo con `"X-Api-Key": null` oppure `Authorization: null` in `defaultHeaders`. La v1 accetta solo `Authorization: null`.

    Il poller e il worker del lavoro degli ambienti ricevono una propria chiave, quindi escludono gli header predefiniti `X-Api-Key` e `Authorization` dalle proprie richieste.
  </Tab>

  <Tab title="C#">
    Imposta tu stesso l'header con `ExtraHeaders`. Impostare `ApiKey` e `AuthToken` su `null` impedisce anche che venga inviata una credenziale trovata in `ANTHROPIC_API_KEY` o `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">
    Imposta tu stesso l'header. `option.WithHeaderDel` impedisce anche che venga inviata una chiave trovata in `ANTHROPIC_API_KEY`:

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

    `environments.WorkPoller` e `environments.EnvironmentWorker` ricevono una propria chiave, quindi escludono un `X-Api-Key` impostato manualmente dalle proprie richieste.
  </Tab>

  <Tab title="Java">
    Imposta tu stesso l'header anziché chiamare `apiKey`:

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

  <Tab title="PHP">
    Riporta la chiave nell'header originale con 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]]);
    ```

    Non usare gli `extraHeaders` del client per questo scopo. Una richiesta che ha i propri `extraHeaders` sostituisce quelli del client, e ogni endpoint sotto `$client->beta` che richiede un header beta li ha.
  </Tab>

  <Tab title="Ruby">
    Riporta la chiave nell'header originale con 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 prima riga lascia invariata una richiesta quando non contiene la chiave, come una che è stata reindirizzata verso un'altra origine.

    `Anthropic::AWSClient` non accetta alcun argomento `middleware:`. Passa invece il middleware con ogni richiesta, come `request_options: {middleware: send_x_api_key}`.
  </Tab>
</Tabs>

#### Se impostavi o rimuovevi `X-Api-Key` su una richiesta

Questa modifica riguarda gli SDK Python, TypeScript, Go, PHP e Ruby.

Se rimuovevi `X-Api-Key` affinché una richiesta inviasse solo un token di autenticazione, elimina quel codice anziché modificarlo, perché rimuovere `Authorization` rimuoverebbe il token. [Un client contiene una sola credenziale](https://platform.claude.com/docs/it/api/migration-2026-10-21#sdk-one-credential), quindi assicurati che sia il token: se nessuna viene passata nel codice e sono impostate sia `ANTHROPIC_API_KEY` sia `ANTHROPIC_AUTH_TOKEN`, il client usa la chiave.

<Tabs exclude="shell, csharp, java">
  <Tab title="Python">
    Il codice che passa `extra_headers={"X-Api-Key": omit}` per escludere la chiave da una richiesta non ottiene più questo effetto. Passa invece `extra_headers={"Authorization": omit}`.

    `extra_headers={"X-Api-Key": other_key}` non sostituisce più la chiave del client: vengono inviate entrambe le chiavi. Per inviare un'altra chiave con una singola richiesta, passa `extra_headers={"Authorization": f"Bearer {other_key}"}`.
  </Tab>

  <Tab title="TypeScript">
    `headers: { "X-Api-Key": otherKey }` nelle opzioni di una richiesta non sostituisce più la chiave del client: vengono inviate entrambe le chiavi. Per inviare un'altra chiave con una singola richiesta, passa ``headers: { Authorization: `Bearer $\{otherKey}` }``.
  </Tab>

  <Tab title="Go">
    `option.WithHeaderDel("X-Api-Key")` non esclude più la chiave da una richiesta. Elimina invece `Authorization`:

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

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

    `option.WithHeader("X-Api-Key", otherKey)` non sostituisce più la chiave del client: vengono inviate entrambe le chiavi. Per inviare un'altra chiave con una singola richiesta, passa `option.WithAPIKey(otherKey)`.
  </Tab>

  <Tab title="PHP">
    `'extraHeaders' => ['X-Api-Key' => null]` non esclude più la chiave da una richiesta. Per inviare una richiesta senza credenziali, imposta invece `Authorization` su `null`, oppure rimuovilo in un middleware se lo facevi per l'intero client.

    `'extraHeaders' => ['X-Api-Key' => $otherKey]` non sostituisce più la chiave del client: vengono inviate entrambe le chiavi. Per inviare un'altra chiave con una singola richiesta, imposta `Authorization` su `"Bearer {$otherKey}"`.
  </Tab>

  <Tab title="Ruby">
    `extra_headers: {"x-api-key" => nil}` non esclude più la chiave da una richiesta. Imposta invece `"authorization"` su `nil`. Per inviare un'altra chiave con una singola richiesta, imposta `"authorization"` su `"Bearer #{other_key}"`, non `"x-api-key"`.
  </Tab>
</Tabs>

### Un client contiene una sola credenziale

Una chiave API e un "auth token" (token di autenticazione) ora condividono un header, quindi un client SDK contiene una sola credenziale. Se nel codice non ne viene passata nessuna, il client segue l'ordine di [precedenza delle credenziali](https://platform.claude.com/docs/it/manage-claude/wif-reference#credential-precedence).

<Tabs exclude="shell">
  <Tab title="Python">
    La v1 inviava sia una chiave API sia un auth token quando il client li aveva entrambi, ciascuno nel proprio header. La credenziale è una tra `api_key`, `auth_token`, `credentials`, `config` o `profile`.

    * **Passane al massimo una.** Due o più nel costruttore, o in una singola chiamata a `copy()` o `with_options()`, sollevano `ValueError`. `None` non conta. La v1 sollevava `TypeError`, e solo per due tra `credentials`, `config` e `profile`.
    * **Quella che passi è l'unica.** Come nella v1, il client non ne cerca un'altra nell'ambiente o su disco.
    * **Se non ne passi nessuna, viene usata solo la prima di queste che risulta impostata:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, il profilo indicato da `ANTHROPIC_PROFILE`, le variabili di "workload identity federation" (federazione delle identità dei carichi di lavoro), il profilo attivo su disco (quello indicato dal file `active_config`, altrimenti `default`). Quando le prime due sono entrambe impostate, il client registra un avviso una sola volta. La v1 usava il profilo attivo prima delle variabili di federazione quando `ANTHROPIC_CONFIG_DIR` era impostata o esisteva un file `active_config`; imposta `ANTHROPIC_PROFILE` per continuare a usarlo.
    * **`copy()` e `with_options()` sostituiscono.** Una credenziale che passi sostituisce quella del client, qualunque sia il tipo dell'una o dell'altra. Un base URL e gli header provenienti dalla config o dal profilo della vecchia credenziale vengono rimossi con essa, e vengono usati quelli della nuova credenziale. Un base URL che hai passato tu rimane.

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

    # Prima: inviava `X-Api-Key: <key>` e `Authorization: Bearer <token>`
    # Dopo:  solleva `ValueError`
    ```

    I client delle piattaforme mantengono le proprie regole. `AnthropicAWS` accetta `auth_token` insieme ad `api_key` senza errori, e invia la chiave.

    Le docstring di `Anthropic.__init__` e `Anthropic.copy` in [`_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) contengono i dettagli.

    Se facevi affidamento sull'invio di entrambe, ad esempio un token per un gateway e una chiave per l'API dietro di esso, passa il token come `auth_token` e imposta `X-Api-Key` in `default_headers`. Fai in modo che il gateway rimuova il proprio header `Authorization` prima di inoltrare la richiesta. La Claude API si aspetta una sola credenziale per richiesta.
  </Tab>

  <Tab title="TypeScript">
    Nella v0 un client che aveva sia una chiave API sia un auth token li inviava entrambi, ciascuno nel proprio header. La credenziale è una tra `apiKey`, `authToken`, `credentials`, `config` o `profile`.

    * **Passane al massimo una.** Due o più in `new Anthropic()`, o in una singola chiamata a `withOptions()`, lanciano un `TypeError`. `null` e `undefined` non contano.
    * **Quella che passi è l'unica.** Il client non ne cerca un'altra nell'ambiente o su disco.
    * **Se non ne passi nessuna, viene usata la prima di queste:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, il profilo indicato da `ANTHROPIC_PROFILE`, le variabili di "workload identity federation" (federazione delle identità dei carichi di lavoro), il profilo attivo su disco (quello indicato dal file `active_config`, altrimenti `default`). Quando le prime due sono entrambe impostate, il client registra un avviso una sola volta. Nella v0 il profilo attivo veniva prima delle variabili di federazione. Un `ANTHROPIC_PROFILE` che indica un profilo mancante veniva ignorato nella v0, mentre ora la prima richiesta lancia un `AnthropicError`. `loadConfig()` senza argomenti segue lo stesso ordine e lancia lo stesso errore.
    * **`withOptions` sostituisce.** Una credenziale che passi sostituisce quella del client che copi, quindi `client.withOptions({ authToken })` non ha più bisogno di `apiKey: null` accanto.
    * **Un client di piattaforma accetta solo le credenziali della propria piattaforma.** I client AWS, Bedrock e Foundry e `AnthropicVertex` lanciano un `AnthropicError` per un'opzione di credenziale con cui non si autenticano, come già faceva `AnthropicGoogleCloud`. Sui client AWS e Bedrock `apiKey: null` ora cancella la chiave, quindi il client firma con le credenziali AWS. `AnthropicBedrock` conserva la sua chiave in `client.apiKey`, mentre la v0 la conservava in `client.authToken`.

    ```typescript
    // Prima: inviava la chiave API e ignorava `credentials`
    const client = new Anthropic({ apiKey, credentials });

    // Dopo: la riga sopra genera un TypeError
    const client = new Anthropic({ credentials });
    ```

    I commenti di documentazione su [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/src/client.ts) spiegano come si comporta ciascuna opzione, e il commento di documentazione sul costruttore di ciascuno di quei client di piattaforma elenca le opzioni che rifiuta.

    Se facevi affidamento sull'invio di entrambe, ad esempio un token per un gateway e una chiave per l'API dietro di esso, imposta `X-Api-Key` in `defaultHeaders` e mantieni `authToken`. Fai in modo che il gateway rimuova il proprio header `Authorization` prima di inoltrare la richiesta. La Claude API si aspetta una sola credenziale per richiesta.
  </Tab>

  <Tab title="C#">
    Nella v12 un client che aveva sia una chiave API sia un auth token li inviava entrambi, ciascuno nel proprio header. La credenziale è una tra `ApiKey`, `AuthToken` o `ClientOptions.Credentials`.

    * **Passarne due è un errore.** Impostarne una seconda lancia un'`ArgumentException`. `null` non conta, quindi per sostituire la credenziale in `ClientOptions` che hai costruito tu, imposta prima quella vecchia a `null`.
    * **Passarne una la usa e ignora l'ambiente.** Non viene letta alcuna variabile d'ambiente di credenziale né alcun profilo su disco. Allo stesso modo, `AnthropicCredentials.Resolve(profile: "name")` ora restituisce le credenziali di quel profilo quando `ANTHROPIC_API_KEY` o `ANTHROPIC_AUTH_TOKEN` è impostata.
    * **Non passarne nessuna usa la prima corrispondenza nell'ambiente:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, le variabili di "workload identity federation" (federazione delle identità dei carichi di lavoro), poi il profilo attivo su disco. Una `ANTHROPIC_API_KEY` o `ANTHROPIC_AUTH_TOKEN` vuota conta come non impostata. Quando le prime due sono entrambe impostate, un avviso viene scritto su stderr una sola volta. Il client effettua la ricerca al primo utilizzo, quindi un `ANTHROPIC_PROFILE` che non esiste ora genera un'eccezione dalla prima richiesta invece che dal costruttore.
    * **`WithOptions` sostituisce.** Una credenziale che passi nel modificatore sostituisce quella del client, qualunque fosse il suo tipo, quindi `AuthToken = token` non ha più bisogno di `ApiKey = null` accanto. Se non ne passi nessuna, la copia mantiene la credenziale, il `BaseUrl` e gli `ExtraHeaders` del client, anche quando il modificatore restituisce nuove `ClientOptions`.

    ```csharp
    // Prima: inviava entrambi, ciascuno nella propria intestazione
    AnthropicClient client = new() { ApiKey = apiKey, AuthToken = token };

    // Dopo: la riga sopra genera un'ArgumentException
    AnthropicClient client = new() { AuthToken = token };
    ```

    La documentazione XML di quelle tre proprietà di [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-csharp/blob/main/src/Anthropic/Core/ClientOptions.cs) contiene i dettagli.

    I client delle piattaforme cloud mantengono le credenziali con cui sono stati costruiti. I client Bedrock, Bedrock Mantle, Foundry, Google Cloud e AWS e `AnthropicVertexClient` decidono come autenticarsi quando li costruisci, e la maggior parte di essi usa l'header `Authorization` a tale scopo. Le release di questi pacchetti che dipendono dalla v13 ignorano un `ApiKey` o un `AuthToken` impostato tramite `WithOptions`. Per usare un'altra chiave con `AnthropicAwsClient`, costruisci un nuovo client con `ApiKey` in `AwsClientOptions`.

    Se facevi affidamento sull'invio di entrambe, ad esempio un token per un gateway e una chiave per l'API dietro di esso, imposta `X-Api-Key` con `ExtraHeaders` e mantieni `AuthToken`. Fai in modo che il gateway rimuova il proprio header `Authorization` prima di inoltrare la richiesta. La Claude API si aspetta una sola credenziale per richiesta.
  </Tab>

  <Tab title="Go">
    Nella v1 un client che aveva sia una chiave API sia un auth token li inviava entrambi, ciascuno nel proprio header. La credenziale proviene da `option.WithAPIKey`, `option.WithAuthToken`, `option.WithConfig`, `option.WithProfile` o `option.WithFederationTokenProvider`.

    * **Passarne due ad `anthropic.NewClient` è un errore.** `NewClient` non restituisce errori, quindi ogni richiesta effettuata dal client fallisce con quell'errore. `NewClient` applica già `anthropic.DefaultClientOptions()`, quindi non passare anche il suo risultato: la credenziale che trova nell'ambiente conterebbe allora come una che hai passato tu.
    * **Una di esse viene usata così com'è.** Nessuna credenziale viene letta dall'ambiente o da un profilo su disco. Nella v1 `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` prevalevano sulle ultime tre.
    * **Se non ne passi nessuna, viene usata la prima di queste che risulta impostata,** nello stesso ordine della v1: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, le variabili di "workload identity federation" (federazione delle identità dei carichi di lavoro), il profilo attivo su disco. Quando le prime due sono entrambe impostate, l'SDK registra un avviso una sola volta.
    * **Una di esse su una richiesta sostituisce la credenziale del client per quella richiesta,** quindi `option.WithAuthToken` non ha più bisogno di `option.WithHeaderDel("X-Api-Key")` accanto.

    ```go
    // Prima: la chiave API veniva inviata e veniva registrato un avviso
    client := anthropic.NewClient(
    	option.WithAPIKey(apiKey),
    	option.WithProfile("work"),
    )

    // Dopo: ogni richiesta del client sopra fallisce, quindi passa quella che vuoi
    client := anthropic.NewClient(option.WithAPIKey(apiKey))
    ```

    L'avviso che la v1 registrava non esiste più, quindi `option.WithConfigQuiet`, che lo sopprimeva, ora fa ciò che fa `option.WithConfig` ed è deprecata.

    I commenti di documentazione su `anthropic.NewClient` e `anthropic.DefaultClientOptions` in [`client.go`](https://github.com/anthropics/anthropic-sdk-go/blob/main/client.go) contengono i dettagli.

    Se facevi affidamento sull'invio di entrambe, ad esempio un token per un gateway e una chiave per l'API dietro di esso, imposta `X-Api-Key` con `option.WithHeader` e mantieni `option.WithAuthToken`. Fai in modo che il gateway rimuova il proprio header `Authorization` prima di inoltrare la richiesta. La Claude API si aspetta una sola credenziale per richiesta.

    `ANTHROPIC_CUSTOM_HEADERS` e `ANTHROPIC_WEBHOOK_SIGNING_KEY` ora si applicano a ogni client costruito da `anthropic.NewClient`. Nella v1 venivano lette solo quando né l'ambiente né un profilo su disco contenevano una credenziale.
  </Tab>

  <Tab title="Java">
    Nella v2 un client che aveva sia una chiave API sia un auth token li inviava entrambi, ciascuno nel proprio header. La credenziale è una tra `apiKey`, `authToken` o `configurationProvider` sui builder `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` e `AnthropicBackend`.

    * **Impostane al massimo una.** Con due sullo stesso builder, `build()` lancia un'`IllegalStateException` che le nomina. `null` o un `Optional` vuoto non contano.
    * **Quella che imposti è l'unica.** `fromEnv()`, chiamato prima o dopo, non prende alcuna credenziale dall'ambiente o da un profilo su disco. Nella v2, una chiave o un token trovati da `fromEnv()` potevano essere inviati in aggiunta, o al suo posto.
    * **Se non ne imposti nessuna, `fromEnv()` usa la prima di queste che trova:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, le variabili di "workload identity federation" (federazione delle identità dei carichi di lavoro), il profilo attivo su disco. Quando le prime due sono entrambe impostate, un avviso viene scritto su `System.err` una sola volta. Le proprietà di sistema `anthropic.apiKey` e `anthropic.authToken` contano come ambiente. Una chiave o un token vuoti, in una variabile o in una proprietà di sistema, contano come non impostati. Nella v2, `fromEnv()` usava il valore vuoto come chiave o token.

    ```java
    // Prima: venivano inviati entrambi. In v3, build() genera una IllegalStateException
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .apiKey(apiKey)
        .authToken(authToken)
        .build();

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

    La documentazione di `fromEnv()` su quei builder contiene i dettagli.

    Se facevi affidamento sull'invio di entrambe, ad esempio un token per un gateway e una chiave per l'API dietro di esso, imposta tu stesso entrambi gli header:

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

    Fai in modo che il gateway rimuova il proprio header `Authorization` prima di inoltrare la richiesta. La Claude API si aspetta una sola credenziale per richiesta.
  </Tab>

  <Tab title="PHP">
    Le versioni precedenti inviavano sia una chiave API sia un auth token quando il client li aveva entrambi, ciascuno nel proprio header. `Anthropic\Client` accetta una sola credenziale, tra `apiKey`, `authToken` o `credentials`:

    * Passarne più di una lancia `\InvalidArgumentException`. Solo `null` conta come non passato. Una stringa vuota conta come passata, quindi `new Client(apiKey: '')` non invia alcuna credenziale.
    * Passarne una la usa, e nessuna credenziale viene letta dall'ambiente o da un profilo su disco. Con `ANTHROPIC_API_KEY` impostata, `new Client(authToken: $token)` invia il token. Le versioni precedenti inviavano insieme ad esso la chiave dell'ambiente.
    * Non passarne nessuna usa la prima di queste che risulta impostata: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, il profilo indicato da `ANTHROPIC_PROFILE`, le variabili di "workload identity federation" (federazione delle identità dei carichi di lavoro), il profilo attivo su disco (quello indicato dal file `active_config`, altrimenti `default`). Le versioni precedenti usavano il profilo attivo prima delle variabili di federazione, e non usavano alcun profilo quando non c'era un file `active_config`. Ignoravano inoltre un `ANTHROPIC_PROFILE` che indicava un profilo mancante o non valido. In quel caso, `new Client()` ora lancia `Anthropic\Core\Exceptions\AnthropicException`. Con `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` entrambe impostate, il client invia la chiave e la sua proprietà `authToken` è vuota. Il primo client costruito in questo modo scrive anche un avviso con `error_log()`, una volta per processo, il che su un server web significa una volta per richiesta: `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Per interromperlo, rimuovi la variabile che non usi.

    ```php
    // Prima: inviava la chiave come X-Api-Key e il token come Authorization.
    // Dopo: genera l'errore "Pass at most one of `apiKey`, `authToken`, or `credentials`. Received `apiKey`, `authToken`."
    $client = new Client(apiKey: $key, authToken: $token);
    ```

    Se facevi affidamento sull'invio di entrambe, ad esempio un token per un gateway e una chiave per l'API dietro di esso, passa il token come `authToken` e aggiungi `X-Api-Key` in un middleware come quello in [Se un proxy o un gateway legge `X-Api-Key`](https://platform.claude.com/docs/it/api/migration-2026-10-21#sdk-proxy-x-api-key), senza la chiamata a `withoutHeader`. Fai in modo che il gateway rimuova il proprio header `Authorization` prima di inoltrare la richiesta. La Claude API si aspetta una sola credenziale per richiesta.
  </Tab>

  <Tab title="Ruby">
    Gli argomenti di credenziale di `Anthropic::Client.new` sono `api_key:`, `auth_token:`, `credentials:` e `config:`. Un argomento `nil` conta come non passato. I client delle piattaforme mantengono le proprie regole.

    * **Due o più passati:** `Anthropic::Client.new` solleva `ArgumentError`. Le versioni precedenti sollevavano l'errore solo per `credentials:` insieme a `config:`, e altrimenti inviavano la chiave se presente, poi il token.
    * **Uno passato:** il client lo usa, e non ricorre a una credenziale dall'ambiente o da un profilo su disco.
    * **Nessuno passato:** il client usa la prima di queste che trova: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, le variabili di "workload identity federation" (federazione delle identità dei carichi di lavoro), il profilo attivo su disco. L'ordine non è cambiato, ma con `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` entrambe impostate, `client.auth_token` ora è `nil`. Una `ANTHROPIC_API_KEY` o `ANTHROPIC_AUTH_TOKEN` vuota ora conta come non impostata, mentre le versioni precedenti lasciavano che una `ANTHROPIC_API_KEY` vuota nascondesse il token e tutto ciò che veniva dopo.

    Quando non viene passata alcuna credenziale e `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` sono entrambe impostate, l'SDK emette anche un avviso una volta per processo, sullo standard error tramite `Kernel#warn`: `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Rimuovi la variabile che non usi per silenziarlo.

    ```ruby
    # Prima: inviava la chiave e ignorava il token.
    # Dopo: 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)

    # Passa solo quello che vuoi inviare.
    Anthropic::Client.new(api_key: api_key)
    ```
  </Tab>
</Tabs>

### Modifiche in un singolo SDK o nella CLI

Ciascuna di queste modifiche riguarda un singolo SDK o la CLI.

<Tabs exclude="shell:cURL, python, typescript, go, ruby">
  <Tab title="CLI">
    **`--api-key` e `--auth-token` sono stati rimossi.** `ant` non accetta più una chiave API o un auth token come valore di un flag, perché un valore sulla riga di comando è visibile nella cronologia della shell e negli elenchi dei processi. Entrambi i flag stampano un avviso di deprecazione dalla v1.27.0. Un comando che ne passa ancora uno si interrompe con `flag provided but not defined`.

    | Rimosso                | Usa invece                                                |
    | ---------------------- | --------------------------------------------------------- |
    | `--api-key <key>`      | `ANTHROPIC_API_KEY`, `--api-key-stdin` o `ant auth login` |
    | `--auth-token <token>` | `ANTHROPIC_AUTH_TOKEN` o `--auth-token-stdin`             |

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

    # Dopo, dall'ambiente
    export ANTHROPIC_API_KEY="$KEY"
    ant models list

    # Dopo, da un secret manager
    op read op://vault/anthropic/api-key | ant --api-key-stdin models list
    ```

    `--api-key-stdin` e `--auth-token-stdin` leggono tutto lo standard input, quindi un comando che ne usa uno prende il corpo della richiesta dai flag.

    `ant auth status`, il prompt di primo avvio di `ant apply` e la nota sulle fonti di autenticazione multiple ora chiamano queste credenziali `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN`, mentre prima stampavano `--api-key / ANTHROPIC_API_KEY` e `--auth-token / ANTHROPIC_AUTH_TOKEN`.
  </Tab>

  <Tab title="C#">
    **Il `Type` di una union è un enum.** Nella v12, la proprietà `Type` di una classe union, come `ContentBlock.Type` o `RawMessageStreamEvent.Type`, era un `JsonElement`. Nella v13 è un `ApiEnum<string, T>`, dove `T` è un nuovo enum con un membro per ciascuna variante, come `ContentBlockType`. Alcune union si distinguono invece tramite `Name` o `Command`, come `BetaMemoryTool20250818Command.Command`, e quelle proprietà cambiano allo stesso modo. Il `Type` di una classe variante, come `TextBlock.Type`, è ancora un `JsonElement`.

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

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

    `block.Type.Raw()` restituisce la stringa, anche una per cui questa versione dell'SDK non ha un membro enum.

    **`IChatClient` ignora le opzioni di campionamento.** Gli adattatori `IChatClient` (`AsIChatClient()`) ora ignorano `ChatOptions.Temperature`, `ChatOptions.TopK` e `ChatOptions.TopP`. Consulta [I parametri di campionamento sono stati rimossi](https://platform.claude.com/docs/it/api/migration-2026-10-21#sampling-parameters).
  </Tab>

  <Tab title="Java">
    **Getter che ora restituiscono un `Optional`.** `apiKey()` e `authToken()` su `AnthropicBackend` ora restituiscono un `Optional<String>`, come già facevano `apiKey()` su `AwsBackend` e `BedrockMantleBackend`. Nella v2 ciascuno restituiva una `String`, che era `null` quando il backend non aveva una credenziale di quel tipo.

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

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

    Anche questi getter ora restituiscono un `Optional`. Nella v2 ciascuno restituiva il valore stesso, che era `null` quando non ce n'era uno:

    * `apiKey()` e `awsCredentialsProvider()` su `BedrockBackend`
    * `filename()` e `mimeType()` su `McpResourceFile`
    * `detail()` su `CredentialSource`
    * `body()` su `HttpRequest`
    * `resource()` su `FoundryBackend`, che era `getResource()`
    * `responseValidation()`, `timeout()`, `followRedirects()`, `fallbackState()` e `openTelemetry()` su `RequestOptions`, che erano `getResponseValidation()`, `getTimeout()`, `getFollowRedirects()`, `getFallbackState()` e `getOpenTelemetry()`

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

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

    `getBaseUrl()` su `FoundryBackend` è stato rimosso. Chiama `baseUrl()`, che restituisce l'URL a cui vanno le richieste. Si tratta del base URL che hai impostato, o di quello costruito a partire dalla risorsa, e termina con `/anthropic`.

    Anche `getBaseUrl()` su `AnthropicBackend` è stato rimosso. Chiama `baseUrl()`, che restituisce lo stesso valore.

    **`HttpRequest` richiede un base URL.** Se costruisci tu stesso un `HttpRequest`, ad esempio in un test di un interceptor, imposta il suo base URL. Senza di esso, `build()` ora lancia un'`IllegalStateException`. Nella v2 restituiva una richiesta il cui `baseUrl()` era `null`. Le richieste costruite dall'SDK ne avevano già uno.

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

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

    `baseUrl()` restituisce ancora una `String`, che ora non è mai `null`. Sul builder, `baseUrl(Optional<String>)` è stato rimosso e `baseUrl(String)` non accetta più `null`.

    **Gli interceptor vedono `anthropic-version`.** Il client ora aggiunge l'header predefinito `anthropic-version` prima dell'esecuzione degli interceptor. Nella v2, il backend lo aggiungeva dopo di essi. Se il tuo interceptor imposta una propria versione, chiama `replaceHeaders`, perché `putHeader` ora aggiunge un secondo valore:

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

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

  <Tab title="PHP">
    **I casi enum che passi vengono riletti come i loro valori.** `with()` e i setter come `withAllowedCallers()` accettano ancora un caso enum o il suo valore. Le versioni precedenti conservavano un caso così come lo passavi. La v1 conserva il valore del caso, che è ciò che i tipi delle proprietà già dichiarano. Gli oggetti che l'SDK costruisce da una risposta non cambiano, e il JSON che l'SDK invia è lo stesso. Se rileggi una proprietà e la confronti con un caso, il confronto ora è falso e non viene lanciata alcuna eccezione, quindi confrontala con il valore del caso:

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

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

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

### La licenza è Apache 2.0

A partire da queste versioni, l'SDK e la CLI sono distribuiti con la Apache License, Version 2.0. Le versioni precedenti restano sotto la MIT License. Non sono necessarie modifiche al codice. Se tieni traccia delle licenze delle tue dipendenze, aggiorna le relative voci.

* **TypeScript:** i pacchetti delle piattaforme (`@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` e `@anthropic-ai/google-cloud-sdk`) cambiano licenza nelle rispettive release 1.0.0.
* **C#:** gli altri pacchetti (`Anthropic.Bedrock`, `Anthropic.Vertex`, `Anthropic.Foundry`, `Anthropic.Aws`, `Anthropic.GoogleCloud` e `Anthropic.Mcp`) cambiano licenza nelle rispettive release 1.0.0.
* **Java:** la modifica riguarda ogni artefatto `com.anthropic`.
