---
title: Java SDK
url: https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java
description: Instale e configure o Anthropic Java SDK com padrões builder e suporte assíncrono
---

O Anthropic Java SDK fornece acesso conveniente à Claude API a partir de aplicações escritas em Java. Ele usa o padrão builder para criar requisições e suporta operações síncronas e assíncronas.

<Info>
  Para documentação de recursos da API com exemplos de código, consulte a [referência da API](https://platform.claude.com/docs/pt-BR/api/overview). Esta página aborda recursos e configuração específicos do SDK Java.
</Info>

## Instalação

<Tabs>
  <Tab title="Gradle">
    ```kotlin
    implementation("com.anthropic:anthropic-java:3.1.0")
    ```
  </Tab>

  <Tab title="Maven">
    ```xml
    <dependency>
        <groupId>com.anthropic</groupId>
        <artifactId>anthropic-java</artifactId>
        <version>3.1.0</version>
    </dependency>
    ```
  </Tab>
</Tabs>

## Requisitos

Esta biblioteca requer Java 8 ou posterior.

<Note>
  O SDK suporta Java 8 e posteriores. Os exemplos de código nesta documentação são escritos como [arquivos-fonte compactos do JDK 25](https://openjdk.org/jeps/512), usando um ponto de entrada `void main()` simples e `IO.println()` para saída. As chamadas de API em si são idênticas em todos os JDKs suportados; para compilar um exemplo em uma versão anterior, substitua `IO.println(...)` por `System.out.println(...)` e coloque o corpo dentro de `public static void main(String[] args)` em uma classe.
</Note>

## Início rápido

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;

// Configura usando as propriedades de sistema `anthropic.apiKey`, `anthropic.authToken` e `anthropic.baseUrl`
// Ou configura usando as variáveis de ambiente `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN` e `ANTHROPIC_BASE_URL`
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

MessageCreateParams params = MessageCreateParams.builder()
  .maxTokens(1024L)
  .addUserMessage("Hello, Claude")
  .model(Model.CLAUDE_OPUS_5_5)
  .build();

Message message = client.messages().create(params);
```

## Configuração do cliente

### Configuração da chave de API

Configure o cliente usando propriedades do sistema ou variáveis de ambiente:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

// Configura usando as propriedades de sistema `anthropic.apiKey`, `anthropic.authToken` e `anthropic.baseUrl`
// Ou configura usando as variáveis de ambiente `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN` e `ANTHROPIC_BASE_URL`
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
```

Ou configure manualmente:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .apiKey("my-anthropic-api-key")
  .build();
```

Ou use uma combinação das duas abordagens:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  // Configura usando propriedades do sistema ou variáveis de ambiente
  .fromEnv()
  .apiKey("my-anthropic-api-key")
  .build();
```

Para opções de autenticação, incluindo Workload Identity Federation, consulte [Autenticação](https://platform.claude.com/docs/pt-BR/manage-claude/authentication). Se sua chave de API for uma [chave pessoal ou de conta de serviço](https://platform.claude.com/docs/pt-BR/manage-claude/authentication#key-types) com acesso a vários workspaces, defina o ID do workspace no cabeçalho de requisição `anthropic-workspace-id`; [Selecionar um workspace](https://platform.claude.com/docs/pt-BR/manage-claude/authentication#select-a-workspace) mostra a opção por requisição para este SDK.

### Opções de configuração

| Setter      | Propriedade do sistema | Variável de ambiente   | Obrigatório | Valor padrão                  |
| ----------- | ---------------------- | ---------------------- | ----------- | ----------------------------- |
| `apiKey`    | `anthropic.apiKey`     | `ANTHROPIC_API_KEY`    | false       | -                             |
| `authToken` | `anthropic.authToken`  | `ANTHROPIC_AUTH_TOKEN` | false       | -                             |
| `baseUrl`   | `anthropic.baseUrl`    | `ANTHROPIC_BASE_URL`   | true        | `"https://api.anthropic.com"` |

As propriedades do sistema têm precedência sobre as variáveis de ambiente.

<Tip>
  Não crie mais de um cliente na mesma aplicação. Cada cliente tem um pool de conexões e pools de threads, que são mais eficientes quando compartilhados entre requisições.
</Tip>

### Modificando a configuração

Para usar temporariamente uma configuração de cliente modificada reutilizando os mesmos pools de conexões e de threads, chame `withOptions()` em qualquer cliente ou serviço:

```java
import com.anthropic.client.AnthropicClient;

AnthropicClient clientWithOptions = client.withOptions(optionsBuilder -> {
  optionsBuilder.baseUrl("https://example.com");
  optionsBuilder.maxRetries(42);
});
```

O método `withOptions()` não afeta o cliente ou serviço original.

## Uso assíncrono

O cliente padrão é síncrono. Para mudar para execução assíncrona, chame o método `async()`:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;

AnthropicClient client = AnthropicOkHttpClient.fromEnv();

MessageCreateParams params = MessageCreateParams.builder()
  .maxTokens(1024L)
  .addUserMessage("Hello, Claude")
  .model(Model.CLAUDE_OPUS_5_5)
  .build();

CompletableFuture<Message> message = client.async().messages().create(params);
```

Ou crie um cliente assíncrono desde o início:

```java
import com.anthropic.client.AnthropicClientAsync;
import com.anthropic.client.okhttp.AnthropicOkHttpClientAsync;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;

AnthropicClientAsync client = AnthropicOkHttpClientAsync.fromEnv();

MessageCreateParams params = MessageCreateParams.builder()
  .maxTokens(1024L)
  .addUserMessage("Hello, Claude")
  .model(Model.CLAUDE_OPUS_5_5)
  .build();

CompletableFuture<Message> message = client.messages().create(params);
```

O cliente assíncrono suporta as mesmas opções que o síncrono, exceto que a maioria dos métodos retorna `CompletableFuture`s.

## Streaming

O SDK define métodos que retornam streams de "chunks" de resposta, em que cada chunk pode ser processado individualmente assim que chega, em vez de esperar pela resposta completa.

### Streaming síncrono

Esses métodos de streaming retornam `StreamResponse` para clientes síncronos:

```java
import com.anthropic.core.http.StreamResponse;
import com.anthropic.models.messages.RawMessageStreamEvent;

try (StreamResponse<RawMessageStreamEvent> streamResponse = client.messages().createStreaming(params)) {
    streamResponse.stream().forEach(chunk -> {
        IO.println(chunk);
    });
    IO.println("No more chunks!");
}
```

### Streaming assíncrono

Para clientes assíncronos, o método retorna `AsyncStreamResponse`:

```java
import com.anthropic.core.http.AsyncStreamResponse;
import com.anthropic.models.messages.RawMessageStreamEvent;

client.async().messages().createStreaming(params).subscribe(chunk -> {
    IO.println(chunk);
});

// Se você precisar tratar erros ou a conclusão do stream
client.async().messages().createStreaming(params).subscribe(new AsyncStreamResponse.Handler<>() {
    @Override
    public void onNext(RawMessageStreamEvent chunk) {
        IO.println(chunk);
    }

    @Override
    public void onComplete(Optional<Throwable> error) {
        if (error.isPresent()) {
            IO.println("Something went wrong!");
            throw new RuntimeException(error.get());
        } else {
            IO.println("No more chunks!");
        }
    }
});

// Ou use futures
client.async().messages().createStreaming(params)
    .subscribe(chunk -> {
        IO.println(chunk);
    })
    .onCompleteFuture()
    .whenComplete((unused, error) -> {
        if (error != null) {
            IO.println("Something went wrong!");
            throw new RuntimeException(error);
        } else {
            IO.println("No more chunks!");
        }
    });
```

O streaming assíncrono usa um `Executor` dedicado de pool de threads em cache por cliente para fazer streaming sem bloquear a thread atual. Para usar um `Executor` diferente:

```java
Executor executor = Executors.newFixedThreadPool(4);
client.async().messages().createStreaming(params).subscribe(
    chunk -> IO.println(chunk), executor
);
```

Ou configure o cliente globalmente usando o método `streamHandlerExecutor`:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .streamHandlerExecutor(Executors.newFixedThreadPool(4))
  .build();
```

### Streaming com acumulador de mensagens

Um `MessageAccumulator` pode registrar o stream de eventos na resposta à medida que são processados e acumular um objeto `Message` semelhante ao que teria sido retornado pela API sem streaming.

Para uma resposta síncrona, adicione uma chamada `Stream.peek()` ao pipeline do stream para acumular cada evento:

```java
import com.anthropic.core.http.StreamResponse;
import com.anthropic.helpers.MessageAccumulator;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.RawMessageStreamEvent;

MessageAccumulator messageAccumulator = MessageAccumulator.create();

try (StreamResponse<RawMessageStreamEvent> streamResponse =
         client.messages().createStreaming(createParams)) {
    streamResponse.stream()
            .peek(messageAccumulator::accumulate)
            .flatMap(event -> event.contentBlockDelta().stream())
            .flatMap(deltaEvent -> deltaEvent.delta().text().stream())
            .forEach(textDelta -> IO.print(textDelta.text()));
}

Message message = messageAccumulator.message();
```

Para uma resposta assíncrona, adicione o `MessageAccumulator` à chamada `subscribe()`:

```java
import com.anthropic.helpers.MessageAccumulator;
import com.anthropic.models.messages.Message;

MessageAccumulator messageAccumulator = MessageAccumulator.create();

client.async().messages()
        .createStreaming(createParams)
        .subscribe(event -> messageAccumulator.accumulate(event).contentBlockDelta().stream()
                .flatMap(deltaEvent -> deltaEvent.delta().text().stream())
                .forEach(textDelta -> IO.print(textDelta.text())))
        .onCompleteFuture()
        .join();

Message message = messageAccumulator.message();
```

Um `BetaMessageAccumulator` também está disponível para a acumulação de um objeto `BetaMessage`. Ele é usado da mesma maneira que o `MessageAccumulator`.

## Saídas estruturadas

Para a documentação completa de "structured outputs" (saídas estruturadas), incluindo exemplos em Java, consulte [Saídas estruturadas](https://platform.claude.com/docs/pt-BR/build-with-claude/structured-outputs).

## Uso de ferramentas

O ["tool use" (uso de ferramentas) com Claude](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/overview) permite integrar ferramentas e funções externas diretamente nas respostas do modelo de IA. Em vez de produzir texto simples, o modelo pode gerar instruções (com parâmetros) para chamar uma ferramenta ou função quando apropriado. Você define JSON schemas para as ferramentas, e o modelo usa os schemas para determinar quando e como usar essas ferramentas.

O recurso de uso de ferramentas suporta um modo "strict" que garante que a saída JSON do modelo de IA estará em conformidade com o JSON schema que você fornece nos parâmetros de entrada.

O SDK pode derivar uma ferramenta e seus parâmetros automaticamente a partir da estrutura de uma classe Java arbitrária: o nome da classe (convertido para snake case) fornece o nome da ferramenta, e os campos da classe definem os parâmetros da ferramenta.

<Note>
  Declare suas classes de ferramentas como classes de nível superior ou classes aninhadas `static`. Esse requisito vem da biblioteca Jackson Databind (`com.fasterxml.jackson.databind`), que o SDK usa para desserializar as entradas das ferramentas em instâncias das suas classes e que não consegue instanciar classes internas não estáticas.
</Note>

### Definindo ferramentas com anotações

```java
import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;

enum Unit {
  CELSIUS,
  FAHRENHEIT;

  public String toString() {
    return switch (this) {
      case CELSIUS -> "C";
      case FAHRENHEIT -> "F";
    };
  }

  public double fromKelvin(double temperatureK) {
    return switch (this) {
      case CELSIUS -> temperatureK - 273.15;
      case FAHRENHEIT -> (temperatureK - 273.15) * 1.8 + 32.0;
    };
  }
}

@JsonClassDescription("Get the weather in a given location")
static class GetWeather {

  @JsonPropertyDescription("The city and state, e.g. San Francisco, CA")
  public String location;

  @JsonPropertyDescription("The unit of temperature")
  public Unit unit;

  public Weather execute() {
    double temperatureK = switch (location) {
      case "San Francisco, CA" -> 300.0;
      case "New York, NY" -> 310.0;
      case "Dallas, TX" -> 305.0;
      default -> 295;
    };
    return new Weather(String.format("%.0f%s", unit.fromKelvin(temperatureK), unit));
  }
}

static class Weather {

  public String temperature;

  public Weather(String temperature) {
    this.temperature = temperature;
  }
}
```

### Chamando ferramentas

Quando suas classes de ferramentas estiverem definidas, adicione-as aos parâmetros da mensagem usando `MessageCreateParams.Builder.addTool(Class<T>)` e então chame-as se isso for solicitado na resposta do modelo de IA. `BetaToolUseBlock.input(Class<T>)` pode ser usado para converter os parâmetros de uma ferramenta em formato JSON em uma instância da sua classe que define a ferramenta.

Depois de chamar a ferramenta, use `BetaToolResultBlockParam.Builder.contentAsJson(Object)` para passar o resultado da ferramenta de volta ao modelo de IA:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.beta.messages.*;
import com.anthropic.models.messages.Model;

AnthropicClient client = AnthropicOkHttpClient.fromEnv();

MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
        .model(Model.CLAUDE_OPUS_5_5)
        .maxTokens(2048)
        .addTool(GetWeather.class)
        .addUserMessage("What's the temperature in New York?");

client.beta().messages().create(createParamsBuilder.build()).content().stream()
        .flatMap(contentBlock -> contentBlock.toolUse().stream())
        .forEach(toolUseBlock -> createParamsBuilder
              // Adiciona uma mensagem indicando que o uso de ferramentas foi solicitado.
              .addAssistantMessageOfContentBlockParams(
                      List.of(BetaContentBlockParam.ofToolUse(BetaToolUseBlockParam.builder()
                              .name(toolUseBlock.name())
                              .id(toolUseBlock.id())
                              .input(toolUseBlock._input())
                              .build())))
              // Adiciona uma mensagem com o resultado do uso de ferramentas solicitado.
              .addUserMessageOfContentBlockParams(
                      List.of(BetaContentBlockParam.ofToolResult(BetaToolResultBlockParam.builder()
                              .toolUseId(toolUseBlock.id())
                              .contentAsJson(callTool(toolUseBlock))
                              .build()))));

client.beta().messages().create(createParamsBuilder.build()).content().stream()
        .flatMap(contentBlock -> contentBlock.text().stream())
        .forEach(textBlock -> IO.println(textBlock.text()));

private static Object callTool(BetaToolUseBlock toolUseBlock) {
  if (!"get_weather".equals(toolUseBlock.name())) {
    throw new IllegalArgumentException("Unknown tool: " + toolUseBlock.name());
  }

  GetWeather tool = toolUseBlock.input(GetWeather.class);
  return tool != null ? tool.execute() : new Weather("unknown");
}
```

### Conversão de nomes de ferramentas

Os nomes das ferramentas são derivados dos nomes das classes de ferramentas em camel case (por exemplo, `GetWeather`) e convertidos para snake case (por exemplo, `get_weather`). Os limites de palavras começam onde o caractere atual não é o primeiro caractere, é maiúsculo, e o caractere anterior é minúsculo ou o caractere seguinte é minúsculo. Por exemplo, `MyJSONParser` se torna `my_json_parser` e `ParseJSON` se torna `parse_json`. Essa conversão pode ser substituída usando a anotação `@JsonTypeName`.

### Validação local do JSON schema da ferramenta

Você pode realizar uma validação local para verificar se o JSON schema derivado da sua classe de ferramenta respeita as restrições da Anthropic. A validação local é habilitada por padrão, mas pode ser desabilitada:

```java
MessageCreateParams.Builder createParamsBuilder = MessageCreateParams.builder()
  .model(Model.CLAUDE_OPUS_5_5)
  .maxTokens(2048)
  .addTool(GetWeather.class, JsonSchemaLocalValidation.NO)
  .addUserMessage("What's the temperature in New York?");
```

### Anotando classes de ferramentas

Você pode usar anotações para adicionar mais informações sobre as ferramentas aos JSON schemas:

* `@JsonClassDescription` - Adiciona uma descrição a uma classe de ferramenta detalhando quando e como usar essa ferramenta.
* `@JsonTypeName` - Define o nome da ferramenta como algo diferente do nome simples da classe convertido para snake case.
* `@JsonPropertyDescription` - Adiciona uma descrição detalhada a um parâmetro da ferramenta.
* `@JsonIgnore` - Exclui um campo ou método getter `public` do JSON schema gerado para os parâmetros de uma ferramenta.
* `@JsonProperty` - Inclui um campo ou método getter não `public` no JSON schema gerado para os parâmetros de uma ferramenta.

## Lotes de mensagens

O SDK oferece suporte ao [Processamento em lote](https://platform.claude.com/docs/pt-BR/build-with-claude/batch-processing) no namespace `client.messages().batches()`. Consulte [Paginação](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#pagination) para saber como listar e paginar lotes.

## Upload de arquivos

O SDK define métodos que aceitam arquivos por meio da classe `MultipartField`:

```java
import com.anthropic.core.MultipartField;
import com.anthropic.models.files.FileMetadata;
import com.anthropic.models.files.FileUploadParams;

FileUploadParams params = FileUploadParams.builder()
  .file(
    MultipartField.<InputStream>builder()
      .value(Files.newInputStream(Paths.get("/path/to/file.pdf")))
      .contentType("application/pdf")
      .build()
  )
  .build();

FileMetadata fileMetadata = client.files().upload(params);
```

Ou a partir de um `InputStream`:

```java
import com.anthropic.core.MultipartField;
import com.anthropic.models.files.FileMetadata;
import com.anthropic.models.files.FileUploadParams;

FileUploadParams params = FileUploadParams.builder()
  .file(
    MultipartField.<InputStream>builder()
      .value(URI.create("https://example.com/path/to/file").toURL().openStream())
      .filename("document.pdf")
      .contentType("application/pdf")
      .build()
  )
  .build();

FileMetadata fileMetadata = client.files().upload(params);
```

Ou a partir de bytes em memória:

```java
import com.anthropic.core.MultipartField;
import com.anthropic.models.files.FileMetadata;
import com.anthropic.models.files.FileUploadParams;

FileUploadParams params = FileUploadParams.builder()
  .file(
    MultipartField.<InputStream>builder()
      .value(new ByteArrayInputStream("content".getBytes()))
      .filename("document.txt")
      .contentType("text/plain")
      .build()
  )
  .build();

FileMetadata fileMetadata = client.files().upload(params);
```

### Respostas binárias

O SDK define métodos que retornam respostas binárias para respostas da API que não são necessariamente interpretadas como JSON:

```java
import com.anthropic.core.http.HttpResponse;

HttpResponse response = client.files().download("file_abc123");
```

Para salvar o conteúdo da resposta em um arquivo:

```java
import com.anthropic.core.http.HttpResponse;

try (HttpResponse response = client.files().download(params)) {
    Files.copy(
        response.body(),
        Paths.get(path),
        StandardCopyOption.REPLACE_EXISTING
    );
} catch (Exception e) {
    IO.println("Something went wrong!");
    throw new RuntimeException(e);
}
```

Ou transfira o conteúdo da resposta para qualquer `OutputStream`:

```java
import com.anthropic.core.http.HttpResponse;

try (HttpResponse response = client.files().download(params)) {
    response.body().transferTo(Files.newOutputStream(Paths.get(path)));
} catch (Exception e) {
    IO.println("Something went wrong!");
    throw new RuntimeException(e);
}
```

## Tratamento de erros

O SDK lança tipos de exceção personalizados não verificados (unchecked):

* `AnthropicServiceException` - Classe base para erros HTTP.
* `AnthropicIoException` - Erros de rede de E/S.
* `AnthropicRetryableException` - Erro genérico indicando uma falha que poderia ser tentada novamente.
* `AnthropicInvalidDataException` - Falha ao interpretar dados analisados com sucesso (por exemplo, ao acessar uma propriedade que deveria ser obrigatória, mas que a API omitiu inesperadamente).
* `AnthropicException` - Classe base para todas as exceções.

### Mapeamento de códigos de status

| Status | Exceção                         |
| ------ | ------------------------------- |
| 400    | `BadRequestException`           |
| 401    | `UnauthorizedException`         |
| 403    | `PermissionDeniedException`     |
| 404    | `NotFoundException`             |
| 422    | `UnprocessableEntityException`  |
| 429    | `RateLimitException`            |
| 5xx    | `InternalServerException`       |
| outros | `UnexpectedStatusCodeException` |

`SseException` é lançada para erros encontrados durante o streaming SSE após uma resposta HTTP inicial bem-sucedida.

```java
import com.anthropic.errors.*;

try {
    Message message = client.messages().create(params);
} catch (RateLimitException e) {
    IO.println("Rate limited, retry after: " + e.headers());
} catch (UnauthorizedException e) {
    IO.println("Invalid API key");
} catch (AnthropicServiceException e) {
    IO.println("API error: " + e.statusCode());
} catch (AnthropicIoException e) {
    IO.println("Network error: " + e.getMessage());
}
```

## IDs de requisição

Ao usar [respostas brutas](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#raw-response-access), você pode acessar o cabeçalho de resposta `request-id` usando o método `requestId()`:

```java
import com.anthropic.core.http.HttpResponseFor;
import com.anthropic.models.messages.Message;

HttpResponseFor<Message> message = client.messages().withRawResponse().create(params);

Optional<String> requestId = message.requestId();
```

Isso pode ser usado para registrar rapidamente requisições com falha e reportá-las à Anthropic. Para mais informações sobre depuração de requisições, consulte [ID de requisição](https://platform.claude.com/docs/pt-BR/api/errors#request-id).

## Novas tentativas

O SDK faz automaticamente 2 novas tentativas por padrão, com um breve backoff exponencial entre as requisições.

Apenas os seguintes tipos de erro são tentados novamente:

* Erros de conexão (por exemplo, devido a um problema de conectividade de rede)
* 408 Request Timeout
* 409 Conflict
* 429 Rate Limit
* 5xx Internal

A API também pode instruir explicitamente o SDK a tentar ou não novamente uma requisição.

Para definir um número personalizado de novas tentativas, configure o cliente usando o método `maxRetries`:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder().fromEnv().maxRetries(4).build();
```

## Timeouts

As requisições expiram após 10 minutos por padrão.

No entanto, para métodos que aceitam `maxTokens`, se você especificar um valor grande de `maxTokens` e estiver usando streaming, o timeout padrão será calculado dinamicamente usando esta fórmula:

```java
Duration.ofSeconds(
    Math.min(
        60 * 60, // 1 hour max
        Math.max(
            10 * 60, // 10 minute minimum
            60 * 60 * maxTokens / 128_000
        )
    )
)
```

Isso resulta em um timeout de até 60 minutos, escalonado pelo parâmetro `maxTokens`, a menos que seja substituído.

Para requisições sem streaming, o timeout dinâmico escala de um mínimo de 30 segundos até um máximo de 10 minutos com base em `maxTokens`.

Para definir um timeout personalizado por requisição:

```java
import com.anthropic.models.messages.Message;

Message message = client
  .messages()
  .create(params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build());
```

Ou configure o padrão para todas as chamadas de método no nível do cliente:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .timeout(Duration.ofSeconds(30))
  .build();
```

## Requisições longas

<Warning>
  Considere usar [streaming](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#streaming) para requisições de execução mais longa.
</Warning>

Evite definir um valor grande de `maxTokens` sem usar streaming. Algumas redes podem encerrar conexões ociosas após um certo período de tempo, o que pode fazer com que a requisição falhe ou [expire](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#timeouts) sem receber uma resposta da Anthropic. O SDK envia pings periodicamente à API para manter a conexão ativa e reduzir o impacto dessas redes.

O SDK lança um erro se uma requisição sem streaming tiver previsão de levar mais de 10 minutos. Usar um [método de streaming](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#streaming) ou [substituir o timeout](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#timeouts) no nível do cliente ou da requisição desabilita o erro.

## Paginação

O SDK oferece maneiras convenientes de acessar resultados paginados, seja uma página por vez ou item por item em todas as páginas.

### Paginação automática

Para iterar por todos os resultados em todas as páginas, use o método `autoPager()`, que busca automaticamente mais páginas conforme necessário.

```java
import com.anthropic.models.messages.batches.BatchListPage;
import com.anthropic.models.messages.batches.MessageBatch;

BatchListPage page = client.messages().batches().list();

// Processar como um Iterable
for (MessageBatch batch : page.autoPager()) {
    IO.println(batch);
}

// Processar como um Stream
page.autoPager()
    .stream()
    .limit(50)
    .forEach(batch -> IO.println(batch));
```

Ao usar o cliente assíncrono, o método retorna um `AsyncStreamResponse`:

```java
import com.anthropic.core.http.AsyncStreamResponse;
import com.anthropic.models.messages.batches.BatchListPageAsync;
import com.anthropic.models.messages.batches.MessageBatch;

CompletableFuture<BatchListPageAsync> pageFuture = client.async().messages().batches().list();

pageFuture.thenAccept(page -> page.autoPager().subscribe(batch -> {
    IO.println(batch);
}));

// Se você precisar tratar erros ou a conclusão do stream
pageFuture.thenAccept(page -> page.autoPager().subscribe(new AsyncStreamResponse.Handler<>() {
    @Override
    public void onNext(MessageBatch batch) {
        IO.println(batch);
    }

    @Override
    public void onComplete(Optional<Throwable> error) {
        if (error.isPresent()) {
            IO.println("Something went wrong!");
            throw new RuntimeException(error.get());
        } else {
            IO.println("No more!");
        }
    }
}));

// Ou use futures
pageFuture.thenAccept(page -> page.autoPager()
    .subscribe(batch -> {
        IO.println(batch);
    })
    .onCompleteFuture()
    .whenComplete((unused, error) -> {
        if (error != null) {
            IO.println("Something went wrong!");
            throw new RuntimeException(error);
        } else {
            IO.println("No more!");
        }
    }));
```

### Paginação manual

Para acessar itens individuais da página e solicitar manualmente a próxima página:

```java
import com.anthropic.models.messages.batches.BatchListPage;
import com.anthropic.models.messages.batches.MessageBatch;

BatchListPage page = client.messages().batches().list();
while (true) {
    for (MessageBatch batch : page.items()) {
        IO.println(batch);
    }

    if (!page.hasNextPage()) {
        break;
    }

    page = page.nextPage();
}
```

## Sistema de tipos

### Imutabilidade e builders

Cada classe no SDK tem um builder associado para construí-la. Cada classe é imutável depois de construída. Se a classe tiver um builder associado, ela terá um método `toBuilder()`, que pode ser usado para convertê-la de volta em um builder para criar uma cópia modificada.

```java
MessageCreateParams params = MessageCreateParams.builder()
  .maxTokens(1024L)
  .addUserMessage("Hello, Claude")
  .model(Model.CLAUDE_OPUS_5_5)
  .build();

// Cria uma cópia modificada usando toBuilder()
MessageCreateParams modified = params.toBuilder().maxTokens(2048L).build();
```

Como cada classe é imutável, a modificação do builder nunca afeta instâncias de classe já construídas.

### Requisições e respostas

Para enviar uma requisição à Claude API, construa uma instância de alguma classe `Params` e passe-a para o método correspondente do cliente. Quando a resposta é recebida, ela é desserializada em uma instância de uma classe Java.

Por exemplo, `client.messages().create(...)` deve ser chamado com uma instância de `MessageCreateParams` e retorna uma instância de `Message`.

### Parâmetros não documentados

Para definir parâmetros não documentados, chame os métodos `putAdditionalHeader`, `putAdditionalQueryParam` ou `putAdditionalBodyProperty` em qualquer classe `Params`:

```java
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;

MessageCreateParams params = MessageCreateParams.builder()
  .putAdditionalHeader("Secret-Header", "42")
  .putAdditionalQueryParam("secret_query_param", "42")
  .putAdditionalBodyProperty("secretProperty", JsonValue.from("42"))
  .build();
```

Eles podem ser acessados posteriormente no objeto construído usando os métodos `_additionalHeaders()`, `_additionalQueryParams()` e `_additionalBodyProperties()`.

<Warning>
  Os valores passados para esses métodos sobrescrevem os valores passados para métodos anteriores. Por motivos de segurança, garanta que esses métodos sejam usados apenas com dados de entrada confiáveis.
</Warning>

Para definir parâmetros não documentados em classes aninhadas de cabeçalhos, parâmetros de consulta ou corpo:

```java
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Metadata;

MessageCreateParams params = MessageCreateParams.builder()
  .metadata(
    Metadata.builder().putAdditionalProperty("secretProperty", JsonValue.from("42")).build()
  )
  .build();
```

Essas propriedades podem ser acessadas posteriormente no objeto aninhado construído usando o método `_additionalProperties()`.

Para definir um parâmetro ou propriedade documentado com um valor não documentado ou ainda não suportado, passe um objeto `JsonValue` para o seu setter:

```java
import com.anthropic.core.JsonValue;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;

MessageCreateParams params = MessageCreateParams.builder()
  .maxTokens(JsonValue.from(3.14))
  .addUserMessage("Hello, Claude")
  .model(Model.CLAUDE_OPUS_5_5)
  .build();
```

### Criação de JsonValue

A maneira mais direta de criar um `JsonValue` é usando seu método `from(...)`:

```java
import com.anthropic.core.JsonValue;

// Cria valores JSON primitivos
JsonValue nullValue = JsonValue.from(null);

JsonValue booleanValue = JsonValue.from(true);

JsonValue numberValue = JsonValue.from(42);

JsonValue stringValue = JsonValue.from("Hello World!");

// Cria um valor de array JSON equivalente a `["Hello", "World"]`
JsonValue arrayValue = JsonValue.from(List.of("Hello", "World"));

// Cria um valor de objeto JSON equivalente a `{ "a": 1, "b": 2 }`
JsonValue objectValue = JsonValue.from(Map.of("a", 1, "b", 2));

// Cria um JSON aninhado arbitrariamente, equivalente a:
// { "a": [1, 2], "b": [3, 4] }
JsonValue complexValue = JsonValue.from(Map.of("a", List.of(1, 2), "b", List.of(3, 4)));
```

### Omitindo forçadamente parâmetros obrigatórios

Normalmente, o método `build` de uma classe `Builder` lançará `IllegalStateException` se algum parâmetro ou propriedade obrigatório não estiver definido. Para omitir forçadamente um parâmetro ou propriedade obrigatório, passe `JsonMissing`:

```java
import com.anthropic.core.JsonMissing;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;

MessageCreateParams params = MessageCreateParams.builder()
  .addUserMessage("Hello, world")
  .model(Model.CLAUDE_OPUS_5_5)
  .maxTokens(JsonMissing.of())
  .build();
```

### Propriedades da resposta

Para acessar propriedades não documentadas da resposta, chame o método `_additionalProperties()`:

```java
import com.anthropic.core.JsonValue;

Map<String, JsonValue> additionalProperties = client
  .messages()
  .create(params)
  ._additionalProperties();

JsonValue secretPropertyValue = additionalProperties.get("secretProperty");

String result = secretPropertyValue.accept(new JsonValue.Visitor<>() {
    @Override
    public String visitNull() {
        return "It's null!";
    }

    @Override
    public String visitBoolean(boolean value) {
        return "It's a boolean!";
    }

    @Override
    public String visitNumber(Number value) {
        return "It's a number!";
    }

    // Outros métodos incluem `visitMissing`, `visitString`, `visitArray` e `visitObject`
    // A implementação padrão de cada método não implementado delega para `visitDefault`,
    // que lança uma exceção por padrão, mas também pode ser sobrescrito
});
```

Para acessar o valor JSON bruto de uma propriedade, chame seu método com prefixo `_`:

```java
import com.anthropic.core.JsonField;
import com.anthropic.models.messages.StopReason;

JsonField<StopReason> stopReason = client.messages().create(params)._stopReason();

if (stopReason.isMissing()) {
  // A propriedade está ausente da resposta JSON
} else if (stopReason.isNull()) {
  // A propriedade foi definida como null literal
} else {
  // Verifica se o valor foi fornecido como string
  // Outros métodos incluem `asNumber()`, `asBoolean()` etc.
  Optional<String> jsonString = stopReason.asString();

  // Tenta desserializar em um tipo personalizado
  MyClass myObject = stopReason.asUnknown().orElseThrow().convert(MyClass.class);
}
```

### Validação da resposta

Por padrão, o SDK não lança uma exceção quando a API retorna uma resposta que não corresponde ao tipo esperado. Ele lança `AnthropicInvalidDataException` apenas se você acessar diretamente a propriedade.

Para verificar antecipadamente se a resposta está completamente bem tipada, chame `validate()`:

```java
import com.anthropic.models.messages.Message;

Message message = client.messages().create(params).validate();
```

Ou configure por requisição:

```java
import com.anthropic.models.messages.Message;

Message message = client
  .messages()
  .create(params, RequestOptions.builder().responseValidation(true).build());
```

Ou configure o padrão para todas as chamadas de método no nível do cliente:

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .responseValidation(true)
  .build();
```

## Personalização do cliente HTTP

### Configuração de proxy

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import java.net.Proxy;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("https://example.com", 8080)))
  .build();
```

### Configuração HTTPS / SSL

<Note>
  A maioria das aplicações não deve chamar esses métodos e, em vez disso, deve usar os padrões do sistema. Os padrões incluem otimizações especiais que podem ser perdidas se as implementações forem modificadas.
</Note>

```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;

AnthropicClient client = AnthropicOkHttpClient.builder()
  .fromEnv()
  .sslSocketFactory(yourSSLSocketFactory)
  .trustManager(yourTrustManager)
  .hostnameVerifier(yourHostnameVerifier)
  .build();
```

### Cliente HTTP personalizado

O SDK consiste em três artefatos:

* `anthropic-java-core` - Contém a lógica principal do SDK e não depende do OkHttp. Expõe `AnthropicClient`, `AnthropicClientAsync` e suas classes de implementação, todas as quais podem funcionar com qualquer cliente HTTP.
* `anthropic-java-client-okhttp` - Depende do OkHttp. Expõe `AnthropicOkHttpClient` e `AnthropicOkHttpClientAsync`.
* `anthropic-java` - Depende de e expõe as APIs de `anthropic-java-core` e `anthropic-java-client-okhttp`. Não tem lógica própria.

Essa estrutura permite substituir o cliente HTTP padrão do SDK sem incluir dependências desnecessárias.

#### OkHttpClient personalizado

<Tip>
  Experimente as [opções de rede](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#retries) disponíveis antes de substituir o cliente padrão.
</Tip>

Para usar um `OkHttpClient` personalizado:

1. Substitua sua dependência `anthropic-java` por `anthropic-java-core`.
2. Copie a classe `OkHttpClient` de `anthropic-java-client-okhttp` para o seu código e personalize-a.
3. Construa `AnthropicClientImpl` ou `AnthropicClientAsyncImpl` usando seu cliente personalizado.

#### Cliente HTTP completamente personalizado

Para usar um cliente HTTP completamente personalizado:

1. Substitua sua dependência `anthropic-java` por `anthropic-java-core`.
2. Escreva uma classe que implemente a interface `HttpClient`.
3. Construa `AnthropicClientImpl` ou `AnthropicClientAsyncImpl` usando sua nova classe de cliente.

## Integrações de plataforma

<Note>
  Para guias detalhados de configuração de plataforma com exemplos de código, consulte:

  * [Amazon Bedrock](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-in-amazon-bedrock)
  * [Amazon Bedrock (Opus 4.6 e anteriores)](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-on-amazon-bedrock-legacy)
  * [Claude Platform on AWS](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-platform-on-aws)
  * [Claude Models on Google Cloud (Google managed)](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-models-on-google-cloud/google-managed)
  * [Microsoft Foundry](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-in-microsoft-foundry)

  Consulte também [Claude Models on Google Cloud (Anthropic managed)](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-models-on-google-cloud/anthropic-managed).
</Note>

O Java SDK suporta as seguintes plataformas por meio de dependências separadas que fornecem implementações de `Backend` específicas de cada plataforma:

* **Agent Platform:** `com.anthropic:anthropic-java-vertex`: Use `VertexBackend.builder()` ou `VertexBackend.fromEnv()`. `fromEnv()` lê `CLOUD_ML_REGION` e `ANTHROPIC_VERTEX_PROJECT_ID` e usa Application Default Credentials.
* **Bedrock:** `com.anthropic:anthropic-java-bedrock`: Use `BedrockMantleBackend.fromEnv()` ou `BedrockMantleBackend.builder()` para o endpoint Bedrock da Messages API, ou `BedrockBackend.fromEnv()` / `BedrockBackend.builder()` (caminho `bedrock-runtime`).
* **Claude Platform on AWS:** `com.anthropic:anthropic-java-aws`: Use `AwsBackend.fromEnv()` (lê `ANTHROPIC_AWS_WORKSPACE_ID` e a cadeia padrão de região/credenciais da AWS) ou `AwsBackend.builder()`. Disponível em beta.
* **Foundry:** `com.anthropic:anthropic-java-foundry`: Use `FoundryBackend.fromEnv()` ou `FoundryBackend.builder()`.

Use `BedrockMantleBackend` para novos projetos; `BedrockBackend` permanece para aplicações existentes que usam a API `InvokeModel` do Bedrock.

O SDK Java também oferece suporte a Claude Models on Google Cloud (Anthropic managed) por meio de `GoogleCloudBackend`, da dependência `com.anthropic:anthropic-java-google-cloud`. Este backend está em beta. Crie-o com `GoogleCloudBackend.builder()` ou `GoogleCloudBackend.fromEnv()`. `fromEnv()` lê `ANTHROPIC_GOOGLE_CLOUD_WORKSPACE_ID`, `ANTHROPIC_GOOGLE_CLOUD_PROJECT` e as Google Application Default Credentials. Consulte [Resolução de projeto, localização e workspace](https://platform.claude.com/docs/pt-BR/build-with-claude/claude-models-on-google-cloud/anthropic-managed#project-location-and-workspace-resolution).

Os artefatos de plataforma são complementos da dependência base `com.anthropic:anthropic-java`, que fornece `AnthropicOkHttpClient`, portanto instale ambos. Cada implementação de `Backend` é passada ao cliente com `.backend()` em `AnthropicOkHttpClient.builder()`. Cada backend de nuvem inclui as classes do SDK da respectiva plataforma de nuvem como dependências transitivas.

## Uso avançado

### Acesso à resposta bruta

Para acessar cabeçalhos HTTP, códigos de status e o corpo bruto da resposta, prefixe qualquer chamada de método HTTP com `withRawResponse()`:

```java
import com.anthropic.core.http.Headers;
import com.anthropic.core.http.HttpResponseFor;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;

MessageCreateParams params = MessageCreateParams.builder()
  .maxTokens(1024L)
  .addUserMessage("Hello, Claude")
  .model(Model.CLAUDE_OPUS_5_5)
  .build();

HttpResponseFor<Message> message = client.messages().withRawResponse().create(params);

int statusCode = message.statusCode();

Headers headers = message.headers();
```

Você ainda pode desserializar a resposta em uma instância de uma classe Java, se necessário:

```java
import com.anthropic.models.messages.Message;

Message parsedMessage = message.parse();
```

### Logging

O SDK usa o interceptor de logging padrão do OkHttp.

Habilite o logging definindo a variável de ambiente `ANTHROPIC_LOG` como `info`:

```bash
export ANTHROPIC_LOG=info
```

Ou como `debug` para um logging mais detalhado:

```bash
export ANTHROPIC_LOG=debug
```

<Accordion title="Compatibilidade com Jackson">
  O SDK depende do Jackson para serialização/desserialização JSON. Ele é compatível com a versão 2.13.4 ou superior, mas depende da versão 2.19.4 por padrão.

  O SDK lança uma exceção se detectar uma versão incompatível do Jackson em tempo de execução (por exemplo, se a versão padrão tiver sido substituída na sua configuração do Maven ou Gradle).

  Se o SDK lançou uma exceção, mas você tem certeza de que a versão é compatível, desabilite a verificação de versão usando `checkJacksonVersionCompatibility` em `AnthropicOkHttpClient` ou `AnthropicOkHttpClientAsync`.

  <Warning>
    Não há garantia de que o SDK funcione corretamente quando a verificação de versão do Jackson está desabilitada.
  </Warning>

  Também existem bugs em versões mais antigas do Jackson que podem afetar o SDK. O SDK não contorna todos os bugs do Jackson e espera que os usuários atualizem o Jackson para resolvê-los.
</Accordion>

<Accordion title="Configuração do ProGuard/R8">
  Embora o SDK use reflexão, ele ainda pode ser usado com ProGuard e R8 porque `anthropic-java-core` é publicado com um arquivo de configuração contendo regras keep.

  O ProGuard e o R8 devem detectar e usar automaticamente as regras publicadas, mas você também pode copiar manualmente as regras keep, se necessário.
</Accordion>

### Funcionalidades não documentadas da API

O SDK é tipado para uso conveniente da API documentada. No entanto, ele também suporta trabalhar com partes não documentadas ou ainda não suportadas da API.

#### Parâmetros de requisição não documentados

Para definir parâmetros de requisição não documentados, use os métodos `putAdditionalHeader`, `putAdditionalQueryParam` ou `putAdditionalBodyProperty` conforme descrito em [Parâmetros não documentados](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#undocumented-parameters).

#### Propriedades de resposta não documentadas

Para acessar propriedades de resposta não documentadas, use o método `_additionalProperties()` conforme descrito em [Propriedades da resposta](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#response-properties).

#### Valores de enum novos ou não lançados

Classes semelhantes a enums no SDK, como `Model` e `AnthropicBeta`, não são tipos `enum` Java fechados. Cada uma fornece um método de fábrica `of(String)` que aceita qualquer string, para que você possa usar valores que ainda não foram adicionados ao SDK, como um modelo ou cabeçalho beta lançado após a sua versão do SDK:

```java
import com.anthropic.models.beta.AnthropicBeta;
import com.anthropic.models.messages.Model;

Model model = Model.of("some-new-model");
AnthropicBeta beta = AnthropicBeta.of("some-new-beta-2026-01-01");
```

Métodos de builder que recebem esses tipos frequentemente também fornecem uma sobrecarga `String` que chama `of(...)` para você:

```java
import com.anthropic.models.messages.MessageCreateParams;

MessageCreateParams params = MessageCreateParams.builder()
  .model("some-new-model") // same as .model(Model.of("some-new-model"))
  .maxTokens(1024L)
  .addUserMessage("Hello, Claude")
  .build();
```

Prefira as constantes bem tipadas (por exemplo, `Model.CLAUDE_OPUS_5`) para obter autocompletar e avisos de descontinuação. As sobrecargas `String` e `of(...)` servem principalmente para definir o campo com um valor não documentado ou ainda não suportado enquanto você aguarda uma versão do SDK que o inclua.

## Recursos beta

Os recursos beta ficam disponíveis antes do lançamento geral para obter feedback antecipado e testar novas funcionalidades. Você pode verificar a disponibilidade de todas as capacidades e ferramentas do Claude na [Visão geral de recursos](https://platform.claude.com/docs/pt-BR/build-with-claude/overview).

Você pode acessar a maioria dos recursos beta da API por meio do método `beta()` no cliente. Para habilitar um recurso beta específico, adicione o [cabeçalho beta](https://platform.claude.com/docs/pt-BR/api/beta-headers) apropriado com `.addBeta()` ao construir os parâmetros da mensagem.

Por exemplo, para habilitar a [edição de contexto](https://platform.claude.com/docs/pt-BR/build-with-claude/context-editing):

```java
import com.anthropic.models.beta.AnthropicBeta;
import com.anthropic.models.beta.messages.BetaMessage;
import com.anthropic.models.beta.messages.MessageCreateParams;
// ...
void main() {
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    BetaMessage message = client.beta().messages().create(
        MessageCreateParams.builder()
            .model(Model.CLAUDE_OPUS_5_5)
            .maxTokens(1024L)
            .addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27)
            .addUserMessage("Hello, Claude")
            .build());
}
```

## Perguntas frequentes

<AccordionGroup>
  <Accordion title="Por que o SDK não usa classes enum simples?">
    As classes `enum` do Java não são trivialmente compatíveis com versões futuras. Usá-las no SDK poderia causar exceções em tempo de execução se a API fosse atualizada para responder com um novo valor de enum.

    Como essas classes são abertas, você também pode construí-las com qualquer valor de string por meio do método de fábrica `of(String)`. Consulte [Valores de enum novos ou não lançados](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/sdks/java#new-or-unreleased-enum-values) se precisar usar um valor que ainda não está na sua versão do SDK.
  </Accordion>

  <Accordion title="Por que os campos são representados usando JsonField<T> em vez de apenas T simples?">
    Usar `JsonField<T>` habilita alguns recursos:

    * Permitir o uso de funcionalidades não documentadas da API
    * Validar de forma preguiçosa (lazy) a resposta da API em relação ao formato esperado
    * Representar valores ausentes versus explicitamente nulos
  </Accordion>

  <Accordion title="Por que o SDK não usa data classes?">
    Adicionar novos campos a uma data class não é retrocompatível, e o SDK evita introduzir uma mudança incompatível toda vez que um campo é adicionado a uma classe.
  </Accordion>

  <Accordion title="Por que o SDK não usa exceções verificadas?">
    As exceções verificadas (checked exceptions) são amplamente consideradas um erro na linguagem de programação Java. Na verdade, elas foram omitidas do Kotlin por esse motivo.

    Exceções verificadas:

    * São verbosas de tratar
    * Incentivam o tratamento de erros no nível errado de abstração, onde nada pode ser feito a respeito do erro
    * São tediosas de propagar por causa do problema de coloração de funções
    * Não funcionam bem com lambdas (também por causa do problema de coloração de funções)
  </Accordion>
</AccordionGroup>

## Versionamento semântico

Cada versão principal deste SDK envia uma versão da API no cabeçalho `anthropic-version` por padrão, e uma nova versão principal acompanha cada nova versão da API. A primeira versão principal que envia `2026-10-21` é a 3.0.0; consulte [Migrando para a versão da API 2026-10-21](https://platform.claude.com/docs/pt-BR/api/migration-2026-10-21#upgrade).

Este pacote geralmente segue as convenções do [SemVer](https://semver.org/spec/v2.0.0.html), embora certas mudanças incompatíveis com versões anteriores possam ser lançadas como versões menores:

1. Mudanças em componentes internos da biblioteca que são tecnicamente públicos, mas não destinados ou documentados para uso externo.
2. Mudanças que não devem impactar a grande maioria dos usuários na prática.

## Recursos adicionais

* [Repositório no GitHub](https://github.com/anthropics/anthropic-sdk-java)
* [Javadocs](https://javadoc.io/doc/com.anthropic/anthropic-java)
* [Referência da API](https://platform.claude.com/docs/pt-BR/api/overview)
* [Streaming de mensagens](https://platform.claude.com/docs/pt-BR/build-with-claude/streaming)
* [Uso de ferramentas com Claude](https://platform.claude.com/docs/pt-BR/agents-and-tools/tool-use/overview)
