Claude API Java SDK Usage Example Guide
If you're looking for a working Claude API Java SDK usage example, the short version is: add the official Anthropic Java client to your Maven or Gradle build, instantiate a client with your API key, and call messages().create() with a model name, a max token limit, and a list of messages. The response object gives you the generated text plus usage metadata (input/output token counts) that you can log or bill against.
This article walks through that flow in detail — dependency setup, a basic request, streaming, and tool use — plus notes on error handling and what to do if you want a simpler HTTPS interface instead of managing SDK versions and retry logic yourself.
Adding the SDK to Your Project
The Anthropic Java SDK is published to Maven Central. For Maven:
<dependency>
<groupId>com.anthropic</groupId>
<artifactId>anthropic-java</artifactId>
<version>LATEST</version>
</dependency>
For Gradle:
implementation "com.anthropic:anthropic-java:LATEST"
Pin an actual version number in production rather than LATEST — check the package's release notes before upgrading, since request/response shapes occasionally change between major versions.
Basic Usage Example
Here's a minimal client call that sends a single user message and prints the model's reply:
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;
public class ClaudeExample {
public static void main(String[] args) {
AnthropicClient client = AnthropicOkHttpClient.builder()
.apiKey(System.getenv("ANTHROPIC_API_KEY"))
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_3_5_SONNET_LATEST)
.maxTokens(1024L)
.addUserMessage("Summarize the main idea of REST APIs in two sentences.")
.build();
Message message = client.messages().create(params);
message.content().forEach(block -> {
block.text().ifPresent(text -> System.out.println(text.text()));
});
}
}
The AnthropicOkHttpClient builder pulls your key from an environment variable rather than hardcoding it, which is the right default for anything beyond a local test. The maxTokens field is required and caps output length, not cost — you're still billed for whatever tokens are actually generated.
Streaming Responses
For chat UIs or long completions, streaming avoids making users wait for the full response. The Java SDK exposes a streaming variant that yields events as the model generates text:
client.messages().createStreaming(params).forEach(event -> {
event.contentBlockDelta().ifPresent(delta -> {
delta.delta().text().ifPresent(System.out::print);
});
});
Each event corresponds to a chunk of the response. In production you'd typically push these chunks over a WebSocket or Server-Sent Events connection to the frontend rather than printing to stdout.
Using Tools (Function Calling)
Claude's tool use lets the model call functions you define — database lookups, calculators, internal APIs — and incorporate the results into its answer. Define a tool schema and pass it in MessageCreateParams:
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_3_5_SONNET_LATEST)
.maxTokens(1024L)
.addTool(Tool.builder()
.name("get_weather")
.description("Get current weather for a city")
.inputSchema(/* JSON schema object */)
.build())
.addUserMessage("What's the weather in Lisbon?")
.build();
Message message = client.messages().create(params);
When Claude decides to call get_weather, the response content includes a tool-use block with the arguments it generated. Your code executes the actual function, then sends the result back as a tool result message in a follow-up call. This round trip is the same regardless of which SDK language you use — the Java client just wraps the underlying JSON structure in typed classes.
Error Handling and Retries
Network calls fail. Rate limits get hit. The SDK throws typed exceptions (e.g., RateLimitException, APIConnectionException) that you should catch explicitly rather than relying on a generic catch (Exception e):
try {
Message message = client.messages().create(params);
} catch (RateLimitException e) {
// back off and retry with exponential delay
} catch (APIConnectionException e) {
// network issue, retry once
}
If you're building something customer-facing, you'll want this retry logic duplicated across every service that calls Claude, plus consistent logging of token usage per request for cost tracking. That duplication is the main reason teams eventually wrap the SDK in an internal client.
When a Plain HTTPS API Is Simpler Than Managing the SDK
The Java SDK is fine for a single service owned by one team. It gets harder to manage once you have multiple applications, each needing its own credentials, usage visibility, and rate limits — especially if non-Java services (a Node.js worker, a mobile backend) also need Claude access.
SubToAPI turns your existing Claude access into a plain HTTPS API with its own application keys (sub_live_...), so any service — Java, Python, a curl script — hits the same endpoint without needing a language-specific SDK at all:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize REST APIs in two sentences."}]
}'
From Java, that's just an HttpClient POST request — no extra dependency, no SDK version to track. You get per-key usage metadata, streaming (/docs/streaming), tool use (/docs/tools), and team seats in one dashboard, which is useful when several internal apps or team members share the same Claude access. See /docs/quickstart for setup and /docs/messages for the full request format. Plans start at €9/month for solo use, with team and scale tiers at /pricing, and a free trial at /signup.
Summary
For a Java-native project, the official SDK with typed request/response classes is the straightforward choice — install it, build a MessageCreateParams object, call create(), and handle the typed exceptions. For multi-service setups or teams that want centralized usage tracking and shared API keys across languages, a plain HTTPS layer like SubToAPI removes the SDK dependency entirely while keeping the same request shape.
Questions
Does Anthropic provide an official Java SDK? Yes, Anthropic publishes a Java client (com.anthropic:anthropic-java) on Maven Central with typed builders for messages, streaming, and tool use.
What's the minimum code needed to send a Claude request from Java? Build an AnthropicClient with your API key, construct MessageCreateParams with a model, max tokens, and a user message, then call client.messages().create(params).
Can I call Claude from Java without the official SDK? Yes — the API is plain HTTPS/JSON, so any Java HTTP client works. This is also how services like SubToAPI operate: a single HTTPS endpoint usable from any language without an SDK dependency.