READ-ONLY PACKAGE PREVIEW

anthropics-claude-api/java/claude-api/README.md

Version 8a1541c4.bb1 · Apache-2.0. This preview displays packaged text and does not execute code. Treat the contents as untrusted instructions.

← Return to resource and package checksum

Claude API - Java

Note: The Java SDK supports the Claude API and beta tool use with annotated classes. Agent SDK is not yet available for Java.

Package Reference

Types are organized by package. If a class you need isn't shown in an example below, locate it via this table first - don't block on fetching SDK source over the network.

import prefix Contains
com.anthropic.client / com.anthropic.client.okhttp AnthropicClient, AnthropicOkHttpClient
com.anthropic.models.messages non-beta request/response types - MessageCreateParams, Model, Message, TextBlockParam, ContentBlockParam, ToolUseBlockParam, ToolResultBlockParam, CacheControlEphemeral, Tool* (e.g. ToolBash20250124, ToolTextEditor20250728), StopReason, StructuredMessage*
com.anthropic.models.messages.batches Batch API - BatchResultsParams, MessageBatchIndividualResponse
com.anthropic.models.beta AnthropicBeta (beta-flag constants)
com.anthropic.models.beta.messages beta-endpoint types - MessageCreateParams, BetaMessage, BetaStopReason, BetaContextManagementConfig, BetaMcpToolset, BetaRequestMcpServerUrlDefinition, BetaTool*
com.anthropic.core JsonValue, JsonField, JsonSchemaLocalValidation, com.anthropic.core.http.StreamResponse
com.anthropic.errors typed exceptions - AnthropicServiceException, RateLimitException, NotFoundException, etc. (see shared/error-codes.md)

client.messages() uses com.anthropic.models.messages.*; client.beta().messages() uses com.anthropic.models.beta.messages.*. Both packages define a MessageCreateParams - import the one matching the client path you call.

Key types per feature

Write from this table instead of javap/jar inspection. Endpoint column tells you whether to use client.messages() or client.beta().messages().

Feature Endpoint Key Java types / builder calls
User profiles beta client.beta().userProfiles().create(...) / .retrieve(id) / .list(). Pass the returned profile id on the beta MessageCreateParams. Requires a beta header - check the SDK's beta-headers reference for the current flag.
Agent Skills beta BetaContainerParams, BetaSkillParams, BetaCodeExecutionTool20250825. .addBeta("code-execution-2025-08-25") (Skills is out of beta - no skills-2025-10-02). Download the output via client.beta().files().download(fileId).
Cache diagnostics beta BetaDiagnosticsParam, BetaCacheControlEphemeral
Context editing beta .contextManagement(BetaContextManagementConfig.builder()...). The edit strategy is a BetaClearToolUses20250919Edit (or BetaClearThinking20251015Edit); its trigger is a BetaInputTokensTrigger built separately and passed to the edit's builder - there is no direct .inputTokensTrigger(N) shortcut on the edit builder. javap the edit and trigger classes for the exact setter names.
Memory tool non-beta .addTool(MemoryTool20250818.builder().build()) from com.anthropic.models.messages
Programmatic tool calling non-beta CodeExecutionTool20260120, Tool, ContentBlockParam
Strict tool use non-beta Tool, Tool.InputSchema
Task budgets beta .outputConfig(BetaOutputConfig.builder().taskBudget(BetaTokenTaskBudget.builder()...))
Tool search non-beta .addTool(ToolSearchToolRegex20251119.builder()...) from com.anthropic.models.messages
Web search non-beta WebSearchTool20260209 from com.anthropic.models.messages - the latest variant with dynamic filtering (Claude Fable 5.1 + Claude Opus 5.5 + Claude Opus 5 + Opus 4.8/4.7/4.6 + Claude Sonnet 5.5 + Claude Sonnet 5 + Sonnet 4.6). For older models or Vertex, use WebSearchTool20250305

Discovering type and member names

If a class or builder method you need isn't in the tables above, jar tf <anthropic-java-core jar> | grep -i <term> or javap -classpath <jar> com.anthropic.models.... is fast enough to locate names. Do not compile and run a separate reflection program to enumerate members - the first build is slow enough to be backgrounded in many environments, trapping you in a polling loop. Write the script with the names you found and let the compiler error (cannot find symbol) point at any wrong member.

Installation

Maven:

<dependency>
    <groupId>com.anthropic</groupId>
    <artifactId>anthropic-java</artifactId>
    <version>2.34.0</version>
</dependency>

Gradle:

implementation("com.anthropic:anthropic-java:2.34.0")

Client Initialization

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

// Default (reads ANTHROPIC_API_KEY from environment)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();

// Explicit API key
AnthropicClient client = AnthropicOkHttpClient.builder()
    .apiKey("your-api-key")
    .build();

Basic Message Request

import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Message;

MessageCreateParams params = MessageCreateParams.builder()
    .model("claude-opus-5-5")  // .model(String) overload - works for every model id; typed Model.* constants lag model launches
    .maxTokens(16000L)
    .addUserMessage("What is the capital of France?")
    .build();

Message response = client.messages().create(params);
response.content().stream()
    .flatMap(block -> block.text().stream())
    .forEach(textBlock -> System.out.println(textBlock.text()));

Thinking

Adaptive thinking is the recommended mode for Claude 4.6+ models. Claude decides dynamically when and how much to think. The builder has a direct .thinking(ThinkingConfigAdaptive) overload - no manual union wrapping.

Fable 5, Claude Opus 5.5, Claude Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, and Sonnet 4.6: Use adaptive thinking (below). ThinkingConfigEnabled.builder().budgetTokens(N) is removed on Fable 5, Claude Opus 5.5, Claude Opus 5, Opus 4.8, and 4.7 (400 if sent); deprecated on Opus 4.6 and Sonnet 4.6. Claude Opus 5.5: thinking is always on - omit .thinking(...) (or send ThinkingConfigAdaptive, which is equivalent); ThinkingConfigDisabled returns a 400 at every effort, as does a thinking budget. Control depth with .outputConfig(OutputConfig.builder().effort(...)) instead - the default is medium on this model, where Claude Opus 5 defaults to high. Claude Opus 5: thinking is on by default - omitting .thinking(...) runs adaptive (ThinkingConfigAdaptive is equivalent), unlike Opus 4.8/4.7 where omitting it meant no thinking. ThinkingConfigDisabled is accepted only at effort HIGH or lower; pairing it with XHIGH/MAX returns a 400. Older models: Use .thinking(ThinkingConfigEnabled.builder().budgetTokens(N).build()) (budget must be < maxTokens, min 1024).

import com.anthropic.models.messages.ContentBlock;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.ThinkingConfigAdaptive;

MessageCreateParams params = MessageCreateParams.builder()
    .model("claude-opus-5-5")
    .maxTokens(16000L)
    // display opt-in: default is omitted (empty thinking text) on Fable 5/5.1, Mythos 5/5.1, Claude Opus 5.5, Claude Opus 5, Opus 4.8/4.7, Claude Sonnet 5.5, and Claude Sonnet 5
    .thinking(ThinkingConfigAdaptive.builder().display(ThinkingConfigAdaptive.Display.SUMMARIZED).build())
    .addUserMessage("Solve this step by step: 27 * 453")
    .build();

for (ContentBlock block : client.messages().create(params).content()) {
    block.thinking().ifPresent(t -> System.out.println("[thinking] " + t.thinking()));
    block.text().ifPresent(t -> System.out.println(t.text()));
}

ContentBlock narrowing: .thinking() / .text() return Optional<T> - use .ifPresent(...) or .stream().flatMap(...). Alternative: isThinking() / asThinking() boolean+unwrap pairs (throws on wrong variant).


Effort Parameter

Effort is nested inside OutputConfig - there is NO .effort() directly on MessageCreateParams.Builder.

import com.anthropic.models.messages.OutputConfig;

.outputConfig(OutputConfig.builder()
    .effort(OutputConfig.Effort.HIGH)  // or LOW, MEDIUM, XHIGH, MAX
    .build())

Combine with Thinking = ThinkingConfigAdaptive for cost-quality control.


Prompt Caching

System message as a list of TextBlockParam with CacheControlEphemeral. Use .systemOfTextBlockParams(...) - the plain .system(String) overload can't carry cache control. For placement patterns and the silent-invalidator audit checklist, see shared/prompt-caching.md.

import com.anthropic.models.messages.TextBlockParam;
import com.anthropic.models.messages.CacheControlEphemeral;

.systemOfTextBlockParams(List.of(
    TextBlockParam.builder()
        .text(longSystemPrompt)
        .cacheControl(CacheControlEphemeral.builder()
            .ttl(CacheControlEphemeral.Ttl.TTL_1H)  // optional; also TTL_5M
            .build())
        .build()))

There's also a top-level .cacheControl(CacheControlEphemeral) on MessageCreateParams.Builder and on Tool.builder().

Verify hits via response.usage().cacheCreationInputTokens() / response.usage().cacheReadInputTokens().


Token Counting

import com.anthropic.models.messages.MessageCountTokensParams;

long tokens = client.messages().countTokens(
    MessageCountTokensParams.builder()
        .model("claude-opus-5-5")
        .addUserMessage("Hello")
        .build()
).inputTokens();

PDF / Document Input

DocumentBlockParam builder has source shortcuts. Wrap in ContentBlockParam.ofDocument() and pass via .addUserMessageOfBlockParams().

import com.anthropic.models.messages.DocumentBlockParam;
import com.anthropic.models.messages.ContentBlockParam;
import com.anthropic.models.messages.TextBlockParam;

DocumentBlockParam doc = DocumentBlockParam.builder()
    .source(Base64PdfSource.builder().data(base64String).build())
    // or .source(UrlPdfSource.builder().url("https://...").build())
    .title("My Document")        // optional
    .build();

For Files API document references, use the beta path and beta types - see files-api.md: BetaRequestDocumentBlock.builder().source(BetaFileDocumentSource.builder().fileId(id).build()).

.addUserMessageOfBlockParams(List.of(
    ContentBlockParam.ofDocument(doc),
    ContentBlockParam.ofText(TextBlockParam.builder().text("Summarize this").build())))

Stop Details

When stopReason() is "refusal", the response includes structured stopDetails():

response.stopDetails().ifPresent(details -> {
    System.out.println("Category: " + details.category());
    System.out.println("Explanation: " + details.explanation());
});

Refusal fallbacks (Claude Fable 5.1) - opt in by default. Fallbacks are opt-in: without them a refused request simply stops. New claude-fable-5-1 code should include the server-side fallbacks parameter (beta header server-side-fallback-2026-06-01, fallback model claude-opus-4-8, on the beta messages call) by default. The exact Java builder methods (and the client-side middleware for providers without server-side support) are not documented here - WebFetch the Java SDK repo's examples/ from shared/live-sources.md; full semantics in shared/model-migration.md -> Migrating to Claude Fable 5.1 -> refusal stop reason.


Error Type

AnthropicServiceException exposes .errorType() returning Optional<ErrorType> for programmatic error classification:

try {
    client.messages().create(params);
} catch (AnthropicServiceException e) {
    e.errorType().ifPresent(type ->
        System.out.println("Error type: " + type)  // RATE_LIMIT_ERROR, OVERLOADED_ERROR, etc.
    );
}