java
cli-sdks-libraries/sdks/java
History
cli-sdks-libraries/sdks/java Changed · +3 / -3 lines
<Tabs> <Tab title="Gradle"> ```kotlin - implementation("com.anthropic:anthropic-java:2.57.0") + implementation("com.anthropic:anthropic-java:2.58.0") ``` </Tab>
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java</artifactId> - <version>2.57.0</version> + <version>2.58.0</version> </dependency> ``` </Tab>
.build(); ``` -For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). +For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication). If your API key is a [personal or service account key](https://platform.claude.com/docs/en/manage-claude/authentication#key-types) with access to multiple workspaces, set the workspace ID in the `anthropic-workspace-id` request header; [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace) shows the per-request option for this SDK. ### Configuration options
cli-sdks-libraries/sdks/java Changed · +18 / -29 lines
<Tabs> <Tab title="Gradle"> ```kotlin - implementation("com.anthropic:anthropic-java:2.53.0") + implementation("com.anthropic:anthropic-java:2.57.0") ``` </Tab>
<dependency> <groupId>com.anthropic</groupId> <artifactId>anthropic-java</artifactId> - <version>2.53.0</version> + <version>2.57.0</version> </dependency> ``` </Tab>
```java import com.anthropic.core.MultipartField; -import com.anthropic.models.beta.files.FileMetadata; -import com.anthropic.models.beta.files.FileUploadParams; +import com.anthropic.models.files.FileMetadata; +import com.anthropic.models.files.FileUploadParams; FileUploadParams params = FileUploadParams.builder() .file(
) .build(); -FileMetadata fileMetadata = client.beta().files().upload(params); +FileMetadata fileMetadata = client.files().upload(params); ``` Or from an `InputStream`:
```java import com.anthropic.core.MultipartField; -import com.anthropic.models.beta.files.FileMetadata; -import com.anthropic.models.beta.files.FileUploadParams; +import com.anthropic.models.files.FileMetadata; +import com.anthropic.models.files.FileUploadParams; FileUploadParams params = FileUploadParams.builder() .file(
) .build(); -FileMetadata fileMetadata = client.beta().files().upload(params); +FileMetadata fileMetadata = client.files().upload(params); ``` Or from in-memory bytes:
```java import com.anthropic.core.MultipartField; -import com.anthropic.models.beta.files.FileMetadata; -import com.anthropic.models.beta.files.FileUploadParams; +import com.anthropic.models.files.FileMetadata; +import com.anthropic.models.files.FileUploadParams; FileUploadParams params = FileUploadParams.builder() .file(
) .build(); -FileMetadata fileMetadata = client.beta().files().upload(params); +FileMetadata fileMetadata = client.files().upload(params); ``` ### Binary responses
```java import com.anthropic.core.http.HttpResponse; -HttpResponse response = client.beta().files().download("file_abc123"); +HttpResponse response = client.files().download("file_abc123"); ``` To save the response content to a file:
```java import com.anthropic.core.http.HttpResponse; -try (HttpResponse response = client.beta().files().download(params)) { +try (HttpResponse response = client.files().download(params)) { Files.copy( response.body(), Paths.get(path),
```java import com.anthropic.core.http.HttpResponse; -try (HttpResponse response = client.beta().files().download(params)) { +try (HttpResponse response = client.files().download(params)) { response.body().transferTo(Files.newOutputStream(Paths.get(path))); } catch (Exception e) { IO.println("Something went wrong!");
``` <Accordion title="Jackson compatibility"> - The SDK depends on Jackson for JSON serialization/deserialization. It is compatible with version 2.13.4 or higher, but depends on version 2.18.2 by default. + The SDK depends on Jackson for JSON serialization/deserialization. It is compatible with version 2.13.4 or higher, but depends on version 2.19.4 by default. The SDK throws an exception if it detects an incompatible Jackson version at runtime (for example, if the default version was overridden in your Maven or Gradle config).
You can access most beta API features through the `beta()` method on the client. To enable a particular beta feature, add the appropriate [beta header](https://platform.claude.com/docs/en/api/beta-headers) with `.addBeta()` when building the message params. -For example, to use the [Files API](https://platform.claude.com/docs/en/build-with-claude/files): +For example, to enable [context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing): ```java import com.anthropic.models.beta.AnthropicBeta; -import com.anthropic.models.beta.messages.BetaContentBlockParam; import com.anthropic.models.beta.messages.BetaMessage; -import com.anthropic.models.beta.messages.BetaRequestDocumentBlock; -import com.anthropic.models.beta.messages.BetaTextBlockParam; import com.anthropic.models.beta.messages.MessageCreateParams; // ... void main() {
MessageCreateParams.builder() .model(Model.CLAUDE_OPUS_5) .maxTokens(1024L) - .addBeta(AnthropicBeta.FILES_API_2025_04_14) - .addUserMessageOfBetaContentBlockParams(List.of( - BetaContentBlockParam.ofText( - BetaTextBlockParam.builder() - .text("Please summarize this document for me.") - .build()), - BetaContentBlockParam.ofDocument( - BetaRequestDocumentBlock.builder() - .fileSource("file_abc123") - .build()))) + .addBeta(AnthropicBeta.CONTEXT_MANAGEMENT_2025_06_27) + .addUserMessage("Hello, Claude") .build()); } ```
cli-sdks-libraries/sdks/java First recorded · 1280 lines, first recorded
## Installation ## Requirements ## Quick start ## Client configuration ### API key setup ### Configuration options ### Modifying configuration ## Async usage ## Streaming ### Synchronous streaming ### Asynchronous streaming ### Streaming with message accumulator ## Structured outputs ## Tool use ### Defining tools with annotations ### Calling tools ### Tool name conversion ### Local tool JSON schema validation ### Annotating tool classes ## Message batches ## File uploads ### Binary responses ## Error handling ### Status code mapping ## Request IDs ## Retries ## Timeouts ## Long requests ## Pagination ### Auto-pagination ### Manual pagination ## Type system ### Immutability and builders ### Requests and responses ### Undocumented parameters ### JsonValue creation ### Forcibly omitting required parameters ### Response properties ### Response validation ## HTTP client customization ### Proxy configuration ### HTTPS / SSL configuration ### Custom HTTP client #### Customized OkHttpClient #### Completely custom HTTP client ## Platform integrations ## Advanced usage ### Raw response access ### Logging ### Undocumented API functionality #### Undocumented request parameters #### Undocumented response properties #### New or unreleased enum values ## Beta features ## Frequently asked questions ## Semantic versioning ## Additional resources
The first capture of this source. The page was already there, and this is what it said.
---
title: Java SDK
url: https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/java
description: Install and configure the Anthropic Java SDK with builder patterns and async support
---
The Anthropic Java SDK provides convenient access to the Claude API from applications written in Java. It uses the builder pattern for creating requests and supports both synchronous and asynchronous operations.
<Info>
For API feature documentation with code examples, see the [API reference](https://platform.claude.com/docs/en/api/overview). This page covers Java-specific SDK features and configuration.
</Info>
## Installation
<Tabs>
<Tab title="Gradle">
```kotlin
implementation("com.anthropic:anthropic-java:2.53.0")
```
</Tab>
<Tab title="Maven">
```xml
<dependency>
<groupId>com.anthropic</groupId>
<artifactId>anthropic-java</artifactId>
<version>2.53.0</version>
</dependency>
```
</Tab>
</Tabs>
## Requirements
This library requires Java 8 or later.
<Note>
The SDK supports Java 8 and later. Code examples in this documentation are written as [JDK 25 compact source files](https://openjdk.org/jeps/512), using a bare `void main()` entry point and `IO.println()` for output. The API calls themselves are identical on every supported JDK; to compile an example on an earlier version, replace `IO.println(...)` with `System.out.println(...)` and place the body inside `public static void main(String[] args)` within a class.
</Note>
## Quick start
```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;
// Configures using the `anthropic.apiKey`, `anthropic.authToken` and `anthropic.baseUrl` system properties
// Or configures using the `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_BASE_URL` environment variables
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.maxTokens(1024L)
.addUserMessage("Hello, Claude")
.model(Model.CLAUDE_OPUS_5)
.build();
Message message = client.messages().create(params);
```
## Client configuration
### API key setup
Configure the client using system properties or environment variables:
```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
// Configures using the `anthropic.apiKey`, `anthropic.authToken` and `anthropic.baseUrl` system properties
// Or configures using the `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_BASE_URL` environment variables
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
```
Or configure manually:
```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.apiKey("my-anthropic-api-key")
.build();
```
Or use a combination of both approaches:
```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
// Configures using system properties or environment variables
.fromEnv()
.apiKey("my-anthropic-api-key")
.build();
```
For authentication options including Workload Identity Federation, see [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication).
### Configuration options
| Setter | System property | Environment variable | Required | Default value |
| ----------- | --------------------- | ---------------------- | -------- | ----------------------------- |
| `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"` |
System properties take precedence over environment variables.
<Tip>
Don't create more than one client in the same application. Each client has a connection pool and thread pools, which are more efficient to share between requests.
</Tip>
### Modifying configuration
To temporarily use a modified client configuration while reusing the same connection and thread pools, call `withOptions()` on any client or service:
```java
import com.anthropic.client.AnthropicClient;
AnthropicClient clientWithOptions = client.withOptions(optionsBuilder -> {
optionsBuilder.baseUrl("https://example.com");
optionsBuilder.maxRetries(42);
});
```
The `withOptions()` method does not affect the original client or service.
## Async usage
The default client is synchronous. To switch to asynchronous execution, call the `async()` method:
```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)
.build();
CompletableFuture<Message> message = client.async().messages().create(params);
```
Or create an asynchronous client from the beginning:
```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)
.build();
CompletableFuture<Message> message = client.messages().create(params);
```
The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s.
## Streaming
The SDK defines methods that return response "chunk" streams, where each chunk can be individually processed as soon as it arrives instead of waiting on the full response.
### Synchronous streaming
These streaming methods return `StreamResponse` for synchronous clients:
```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!");
}
```
### Asynchronous streaming
For asynchronous clients, the method returns `AsyncStreamResponse`:
```java
import com.anthropic.core.http.AsyncStreamResponse;
import com.anthropic.models.messages.RawMessageStreamEvent;
client.async().messages().createStreaming(params).subscribe(chunk -> {
IO.println(chunk);
});
// If you need to handle errors or completion of the 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!");
}
}
});
// Or 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!");
}
});
```
Async streaming uses a dedicated per-client cached thread pool `Executor` to stream without blocking the current thread. To use a different `Executor`:
```java
Executor executor = Executors.newFixedThreadPool(4);
client.async().messages().createStreaming(params).subscribe(
chunk -> IO.println(chunk), executor
);
```
Or configure the client globally using the `streamHandlerExecutor` method:
```java
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
AnthropicClient client = AnthropicOkHttpClient.builder()
.fromEnv()
.streamHandlerExecutor(Executors.newFixedThreadPool(4))
.build();
```
### Streaming with message accumulator
A `MessageAccumulator` can record the stream of events in the response as they are processed and accumulate a `Message` object similar to what would have been returned by the non-streaming API.
For a synchronous response, add a `Stream.peek()` call to the stream pipeline to accumulate each event:
```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();
```
For an asynchronous response, add the `MessageAccumulator` to the `subscribe()` call:
```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()
Cut at 300 lines.