The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.
from line 39
3939* **Messages API**: Opt in with `cache_control`, at the top level or on blocks.
4040* **Managed Agents**: Always on. Cache entries use a 5-minute lifetime by default, and cache reads and writes show up in the session’s usage.
4141
42Prompt caching optimizes your API usage by allowing resuming from specific prefixes in your prompts. This significantly reduces processing time and costs for repetitive tasks or prompts with consistent elements.
42Prompt caching optimizes your API usage by letting the API resume from specific prefixes in your prompts. This significantly reduces processing time and costs for repetitive tasks or prompts with consistent elements.
4343
4444There are two ways to enable prompt caching:
4545
from line 162
162162 ```java Java
163163 import com.anthropic.models.messages.CacheControlEphemeral;
164164 // ...
165 public class PromptCachingExample {
166
167 public static void main(String[] args) {
168 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
169
170 MessageCreateParams params = MessageCreateParams.builder()
171 .model(Model.CLAUDE_OPUS_5_5)
172 .maxTokens(1024)
173 .cacheControl(CacheControlEphemeral.builder().build())
174 .system("You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.")
175 .addUserMessage("Analyze the major themes in 'Pride and Prejudice'.")
176 .build();
177
178 Message message = client.messages().create(params);
179 System.out.println(message.usage());
180 }
165 void main() {
166 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
167
168 MessageCreateParams params = MessageCreateParams.builder()
169 .model(Model.CLAUDE_OPUS_5_5)
170 .maxTokens(1024)
171 .cacheControl(CacheControlEphemeral.builder().build())
172 .system("You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.")
173 .addUserMessage("Analyze the major themes in 'Pride and Prejudice'.")
174 .build();
175
176 Message message = client.messages().create(params);
177 IO.println(message.usage());
181178 }
182179 ```
183180
from line 203
206203 model: Anthropic::Model::CLAUDE_OPUS_5_5,
207204 max_tokens: 1024,
208205 cache_control: {type: "ephemeral"},
209 system: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.",
206 system_: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.",
210207 messages: [
211208 {
212209 role: "user",
from line 254
257254
258255## Pricing
259256
260Prompt caching introduces a new pricing structure. The following table shows the price per million tokens for each supported model:
257Prompt caching has its own pricing. The following table shows the price per million tokens for each supported model:
261258
262259| Model | Base input tokens | 5m cache writes | 1h cache writes | Cache hits and refreshes | Output tokens |
263260| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------- | :-------------- | :-------------- | :----------------------- | :------------ |
from line 278
281278| Claude Haiku 5.5 (for prompts up to 100,000 tokens) | $0.10 / MTok | $0.125 / MTok | $0.20 / MTok | $0.01 / MTok | $0.50 / MTok |
282279| Claude Haiku 5.5 (for prompts over 100,000 tokens) | $0.50 / MTok | $0.625 / MTok | $1 / MTok | $0.05 / MTok | $2.50 / MTok |
283280| Claude Haiku 4.5 | $1 / MTok | $1.25 / MTok | $2 / MTok | $0.10 / MTok | $5 / MTok |
284| Claude Haiku 3.5 ([retired, except on Claude Models on Google Cloud (Google managed)](https://platform.claude.com/docs/en/about-claude/model-deprecations)) | $0.80 / MTok | $1 / MTok | $1.60 / MTok | $0.08 / MTok | $4 / MTok |
285281
286282*<sup>1 Cache hits and refreshes on Claude Fable 5.1 and Claude Mythos 5.1 are priced at 0.025x the base input price.</sup>*
287283
from line 292
296292 * Cache write tokens with a 1-hour TTL are 2 times the base input tokens price.
297293 * Cache read tokens are 0.1 times the base input tokens price (see the table footnote for per-model exceptions).
298294
299 These multipliers stack with other pricing modifiers such as the Batch API discount, [long context pricing](https://platform.claude.com/docs/en/about-claude/pricing#long-context-pricing), and data residency. On a model priced by prompt length, cache reads and cache writes count toward a request’s prompt length. See [Claude pricing](https://platform.claude.com/docs/en/about-claude/pricing) for full details.
295 These multipliers stack with other pricing modifiers such as the Batch API discount, [long context pricing](https://platform.claude.com/docs/en/about-claude/pricing#long-context-pricing), and data residency. On a model priced by prompt length, cache reads and cache writes count toward a request’s prompt length. See [Pricing](https://platform.claude.com/docs/en/about-claude/pricing) for full details.
300296</Note>
301297
302298***
from line 432
436432 ```java Java
437433 import com.anthropic.models.messages.CacheControlEphemeral;
438434 // ...
439 public class AutomaticCachingExample {
440
441 public static void main(String[] args) {
442 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
443
444 MessageCreateParams params = MessageCreateParams.builder()
445 .model(Model.CLAUDE_OPUS_5_5)
446 .maxTokens(1024)
447 .cacheControl(CacheControlEphemeral.builder().build())
448 .system("You are a helpful assistant that remembers our conversation.")
449 .addUserMessage("My name is Alex. I work on machine learning.")
450 .addAssistantMessage("Nice to meet you, Alex! How can I help with your ML work today?")
451 .addUserMessage("What did I say I work on?")
452 .build();
453
454 Message message = client.messages().create(params);
455 System.out.println(message.usage());
456 }
435 void main() {
436 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
437
438 MessageCreateParams params = MessageCreateParams.builder()
439 .model(Model.CLAUDE_OPUS_5_5)
440 .maxTokens(1024)
441 .cacheControl(CacheControlEphemeral.builder().build())
442 .system("You are a helpful assistant that remembers our conversation.")
443 .addUserMessage("My name is Alex. I work on machine learning.")
444 .addAssistantMessage("Nice to meet you, Alex! How can I help with your ML work today?")
445 .addUserMessage("What did I say I work on?")
446 .build();
447
448 Message message = client.messages().create(params);
449 IO.println(message.usage());
457450 }
458451 ```
459452
from line 477
484477 model: Anthropic::Model::CLAUDE_OPUS_5_5,
485478 max_tokens: 1024,
486479 cache_control: {type: "ephemeral"},
487 system: "You are a helpful assistant that remembers our conversation.",
480 system_: "You are a helpful assistant that remembers our conversation.",
488481 messages: [
489482 {role: "user", content: "My name is Alex. I work on machine learning."},
490483 {role: "assistant", content: "Nice to meet you, Alex! How can I help with your ML work today?"},
from line 604
611604
612605**Cache breakpoints themselves don’t add any cost.** You are only charged for:
613606
614* **Cache writes:** When new content is written to the cache (25% more than base input tokens for 5-minute TTL)
615* **Cache reads:** When cached content is used (10% of base input token price, with [per-model exceptions](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing))
607* **Cache writes:** When new content is written to the cache (25 percent more than base input tokens for 5-minute TTL)
608* **Cache reads:** When cached content is used (10 percent of base input token price, with [per-model exceptions](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing))
616609* **Regular input tokens:** For any uncached content
617610
618611Adding more `cache_control` breakpoints doesn’t increase your costs; you still pay the same amount based on what content is actually cached and read. The breakpoints give you control over what sections can be cached independently.
from line 623
630623* 4,096 tokens for Claude Opus 4.6 and Claude Opus 4.5
631624* 1,024 tokens for Claude Opus 4.8, Claude Sonnet 5, Claude Sonnet 4.6, Claude Sonnet 4.5 ([deprecated](https://platform.claude.com/docs/en/about-claude/model-deprecations)), Claude Opus 4.1 ([retired, except on Claude Models on Google Cloud (Google managed) and Bedrock](https://platform.claude.com/docs/en/about-claude/model-deprecations)), Claude Opus 4 ([retired, except on Claude Models on Google Cloud (Google managed)](https://platform.claude.com/docs/en/about-claude/model-deprecations)), and Claude Sonnet 4 ([retired, except on Claude Models on Google Cloud (Google managed) and Bedrock](https://platform.claude.com/docs/en/about-claude/model-deprecations))
632625* 4,096 tokens for Claude Haiku 4.5
633* 2,048 tokens for Claude Haiku 3.5 ([retired, except on Claude Models on Google Cloud (Google managed)](https://platform.claude.com/docs/en/about-claude/model-deprecations))
634626
635627These minimums apply on every platform where each model is available.
636628
from line 686
694686On models that support [mid-conversation tool changes](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages#mid-conversation-tool-changes), the `inline-tools-2026-09-15` beta header lets you add a tool, or change a tool’s definition, partway through a conversation without editing `tools`. Send the definition in a `tool_addition` block in a mid-conversation system message and leave `tools` exactly as you first sent it. The cached prefix still matches, so only the appended message is processed as new input. The one exception is a `tools` array with no non-deferred tool, where the first tool defined this way costs one full cache miss on that request. See [Define tools in a message](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages#define-tools-in-a-message-beta).
695687
696688<Note>
697 On Claude Fable 5.1, [Claude Mythos 5.1](https://platform.claude.com/docs/en/models/mythos-5-1/overview), Claude Fable 5, [Claude Mythos 5](https://platform.claude.com/docs/en/models/mythos-5/overview), Claude Opus 5.5, Claude Opus 4.8, Claude Opus 5, Claude Sonnet 5.5, and Claude Haiku 5.5, you can add a new system instruction partway through a conversation without invalidating the system or message caches. Append a `{"role": "system"}` message to `messages` instead of editing the top-level `system` field, so the cached prefix stays unchanged. This feature is not available on Claude Sonnet 5. Use the top-level `system` field instead. See [Mid-conversation system messages](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages).
689 On Claude Fable 5.1, [Claude Mythos 5.1](https://platform.claude.com/docs/en/models/mythos-5-1/overview), Claude Fable 5, [Claude Mythos 5](https://platform.claude.com/docs/en/models/mythos-5/overview), Claude Opus 5.5, Claude Opus 4.8, Claude Opus 5, Claude Sonnet 5.5, and Claude Haiku 5.5, you can add a new system instruction partway through a conversation without invalidating the system or message caches. Append a `{"role": "system"}` message to `messages` instead of editing the top-level `system` field, so the cached prefix stays unchanged. This feature is not available on Claude Sonnet 5. Use the top-level `system` field instead. See [Mid-conversation system messages and tool changes](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages).
698690</Note>
699691
700692### Tracking cache performance
from line 721
729721 * `input_tokens`: 50
730722 * **Total input tokens processed:** 100,050 tokens
731723
732 This is important for understanding both costs and rate limits, as `input_tokens` will typically be much smaller than your total input when using caching effectively.
724 This is important for understanding both costs and rate limits, as `input_tokens` is typically much smaller than your total input when using caching effectively.
733725</Note>
734726
735727### Caching with thinking blocks
from line 805
813805
814806### Troubleshooting common issues
815807
816If experiencing unexpected behavior:
808If you experience unexpected behavior:
817809
818810<Tip>
819811 [Cache diagnostics](https://platform.claude.com/docs/en/build-with-claude/cache-diagnostics) has the API compare consecutive requests and report where the prompt prefix diverged, which automatically handles many of the steps in this list.
from line 860
868860}
869861```
870862
871Note that the current `cache_creation_input_tokens` field equals the sum of the values in the `cache_creation` object.
863The `cache_creation_input_tokens` field equals the sum of the values in the `cache_creation` object.
872864
873865If you see `ephemeral_5m_input_tokens` writes you didn’t request while using server tools such as web search, see [Server tool results are cached automatically](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-use-with-prompt-caching#server-tool-results-are-cached-automatically).
874866
875867### When to use the 1-hour cache
876868
877If you have prompts that are used at a regular cadence (that is, system prompts that are used more frequently than every 5 minutes), continue to use the 5-minute cache, because this will continue to be refreshed at no additional charge.
869If you use a prompt at a regular cadence (for example, a system prompt that you send more often than every 5 minutes), continue to use the 5-minute cache, because it keeps refreshing at no additional charge.
878870
879871The 1-hour cache is best used in the following scenarios:
880872
881* When you have prompts that are likely used less frequently than every 5 minutes, but more frequently than every hour. For example, when an agentic side-agent will take longer than 5 minutes, or when storing a long chat conversation with a user and you generally expect that user might not respond in the next 5 minutes.
873* When you have prompts that are likely used less frequently than every 5 minutes, but more frequently than every hour. For example, when an agentic side-agent takes longer than 5 minutes, or when storing a long chat conversation with a user and you generally expect that user might not respond in the next 5 minutes.
882874* When latency is important and your follow-up prompts might be sent beyond 5 minutes.
883875* When you want to improve your rate limit utilization, because cache hits are not deducted against your rate limit.
884876
from line 884
892884
893885When mixing TTLs, the Claude API determines three billing locations in your prompt:
894886
8951. Position `A`: The token count at the last cache hit in your prompt (or 0 if no hits). A hit on an entry cached with a 5-minute TTL doesn’t count if a 1-hour `cache_control` block after it is a cache miss.
8871. Position `A`: The token count at the last cache hit in your prompt (or 0 if no hits).
888
889 * A hit on an entry cached with a 5-minute TTL doesn’t count if a 1-hour `cache_control` block after it is a cache miss.
890 * A request that reads an entry cached with a 5-minute TTL restarts its 5-minute lifetime, even if the request now sets `"ttl": "1h"`.
891
8968922. Position `B`: The token count at the last 1-hour `cache_control` block after `A` (or equals `A` if none exist).
893
8978943. Position `C`: The token count at the last `cache_control` block.
898895
899896<Note>
from line 903
9069032. 1-hour cache write tokens for `(B - A)`.
9079043. 5-minute cache write tokens for `(C - B)`.
908905
909Here are three examples. This depicts the input tokens of 3 requests, each of which has different cache hits and cache misses. Each has a different calculated pricing, shown in the colored boxes, as a result.
906Here are three example requests, each with different cache hits and cache misses. Each has a different calculated price, shown in the boxes.
910907
911908<Frame>
912909 
from line 1491
14941491 // Later, when the user submits a message, the system-prompt prefix is already cached.
14951492 $response = $respond('How do I implement a binary search tree?');
14961493 foreach ($response->content as $block) {
1497 if ($block->type === 'text') {
1494 if ($block instanceof \Anthropic\Messages\TextBlock) {
14981495 echo $block->text, PHP_EOL;
14991496 }
15001497 }
from line 1534
15371534 # Later, when the user submits a message, the system-prompt prefix is already cached.
15381535 response = respond(client, "How do I implement a binary search tree?")
15391536 response.content.each do |block|
1540 puts block.text if block.type == :text
1537 puts block.text if block.is_a?(Anthropic::Models::TextBlock)
15411538 end
15421539 ```
15431540</CodeGroup>
from line 1554
15571554
15581555### Replacing the `max_tokens=1` workaround
15591556
1560Before `max_tokens: 0` was available, some applications used `max_tokens: 1` warm-up calls to achieve the same effect. The `max_tokens: 0` approach is preferred: no output is produced, so there is no single-token reply to discard, no output tokens are billed, and the intent of the request is unambiguous.
1557Some applications send `max_tokens: 1` requests to warm the cache. Prefer `max_tokens: 0` where the request allows it: no output is produced, so there is no single-token reply to discard, no output tokens are billed, and the intent of the request is unambiguous.
15611558
15621559***
15631560
from line 1731
17341731 ```java Java
17351732 import com.anthropic.models.messages.CacheControlEphemeral;
17361733 // ...
1737 public class LegalDocumentAnalysisExample {
1738
1739 public static void main(String[] args) {
1740 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
1741
1742 MessageCreateParams params = MessageCreateParams.builder()
1743 .model(Model.CLAUDE_OPUS_5_5)
1744 .maxTokens(1024)
1745 .systemOfTextBlockParams(
1746 List.of(
1747 TextBlockParam.builder()
1748 .text("You are an AI assistant tasked with analyzing legal documents.")
1749 .build(),
1750 TextBlockParam.builder()
1751 .text(
1752 "Here is the full text of a complex legal agreement: [Insert full text of a 50-page legal agreement here]"
1753 )
1754 .cacheControl(CacheControlEphemeral.builder().build())
1755 .build()
1756 )
1734 void main() {
1735 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
1736
1737 MessageCreateParams params = MessageCreateParams.builder()
1738 .model(Model.CLAUDE_OPUS_5_5)
1739 .maxTokens(1024)
1740 .systemOfTextBlockParams(
1741 List.of(
1742 TextBlockParam.builder()
1743 .text("You are an AI assistant tasked with analyzing legal documents.")
1744 .build(),
1745 TextBlockParam.builder()
1746 .text(
1747 "Here is the full text of a complex legal agreement: [Insert full text of a 50-page legal agreement here]"
1748 )
1749 .cacheControl(CacheControlEphemeral.builder().build())
1750 .build()
17571751 )
1758 .addUserMessage("What are the key terms and conditions in this agreement?")
1759 .build();
1760
1761 Message message = client.messages().create(params);
1762 System.out.println(message.usage());
1763 }
1752 )
1753 .addUserMessage("What are the key terms and conditions in this agreement?")
1754 .build();
1755
1756 Message message = client.messages().create(params);
1757 IO.println(message.usage());
17641758 }
17651759 ```
17661760
from line 1790
17961790 client = Anthropic::Client.new
17971791
17981792 message = client.messages.create(
1799 model: "claude-opus-5-5",
1793 model: Anthropic::Model::CLAUDE_OPUS_5_5,
18001794 max_tokens: 1024,
1801 system: [
1795 system_: [
18021796 {
18031797 type: "text",
18041798 text: "You are an AI assistant tasked with analyzing legal documents."
from line 2121
21272121 ```java Java
21282122 import com.anthropic.models.messages.CacheControlEphemeral;
21292123 // ...
2130 public class ConversationWithCacheControlExample {
2131
2132 public static void main(String[] args) {
2133 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
2134
2135 // Create ephemeral system prompt
2136 TextBlockParam systemPrompt = TextBlockParam.builder()
2137 .text("...long system prompt")
2138 .cacheControl(CacheControlEphemeral.builder().build())
2139 .build();
2140
2141 // Create message params
2142 MessageCreateParams params = MessageCreateParams.builder()
2143 .model(Model.CLAUDE_OPUS_5_5)
2144 .maxTokens(1024)
2145 .systemOfTextBlockParams(List.of(systemPrompt))
2146 // First user message (without cache control)
2147 .addUserMessage("Hello, can you tell me more about the solar system?")
2148 // Assistant response
2149 .addAssistantMessage(
2150 "Certainly! The solar system is the collection of celestial bodies that orbit our Sun. It consists of eight planets, numerous moons, asteroids, comets, and other objects. The planets, in order from closest to farthest from the Sun, are: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune. Each planet has its own unique characteristics and features. Is there a specific aspect of the solar system you would like to know more about?"
2151 )
2152 // Second user message (with cache control)
2153 .addUserMessageOfContentBlockParams(
2154 List.of(
2155 ContentBlockParam.ofText(TextBlockParam.builder()
2156 .text("Good to know.")
2157 .build()),
2158 ContentBlockParam.ofText(
2159 TextBlockParam.builder()
2160 .text("Tell me more about Mars.")
2161 .cacheControl(CacheControlEphemeral.builder().build())
2162 .build()
2163 )
2124 void main() {
2125 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
2126
2127 // Create ephemeral system prompt
2128 TextBlockParam systemPrompt = TextBlockParam.builder()
2129 .text("...long system prompt")
2130 .cacheControl(CacheControlEphemeral.builder().build())
2131 .build();
2132
2133 // Create message params
2134 MessageCreateParams params = MessageCreateParams.builder()
2135 .model(Model.CLAUDE_OPUS_5_5)
2136 .maxTokens(1024)
2137 .systemOfTextBlockParams(List.of(systemPrompt))
2138 // First user message (without cache control)
2139 .addUserMessage("Hello, can you tell me more about the solar system?")
2140 // Assistant response
2141 .addAssistantMessage(
2142 "Certainly! The solar system is the collection of celestial bodies that orbit our Sun. It consists of eight planets, numerous moons, asteroids, comets, and other objects. The planets, in order from closest to farthest from the Sun, are: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune. Each planet has its own unique characteristics and features. Is there a specific aspect of the solar system you would like to know more about?"
2143 )
2144 // Second user message (with cache control)
2145 .addUserMessageOfContentBlockParams(
2146 List.of(
2147 ContentBlockParam.ofText(TextBlockParam.builder()
2148 .text("Good to know.")
2149 .build()),
2150 ContentBlockParam.ofText(
2151 TextBlockParam.builder()
2152 .text("Tell me more about Mars.")
2153 .cacheControl(CacheControlEphemeral.builder().build())
2154 .build()
21642155 )
21652156 )
2166 .build();
2167
2168 Message message = client.messages().create(params);
2169 System.out.println(message.usage());
2170 }
2157 )
2158 .build();
2159
2160 Message message = client.messages().create(params);
2161 IO.println(message.usage());
21712162 }
21722163 ```
21732164
from line 2210
22192210 client = Anthropic::Client.new
22202211
22212212 message = client.messages.create(
2222 model: "claude-opus-5-5",
2213 model: Anthropic::Model::CLAUDE_OPUS_5_5,
22232214 max_tokens: 1024,
2224 system: [
2215 system_: [
22252216 {
22262217 type: "text",
22272218 text: "...long system prompt",
from line 2252
22612252
22622253 This example demonstrates how to use prompt caching in a multi-turn conversation.
22632254
2264 During each turn, the final block of the final message is marked with `cache_control` so the conversation can be incrementally cached. The system automatically looks up and uses the longest previously cached sequence of blocks for follow-up messages. That is, blocks that were previously marked with a `cache_control` block are later not marked with this, but they will still be considered a cache hit (and also a cache refresh!) if they are hit within 5 minutes.
2265
2266 In addition, note that the `cache_control` parameter is placed on the system message. This is to ensure that if this gets evicted from the cache (after not being used for more than 5 minutes), it will get added back to the cache on the next request.
2255 During each turn, the final block of the final message is marked with `cache_control` so the conversation can be incrementally cached. The system automatically looks up and uses the longest previously cached sequence of blocks for follow-up messages. Blocks that were marked with `cache_control` on an earlier turn aren’t marked again, but a request within 5 minutes still reads them from the cache and refreshes their lifetime.
2256
2257 The `cache_control` parameter is also on the system message. If the system message is evicted from the cache after more than 5 minutes without use, the next request adds it back.
22672258
22682259 This approach is useful for maintaining context in ongoing conversations without repeatedly processing the same information.
22692260
from line 2265
22742265 * `cache_read_input_tokens`: Number of tokens in the conversation up to the previous turn
22752266 </Accordion>
22762267
2277 <Accordion title="Putting it all together: Multiple cache breakpoints">
2268 <Accordion title="Putting it all together: multiple cache breakpoints">
22782269 <CodeGroup>
22792270 ```bash cURL
22802271 curl https://api.anthropic.com/v1/messages \
from line 2825
28342825 ```java Java
28352826 import com.anthropic.models.messages.CacheControlEphemeral;
28362827 // ...
2837 public class MultipleCacheBreakpointsExample {
2838
2839 public static void main(String[] args) {
2840 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
2841
2842 // Search tool schema
2843 InputSchema searchSchema = InputSchema.builder()
2844 .properties(
2845 JsonValue.from(
2846 Map.of("query", Map.of("type", "string", "description", "Search query"))
2847 )
2828 void main() {
2829 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
2830
2831 // Search tool schema
2832 InputSchema searchSchema = InputSchema.builder()
2833 .properties(
2834 JsonValue.from(
2835 Map.of("query", Map.of("type", "string", "description", "Search query"))
28482836 )
2849 .putAdditionalProperty("required", JsonValue.from(List.of("query")))
2850 .build();
2851
2852 // Get document tool schema
2853 InputSchema getDocSchema = InputSchema.builder()
2854 .properties(
2855 JsonValue.from(
2856 Map.of("doc_id", Map.of("type", "string", "description", "Document ID"))
2857 )
2837 )
2838 .putAdditionalProperty("required", JsonValue.from(List.of("query")))
2839 .build();
2840
2841 // Get document tool schema
2842 InputSchema getDocSchema = InputSchema.builder()
2843 .properties(
2844 JsonValue.from(
2845 Map.of("doc_id", Map.of("type", "string", "description", "Document ID"))
28582846 )
2859 .putAdditionalProperty("required", JsonValue.from(List.of("doc_id")))
2860 .build();
2861
2862 MessageCreateParams params = MessageCreateParams.builder()
2863 .model(Model.CLAUDE_OPUS_5_5)
2864 .maxTokens(1024)
2865 // Tools with cache control on the last one
2866 .addTool(
2867 Tool.builder()
2868 .name("search_documents")
2869 .description("Search through the knowledge base")
2870 .inputSchema(searchSchema)
2871 .build()
2872 )
2873 .addTool(
2874 Tool.builder()
2875 .name("get_document")
2876 .description("Retrieve a specific document by ID")
2877 .inputSchema(getDocSchema)
2847 )
2848 .putAdditionalProperty("required", JsonValue.from(List.of("doc_id")))
2849 .build();
2850
2851 MessageCreateParams params = MessageCreateParams.builder()
2852 .model(Model.CLAUDE_OPUS_5_5)
2853 .maxTokens(1024)
2854 // Tools with cache control on the last one
2855 .addTool(
2856 Tool.builder()
2857 .name("search_documents")
2858 .description("Search through the knowledge base")
2859 .inputSchema(searchSchema)
2860 .build()
2861 )
2862 .addTool(
2863 Tool.builder()
2864 .name("get_document")
2865 .description("Retrieve a specific document by ID")
2866 .inputSchema(getDocSchema)
2867 .cacheControl(CacheControlEphemeral.builder().build())
2868 .build()
2869 )
2870 // System prompts with cache control on instructions and context separately
2871 .systemOfTextBlockParams(
2872 List.of(
2873 TextBlockParam.builder()
2874 .text(
2875 "You are a helpful research assistant with access to a document knowledge base.\n\n# Instructions\n- Always search for relevant documents before answering\n- Provide citations for your sources\n- Be objective and accurate in your responses\n- If multiple documents contain relevant information, synthesize them\n- Acknowledge when information is not available in the knowledge base"
2876 )
2877 .cacheControl(CacheControlEphemeral.builder().build())
2878 .build(),
2879 TextBlockParam.builder()
2880 .text(
2881 "# Knowledge Base Context\n\nHere are the relevant documents for this conversation:\n\n## Document 1: Solar System Overview\nThe solar system consists of the Sun and all objects that orbit it...\n\n## Document 2: Planetary Characteristics\nEach planet has unique features. Mercury is the smallest planet...\n\n## Document 3: Mars Exploration\nMars has been a target of exploration for decades...\n\n[Additional documents...]"
2882 )
28782883 .cacheControl(CacheControlEphemeral.builder().build())
28792884 .build()
28802885 )
2881 // System prompts with cache control on instructions and context separately
2882 .systemOfTextBlockParams(
2883 List.of(
2886 )
2887 // Conversation history
2888 .addUserMessage("Can you search for information about Mars rovers?")
2889 .addAssistantMessageOfContentBlockParams(
2890 List.of(
2891 ContentBlockParam.ofToolUse(
2892 ToolUseBlockParam.builder()
2893 .id("tool_1")
2894 .name("search_documents")
2895 .input(JsonValue.from(Map.of("query", "Mars rovers")))
2896 .build()
2897 )
2898 )
2899 )
2900 .addUserMessageOfContentBlockParams(
2901 List.of(
2902 ContentBlockParam.ofToolResult(
2903 ToolResultBlockParam.builder()
2904 .toolUseId("tool_1")
2905 .content(
2906 "Found 3 relevant documents: Document 3 (Mars Exploration), Document 7 (Rover Technology), Document 9 (Mission History)"
2907 )
2908 .build()
2909 )
2910 )
2911 )
2912 .addAssistantMessageOfContentBlockParams(
2913 List.of(
2914 ContentBlockParam.ofText(
28842915 TextBlockParam.builder()
28852916 .text(
2886 "You are a helpful research assistant with access to a document knowledge base.\n\n# Instructions\n- Always search for relevant documents before answering\n- Provide citations for your sources\n- Be objective and accurate in your responses\n- If multiple documents contain relevant information, synthesize them\n- Acknowledge when information is not available in the knowledge base"
2917 "I found 3 relevant documents about Mars rovers. Let me get more details from the Mars Exploration document."
28872918 )
2888 .cacheControl(CacheControlEphemeral.builder().build())
2889 .build(),
2919 .build()
2920 )
2921 )
2922 )
2923 .addUserMessageOfContentBlockParams(
2924 List.of(
2925 ContentBlockParam.ofText(
28902926 TextBlockParam.builder()
2891 .text(
2892 "# Knowledge Base Context\n\nHere are the relevant documents for this conversation:\n\n## Document 1: Solar System Overview\nThe solar system consists of the Sun and all objects that orbit it...\n\n## Document 2: Planetary Characteristics\nEach planet has unique features. Mercury is the smallest planet...\n\n## Document 3: Mars Exploration\nMars has been a target of exploration for decades...\n\n[Additional documents...]"
2893 )
2927 .text("Yes, please tell me about the Perseverance rover specifically.")
28942928 .cacheControl(CacheControlEphemeral.builder().build())
28952929 .build()
28962930 )
28972931 )
2898 // Conversation history
2899 .addUserMessage("Can you search for information about Mars rovers?")
2900 .addAssistantMessageOfContentBlockParams(
2901 List.of(
2902 ContentBlockParam.ofToolUse(
2903 ToolUseBlockParam.builder()
2904 .id("tool_1")
2905 .name("search_documents")
2906 .input(JsonValue.from(Map.of("query", "Mars rovers")))
2907 .build()
2908 )
2909 )
2910 )
2911 .addUserMessageOfContentBlockParams(
2912 List.of(
2913 ContentBlockParam.ofToolResult(
2914 ToolResultBlockParam.builder()
2915 .toolUseId("tool_1")
2916 .content(
2917 "Found 3 relevant documents: Document 3 (Mars Exploration), Document 7 (Rover Technology), Document 9 (Mission History)"
2918 )
2919 .build()
2920 )
2921 )
2922 )
2923 .addAssistantMessageOfContentBlockParams(
2924 List.of(
2925 ContentBlockParam.ofText(
2926 TextBlockParam.builder()
2927 .text(
2928 "I found 3 relevant documents about Mars rovers. Let me get more details from the Mars Exploration document."
2929 )
2930 .build()
2931 )
2932 )
2933 )
2934 .addUserMessageOfContentBlockParams(
2935 List.of(
2936 ContentBlockParam.ofText(
2937 TextBlockParam.builder()
2938 .text("Yes, please tell me about the Perseverance rover specifically.")
2939 .cacheControl(CacheControlEphemeral.builder().build())
2940 .build()
2941 )
2942 )
2943 )
2944 .build();
2945
2946 Message message = client.messages().create(params);
2947 System.out.println(message.usage());
2948 }
2932 )
2933 .build();
2934
2935 Message message = client.messages().create(params);
2936 IO.println(message.usage());
29492937 }
29502938 ```
29512939
from line 3041
30533041 client = Anthropic::Client.new
30543042
30553043 message = client.messages.create(
3056 model: "claude-opus-5-5",
3044 model: Anthropic::Model::CLAUDE_OPUS_5_5,
30573045 max_tokens: 1024,
30583046 tools: [
30593047 {
from line 3074
30863074 cache_control: { type: "ephemeral" }
30873075 }
30883076 ],
3089 system: [
3077 system_: [
30903078 {
30913079 type: "text",
30923080 text: "You are a helpful research assistant with access to a document knowledge base.\n\n# Instructions\n- Always search for relevant documents before answering\n- Provide citations for your sources\n- Be objective and accurate in your responses\n- If multiple documents contain relevant information, synthesize them\n- Acknowledge when information is not available in the knowledge base",
from line 3202
32143202 No, cache breakpoints themselves are free. You only pay for:
32153203
32163204 * Writing content to cache (25 percent more than base input tokens for 5-minute TTL)
3217 * Reading from cache (a fraction of the base input token price, see [Pricing](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing))
3205 * Reading from cache ([a fraction of the base input token price](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing))
32183206 * Regular input tokens for uncached content
32193207
32203208 The number of breakpoints doesn’t affect pricing; only the amount of content cached and read matters.
from line 3219
32313219 * `cache_creation_input_tokens`: New tokens being written to cache (at cache breakpoints)
32323220 * `input_tokens`: Tokens **after the last cache breakpoint** that aren’t cached
32333221
3234 **Important:** `input_tokens` does NOT represent all input tokens, only the portion after your last cache breakpoint. If you have cached content, `input_tokens` will typically be much smaller than your total input.
3235
3236 **Example:** With a 200k token document cached and a 50 token user question:
3222 **Important:** `input_tokens` does NOT represent all input tokens, only the portion after your last cache breakpoint. If you have cached content, `input_tokens` is typically much smaller than your total input.
3223
3224 **Example:** With a 200k-token document cached and a 50-token user question:
32373225
32383226 * `cache_read_input_tokens`: 200,000
32393227 * `cache_creation_input_tokens`: 0
from line 3270
32823270 </Accordion>
32833271
32843272 <Accordion title="How does prompt caching affect pricing?">
3285 Prompt caching introduces a new pricing structure where 5-minute cache writes cost 25 percent more than base input tokens, 1-hour cache writes cost 2x base input tokens, and cache hits cost a fraction of the base input token price (see [Pricing](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing) for the per-model multiplier).
3273 Prompt caching has its own pricing: 5-minute cache writes cost 25 percent more than base input tokens, 1-hour cache writes cost 2x base input tokens, and cache hits cost [a fraction of the base input token price](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing), with a multiplier for each model.
32863274 </Accordion>
32873275
32883276 <Accordion title="Can I manually clear the cache?">
from line 3299
33113299 These measures ensure that prompt caching maintains data privacy and security while offering performance benefits.
33123300 </Accordion>
33133301
3314 <Accordion title="Can I use prompt caching with the Batches API?">
3315 Yes, it is possible to use prompt caching with your [Batches API](https://platform.claude.com/docs/en/build-with-claude/batch-processing) requests. However, because asynchronous batch requests can be processed concurrently and in any order, cache hits are provided on a best-effort basis.
3302 <Accordion title="Can I use prompt caching with the Message Batches API?">
3303 Yes, you can use prompt caching with your [Message Batches API](https://platform.claude.com/docs/en/build-with-claude/batch-processing) requests. However, because asynchronous batch requests can be processed concurrently and in any order, cache hits are provided on a best-effort basis.
33163304
33173305 The [1-hour cache](https://platform.claude.com/docs/en/build-with-claude/prompt-caching#1-hour-cache-duration) can help improve your cache hits. The most cost-effective way of using it is the following:
33183306
from line 3312
33243312 </Accordion>
33253313
33263314 <Accordion title="Why am I seeing the error `AttributeError: 'Beta' object has no attribute 'prompt_caching'` in Python?">
3327 This error typically appears when you have upgraded your SDK or you are using outdated code examples. Prompt caching no longer requires the beta prefix. Instead of:
3315 This error typically appears when you have upgraded your SDK or you are using outdated code examples. Prompt caching is available on `client.messages`, without the beta prefix. Instead of:
33283316
33293317 <CodeGroup exclude="shell:cURL, shell:CLI, typescript, csharp, go, java, php, ruby">
33303318 ```python Python
from line 3330
33423330 </Accordion>
33433331
33443332 <Accordion title="Why am I seeing ‘TypeError: Cannot read properties of undefined (reading ‘messages’)’?">
3345 This error typically appears when you have upgraded your SDK or you are using outdated code examples. Prompt caching no longer requires the beta prefix. Instead of:
3333 This error typically appears when you have upgraded your SDK or you are using outdated code examples. Prompt caching is available on `client.messages`, without the beta prefix. Instead of:
33463334
33473335 ```typescript TypeScript
33483336 client.beta.promptCaching.messages.create(/* ... */);
33493337