Claude API SDK for Java Developers: What to Use
Does Anthropic have an official Java SDK?
No. As of now, Anthropic ships official SDKs for Python and TypeScript/JavaScript, but there's no first-party Java SDK for the Claude API. If you're building on the JVM — Spring Boot, Micronaut, Quarkus, or plain Java — you have three realistic paths: call the REST API directly with Java's built-in HttpClient, use a community-maintained wrapper library, or put a thin HTTP layer like SubToAPI in front and treat Claude like any other REST dependency.
This isn't actually a problem. The Claude API (and SubToAPI's compatible endpoint) is plain HTTPS with JSON request/response bodies and optional Server-Sent Events for streaming. Java has had excellent native HTTP and JSON tooling since Java 11, so you don't need a heavyweight SDK to integrate Claude into a Java service cleanly. Below is exactly how to do it, including streaming and tool use.
Option 1: Call the REST API directly
This is the most durable approach — no third-party library to track for breaking changes, just HTTP. Java's java.net.http.HttpClient (built in since Java 11) handles this fine, paired with Jackson or Gson for JSON.
Maven dependency (Jackson only):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
A basic request:
import java.net.URI;
import java.net.http.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
public class ClaudeClient {
private static final HttpClient client = HttpClient.newHttpClient();
private static final ObjectMapper mapper = new ObjectMapper();
public static String sendMessage(String apiKey, String prompt) throws Exception {
Map<String, Object> body = new HashMap<>();
body.put("model", "claude-sonnet-4");
body.put("max_tokens", 1024);
body.put("messages", List.of(Map.of("role", "user", "content", prompt)));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.subtoapi.app/v1/messages"))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(body)))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
}
}
This is the whole integration. No SDK, no generated boilerplate, just a POST request and a JSON response. If you're using SubToAPI, your application key (sub_live_...) goes in that Authorization header and api.subtoapi.app becomes your single integration point — see the quickstart for the full request/response shape.
Option 2: Community Java SDKs
A handful of community-maintained Java libraries wrap the Claude API with typed request/response classes. They can save you from hand-rolling request bodies, but weigh the tradeoffs:
- Maintenance risk — community SDKs can lag behind new model releases, parameter changes, or new content block types (tool use, extended thinking). You're depending on an unpaid maintainer's free time.
- Dependency surface — every library you add is another thing to patch for security advisories.
- Abstraction mismatch — some wrap the API in ways that make streaming or tool use awkward compared to just reading the HTTP docs directly.
If you go this route, pin the version, read the source before trusting it in production, and keep the direct-HTTP approach above as a fallback you understand.
Streaming in Java
Claude's streaming responses are Server-Sent Events. Java's HttpClient doesn't have native SSE parsing, but you can consume the stream as a line-by-line body handler:
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.subtoapi.app/v1/messages"))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse<Stream<String>> response = client.send(
request, HttpResponse.BodyHandlers.ofLines());
response.body()
.filter(line -> line.startsWith("data: "))
.map(line -> line.substring(6))
.forEach(System.out::println);
Each line is a JSON event — content_block_delta events carry the actual text chunks. If you need this working end-to-end with event types parsed into Java objects, the streaming docs cover the full event schema.
Tool use from Java
Tool calling works the same way as any other request — you declare tools as a JSON array in the request body, and Claude responds with a tool_use content block when it wants to call one:
Map<String, Object> tool = Map.of(
"name", "get_weather",
"description", "Get current weather for a city",
"input_schema", Map.of(
"type", "object",
"properties", Map.of("city", Map.of("type", "string")),
"required", List.of("city")
)
);
Map<String, Object> body = new HashMap<>();
body.put("model", "claude-sonnet-4");
body.put("max_tokens", 1024);
body.put("tools", List.of(tool));
body.put("messages", List.of(Map.of("role", "user", "content", "What's the weather in Berlin?")));
Parse the response, check for a tool_use block, run your Java method, and send the result back in the next message as a tool_result block. Full schema and multi-turn examples are in the tool use docs.
Why wrap Claude behind an API layer in Java services
Enterprise Java shops already lean on API gateways for auth, rate limiting, and billing — Claude access fits the same pattern. If your Java backend calls Claude directly with a personal Anthropic account, you inherit account-level rate limits, no per-team usage breakdown, and manual key management across services.
SubToAPI turns your existing Claude access into a standard HTTPS API with application-scoped keys (sub_live_...), so each Java microservice, each environment, or each team gets its own key, with usage tracked per key in one dashboard. Since it's just REST + SSE, it drops into the HttpClient code above with zero extra Java dependencies — swap the base URL and key, and you're billing and monitoring usage without writing a gateway yourself. Check pricing or start with a free trial at signup.
FAQ
Is there an official Claude Java SDK from Anthropic? No. Anthropic currently publishes official SDKs for Python and TypeScript/JavaScript only. Java developers integrate via direct REST calls or community libraries.
What's the easiest way to call Claude from Spring Boot? Use RestClient or WebClient (Spring's built-in HTTP clients) to POST JSON to the messages endpoint, exactly as shown with java.net.http.HttpClient above — no extra SDK dependency needed.
Can I stream Claude responses in a Java web app? Yes. Consume the SSE response line by line and forward parsed deltas to your frontend over WebSocket or Server-Sent Events — see the streaming docs for the event format.