---
title: Migrando para a versão 2026-10-21 da API
url: https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21
description: "Atualize uma integração com a Claude API da versão 2023-06-01 da API para a 2026-10-21: a versão do SDK a instalar e as alterações de código a fazer."
---

Este guia lista as alterações de código para migrar da versão `2023-06-01` da API para a `2026-10-21`. As [etapas de atualização](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#migration-checklist) dizem o que fazer, em ordem.

## Etapas de atualização

<Steps>
  <Step title="Mude para 2026-10-21">
    Se você usa um SDK, suas requisições usam a versão da API que era a atual quando a versão principal do seu SDK foi lançada. As versões mostradas para a sua linguagem são as primeiras a usar `2026-10-21`, então atualize para elas. Se você chama a API sem um SDK, defina o cabeçalho `anthropic-version` como `2026-10-21`.

    <Tabs>
      <Tab title="cURL">
        Defina o cabeçalho `anthropic-version` como `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">
        Atualize a CLI `ant` para a versão 2.0.0. O comando do Homebrew e os downloads das releases continuam os mesmos.

        O Go exige que o caminho de um módulo na versão principal 2 ou posterior termine com essa versão, então o caminho do módulo da CLI agora é `github.com/anthropics/anthropic-cli/v2`. Se você instala com `go install`, adicione `/v2` ao caminho:

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

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

        O caminho antigo continua instalando a release v1 mais recente, sem nenhum erro ou aviso.
      </Tab>

      <Tab title="Python">
        Atualize o pacote `anthropic` para a versão 2.0.0.
      </Tab>

      <Tab title="TypeScript">
        Atualize o pacote `@anthropic-ai/sdk` para a versão 1.0.0.

        A v1 de `@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` e `@anthropic-ai/google-cloud-sdk` precisa da v1 de `@anthropic-ai/sdk`, e as versões anteriores deles precisam de uma versão abaixo de 1. Se você usa um deles, mova-o para a v1 na mesma atualização. Caso contrário, seu gerenciador de pacotes instala uma segunda cópia, mais antiga, de `@anthropic-ai/sdk` para ele.
      </Tab>

      <Tab title="C#">
        Atualize o pacote `Anthropic` para a versão 13.0.0.
      </Tab>

      <Tab title="Go">
        Atualize para a versão 2.0.0 do SDK para Go, cujo caminho de módulo é `github.com/anthropics/anthropic-sdk-go/v2`. Uma nova versão principal de um módulo Go tem um novo caminho de importação, então altere cada importação de `github.com/anthropics/anthropic-sdk-go`, e de seus pacotes como `github.com/anthropics/anthropic-sdk-go/option`, para começar com `github.com/anthropics/anthropic-sdk-go/v2`. Em seguida, execute `go get github.com/anthropics/anthropic-sdk-go/v2`.
      </Tab>

      <Tab title="Java">
        Atualize o artefato `com.anthropic:anthropic-java` para a versão 3.0.0.
      </Tab>

      <Tab title="PHP">
        Execute `composer require "anthropic-ai/sdk"` para atualizar o pacote para a versão 1.0.0. Apenas `composer update` permanece dentro da sua restrição de versão atual.
      </Tab>

      <Tab title="Ruby">
        Atualize a gem `anthropic` para a versão 2.0.0.
      </Tab>
    </Tabs>

    <Warning>
      No Amazon Bedrock, `2026-10-21` está disponível apenas para modelos Claude 4.7 e posteriores. Se você chama um modelo mais antigo no Bedrock, listado em [Claude no Amazon Bedrock (Opus 4.6 e anteriores)](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-on-amazon-bedrock-legacy), permaneça na versão do SDK que você usa hoje ou, se você mesmo define a versão da API, continue enviando a versão que envia hoje. Para mover essas chamadas para `2026-10-21`, primeiro mude-as para um modelo Claude 4.7 ou posterior.
    </Warning>

    Lance a atualização junto com suas correções da próxima etapa.
  </Step>

  <Step title="Atualize seu código para as alterações incompatíveis">
    Percorra as ["breaking changes" (alterações incompatíveis)](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#breaking-changes) e atualize seu código para cada uma que afete você. Faça também as [alterações de código de que a nova versão do SDK ou da CLI precisa](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#sdk-changes).
  </Step>

  <Step title="Teste com 2026-10-21">
    Teste sua integração com `2026-10-21` antes de lançar.
  </Step>
</Steps>

## Alterações incompatíveis

### Messages API

Estas alterações se aplicam a requisições à Messages API (`POST /v1/messages`), à [contagem de tokens](https://platform.claude.com/docs/pt-BR/build-with-claude/token-counting) e a cada requisição em um [Message Batch](https://platform.claude.com/docs/pt-BR/build-with-claude/batch-processing) criado com `2026-10-21`.

#### Blocos de documento em mensagens do assistente retornam um erro

Afeta você se você envia blocos `document` diretamente em mensagens `assistant`.

Em `2026-10-21`, uma requisição que coloca um bloco `document` diretamente em uma mensagem `assistant` retorna um erro 400. Em vez disso, envie documentos em mensagens `user`. Um documento aninhado dentro de outro bloco, como um resultado da ferramenta de web fetch que Claude retornou, ainda é aceito.

#### Citações em mensagens do usuário retornam um erro

Afeta você se você envia `citations` em blocos `text` em mensagens `user`, inclusive dentro de blocos `search_result`.

Em `2026-10-21`, uma requisição que envia um bloco `text` com um array `citations` não vazio em uma mensagem `user` retorna um erro 400. Remova `citations` desses blocos. Citações em blocos `text` em mensagens `assistant`, como respostas anteriores de Claude que você envia de volta, ainda são aceitas, assim como a configuração `"citations": {"enabled": true}` em documentos e resultados de pesquisa.

#### Os parâmetros de amostragem foram removidos

Afeta você se você envia `temperature`, `top_p` ou `top_k` em requisições de Messages ou de Message Batch.

Em `2026-10-21`, uma requisição que envia `temperature`, `top_p` ou `top_k` retorna um erro 400, mesmo com o valor padrão do parâmetro.

Remova os três parâmetros das suas requisições.

A partir das versões principais mais recentes, o SDK e a CLI não têm mais os três parâmetros.

Sem esses parâmetros, uma requisição faz a amostragem com os valores padrão deles, incluindo uma `temperature` de 1.0, o mesmo que uma requisição `2023-06-01` que os omite. Modelos que já aceitam apenas os valores padrão, como Claude 4.7 e modelos posteriores, fazem a amostragem como antes. Em modelos que aceitam outros valores, como Claude Sonnet 4.6, uma requisição que reduzia `temperature` para obter uma saída mais consistente perde esse efeito. Nenhuma outra configuração o substitui. Se uma requisição depende de um valor não padrão, pare de enviar o parâmetro ou mantenha essa requisição em `2023-06-01`.

### Admin API e Claude Enterprise Analytics API

Afeta você se seu código lê os campos de resposta da Admin API ou da Claude Enterprise Analytics API nas tabelas a seguir.

Em `2026-10-21`, as respostas da Admin API e da [Claude Enterprise Analytics API](https://platform.claude.com/docs/pt-BR/manage-claude/analytics-api) não incluem mais os nomes antigos dos campos renomeados. Use os novos nomes em vez disso.

Admin API:

| Endpoints                                                                                                                                                                                                                                                                           | Nome antigo    | Nome novo                                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Grupos RBAC](https://platform.claude.com/docs/pt-BR/api/beta/organization/rbac_groups/list): criar, listar, recuperar e atualizar                                                                                                                                                  | `roles`        | `role_ids`                                                                                                                                                     |
| [Membros de grupos RBAC](https://platform.claude.com/docs/pt-BR/api/beta/organization/rbac_groups/members/list): listar e adicionar, e a resposta a [remover um membro](https://platform.claude.com/docs/pt-BR/api/beta/organization/rbac_groups/members/remove)                    | `group_id`     | `rbac_group_id`                                                                                                                                                |
| [Funções RBAC](https://platform.claude.com/docs/pt-BR/api/beta/organization/rbac_roles/list): listar e recuperar                                                                                                                                                                    | `name`         | `display_name`                                                                                                                                                 |
| Limites de taxa da [organização](https://platform.claude.com/docs/pt-BR/api/organization/rate_limits/list) e do [workspace](https://platform.claude.com/docs/pt-BR/api/organization/workspaces/rate_limits/list): listar, e a resposta a definir os limites de taxa de um workspace | `group_type`   | `group.type`                                                                                                                                                   |
| [Chaves de API](https://platform.claude.com/docs/pt-BR/api/organization/api_keys/list): listar, recuperar e atualizar                                                                                                                                                               | `workspace_id` | `scope` (valores diferentes; consulte [`workspace_id` em chaves de API](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#api-key-workspace-id)) |

Claude Enterprise Analytics API:

| Endpoints                                                                                                                                                                                                                                 | Nome antigo   | Nome novo             |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------- |
| Relatórios de [uso](https://platform.claude.com/docs/pt-BR/api/beta/organization/analytics/user_usage_report/list) e de [custo](https://platform.claude.com/docs/pt-BR/api/beta/organization/analytics/user_cost_report/list) por usuário | `actor.email` | `actor.email_address` |
| [Resumos de atividade](https://platform.claude.com/docs/pt-BR/api/beta/organization/analytics/summaries/list)                                                                                                                             | `summaries`   | `data`                |

O parâmetro de consulta `group_type` nos endpoints de listagem de limites de taxa e o filtro `workspace_id` no endpoint de listagem de chaves de API não mudam.

#### `workspace_id` em chaves de API

Afeta você se seu código lê `workspace_id` em chaves de API.

Em `2023-06-01`, o `workspace_id` de uma chave de API é o ID do workspace ao qual a chave está vinculada, ou `null` para uma chave vinculada ao Default Workspace e para uma chave que não está vinculada a um único workspace (uma chave de todos os workspaces).

Em `2026-10-21`, `workspace_id` foi removido. Leia `scope` em vez disso: para uma chave vinculada a um workspace, incluindo o Default Workspace, `scope.workspace_id` é o ID real desse workspace, e uma chave de todos os workspaces tem um `scope` de `{"type": "organization"}`, sem `workspace_id`.

Se seu código tratava um `workspace_id` `null` como o Default Workspace, compare `scope.workspace_id` com o ID do seu Default Workspace em vez disso. Para encontrar esse ID, chame [List Workspaces](https://platform.claude.com/docs/pt-BR/api/organization/workspaces/list) com `include_default=true` e pegue o workspace chamado `"Default"`.

## Alterações no SDK e na CLI

As versões anteriores do SDK e da CLI enviavam `anthropic-version: 2023-06-01` em cada requisição. As versões em [Mude para 2026-10-21](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#upgrade) enviam `2026-10-21`, incluindo seus clientes para Amazon Bedrock e Google Cloud. As alterações em [Alterações incompatíveis](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#breaking-changes) também se aplicam a elas: os parâmetros removidos e os nomes de campos antigos também não existem mais nos tipos do SDK nem nas flags e na saída da CLI.

### `MessageParam` é uma união com um tipo por função

Nas versões anteriores, `MessageParam` era um único tipo para todas as funções. Cada função agora tem um tipo próprio: `UserMessageParam`, `AssistantMessageParam` e `SystemMessageParam`. `BetaMessageParam` é dividido da mesma forma, em `BetaUserMessageParam`, `BetaAssistantMessageParam` e `BetaSystemMessageParam`. As requisições que o SDK envia têm os mesmos campos e valores de antes.

<Tabs exclude="shell">
  <Tab title="Python">
    Uma mensagem escrita como um literal de dict, como `{"role": "user", "content": "Hello"}`, não precisa de alteração.

    Na v1, `anthropic.types.MessageParam` era um único `TypedDict`. Na v2 ele é uma união dos três tipos, e `anthropic.types.beta.BetaMessageParam` é uma união dos seus três. Ambos os nomes ainda funcionam em anotações, como `list[MessageParam]`.

    Chamar qualquer um dos nomes agora gera um `TypeError`, e um verificador de tipos o sinaliza. Escreva a mensagem como um dict:

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

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

    Criar uma subclasse de qualquer um dos nomes também gera um `TypeError`. Crie uma subclasse do tipo da função, como `UserMessageParam`.

    As alterações restantes afetam apenas a verificação de tipos. Um dict cujo `role` é uma variável que pode conter mais de uma função não corresponde a nenhum tipo da união, então construa o dict para uma função de cada vez:

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


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

    Mais duas se aplicam apenas a `BetaMessageParam`:

    * `clear_at` e `output_config` são chaves de `BetaSystemMessageParam`, então uma mensagem de usuário ou de assistente não pode tê-las.
    * `content` é opcional em `BetaSystemMessageParam`, então o pyright reporta `message["content"]`. Leia-o com `message.get("content")`, ou verifique primeiro que `message["role"]` não é `"system"`.
  </Tab>

  <Tab title="TypeScript">
    `MessageParam` era uma única interface. Agora é `UserMessageParam | AssistantMessageParam | SystemMessageParam`, e `BetaMessageParam` é a mesma união dos seus três tipos. Apenas os tipos mudaram. Um literal de mensagem que nomeia sua função, como `{ role: "user", content: "Hello, Claude" }`, passa na verificação de tipos como antes, então a maior parte do código não precisa de alteração.

    O tipo de sistema difere dos outros dois. Seu `content` é uma string ou blocos de texto, além de blocos `tool_addition` e `tool_removal` em `beta`, então um bloco de imagem ali não compila mais. Em `beta`, apenas ele tem `clear_at` e `output_config`, e seu `content` é opcional.

    Código que lida com uma mensagem de qualquer função precisa verificar `role` antes de substituir ou adicionar blocos de conteúdo, e antes de ler `clear_at` ou `output_config`:

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

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

    O `content` de um `BetaMessageParam` pode ser `undefined`:

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

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

    O tipo `BetaMessageParam["content"]` também inclui `undefined`. Para o conteúdo de uma mensagem de usuário ou de assistente, use `BetaMessageContentParam`.

    Uma interface não pode estender uma união, e uma classe não pode implementar uma. Use um alias de tipo ou, em vez disso, nomeie o tipo de uma função.

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

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

  <Tab title="C#">
    Na v12, `MessageParam` e `BetaMessageParam` eram classes cujos `Role` e `Content` você definia. Na v13 cada uma é uma união das três classes para suas funções, e os enums `Role` em `Anthropic.Models.Messages` e `Anthropic.Models.Beta.Messages` não existem mais.

    Ao construir uma mensagem, nomeie a classe da sua função e exclua `Role`. Cada classe é convertida implicitamente para a união:

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

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

    `new UserMessageParam("Hello, Claude")` também funciona.

    As classes que contêm `Content` também mudam:

    * `MessageParamContent` agora é `MessageContentParam`, e `BetaMessageParamContent` agora é `BetaMessageContentParam`.
    * Uma mensagem de sistema tem uma classe de conteúdo própria. Um `SystemMessageParamContent` contém uma string ou uma lista de `TextBlockParam`, e um `BetaSystemMessageParamContent` contém uma string ou uma lista de `SystemMessageContentBlock`. Uma `List<ContentBlockParam>` ou uma `List<BetaContentBlockParam>` não é mais convertida para ele.
    * `ClearAt` e `OutputConfig` estão apenas em `BetaSystemMessageParam`.

    Ao ler uma mensagem, a união ainda tem `Role` e `Content`, mas você não pode defini-los, então uma expressão `with` vai na classe da função. `Role` agora contém um `MessageParamRole` ou um `BetaMessageParamRole`. `BetaMessageParam.Content` pode ser `null`, porque `Content` é opcional em `BetaSystemMessageParam`.

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

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

    `TryPickUser`, `TryPickAssistant`, `TryPickSystem`, `Switch` e `Match` fornecem a classe da função.
  </Tab>

  <Tab title="Go">
    Na v1, `MessageParam` era uma única struct com um campo `Role` e um campo `Content`. Na v2 ela é uma união: `OfUser` contém um `*UserMessageParam`, `OfAssistant` um `*AssistantMessageParam` e `OfSystem` um `*SystemMessageParam`. `BetaMessageParam` muda da mesma forma. O SDK envia o mesmo JSON de antes, exceto pela ordem das chaves em uma mensagem de sistema beta.

    `NewUserMessage`, `NewAssistantMessage`, `NewBetaUserMessage` e os métodos `ToParam` de `Message` e `BetaMessage` funcionam como antes, então código que constrói suas mensagens com eles não precisa de alteração.

    Um literal de struct nomeia o tipo da sua função. Omita `Role`, porque cada tipo serializa o seu próprio:

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

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

    Código que lê uma mensagem verifica qual campo está definido:

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

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

    * Os tipos `MessageParamRole` e `BetaMessageParamRole` e suas constantes não existem mais. `message.GetRole()` retorna um ponteiro para a função como uma `string`, ou `nil` quando nenhum campo está definido.
    * `ClearAt` e `OutputConfig` foram movidos de `BetaMessageParam` para `BetaSystemMessageParam`. Os nomes do tipo `BetaMessageParamClearAt` e de suas constantes agora começam com `BetaSystemMessageParamClearAt`.
    * `SystemMessageParam.Content` é um `[]TextBlockParam`. `BetaSystemMessageParam.Content` é um `[]BetaSystemMessageParamContentUnion`, que contém blocos `text`, `tool_addition` e `tool_removal`. `NewBetaSystemMessage` recebe blocos desse tipo, então `anthropic.NewBetaTextBlock("Be brief.")` se torna `anthropic.BetaSystemMessageParamContentUnion{OfText: &anthropic.BetaTextBlockParam{Text: "Be brief."}}`.
    * Uma cópia de um `MessageParam` aponta para a mesma mensagem que o original. Definir `duplicate.OfUser.Content` altera ambos, enquanto definir `duplicate.Content` na v1 alterava apenas a cópia.
    * `mcp.ToMessage` retorna um `*mcp.UnsupportedValueError` para uma função diferente de `user` ou `assistant`. A v1 copiava qualquer função para a mensagem.
  </Tab>

  <Tab title="Java">
    Na v2, `MessageParam` era uma única classe com um `role` e um `content`. Na v3 ela é uma união das três classes, e `MessageParam.Content` agora é o `MessageContentParam` de nível superior. `BetaMessageParam` muda da mesma forma, e suas classes têm os mesmos nomes com um prefixo `Beta`. O JSON que o SDK envia é o mesmo, exceto que uma mensagem de sistema beta agora tem `role` antes de `content`.

    `addUserMessage`, `addAssistantMessage` e `addSystemMessage` com uma `String`, `addMessage` com uma `Message` ou um `MessageParam`, e `Message.toParam()` não mudam.

    `MessageParam.builder()` e `toBuilder()` não existem mais. Chame o método de fábrica da função, que é `ofUser`, `ofAssistant` ou `ofSystem`:

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

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

    Os métodos que recebem uma lista de blocos de conteúdo têm novos nomes nos builders de `MessageCreateParams`, `StructuredMessageCreateParams`, `MessageCountTokensParams` e `BatchCreateParams.Request.Params`:

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

    Na classe de conteúdo, `BlockParams` (`BetaContentBlockParams` em beta) se torna `ContentBlockParams` em `ofBlockParams`, `blockParams()`, `isBlockParams()`, `asBlockParams()` e no `visitBlockParams` do visitor.

    Uma mensagem de sistema tem sua própria classe de conteúdo, `SystemMessageParam.Content`, que `addSystemMessage` agora recebe. Seus blocos são `TextBlockParam`, não `ContentBlockParam`. Em beta eles são `BetaSystemMessageParam.Content.SystemMessageContentBlock`, que tem `ofText`, `ofToolAddition` e `ofToolRemoval`.

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

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

    Ao ler uma mensagem, `role()` não muda. `content()` retorna um `MessageContentParam`, ou um `Optional<BetaMessageContentParam>` em beta, onde uma mensagem de sistema pode não ter conteúdo. `_role()`, `_content()` e `_additionalProperties()` agora estão na classe da função, que `asUser()`, `asAssistant()` ou `asSystem()` retorna.
  </Tab>

  <Tab title="PHP">
    As classes estão em `Anthropic\Messages`, e as classes beta em `Anthropic\Beta\Messages`. Mensagens que você escreve como arrays não mudam e ainda precisam do seu `'role'`.

    `MessageParam::with()` e `BetaMessageParam::with()` permanecem e retornam a classe correspondente a `role`. Uma chamada com argumentos nomeados não precisa de alteração. `role` agora é o primeiro parâmetro, então em uma chamada posicional troque `content` e `role` de lugar, ou chame `with()` na classe da função, que não recebe `role`. Para argumentos na ordem antiga, o PHP lança `UnhandledMatchError`, sobre o qual o PHPStan não avisa, ou um `TypeError` se `content` for uma lista ou `role` for um case de enum.

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

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

    Nenhum objeto é mais um `MessageParam`: `instanceof MessageParam` é falso, e o PHP lança um `TypeError` onde um tipo de parâmetro ou de retorno o nomeia. Nomeie as três classes em vez disso:

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

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

    * `MessageParam::fromArray()` e `(new MessageParam)->withContent()` lançam "Call to undefined method". Chame-os na classe da função, que define `role` por conta própria.
    * `withRole()` agora recebe apenas a string: o PHP lança um `TypeError` para um case de `Role`. Para dar outra função a uma mensagem, construa a classe dessa função.
    * `clearAt` e `outputConfig` existem apenas em `BetaSystemMessageParam`, e `BetaMessageParam::with()` os descarta para as outras duas funções. O enum `BetaMessageParam\ClearAt` agora é `BetaSystemMessageParam\ClearAt`.
    * `MessageParam\Content` agora é `MessageContentParam`, e `BetaMessageParam\Content` agora é `BetaMessageContentParam`. Seus tipos do PHPStan também recebem o novo nome: `ContentShape` agora é `MessageContentParamShape`.
    * Um array cujo `'role'` é um case de `Role` ainda funciona, mas o PHPStan agora o reporta. Escreva a string.
  </Tab>

  <Tab title="Ruby">
    Mensagens que você escreve como hashes não mudam.

    Na v2, `Anthropic::MessageParam` é uma união de `Anthropic::UserMessageParam`, `Anthropic::AssistantMessageParam` e `Anthropic::SystemMessageParam`. Da mesma forma, `Anthropic::Beta::BetaMessageParam` é uma união das suas três classes.

    `Anthropic::MessageParam.new(role: :user, content: "Hello, Claude")` ainda funciona e retorna uma instância da classe dessa função. Você também pode construir essa classe por conta própria, sem `role:`, como `Anthropic::UserMessageParam.new(content: "Hello, Claude")`. Quatro coisas mudam para código que constrói ou inspeciona essas instâncias:

    * `MessageParam.new` recebe apenas palavras-chave, então passe um hash como `MessageParam.new(**hash)`. Ele gera um `ArgumentError` quando `role:` está ausente ou não é uma das três funções.
    * `message.is_a?(Anthropic::MessageParam)` é `false`. Um ramo `when Anthropic::MessageParam` e `messages.grep(Anthropic::MessageParam)` ainda correspondem.
    * Uma instância construída com `.new` não tem `:role` no seu `to_h`, e `message[:role]` é `nil`. `message.role` ainda retorna a função.
    * Apenas `BetaSystemMessageParam` tem `clear_at` e `output_config`. Em uma mensagem de usuário ou de assistente eles retornavam `nil`, e agora geram um `NoMethodError`.

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

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

    Os módulos de enum `Role` permanecem. Estas constantes foram movidas. Os nomes que começam com `Beta` estão em `Anthropic::Beta`, e os outros estão em `Anthropic`:

    | Removido                    | Use em vez disso                                                                             |
    | --------------------------- | -------------------------------------------------------------------------------------------- |
    | `MessageParam::Content`     | `MessageContentParam`, ou `SystemMessageParam::Content` para uma mensagem de sistema         |
    | `BetaMessageParam::Content` | `BetaMessageContentParam`, ou `BetaSystemMessageParam::Content` para uma mensagem de sistema |
    | `BetaMessageParam::ClearAt` | `BetaSystemMessageParam::ClearAt`                                                            |

    Se você faz verificação de tipos com Sorbet, `MessageParam::OrHash` não existe mais, e `Anthropic::MessageParam` como tipo não aceita mais uma instância. Use `Anthropic::MessageParam::Variants` para as três classes, cada uma das quais tem seu próprio `OrHash`. Em RBS, um valor tipado como `Anthropic::MessageParam` não tem `role` nem `content`. Use o alias `Anthropic::Models::message_param`, que era a forma de hash de uma mensagem e agora é a união das três classes. Os nomes beta são `BetaMessageParam::Variants` e `Anthropic::Models::Beta::beta_message_param`.
  </Tab>
</Tabs>

### Enums de um único valor são constantes

Isto afeta os SDKs para C#, Go, Java, PHP e Ruby e uma flag da CLI. Nas versões anteriores, um campo obrigatório que só pode conter um valor tinha um tipo enum próprio com um único membro. Esses campos agora são constantes, e os tipos enum não existem mais. O JSON que o SDK envia e lê é o mesmo.

<Tabs exclude="shell:cURL, python, typescript">
  <Tab title="CLI">
    `--type` é opcional em `ant beta:sessions:resources add`. `file` é o único valor que `--type` pode receber ali, então a v2 o envia por você. Comandos que ainda passam `--type file` continuam funcionando, então não há nada a alterar.
  </Tab>

  <Tab title="C#">
    Na v12, uma propriedade `required` desse tipo tinha um enum com um único membro, como `BetaManagedAgentsTextBlockType.Text`. Quase todas elas são a propriedade `Type` de uma classe em `Anthropic.Models.Beta`: `Agents`, `DeploymentRuns`, `Deployments`, `Dreams`, `Environments`, `MemoryStores`, `Sessions`, `UserProfiles` e `Vaults`. Na v13 essas propriedades são um `JsonElement` que o construtor preenche, como `TextBlockParam.Type` já era.

    Uma propriedade opcional, como `BetaManagedAgentsGlobToolConfigParams.Type`, mantém seu enum. Dois desses enums têm um novo nome:

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

    Ao construir um objeto, exclua a propriedade:

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

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

    Uma classe que fica com uma única propriedade obrigatória também ganha um construtor que a recebe, então `new BetaManagedAgentsTextBlock("Hello Claude!")` também funciona. Uma classe que fica sem nenhuma é construída com `new BetaManagedAgentsAlwaysAllowPolicy()`.

    Ao ler um, compare a string:

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

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

    Para distinguir as variantes de uma união, continue usando seus métodos `TryPick*`, `Switch` e `Match`, que não mudam.
  </Tab>

  <Tab title="Go">
    Um exemplo desse tipo enum e de sua constante é `BetaManagedAgentsTextBlockType` e `BetaManagedAgentsTextBlockTypeText`. Quase todos eles são o campo `Type` de uma struct em `client.Beta`: Agents, Deployments, Deployment Runs, Dreams, Environments, Memory Stores, Sessions, User Profiles e Vaults. Na v2 esses campos usam um tipo do pacote `shared/constant`, como `TextBlockParam.Type` já fazia. Um campo opcional, como `BetaManagedAgentsBashToolConfigParams.Type`, mantém seu enum.

    Em uma requisição, exclua o campo. Ele é serializado como seu único valor quando você o omite:

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

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

    Uma struct cujo único campo era esse `Type` agora tem um construtor, como `NewBetaManagedAgentsAlwaysAllowPolicyParam()`. Como membro de uma união, um ponteiro para a struct vazia também funciona: `OfAlwaysAllow: &anthropic.BetaManagedAgentsAlwaysAllowPolicyParam{}`.

    Em uma resposta, compare com a string:

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

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

    Uma variável, campo ou parâmetro seu que foi declarado com um dos tipos removidos recebe o novo tipo do campo, como `constant.AgentMessage`. `constant.ValueOf[constant.AgentMessage]()` retorna seu valor.

    Os construtores de união mudam junto com os campos. Estes cinco perdem seu argumento `type_`:

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

    Estes quatro não recebiam nenhum outro argumento, então não existem mais. Defina o campo da união como um ponteiro para a struct vazia, como `BetaManagedAgentsEventParamsUnion{OfUserInterrupt: &anthropic.BetaManagedAgentsUserInterruptEventParams{}}`:

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

  <Tab title="Java">
    Um exemplo desse enum é a classe aninhada `BetaManagedAgentsTextBlock.Type`, com seu único membro `TEXT`. Quase todos eles são o `type` de uma classe em `com.anthropic.models.beta`: `agents`, `deploymentruns`, `deployments`, `dreams`, `environments`, `memorystores`, `sessions`, `userprofiles` e `vaults`. Na v3 esses campos são um `JsonValue` que o builder preenche, como o de `TextBlockParam` já era. Um campo opcional, como o `type` de `BetaManagedAgentsBashToolConfigParams`, mantém seu enum.

    Ao construir um objeto, exclua a chamada:

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

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

    Uma classe que fica com um único campo obrigatório também ganha um método de fábrica que o recebe, então `BetaManagedAgentsTextBlock.of("Hello Claude!")` também funciona. Uma classe que fica sem nenhum perde `of(type)`, e suas uniões perdem a sobrecarga que recebia o enum, como `ofAlwaysAllow(type)`. Construa-a com `BetaManagedAgentsAlwaysAllowPolicy.builder().build()`.

    Ao ler um, `type()` não existe mais e `_type()` retorna o `com.anthropic.core.JsonValue`:

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

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

    Para distinguir as variantes de uma união, continue usando seus métodos `is*()` e `as*()` e seu visitor, que não mudam.
  </Tab>

  <Tab title="PHP">
    Um exemplo desse case de enum é `Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock\Type::TEXT`. Quase todos eles são o `type` de uma classe de Managed Agents em `Anthropic\Beta`. Essas propriedades agora são uma string com esse único valor como padrão, como o `type` de `Anthropic\Messages\TextBlockParam` já era. Uma propriedade opcional, como o `type` de `Anthropic\Beta\Environments\BetaPackages`, mantém seu enum.

    `with()` não recebe mais `type`. Remova-o: o PHP lança "Unknown named parameter" para um `type:` remanescente, e em uma chamada posicional os argumentos depois dele avançam uma posição.

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

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

    Onde você comparava com um case de enum, compare com a string:

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

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

    * `withType()` e o argumento `type` de `$client->beta->sessions->resources->add()` agora recebem apenas a string. Em `add()` ele tem `'file'` como padrão, então você pode omiti-lo.
    * Requisições que você escreve como arrays não mudam e ainda precisam do seu `'type'`.
  </Tab>

  <Tab title="Ruby">
    Um exemplo dessa constante de enum é `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock::Type::TEXT`. Quase todas elas são o `type` de uma classe de Managed Agents em `Anthropic::Beta`. Na v2 esses campos são declarados como uma constante, como o `type` de `Anthropic::TextBlockParam` já era. Um campo opcional, como o `type` de `Anthropic::Beta::BetaManagedAgentsGlobToolConfigParams`, mantém seu enum.

    Substitua uma constante removida pelo seu símbolo:

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

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

    Requisições que você escreve como hashes não mudam e ainda precisam do seu `type`:

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

    Ao construir uma instância de modelo, `type:` agora tem um padrão, então você pode omiti-lo: `Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock.new(text: "Hello Claude!")`. O mesmo vale para a palavra-chave `type:` de `client.beta.sessions.resources.add`.

    Se você faz verificação de tipos com Sorbet, os aliases `Type::OrSymbol` e `Type::TaggedSymbol` desses módulos deixaram de existir junto com eles, e os campos são um `Symbol`. `OrSymbol` também permitia uma `String`, então `.new(type: "text")` não passa mais na verificação de tipos. Remova a palavra-chave ou passe `:text`. Em RBS, o alias `type_` de cada classe não existe mais, e o campo é o literal, como `:text`.
  </Tab>
</Tabs>

### A compactação no lado do cliente foi removida do tool runner

Isso afeta os SDKs de TypeScript e Ruby. A "client-side compaction" (compactação no lado do cliente) no "tool runner" (executor de ferramentas) foi removida em favor da compactação no lado do servidor, que resume a conversa dentro da API em vez de fazê-lo com uma requisição extra do cliente.

<Tabs exclude="shell, python, csharp, go, java, php">
  <Tab title="TypeScript">
    A opção `compactionControl` e o módulo `@anthropic-ai/sdk/lib/tools/CompactionControl` não existem mais. A opção parou de funcionar na v0.129.0, em que passá-la lançava um `AnthropicError`. Ela não está no tipo de parâmetros, então o TypeScript a reporta como uma propriedade desconhecida.

    Para continuar compactando automaticamente a partir de um limite de tokens:

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

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

    Para decidir você mesmo quando a conversa é compactada, chame [`runner.compactBeforeNextTurn()`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/helpers.md#compaction).
  </Tab>

  <Tab title="Ruby">
    A opção `compaction_control:` não existe mais. Ela parou de funcionar na v1.74.0, em que passá-la levantava um `ArgumentError`.

    Para continuar compactando automaticamente a partir de um limite de tokens:

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

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

    Para decidir você mesmo quando a conversa é compactada, chame [`#compact_before_next_turn`](https://github.com/anthropics/anthropic-sdk-ruby/blob/main/helpers.md#compact_before_next_turn---compact-the-conversation) no runner.
  </Tab>
</Tabs>

O limite de acionamento deve ser de pelo menos 50.000 tokens. Consulte [compactação](https://platform.claude.com/docs/pt-BR/build-with-claude/compaction-threshold) para as outras opções (`pause_after_compaction`, `instructions` personalizadas).

### Text Completions foi removido

A API legada de Text Completions foi removida dos SDKs de TypeScript, Go, Java e Ruby e da CLI. Modelos e recursos mais novos não a suportam. Use a [Messages API](https://platform.claude.com/docs/pt-BR/api/messages) em vez disso.

<Tabs exclude="shell:cURL, python, csharp, php">
  <Tab title="CLI">
    O comando `ant completions create` não existe mais.

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

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

    O texto da resposta passa do campo `completion` para `content.0.text`, então um script que passava `--transform completion` passa `--transform content.0.text` em vez disso.

    `ant messages create` também aceita `--stream`, mas seus eventos têm outro formato: o texto chega em `delta.text` dos eventos `content_block_delta`, então `--transform content.0.text` não se aplica a um stream.
  </Tab>

  <Tab title="TypeScript">
    `client.completions` não existe mais, assim como a classe de recurso `Completions` e os tipos `Completion`, `CompletionCreateParams`, `CompletionCreateParamsNonStreaming` e `CompletionCreateParamsStreaming`. `AnthropicBedrock` também não tem mais uma propriedade `completions`. As constantes `HUMAN_PROMPT` e `AI_PROMPT`, que apenas os prompts de Text Completions usavam, também não existem mais, tanto como exports quanto como propriedades estáticas do cliente.

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

    // Depois
    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 })` passa a ser `client.messages.create({ ..., stream: true })` ou `client.messages.stream({ ... })`.
  </Tab>

  <Tab title="Go">
    `client.Completions` não existe mais, assim como `CompletionService`, `NewCompletionService`, `CompletionNewParams` e `Completion`. `aws.Client` também não tem mais um campo `Completions`. `bedrock.DefaultEndpoints` não lista mais `/v1/complete`.

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

    // Depois
    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` passa a ser `client.Messages.NewStreaming`.
  </Tab>

  <Tab title="Java">
    `client.completions()` não existe mais em `AnthropicClient` e `AnthropicClientAsync`, assim como `CompletionService`, `CompletionServiceAsync` e o pacote `com.anthropic.models.completions` (`CompletionCreateParams` e `Completion`).

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

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

    // Depois
    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` passa a ser `client.messages().createStreaming`.
  </Tab>

  <Tab title="Ruby">
    `client.completions` não existe mais, assim como `Anthropic::Resources::Completions`, `Anthropic::CompletionCreateParams` e `Anthropic::Completion`. `Anthropic::BedrockClient` também não tem mais um leitor `completions`. Em `Anthropic::BedrockMantleClient` e `Anthropic::GoogleCloudClient`, onde `completions` levantava `NotImplementedError`, o método não existe mais.

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

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

    `client.completions.create_streaming` passa a ser `client.messages.stream`.
  </Tab>
</Tabs>

### `betas` foi removido dos métodos não beta de Models

Os métodos não beta de Models não aceitam mais `betas` (csharp, go: `Betas`; java: `.addBeta()`), e os comandos `ant models` não aceitam mais `--beta`. Para enviar cabeçalhos beta, chame os mesmos métodos em `client.beta.models` (csharp, go: `client.Beta.Models`; java: `client.beta().models()`; php: `$client->beta->models`), ou `ant beta:models` na CLI. No SDK, esses métodos retornam `BetaModelInfo` (ruby: `Anthropic::Beta::BetaModelInfo`) onde os não beta retornam `ModelInfo` (ruby: `Anthropic::ModelInfo`).

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

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

  <Tab title="Python">
    `client.models.retrieve()` e `client.models.list()` não aceitam mais `betas` (passá-lo é um `TypeError`, e um verificador de tipos o sinaliza), e `anthropic.types.ModelListParams` não tem mais uma chave `betas`.

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

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

  <Tab title="TypeScript">
    `Anthropic.ModelRetrieveParams` e `Anthropic.ModelListParams` não têm mais uma propriedade `betas`.

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

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

  <Tab title="C#">
    `ModelRetrieveParams` e `ModelListParams` em `Anthropic.Models.Models` não têm mais uma propriedade `Betas`. Os métodos em `client.Beta.Models` aceitam as classes de mesmo nome em `Anthropic.Models.Beta.Models`.

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

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

    // Depois
    using Anthropic.Models.Beta.Models;

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

  <Tab title="Go">
    `ModelGetParams` e `ModelListParams` não têm mais um campo `Betas`.

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

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

  <Tab title="Java">
    `ModelRetrieveParams` e `ModelListParams` em `com.anthropic.models.models` não têm mais `betas()`, e seus builders não têm mais `betas` e `addBeta`. Os métodos em `client.beta().models()` aceitam as classes de mesmo nome em `com.anthropic.models.beta.models`.

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

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

    // Depois
    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()` não aceitam mais `betas` (passá-lo lança `Error: Unknown named parameter $betas`), e `Anthropic\Models\ModelRetrieveParams` e `Anthropic\Models\ModelListParams` não têm mais uma propriedade `betas`.

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

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

    Se você passa argumentos por posição, `workspaceID` e `requestOptions` sobem cada um uma posição em ambos os métodos.
  </Tab>

  <Tab title="Ruby">
    `client.models.retrieve` e `client.models.list` não aceitam mais `betas:`, e `Anthropic::ModelRetrieveParams` e `Anthropic::ModelListParams` não têm mais um campo `betas`.

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

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

    Passar `betas:` para `client.models` não levanta erro, mas não define mais o cabeçalho `anthropic-beta`.
  </Tab>
</Tabs>

### Chaves de API são enviadas como `Authorization: Bearer`

O SDK e a CLI enviam sua chave de API como `Authorization: Bearer <key>` em vez de no cabeçalho `X-Api-Key`, então altere qualquer proxy ou gateway que leia ou defina `X-Api-Key` para usar `Authorization`, ou [envie a chave em `X-Api-Key` você mesmo](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#sdk-proxy-x-api-key). A Claude API aceita uma chave em qualquer um dos cabeçalhos, então um programa que se comunica diretamente com a API não precisa de alteração.

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

# After
Authorization: Bearer <key>
```

<Tabs>
  <Tab title="CLI">
    Isso se aplica a uma chave em `ANTHROPIC_API_KEY` e a uma enviada via pipe para `--api-key-stdin`.

    Com `--debug`, o log de requisições agora mostra `Authorization: Bearer <REDACTED>` onde mostrava `X-Api-Key: <REDACTED>`.
  </Tab>

  <Tab title="Python">
    `Authorization` é o cabeçalho que `auth_token` já usa.

    Isso se aplica ao argumento `api_key` e à variável de ambiente `ANTHROPIC_API_KEY` de `Anthropic` e `AsyncAnthropic`, e a `api_key` e `ANTHROPIC_AWS_API_KEY` de `AnthropicAWS`. `AnthropicFoundry` ainda envia sua chave como `x-api-key`, e `AnthropicBedrockMantle` já enviava um bearer token.
  </Tab>

  <Tab title="TypeScript">
    `Authorization` é o cabeçalho que a opção `authToken` já usa.

    Isso se aplica à opção `apiKey`, à variável de ambiente `ANTHROPIC_API_KEY` e a `apiKey` e `ANTHROPIC_AWS_API_KEY` em `@anthropic-ai/aws-sdk`. `apiKey` em `@anthropic-ai/foundry-sdk` ainda sai como `X-Api-Key`, e `apiKey` em `@anthropic-ai/bedrock-sdk` já era um bearer token.

    Um middleware ou um `fetch` personalizado que lê a chave do cabeçalho de requisição `x-api-key` precisa ler `authorization` em vez disso, onde a chave vem depois de `Bearer `.
  </Tab>

  <Tab title="C#">
    `Authorization` é o cabeçalho que `AuthToken` já usa.

    Isso se aplica a `ApiKey` em `AnthropicClient` e `ClientOptions` e à variável de ambiente `ANTHROPIC_API_KEY`. Na versão de `Anthropic.Aws` que depende da v13, também se aplica a `ApiKey` em `AwsClientOptions` e a `ANTHROPIC_AWS_API_KEY`. `AnthropicFoundryApiKeyCredentials` ainda envia sua chave como `x-api-key`, e `ApiKey` em `MantleAwsClientOptions` já era um bearer token.
  </Tab>

  <Tab title="Go">
    Isso se aplica a `option.WithAPIKey`, à variável de ambiente `ANTHROPIC_API_KEY` e a `APIKey` em `aws.ClientConfig` (ou `ANTHROPIC_AWS_API_KEY`). `APIKey` em `foundry.ClientConfig` (ou `ANTHROPIC_FOUNDRY_API_KEY`) ainda sai como `X-Api-Key`, e `APIKey` em `bedrock.MantleClientConfig` já era um bearer token.
  </Tab>

  <Tab title="Java">
    `Authorization` é o cabeçalho que `authToken` já usa.

    Isso se aplica a `apiKey` nos builders `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` e `AnthropicBackend`, à variável de ambiente `ANTHROPIC_API_KEY` e à propriedade de sistema `anthropic.apiKey`. `apiKey` no builder `FoundryBackend` ainda sai como `x-api-key`. `apiKey` nos builders `AwsBackend`, `BedrockBackend` e `BedrockMantleBackend` já era um bearer token.

    Um interceptor agora vê a chave em `Authorization` em vez de `X-Api-Key`.
  </Tab>

  <Tab title="PHP">
    `Authorization` é o cabeçalho que `authToken` já usa.

    Isso se aplica ao argumento `apiKey` e à variável de ambiente `ANTHROPIC_API_KEY` de `Anthropic\Client`, e a `apiKey` e `ANTHROPIC_AWS_API_KEY` de `Anthropic\Aws\Client`. `Anthropic\Foundry\Client` ainda envia sua chave como `x-api-key`, e `Anthropic\Bedrock\MantleClient` já enviava um bearer token.
  </Tab>

  <Tab title="Ruby">
    `Authorization` é o cabeçalho que `auth_token:` já usa.

    Isso se aplica ao argumento `api_key:` e à variável de ambiente `ANTHROPIC_API_KEY` de `Anthropic::Client`, e a `api_key:` e `ANTHROPIC_AWS_API_KEY` de `Anthropic::AWSClient`. `Anthropic::BedrockMantleClient` já enviava um bearer token.

    O SDK descarta `Authorization` quando segue um redirecionamento para outra origem, o que inclui um redirecionamento de `http` para `https` no mesmo host. A chave agora também é descartada nesse caso.
  </Tab>
</Tabs>

#### Se um proxy ou gateway lê `X-Api-Key`

<Tabs exclude="shell:cURL">
  <Tab title="CLI">
    Se `--base-url` ou `ANTHROPIC_BASE_URL` aponta o `ant` para um proxy ou gateway que lê `X-Api-Key`, altere-o para ler a chave de `Authorization`. O `ant` não tem flag nem variável de ambiente para adicionar um cabeçalho próprio, então ele não consegue enviar `X-Api-Key`.
  </Tab>

  <Tab title="Python">
    Mova a chave de volta com uma função `auth` no cliente HTTP. Ela é executada em cada requisição que o cliente envia, incluindo novas tentativas:

    ```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` aceita a mesma função, em `http_client=DefaultAsyncHttpxClient(auth=send_x_api_key)`.
  </Tab>

  <Tab title="TypeScript">
    Defina o cabeçalho você mesmo. `Authorization: null` impede que a chave também saia ali:

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

    Se o proxy adiciona a credencial e seu cliente não tem nenhuma, a v0 permitia indicar isso com `"X-Api-Key": null` ou `Authorization: null` em `defaultHeaders`. A v1 aceita apenas `Authorization: null`.

    O poller e o worker de trabalho de ambiente recebem sua própria chave, então deixam os cabeçalhos padrão `X-Api-Key` e `Authorization` de fora de suas próprias requisições.
  </Tab>

  <Tab title="C#">
    Defina o cabeçalho você mesmo com `ExtraHeaders`. Definir `ApiKey` e `AuthToken` como `null` impede que uma credencial encontrada em `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` também saia:

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

  <Tab title="Go">
    Defina o cabeçalho você mesmo. `option.WithHeaderDel` impede que uma chave encontrada em `ANTHROPIC_API_KEY` também saia:

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

    `environments.WorkPoller` e `environments.EnvironmentWorker` recebem sua própria chave, então deixam um `X-Api-Key` definido manualmente de fora de suas próprias requisições.
  </Tab>

  <Tab title="Java">
    Defina o cabeçalho você mesmo em vez de chamar `apiKey`:

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

  <Tab title="PHP">
    Mova a chave de volta com um middleware:

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

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

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

    Não use os `extraHeaders` do cliente para isso. Uma requisição que tem seus próprios `extraHeaders` substitui os do cliente, e todo endpoint em `$client->beta` que precisa de um cabeçalho beta os tem.
  </Tab>

  <Tab title="Ruby">
    Mova a chave de volta com um 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)
    ```

    A primeira linha deixa uma requisição intacta quando ela não carrega a chave, como uma que foi redirecionada para outra origem.

    `Anthropic::AWSClient` não aceita o argumento `middleware:`. Passe o middleware com cada requisição em vez disso, como `request_options: {middleware: send_x_api_key}`.
  </Tab>
</Tabs>

#### Se você definia ou removia `X-Api-Key` em uma requisição

Isso afeta os SDKs de Python, TypeScript, Go, PHP e Ruby.

Se você removia `X-Api-Key` para que uma requisição enviasse apenas um token de autenticação, exclua esse código em vez de alterá-lo, porque remover `Authorization` removeria o token. [Um cliente mantém uma credencial](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#sdk-one-credential), então certifique-se de que ela seja o token: sem nenhuma passada no código e com `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` ambos definidos, o cliente usa a chave.

<Tabs exclude="shell, csharp, java">
  <Tab title="Python">
    Código que passa `extra_headers={"X-Api-Key": omit}` para manter a chave fora de uma requisição não faz mais isso. Passe `extra_headers={"Authorization": omit}` em vez disso.

    `extra_headers={"X-Api-Key": other_key}` não substitui mais a chave do cliente: ambas as chaves saem. Para enviar outra chave com uma requisição, passe `extra_headers={"Authorization": f"Bearer {other_key}"}`.
  </Tab>

  <Tab title="TypeScript">
    `headers: { "X-Api-Key": otherKey }` nas opções de uma requisição não substitui mais a chave do cliente: ambas as chaves saem. Para enviar outra chave com uma requisição, passe ``headers: { Authorization: `Bearer $\{otherKey}` }``.
  </Tab>

  <Tab title="Go">
    `option.WithHeaderDel("X-Api-Key")` não mantém mais a chave fora de uma requisição. Exclua `Authorization` em vez disso:

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

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

    `option.WithHeader("X-Api-Key", otherKey)` não substitui mais a chave do cliente: ambas as chaves saem. Para enviar outra chave com uma requisição, passe `option.WithAPIKey(otherKey)`.
  </Tab>

  <Tab title="PHP">
    `'extraHeaders' => ['X-Api-Key' => null]` não mantém mais a chave fora de uma requisição. Para enviar uma requisição sem credencial, defina `Authorization` como `null` em vez disso, ou remova-o em um middleware se você fazia isso para o cliente inteiro.

    `'extraHeaders' => ['X-Api-Key' => $otherKey]` não substitui mais a chave do cliente: ambas as chaves saem. Para enviar outra chave com uma requisição, defina `Authorization` como `"Bearer {$otherKey}"`.
  </Tab>

  <Tab title="Ruby">
    `extra_headers: {"x-api-key" => nil}` não mantém mais a chave fora de uma requisição. Defina `"authorization"` como `nil` em vez disso. Para enviar outra chave com uma requisição, defina `"authorization"` como `"Bearer #{other_key}"`, não `"x-api-key"`.
  </Tab>
</Tabs>

### Um cliente mantém uma credencial

Uma chave de API e um token de autenticação agora compartilham um cabeçalho, então um cliente do SDK mantém uma credencial. Sem nenhuma passada no código, ele segue a ordem de [precedência de credenciais](https://platform.claude.com/docs/pt-BR/manage-claude/wif-reference#credential-precedence).

<Tabs exclude="shell">
  <Tab title="Python">
    A v1 enviava tanto uma chave de API quanto um token de autenticação quando o cliente tinha ambos, cada um em seu próprio cabeçalho. A credencial é uma de `api_key`, `auth_token`, `credentials`, `config` ou `profile`.

    * **Passe no máximo uma.** Duas ou mais no construtor, ou em uma chamada de `copy()` ou `with_options()`, levantam `ValueError`. `None` não conta. A v1 levantava `TypeError`, e apenas para duas de `credentials`, `config` e `profile`.
    * **A que você passa é a única.** Como na v1, o cliente não procura outra no ambiente ou no disco.
    * **Sem nenhuma passada, apenas a primeira destas que estiver definida é usada:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, o perfil que `ANTHROPIC_PROFILE` nomeia, as variáveis de "workload identity federation" (federação de identidade de carga de trabalho), o perfil ativo no disco (aquele que o arquivo `active_config` nomeia, caso contrário `default`). Quando as duas primeiras estão definidas, o cliente registra um aviso uma vez. A v1 usava o perfil ativo antes das variáveis de federação quando `ANTHROPIC_CONFIG_DIR` estava definida ou um arquivo `active_config` existia; defina `ANTHROPIC_PROFILE` para continuar usando-o.
    * **`copy()` e `with_options()` substituem.** Uma credencial que você passa substitui a do próprio cliente, seja qual for o tipo de cada uma. Uma URL base e cabeçalhos que vieram da config ou do perfil da credencial antiga vão junto com ela, e os da nova credencial são usados. Uma URL base que você passou permanece.

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

    # Antes: enviava `X-Api-Key: <key>` e `Authorization: Bearer <token>`
    # Depois: lança `ValueError`
    ```

    Os clientes de plataforma mantêm suas próprias regras. `AnthropicAWS` aceita `auth_token` junto com `api_key` sem erro, e envia a chave.

    As docstrings de `Anthropic.__init__` e `Anthropic.copy` em [`_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) têm os detalhes.

    Se você dependia de enviar ambos, por exemplo um token para um gateway e uma chave para a API por trás dele, passe o token como `auth_token` e defina `X-Api-Key` em `default_headers`. Faça o gateway remover seu cabeçalho `Authorization` antes de encaminhar a requisição. A Claude API espera uma credencial por requisição.
  </Tab>

  <Tab title="TypeScript">
    Na v0, um cliente que tinha tanto uma chave de API quanto um token de autenticação enviava ambos, cada um em seu próprio cabeçalho. A credencial é uma de `apiKey`, `authToken`, `credentials`, `config` ou `profile`.

    * **Passe no máximo uma.** Duas ou mais em `new Anthropic()`, ou em uma chamada de `withOptions()`, lançam um `TypeError`. `null` e `undefined` não contam.
    * **A que você passa é a única.** O cliente não procura outra no ambiente ou no disco.
    * **Sem nenhuma passada, a primeira destas é usada:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, o perfil que `ANTHROPIC_PROFILE` nomeia, as variáveis de federação de identidade de carga de trabalho, o perfil ativo no disco (aquele que o arquivo `active_config` nomeia, caso contrário `default`). Quando as duas primeiras estão definidas, o cliente registra um aviso uma vez. Na v0, o perfil ativo vinha antes das variáveis de federação. Um `ANTHROPIC_PROFILE` que nomeia um perfil inexistente era ignorado na v0, e agora a primeira requisição lança um `AnthropicError`. `loadConfig()` sem argumento segue a mesma ordem e lança o mesmo erro.
    * **`withOptions` substitui.** Uma credencial que você passa substitui a do cliente que você copia, então `client.withOptions({ authToken })` não precisa mais de `apiKey: null` ao lado.
    * **Um cliente de plataforma aceita apenas as credenciais de sua plataforma.** Os clientes AWS, Bedrock e Foundry e `AnthropicVertex` lançam um `AnthropicError` para uma opção de credencial com a qual não se autenticam, como `AnthropicGoogleCloud` já fazia. Nos clientes AWS e Bedrock, `apiKey: null` agora limpa a chave, então o cliente assina com credenciais da AWS. `AnthropicBedrock` mantém sua chave em `client.apiKey`, onde a v0 a mantinha em `client.authToken`.

    ```typescript
    // Antes: enviava a chave de API e ignorava `credentials`
    const client = new Anthropic({ apiKey, credentials });

    // Depois: a linha acima lança um TypeError
    const client = new Anthropic({ credentials });
    ```

    Os comentários de documentação em [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/src/client.ts) dizem como cada opção se comporta, e o comentário de documentação no construtor de cada um desses clientes de plataforma lista as opções que ele rejeita.

    Se você dependia de enviar ambos, por exemplo um token para um gateway e uma chave para a API por trás dele, defina `X-Api-Key` em `defaultHeaders` e mantenha `authToken`. Faça o gateway remover seu cabeçalho `Authorization` antes de encaminhar a requisição. A Claude API espera uma credencial por requisição.
  </Tab>

  <Tab title="C#">
    Na v12, um cliente que tinha tanto uma chave de API quanto um token de autenticação enviava ambos, cada um em seu próprio cabeçalho. A credencial é uma de `ApiKey`, `AuthToken` ou `ClientOptions.Credentials`.

    * **Passar duas é um erro.** Definir uma segunda lança um `ArgumentException`. `null` não conta, então para trocar a credencial em `ClientOptions` que você mesmo construiu, defina a antiga como `null` primeiro.
    * **Passar uma a usa e ignora o ambiente.** Nenhuma variável de ambiente de credencial ou perfil no disco é lido. Da mesma forma, `AnthropicCredentials.Resolve(profile: "name")` agora retorna as credenciais desse perfil quando `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` está definida.
    * **Não passar nenhuma usa a primeira correspondência no ambiente:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, as variáveis de federação de identidade de carga de trabalho e, em seguida, o perfil ativo no disco. Uma `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` vazia conta como não definida. Quando as duas primeiras estão definidas, um aviso vai para o stderr uma vez. O cliente procura quando é usado pela primeira vez, então um `ANTHROPIC_PROFILE` que não existe agora lança a partir da primeira requisição em vez do construtor.
    * **`WithOptions` substitui.** Uma credencial que você passa no modificador substitui a do cliente, seja qual for o tipo dela, então `AuthToken = token` não precisa mais de `ApiKey = null` ao lado. Sem nenhuma passada, a cópia mantém a credencial, a `BaseUrl` e os `ExtraHeaders` do cliente, mesmo quando o modificador retorna novas `ClientOptions`.

    ```csharp
    // Antes: enviava ambos, cada um em seu próprio cabeçalho
    AnthropicClient client = new() { ApiKey = apiKey, AuthToken = token };

    // Depois: a linha acima lança uma ArgumentException
    AnthropicClient client = new() { AuthToken = token };
    ```

    A documentação XML dessas três propriedades de [`ClientOptions`](https://github.com/anthropics/anthropic-sdk-csharp/blob/main/src/Anthropic/Core/ClientOptions.cs) tem os detalhes.

    Os clientes de plataformas de nuvem mantêm as credenciais com as quais foram construídos. Os clientes Bedrock, Bedrock Mantle, Foundry, Google Cloud e AWS e `AnthropicVertexClient` decidem como se autenticar quando você os constrói, e a maioria deles usa o cabeçalho `Authorization` para isso. As versões desses pacotes que dependem da v13 ignoram uma `ApiKey` ou `AuthToken` que você define por meio de `WithOptions`. Para usar outra chave com `AnthropicAwsClient`, construa um novo cliente com `ApiKey` em `AwsClientOptions`.

    Se você dependia de enviar ambos, por exemplo um token para um gateway e uma chave para a API por trás dele, defina `X-Api-Key` com `ExtraHeaders` e mantenha `AuthToken`. Faça o gateway remover seu cabeçalho `Authorization` antes de encaminhar a requisição. A Claude API espera uma credencial por requisição.
  </Tab>

  <Tab title="Go">
    Na v1, um cliente que tinha tanto uma chave de API quanto um token de autenticação enviava ambos, cada um em seu próprio cabeçalho. A credencial vem de `option.WithAPIKey`, `option.WithAuthToken`, `option.WithConfig`, `option.WithProfile` ou `option.WithFederationTokenProvider`.

    * **Duas delas passadas para `anthropic.NewClient` são um erro.** `NewClient` não retorna erro, então toda requisição que o cliente faz falha com ele. `NewClient` já aplica `anthropic.DefaultClientOptions()`, então não passe o resultado dela também: a credencial que ela encontra no ambiente passa então a contar como uma que você passou.
    * **Uma delas é usada como está.** Nenhuma credencial é lida do ambiente ou de um perfil no disco. Na v1, `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` prevaleciam sobre as três últimas.
    * **Sem nenhuma delas, a primeira destas que estiver definida é usada,** na mesma ordem da v1: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, as variáveis de federação de identidade de carga de trabalho, o perfil ativo no disco. Quando as duas primeiras estão definidas, o SDK registra um aviso uma vez.
    * **Uma delas em uma requisição substitui a credencial do cliente para essa requisição,** então `option.WithAuthToken` não precisa mais de `option.WithHeaderDel("X-Api-Key")` ao lado.

    ```go
    // Antes: a chave de API era enviada e um aviso era registrado no log
    client := anthropic.NewClient(
    	option.WithAPIKey(apiKey),
    	option.WithProfile("work"),
    )

    // Depois: toda requisição do cliente acima falha, então passe a que você quiser
    client := anthropic.NewClient(option.WithAPIKey(apiKey))
    ```

    O aviso que a v1 registrava não existe mais, então `option.WithConfigQuiet`, que o suprimia, agora faz o que `option.WithConfig` faz e está descontinuado.

    Os comentários de documentação em `anthropic.NewClient` e `anthropic.DefaultClientOptions` em [`client.go`](https://github.com/anthropics/anthropic-sdk-go/blob/main/client.go) têm os detalhes.

    Se você dependia de enviar ambos, por exemplo um token para um gateway e uma chave para a API por trás dele, defina `X-Api-Key` com `option.WithHeader` e mantenha `option.WithAuthToken`. Faça o gateway remover seu cabeçalho `Authorization` antes de encaminhar a requisição. A Claude API espera uma credencial por requisição.

    `ANTHROPIC_CUSTOM_HEADERS` e `ANTHROPIC_WEBHOOK_SIGNING_KEY` agora se aplicam a todo cliente que `anthropic.NewClient` constrói. Na v1, elas eram lidas apenas quando nem o ambiente nem um perfil no disco continham uma credencial.
  </Tab>

  <Tab title="Java">
    Na v2, um cliente que tinha tanto uma chave de API quanto um token de autenticação enviava ambos, cada um em seu próprio cabeçalho. A credencial é uma de `apiKey`, `authToken` ou `configurationProvider` nos builders `AnthropicOkHttpClient`, `AnthropicOkHttpClientAsync` e `AnthropicBackend`.

    * **Defina no máximo uma.** Com duas em um builder, `build()` lança uma `IllegalStateException` que as nomeia. `null` ou um `Optional` vazio não conta.
    * **A que você define é a única.** `fromEnv()`, chamado antes ou depois, não obtém nenhuma credencial do ambiente ou de um perfil no disco. Na v2, uma chave ou token que `fromEnv()` encontrava podia ser enviado também, ou em vez disso.
    * **Sem nenhuma definida, `fromEnv()` usa a primeira destas que encontrar:** `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, as variáveis de federação de identidade de carga de trabalho, o perfil ativo no disco. Quando as duas primeiras estão definidas, um aviso vai para `System.err` uma vez. As propriedades de sistema `anthropic.apiKey` e `anthropic.authToken` contam como o ambiente. Uma chave ou token vazio, em uma variável ou em uma propriedade de sistema, conta como não definido. Na v2, `fromEnv()` usava o valor vazio como a chave ou o token.

    ```java
    // Antes: ambos eram enviados. Na v3, build() lança uma IllegalStateException
    AnthropicClient client = AnthropicOkHttpClient.builder()
        .apiKey(apiKey)
        .authToken(authToken)
        .build();

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

    A documentação de `fromEnv()` nesses builders tem os detalhes.

    Se você dependia de enviar ambos, por exemplo um token para um gateway e uma chave para a API por trás dele, defina ambos os cabeçalhos você mesmo:

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

    Faça o gateway remover seu cabeçalho `Authorization` antes de encaminhar a requisição. A Claude API espera uma credencial por requisição.
  </Tab>

  <Tab title="PHP">
    Versões anteriores enviavam tanto uma chave de API quanto um token de autenticação quando o cliente tinha ambos, cada um em seu próprio cabeçalho. `Anthropic\Client` aceita uma credencial, de `apiKey`, `authToken` ou `credentials`:

    * Passar mais de uma delas lança `\InvalidArgumentException`. Apenas `null` conta como não passado. Uma string vazia conta como passada, então `new Client(apiKey: '')` não envia nenhuma credencial.
    * Passar uma a usa, e nenhuma credencial é lida do ambiente ou de um perfil no disco. Com `ANTHROPIC_API_KEY` definida, `new Client(authToken: $token)` envia o token. Versões anteriores enviavam a chave do ambiente junto com ele.
    * Não passar nenhuma usa a primeira destas que estiver definida: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, o perfil nomeado por `ANTHROPIC_PROFILE`, as variáveis de federação de identidade de carga de trabalho, o perfil ativo no disco (aquele que o arquivo `active_config` nomeia, caso contrário `default`). Versões anteriores usavam o perfil ativo antes das variáveis de federação, e não usavam nenhum perfil quando não havia arquivo `active_config`. Elas também ignoravam um `ANTHROPIC_PROFILE` que nomeava um perfil inexistente ou inválido. Nesse caso, `new Client()` agora lança `Anthropic\Core\Exceptions\AnthropicException`. Com `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` ambas definidas, o cliente envia a chave e sua propriedade `authToken` fica vazia. O primeiro cliente construído dessa forma também escreve um aviso com `error_log()`, uma vez por processo, o que em um servidor web significa uma vez por requisição: `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Para interrompê-lo, remova a definição da variável que você não usa.

    ```php
    // Antes: enviava a chave como X-Api-Key e o token como Authorization.
    // Depois: lança "Pass at most one of `apiKey`, `authToken`, or `credentials`. Received `apiKey`, `authToken`."
    $client = new Client(apiKey: $key, authToken: $token);
    ```

    Se você dependia de enviar ambos, por exemplo um token para um gateway e uma chave para a API por trás dele, passe o token como `authToken` e adicione `X-Api-Key` em um middleware como o de [Se um proxy ou gateway lê `X-Api-Key`](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#sdk-proxy-x-api-key), sem a chamada `withoutHeader`. Faça o gateway remover seu cabeçalho `Authorization` antes de encaminhar a requisição. A Claude API espera uma credencial por requisição.
  </Tab>

  <Tab title="Ruby">
    Os argumentos de credencial de `Anthropic::Client.new` são `api_key:`, `auth_token:`, `credentials:` e `config:`. Um argumento `nil` conta como não passado. Os clientes de plataforma mantêm suas próprias regras.

    * **Duas ou mais passadas:** `Anthropic::Client.new` levanta `ArgumentError`. Versões anteriores levantavam apenas para `credentials:` com `config:`, e caso contrário enviavam a chave, se houvesse uma, e depois o token.
    * **Uma passada:** O cliente a usa, e não recorre a uma credencial do ambiente ou de um perfil no disco.
    * **Nenhuma passada:** O cliente usa a primeira destas que encontrar: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_PROFILE`, as variáveis de federação de identidade de carga de trabalho, o perfil ativo no disco. A ordem não mudou, mas com `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` ambas definidas, `client.auth_token` agora é `nil`. Uma `ANTHROPIC_API_KEY` ou `ANTHROPIC_AUTH_TOKEN` vazia agora conta como não definida, enquanto versões anteriores deixavam uma `ANTHROPIC_API_KEY` vazia ocultar o token e tudo o que vinha depois dele.

    Quando nenhuma credencial é passada e `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN` estão ambas definidas, o SDK também avisa uma vez por processo, na saída de erro padrão por meio de `Kernel#warn`: `Anthropic: ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both set. Using ANTHROPIC_API_KEY.` Remova a definição da variável que você não usa para silenciá-lo.

    ```ruby
    # Antes: enviava a chave e ignorava o token.
    # Depois: 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)

    # Passe apenas aquele que você quer enviar.
    Anthropic::Client.new(api_key: api_key)
    ```
  </Tab>
</Tabs>

### Alterações em um SDK ou na CLI

Cada uma destas alterações afeta um SDK ou a CLI.

<Tabs exclude="shell:cURL, python, typescript">
  <Tab title="CLI">
    **`--api-key` e `--auth-token` foram removidos.** O `ant` não aceita mais uma chave de API ou um token de autenticação como valor de flag, porque um valor na linha de comando fica visível no histórico do shell e nas listagens de processos. Ambas as flags exibem um aviso de descontinuação desde a v1.27.0. Um comando que ainda passe uma delas é interrompido com `flag provided but not defined`.

    | Removido               | Use em vez disso                                           |
    | ---------------------- | ---------------------------------------------------------- |
    | `--api-key <key>`      | `ANTHROPIC_API_KEY`, `--api-key-stdin` ou `ant auth login` |
    | `--auth-token <token>` | `ANTHROPIC_AUTH_TOKEN` ou `--auth-token-stdin`             |

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

    # Depois, a partir do ambiente
    export ANTHROPIC_API_KEY="$KEY"
    ant models list

    # Depois, a partir de um gerenciador de segredos
    op read op://vault/anthropic/api-key | ant --api-key-stdin models list
    ```

    `--api-key-stdin` e `--auth-token-stdin` leem toda a entrada padrão, então um comando que use uma delas obtém o corpo da requisição a partir de flags.

    `ant auth status`, o prompt da primeira execução de `ant apply` e a nota sobre múltiplas fontes de autenticação agora chamam essas credenciais de `ANTHROPIC_API_KEY` e `ANTHROPIC_AUTH_TOKEN`, onde antes exibiam `--api-key / ANTHROPIC_API_KEY` e `--auth-token / ANTHROPIC_AUTH_TOKEN`.
  </Tab>

  <Tab title="C#">
    **O `Type` de uma union é um enum.** Na v12, a propriedade `Type` de uma classe union, como `ContentBlock.Type` ou `RawMessageStreamEvent.Type`, era um `JsonElement`. Na v13 ela é um `ApiEnum<string, T>`, onde `T` é um novo enum com um membro para cada variante, como `ContentBlockType`. Algumas unions são diferenciadas por `Name` ou `Command`, como `BetaMemoryTool20250818Command.Command`, e essas propriedades mudam da mesma forma. O `Type` de uma classe variante, como `TextBlock.Type`, continua sendo um `JsonElement`.

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

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

    `block.Type.Raw()` retorna a string, inclusive uma para a qual esta versão do SDK não tem membro de enum.

    **`IChatClient` ignora opções de amostragem.** Os adaptadores de `IChatClient` (`AsIChatClient()`) agora ignoram `ChatOptions.Temperature`, `ChatOptions.TopK` e `ChatOptions.TopP`. Consulte [Os parâmetros de amostragem foram removidos](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#sampling-parameters).
  </Tab>

  <Tab title="Go">
    **`vertex.DefaultVersion` e `bedrock.DefaultVersion` foram removidos.**
  </Tab>

  <Tab title="Java">
    **Getters que agora retornam um `Optional`.** `apiKey()` e `authToken()` em `AnthropicBackend` agora retornam um `Optional<String>`, como `apiKey()` em `AwsBackend` e `BedrockMantleBackend` já faziam. Na v2, cada um retornava uma `String`, que era `null` quando o backend não tinha uma credencial desse tipo.

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

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

    Estes getters agora também retornam um `Optional`. Na v2, cada um retornava o próprio valor, que era `null` quando não havia nenhum:

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

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

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

    `getBaseUrl()` em `FoundryBackend` foi removido. Chame `baseUrl()`, que retorna a URL para a qual as requisições são enviadas. Essa é a URL base que você definiu, ou a construída a partir do recurso, e ela termina em `/anthropic`.

    `getBaseUrl()` em `AnthropicBackend` também foi removido. Chame `baseUrl()`, que retorna o mesmo valor.

    **`HttpRequest` exige uma URL base.** Se você mesmo constrói um `HttpRequest`, como em um teste de um interceptor, defina sua URL base. Sem ela, `build()` agora lança uma `IllegalStateException`. Na v2, ele retornava uma requisição cujo `baseUrl()` era `null`. As requisições que o SDK constrói já tinham uma.

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

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

    `baseUrl()` ainda retorna uma `String`, que agora nunca é `null`. No builder, `baseUrl(Optional<String>)` foi removido e `baseUrl(String)` não aceita mais `null`.

    **Interceptors veem `anthropic-version`.** O cliente agora adiciona o cabeçalho padrão `anthropic-version` antes de os interceptors serem executados. Na v2, o backend o adicionava depois deles. Se o seu interceptor define sua própria versão, chame `replaceHeaders`, porque `putHeader` agora adiciona um segundo valor:

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

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

  <Tab title="PHP">
    **Os casos de enum que você passa são lidos de volta como seus valores.** `with()` e setters como `withAllowedCallers()` ainda aceitam um caso de enum ou seu valor. Versões anteriores mantinham o caso como você o passava. A v1 mantém o valor do caso, que é o que os tipos das propriedades já declaram. Objetos que o SDK constrói a partir de uma resposta não mudam, e o JSON que o SDK envia é o mesmo. Se você lê uma propriedade de volta e a compara com um caso, a comparação agora é falsa e nada é lançado, então compare-a com o valor do caso:

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

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

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

  <Tab title="Ruby">
    **`Anthropic::VertexClient::DEFAULT_VERSION` e `Anthropic::BedrockClient::DEFAULT_VERSION` foram removidos.**
  </Tab>
</Tabs>

### A licença é Apache 2.0

A partir destas versões, o SDK e a CLI são licenciados sob a Apache License, Version 2.0. Versões anteriores permanecem sob a MIT License. Nenhuma alteração de código é necessária. Se você acompanha as licenças das suas dependências, atualize as entradas correspondentes.

* **TypeScript:** Os pacotes de plataforma (`@anthropic-ai/bedrock-sdk`, `@anthropic-ai/vertex-sdk`, `@anthropic-ai/foundry-sdk`, `@anthropic-ai/aws-sdk` e `@anthropic-ai/google-cloud-sdk`) mudam de licença em suas próprias versões 1.0.0.
* **C#:** Os outros pacotes (`Anthropic.Bedrock`, `Anthropic.Vertex`, `Anthropic.Foundry`, `Anthropic.Aws`, `Anthropic.GoogleCloud` e `Anthropic.Mcp`) mudam de licença em suas próprias versões 1.0.0.
* **Java:** A alteração abrange todos os artefatos `com.anthropic`.
