Sweep 22 Sep 2026 · 17:19Z Build v2.1.280 501 read Stable v2.1.267 Latest v2.1.280 Next v2.1.280 Feeds RSS JSON llms.txt Unofficial
One capture · api

One read of Claude Developer Platform

8 pages moved out of 634 read.

api-20260922T040718Z

Pages moved 8 significant first
Pages read 634 in this capture
Captured 04:07 UTC
Corpus hash 8e5301b854f1 corpus-hash

What this read moved

1–8 of 8

about-claude/models/optimizing-for-cost-and-intelligence Changed · +11 / -11 lines

from line 30
3030| You are choosing or switching models | Compare on cost per completed task, not per token | [Compare models](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#compare-models-on-cost-per-task) |
3131| Quality isn't good enough | If you lowered effort, restore it; otherwise try the next tier up at `low` effort | [Tune effort](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#tune-effort) · [Compare models](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#compare-models-on-cost-per-task) |
3232| Attempts end with `stop_reason: max_tokens` | Raise `max_tokens`; 64,000 covered all but 2 of 14,000 turns measured at the default effort, and 128,000 cost nothing extra per solved task | [Set budgets](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) |
33| You can check outputs (tests, a verifier) | Run everything at low effort and re-run failures at the default (`high`); on the coding benchmark measured, the pass rate held at about half the cost | [Re-run failures](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#re-run-failures-at-higher-effort) |
33| You can check outputs (tests, a verifier) | Run everything at low effort and re-run failures at `high`; on the coding benchmark measured, the pass rate held at about half the cost | [Re-run failures](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#re-run-failures-at-higher-effort) |
3434| Agent loops with a few very costly runs | Set a task budget (beta; check the support table for which models), a Claude Managed Agents session budget, and a workspace spend limit | [Set budgets](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#set-budgets-and-output-caps) |
3535| A lower-cost model stalls only on hard decisions | Add a frontier advisor. It pays off when priced well above the executor and actually consulted, so first price the advisor's model alone at low effort and measure the consult rate | [Advisor strategy](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#advisor-strategy-escalate-hard-decisions) |
3636| The work exceeds one context window | Delegate partitions to cheaper workers | [Orchestrator strategy](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#orchestrator-strategy-delegate-bulk-work) |
from line 269
269269 
270270![Two charts of cost per solved task against tasks solved: on SWE-bench Pro every model solves most tasks and the upgrade steps are small; on Terminal-Bench 3 the Opus ladder falls from $183 to $63 to $28 per solved task](https://platform.claude.com/docs/images/cost-intel-upgrade-ladder.png)
271271 
272Anthropic prices the Opus line identically per token across versions, so any difference comes from how much work each model does per task: priced as a customer is billed, Claude Opus 4.8 solves the same share of tasks as Claude Opus 4.7 for 14% less per solved task, and Claude Opus 5 then solves 12 more points of tasks at 21% more per solved task. Claude Opus 5 at `low` effort beats Opus 4.8's default on this benchmark for about 30% of its cost per solved task, so the cheapest upgrade is the new model at a lower setting. Sonnet 5's saving comes from its lower per-token price, which more than offsets the extra tokens it uses per task compared with Sonnet 4.6: 15% less per solved task for 5 more points. The frontier tier gained the same way: Claude Fable 5.1 matches Claude Fable 5's score for 43% less per solved task, most of it the lower cache-read price. That direction is not guaranteed: on DeepResearch Bench II[7](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#refs) the same upgrade costs 41% more per task at `high` (79% more at `low`) for its 2 to 3 extra points on the tasks clean in every arm (reference 7), because the new model does more work per task there. The input and output prices are the same and the cache read is 4x cheaper, so measure the upgrade on your own workload before assuming it saves.
272Anthropic prices Claude Opus 4.7, Opus 4.8, and Opus 5 identically per token, so any difference among them comes from how much work each model does per task: priced as a customer is billed, Claude Opus 4.8 solves the same share of tasks as Claude Opus 4.7 for 14% less per solved task, and Claude Opus 5 then solves 12 more points of tasks at 21% more per solved task. Claude Opus 5 at `low` effort beats Opus 4.8's default on this benchmark for about 30% of its cost per solved task, so the cheapest upgrade is the new model at a lower setting. Sonnet 5's saving comes from its lower per-token price, which more than offsets the extra tokens it uses per task compared with Sonnet 4.6: 15% less per solved task for 5 more points. The frontier tier gained the same way: Claude Fable 5.1 matches Claude Fable 5's score for 43% less per solved task, most of it the lower cache-read price. That direction is not guaranteed: on DeepResearch Bench II[7](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#refs) the same upgrade costs 41% more per task at `high` (79% more at `low`) for its 2 to 3 extra points on the tasks clean in every arm (reference 7), because the new model does more work per task there. The input and output prices are the same and the cache read is 4x cheaper, so measure the upgrade on your own workload before assuming it saves.
273273 
274274On harder work the gap widens. On Terminal-Bench 3[20](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence#refs), where the tasks are hard enough that pass rate rather than tokens sets the bill, Claude Opus 4.7, Opus 4.8, and Opus 5 each spend $8 to $15 per task but solve 7%, 15%, and 41% of tasks, so cost per solved task falls from $183 to $63 to $28 up the ladder. The 21% premium Claude Opus 5 carries over Opus 4.8 on the saturated coding subset becomes a 56% saving on Terminal-Bench 3, where the older model mostly fails: the more your workload defeats the old model, the more the upgrade saves per result.
275275 
from line 461
461461 ```bash cURL
462462 # Per-million-token prices from the pricing page; change these three for another model.
463463 INPUT_PER_MTOK=5.00 # Claude Opus 5
464 CACHE_READ_PER_MTOK=0.50 # 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
464 CACHE_READ_PER_MTOK=0.50 # 0.1x the input price on Claude Opus 5; some models use a different multiplier
465465 OUTPUT_PER_MTOK=25.00
466466 
467467 response=$(curl --fail-with-body -sS https://api.anthropic.com/v1/messages \
from line 488
488488 ```bash CLI
489489 # Per-million-token prices from the pricing page; change these three for another model.
490490 INPUT_PER_MTOK=5.00 # Claude Opus 5
491 CACHE_READ_PER_MTOK=0.50 # 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
491 CACHE_READ_PER_MTOK=0.50 # 0.1x the input price on Claude Opus 5; some models use a different multiplier
492492 OUTPUT_PER_MTOK=25.00
493493 
494494 USAGE=$(ant messages create \
from line 510
510510 ```python Python
511511 # Per-million-token prices from the pricing page; change these three for another model.
512512 INPUT_PER_MTOK = 5.00 # Claude Opus 5
513 # 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
513 # 0.1x the input price on Claude Opus 5; some models use a different multiplier
514514 CACHE_READ_PER_MTOK = 0.50
515515 OUTPUT_PER_MTOK = 25.00
516516 
from line 538
538538 ```typescript TypeScript
539539 // Per-million-token prices from the pricing page; change these three for another model.
540540 const INPUT_PER_MTOK = 5.0; // Claude Opus 5
541 const CACHE_READ_PER_MTOK = 0.5; // 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
541 const CACHE_READ_PER_MTOK = 0.5; // 0.1x the input price on Claude Opus 5; some models use a different multiplier
542542 const OUTPUT_PER_MTOK = 25.0;
543543 
544544 const client = new Anthropic();
from line 561
561561 ```csharp C#
562562 // Per-million-token prices from the pricing page; change these three for another model.
563563 const double InputPerMtok = 5.00; // Claude Opus 5
564 const double CacheReadPerMtok = 0.50; // 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
564 const double CacheReadPerMtok = 0.50; // 0.1x the input price on Claude Opus 5; some models use a different multiplier
565565 const double OutputPerMtok = 25.00;
566566 
567567 AnthropicClient client = new();
from line 589
589589 // Per-million-token prices from the pricing page; change these three for another model.
590590 const (
591591 inputPerMTok = 5.00 // Claude Opus 5
592 cacheReadPerMTok = 0.50 // 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
592 cacheReadPerMTok = 0.50 // 0.1x the input price on Claude Opus 5; some models use a different multiplier
593593 outputPerMTok = 25.00
594594 )
595595 
from line 619
619619 ```java Java
620620 // Per-million-token prices from the pricing page; change these three for another model.
621621 static final double INPUT_PER_MTOK = 5.00; // Claude Opus 5
622 static final double CACHE_READ_PER_MTOK = 0.50; // 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
622 static final double CACHE_READ_PER_MTOK = 0.50; // 0.1x the input price on Claude Opus 5; some models use a different multiplier
623623 static final double OUTPUT_PER_MTOK = 25.00;
624624 
625625 void main() {
from line 646
646646 ```php PHP
647647 // Per-million-token prices from the pricing page; change these three for another model.
648648 const INPUT_PER_MTOK = 5.00; // Claude Opus 5
649 const CACHE_READ_PER_MTOK = 0.50; // 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
649 const CACHE_READ_PER_MTOK = 0.50; // 0.1x the input price on Claude Opus 5; some models use a different multiplier
650650 const OUTPUT_PER_MTOK = 25.00;
651651 
652652 $client = new Client();
from line 669
669669 ```ruby Ruby
670670 # Per-million-token prices from the pricing page; change these three for another model.
671671 INPUT_PER_MTOK = 5.00 # Claude Opus 5
672 CACHE_READ_PER_MTOK = 0.50 # 0.1x the input price; 0.025x on Claude Fable 5.1 and Claude Mythos 5.1
672 CACHE_READ_PER_MTOK = 0.50 # 0.1x the input price on Claude Opus 5; some models use a different multiplier
673673 OUTPUT_PER_MTOK = 25.00
674674 
675675 client = Anthropic::Client.new

build-with-claude/preserved-thinking Changed · +428 / -9 lines

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 26
2626* [Drops some `thinking` blocks and keeps later ones](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned), or removes them and [later puts them back](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#prefix-check)
2727* [Rebuilds a saved session from templates](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#faq) instead of replaying what it sent
2828 
29On an older account, none of these produces an error unless the request sets `prefix_mismatch_behavior`, so a run with no errors on your own key doesn't show whether your code is affected. If people run your tool with their own API keys, those on newer accounts get the 400 error before you do. [Set `prefix_mismatch_behavior` in your tests](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#how-to-tell-whether-your-integration-is-impacted) to see what they see.
29On an older account, none of these produces an error unless the request sets `prefix_mismatch_behavior`, so a run with no errors on your own key doesn't show whether your code is affected. If people run your tool with their own API keys, those on newer accounts get the 400 error before you do. To see what they see without changing how your requests behave, send the `thinking-binding-controls-2026-08-01` beta header. On an older account, each response then flags blocks that fail the check, and the model still reads them (see [Set the mismatch behavior and read `input_transformations`](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#preserved-thinking-controls)).
3030 
3131## Switching models mid-conversation
3232 
from line 78
7878* **`"error"` (the default):** the API rejects the request with a 400 `invalid_request_error` that names the first failing block.
7979* **`"drop_block"`:** the API drops each failing block and every thinking block after it, and the request succeeds. Dropped blocks aren't billed. The model answers that turn without using reasoning from dropped blocks, and the prompt cache restarts at the edit. The response lists each dropped block in `input_transformations` (on the `message_start` event when streaming) with `reason: "prefix_binding_mismatch"`.
8080 
81`"drop_block"` keeps requests succeeding but doesn't fix the edit. Count the responses in each session whose `input_transformations` has a `prefix_binding_mismatch` entry, and alert on them. In the Message Batches API, an item that leaves the field unset drops failing blocks instead of erroring, so set `"error"` explicitly there if you want batch items to fail.
81`"drop_block"` keeps requests succeeding but doesn't fix the edit. Count the responses in each session whose `input_transformations` has a `prefix_binding_mismatch` entry, and alert on them. In the Message Batches API, an item that leaves the field unset doesn't fail. Where the API enforces the check by default, it drops the failing blocks instead. Set `"error"` explicitly there if you want batch items to fail.
8282 
8383Both the field and the `input_transformations` array require the `thinking-binding-controls-2026-08-01` [beta header](https://platform.claude.com/docs/en/api/beta-headers). [Set the mismatch behavior and read `input_transformations`](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#preserved-thinking-controls) shows the request in each SDK.
8484 
from line 365
365365Input transformations: 0
366366```
367367 
368Under the beta header, every response from a thinking-capable model carries `input_transformations`. It's empty when nothing was dropped. Each entry has `type: "thinking_dropped"`, the `path` of the dropped block (for example `messages.1.content.0`), and a `reason` of `prefix_binding_mismatch` or `model_binding_mismatch` (see [Switching models mid-conversation](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#switching-models)). Ignore entries whose `type` or `reason` you don't recognize, because later checks add values.
369 
370When [streaming](https://platform.claude.com/docs/en/build-with-claude/streaming), the array arrives on the `message` object in the `message_start` event. After a mid-stream server-side fallback, the final `message_delta` event carries it again with the serving model's entries. In a [message batch](https://platform.claude.com/docs/en/build-with-claude/batch-processing), an item whose block fails the prefix check under an explicit `"error"` resolves as `errored`, and an item that leaves the field unset drops the failing blocks instead. The [token counting](https://platform.claude.com/docs/en/build-with-claude/token-counting) endpoint runs the same prefix check and returns the same 400.
368Under the beta header, every response from a thinking-capable model carries `input_transformations`. Each entry names one thinking block by its `path` (for example `messages.1.content.0`) and gives a `reason`. There are two entry types:
369 
370* **`thinking_dropped`:** the API drops the block before the model reads it, and the block isn't billed. The `reason` is `prefix_binding_mismatch` or `model_binding_mismatch` (see [Switching models mid-conversation](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#switching-models)).
371* **`thinking_mismatch_allowed`:** the block fails the prefix check, but the API doesn't enforce that check for this request, so the block reaches the model unchanged and is billed. The `reason` is always `prefix_binding_mismatch`. This entry appears only on requests where the API doesn't enforce the check by default, such as those from an older account (see [When the API enforces the check](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#enforcement)). Setting `prefix_mismatch_behavior` to either value opts the request into enforcement, so a request that sets it never gets this entry.
372 
373The array is empty when no block was dropped and none failed the prefix check. Ignore entries whose `type` or `reason` you don't recognize, because later checks add values.
374 
375When [streaming](https://platform.claude.com/docs/en/build-with-claude/streaming), the array arrives on the `message` object in the `message_start` event. After a mid-stream server-side fallback, the final `message_delta` event carries it again with the serving model's entries. In a [message batch](https://platform.claude.com/docs/en/build-with-claude/batch-processing), an item whose block fails the prefix check under an explicit `"error"` resolves as `errored`. An item that leaves the field unset doesn't fail. Where the API enforces the check by default, it drops the failing blocks instead. The [token counting](https://platform.claude.com/docs/en/build-with-claude/token-counting) endpoint runs the same prefix check and returns the same 400.
371376 
372377### When the API enforces the check
373378 
374The prefix check runs on Claude Fable 5.1 for new accounts.
379The API enforces the prefix check on Claude Fable 5.1 for new accounts.
375380 
376381* **Accounts created on or after August 31, 2026, 00:00 UTC:** the API checks Claude Fable 5.1 requests and applies `"error"` unless you set `"drop_block"`. The same definition of a new account applies to the Claude API and to cloud platforms.
377* **Older accounts:** the API checks requests that set `prefix_mismatch_behavior`. This parameter opts a request in, so you can see what a new account sees without creating one.
382* **Older accounts:** the API enforces the check only on requests that set `prefix_mismatch_behavior`. Setting the field opts a request in, so you can see what a new account sees without creating one. On requests that leave it unset, the API still runs the check but lets failing blocks through to the model. With the beta header, the response lists each one in `input_transformations` as `thinking_mismatch_allowed`, so you can find prefix edits without changing what the model receives.
378383* **Later models:** every account, on every request.
379384 
380To find out which group your account is in, take a Claude Fable 5.1 conversation that contains a thinking block, change something before that block, and send it to Claude Fable 5.1 without the beta header or the `block_binding` field. A 400 response that names the header means your account is enforced by default.
385To find out which group your account is in, take a Claude Fable 5.1 conversation that contains a thinking block, change something before that block, and send it to Claude Fable 5.1 without the beta header or the `block_binding` field. A 400 response that names the header means your account is enforced by default. A 200 response means it isn't. To confirm, send the same request again with the beta header, still without `block_binding`: the response lists every thinking block after your edit in `input_transformations` as `thinking_mismatch_allowed`.
381386 
382387### What counts as an edit
383388 
from line 785
780785* A long tool loop, if you add reminders or shorten old tool results
781786* A switch to another model and back
782787* A save, a restart, and a resume on a later date
788 
789On an older account, you can also watch production traffic without opting into enforcement: send the beta header, leave `block_binding` out, and log `input_transformations`. Sending the header alone doesn't change what the model receives. Every thinking block that comes after the content you edited fails the check and gets its own `thinking_mismatch_allowed` entry, with the same `path` and `reason` fields as a `thinking_dropped` entry. Blocks before the edit still pass. An edit to `system` or `tools` comes before every block, so it fails every thinking block in the request. One entry looks like this:
790 
791```json
792{
793 "input_transformations": [
794 {
795 "type": "thinking_mismatch_allowed",
796 "path": "messages.1.content.0",
797 "reason": "prefix_binding_mismatch"
798 }
799 ]
800}
801```
802 
803Run the following example from an [older account](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#enforcement), because a newer account rejects its third request with the 400. It sends the header without `block_binding` and extends the earlier session with a third request that adds a system prompt, which changes the prefix on purpose. After each turn it prints the number of `thinking` blocks and flagged blocks:
804 
805<CodeGroup>
806 ```bash cURL
807 # Counts the thinking blocks in a response and the blocks that failed the prefix check
808 COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
809 "flagged: \([.input_transformations[] |
810 select(.type == "thinking_mismatch_allowed")] | length)"'
811 
812 FIRST=$(curl -s https://api.anthropic.com/v1/messages \
813 -H "content-type: application/json" \
814 -H "x-api-key: $ANTHROPIC_API_KEY" \
815 -H "anthropic-version: 2023-06-01" \
816 -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
817 -d '{
818 "model": "claude-fable-5-1",
819 "max_tokens": 16000,
820 "thinking": { "type": "adaptive" },
821 "messages": [
822 {
823 "role": "user",
824 "content": "How many positive integers below 500 have exactly 6 positive divisors?"
825 }
826 ]
827 }')
828 echo "$FIRST" | jq -r "$COUNTS"
829 
830 # Turn 2: the assistant turn goes back exactly as returned, then the next user message
831 MESSAGES=$(jq -n --argjson first "$FIRST" '[
832 {
833 role: "user",
834 content: "How many positive integers below 500 have exactly 6 positive divisors?"
835 },
836 { role: "assistant", content: $first.content },
837 { role: "user", content: "How many of those are odd?" }
838 ]')
839 
840 SECOND=$(jq -n --argjson messages "$MESSAGES" '{
841 model: "claude-fable-5-1",
842 max_tokens: 16000,
843 thinking: { type: "adaptive" },
844 messages: $messages
845 }' | curl -s https://api.anthropic.com/v1/messages \
846 -H "content-type: application/json" \
847 -H "x-api-key: $ANTHROPIC_API_KEY" \
848 -H "anthropic-version: 2023-06-01" \
849 -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
850 -d @-)
851 echo "$SECOND" | jq -r "$COUNTS"
852 
853 # Turn 3: only this request adds a system prompt, which changes the prefix on purpose
854 jq -n --argjson messages "$MESSAGES" --argjson second "$SECOND" '{
855 model: "claude-fable-5-1",
856 max_tokens: 16000,
857 thinking: { type: "adaptive" },
858 system: "Answer briefly.",
859 messages: ($messages + [
860 { role: "assistant", content: $second.content },
861 { role: "user", content: "And how many of the odd ones are below 100?" }
862 ])
863 }' | curl -s https://api.anthropic.com/v1/messages \
864 -H "content-type: application/json" \
865 -H "x-api-key: $ANTHROPIC_API_KEY" \
866 -H "anthropic-version: 2023-06-01" \
867 -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
868 -d @- | jq -r "$COUNTS"
869 ```
870 
871 ```bash CLI
872 # Counts the thinking blocks in a response and the blocks that failed the prefix check
873 COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
874 "flagged: \([.input_transformations[] |
875 select(.type == "thinking_mismatch_allowed")] | length)"'
876 
877 FIRST=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
878 --format json <<'YAML'
879 model: claude-fable-5-1
880 max_tokens: 16000
881 thinking:
882 type: adaptive
883 messages:
884 - role: user
885 content: How many positive integers below 500 have exactly 6 positive divisors?
886 YAML
887 )
888 echo "$FIRST" | jq -r "$COUNTS"
889 
890 # Turn 2: the assistant turn goes back exactly as returned, then the next user message
891 SECOND=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
892 --format json <<YAML
893 model: claude-fable-5-1
894 max_tokens: 16000
895 thinking:
896 type: adaptive
897 messages:
898 - role: user
899 content: How many positive integers below 500 have exactly 6 positive divisors?
900 - role: assistant
901 content: $(echo "$FIRST" | jq -c .content)
902 - role: user
903 content: How many of those are odd?
904 YAML
905 )
906 echo "$SECOND" | jq -r "$COUNTS"
907 
908 # Turn 3: only this request adds a system prompt, which changes the prefix on purpose
909 ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
910 --format json <<YAML | jq -r "$COUNTS"
911 model: claude-fable-5-1
912 max_tokens: 16000
913 thinking:
914 type: adaptive
915 system: Answer briefly.
916 messages:
917 - role: user
918 content: How many positive integers below 500 have exactly 6 positive divisors?
919 - role: assistant
920 content: $(echo "$FIRST" | jq -c .content)
921 - role: user
922 content: How many of those are odd?
923 - role: assistant
924 content: $(echo "$SECOND" | jq -c .content)
925 - role: user
926 content: And how many of the odd ones are below 100?
927 YAML
928 ```
929 
930 ```python Python
931 client = anthropic.Anthropic()
932 
933 user_turns = [
934 "How many positive integers below 500 have exactly 6 positive divisors?",
935 "How many of those are odd?",
936 "And how many of the odd ones are below 100?",
937 ]
938 
939 # messages grows across turns: each assistant turn goes back exactly as returned
940 messages = []
941 for turn, user_turn in enumerate(user_turns, start=1):
942 messages.append({"role": "user", "content": user_turn})
943 response = client.beta.messages.create(
944 model="claude-fable-5-1",
945 max_tokens=16000,
946 thinking={"type": "adaptive"},
947 # Only the last request adds a system prompt, which changes the prefix on purpose
948 system="Answer briefly." if turn == len(user_turns) else anthropic.omit,
949 messages=messages,
950 betas=["thinking-binding-controls-2026-08-01"],
951 )
952 messages.append({"role": "assistant", "content": response.content})
953 thinking_blocks = sum(block.type == "thinking" for block in response.content)
954 flagged = sum(
955 transformation.type == "thinking_mismatch_allowed"
956 for transformation in response.input_transformations or []
957 )
958 print(f"thinking blocks: {thinking_blocks}, flagged: {flagged}")
959 ```
960 
961 ```typescript TypeScript
962 const client = new Anthropic();
963 
964 const userTurns = [
965 "How many positive integers below 500 have exactly 6 positive divisors?",
966 "How many of those are odd?",
967 "And how many of the odd ones are below 100?"
968 ];
969 
970 // messages grows across turns: each assistant turn goes back exactly as returned
971 const messages: Anthropic.Beta.BetaMessageParam[] = [];
972 for (const [turnIndex, userTurn] of userTurns.entries()) {
973 messages.push({ role: "user", content: userTurn });
974 const response = await client.beta.messages.create({
975 model: "claude-fable-5-1",
976 max_tokens: 16000,
977 thinking: { type: "adaptive" },
978 // Only the last request adds a system prompt, which changes the prefix on purpose
979 system: turnIndex === userTurns.length - 1 ? "Answer briefly." : undefined,
980 messages,
981 betas: ["thinking-binding-controls-2026-08-01"]
982 });
983 messages.push({ role: "assistant", content: response.content });
984 const thinkingBlocks = response.content.filter((block) => block.type === "thinking");
985 const flagged = (response.input_transformations ?? []).filter(
986 (transformation) => transformation.type === "thinking_mismatch_allowed"
987 );
988 console.log(`thinking blocks: ${thinkingBlocks.length}, flagged: ${flagged.length}`);
989 }
990 ```
991 
992 ```csharp C#
993 AnthropicClient client = new();
994 
995 string[] userTurns =
996 [
997 "How many positive integers below 500 have exactly 6 positive divisors?",
998 "How many of those are odd?",
999 "And how many of the odd ones are below 100?",
1000 ];
1001 
1002 // messages grows across turns: each assistant turn goes back exactly as returned
1003 List<BetaMessageParam> messages = [];
1004 for (var turnIndex = 0; turnIndex < userTurns.Length; turnIndex++)
1005 {
1006 messages.Add(new() { Role = Role.User, Content = userTurns[turnIndex] });
1007 var response = await client.Beta.Messages.Create(
1008 new()
1009 {
1010 Model = "claude-fable-5-1",
1011 MaxTokens = 16000,
1012 Thinking = new BetaThinkingConfigAdaptive(),
1013 // Only the last request adds a system prompt, which changes the prefix on purpose
1014 System = turnIndex == userTurns.Length - 1 ? new("Answer briefly.") : null,
1015 Messages = messages,
1016 Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
1017 }
1018 );
1019 messages.Add(new()
1020 {
1021 Role = Role.Assistant,
1022 Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
1023 });
1024 var thinkingBlocks = response.Content.Count(block => block.TryPickThinking(out _));
1025 var flagged = response.InputTransformations?.Count(transformation =>
1026 transformation.TryPickThinkingMismatchAllowed(out _)
1027 ) ?? 0;
1028 Console.WriteLine($"thinking blocks: {thinkingBlocks}, flagged: {flagged}");
1029 }
1030 ```
1031 
1032 ```go Go
1033 client := anthropic.NewClient()
1034 
1035 userTurns := []string{
1036 "How many positive integers below 500 have exactly 6 positive divisors?",
1037 "How many of those are odd?",
1038 "And how many of the odd ones are below 100?",
1039 }
1040 
1041 // messages grows across turns: each assistant turn goes back exactly as returned
1042 messages := []anthropic.BetaMessageParam{}
1043 for i, userTurn := range userTurns {
1044 messages = append(messages, anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(userTurn)))
1045 // Only the last request adds a system prompt, which changes the prefix on purpose
1046 var system []anthropic.BetaTextBlockParam
1047 if i == len(userTurns)-1 {
1048 system = []anthropic.BetaTextBlockParam{{Text: "Answer briefly."}}
1049 }
1050 response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
1051 Model: "claude-fable-5-1",
1052 MaxTokens: 16000,
1053 Thinking: anthropic.BetaThinkingConfigParamUnion{
1054 OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{},
1055 },
1056 System: system,
1057 Messages: messages,
1058 Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
1059 })
1060 if err != nil {
1061 log.Fatal(err)
1062 }
1063 messages = append(messages, response.ToParam())
1064 thinkingBlocks := 0
1065 for _, block := range response.Content {
1066 if block.Type == "thinking" {
1067 thinkingBlocks++
1068 }
1069 }
1070 flagged := 0
1071 for _, transformation := range response.InputTransformations {
1072 if transformation.Type == "thinking_mismatch_allowed" {
1073 flagged++
1074 }
1075 }
1076 fmt.Printf("thinking blocks: %d, flagged: %d\n", thinkingBlocks, flagged)
1077 }
1078 ```
1079 
1080 ```java Java
1081 import com.anthropic.models.beta.AnthropicBeta;
1082 import com.anthropic.models.beta.messages.BetaContentBlock;
1083 import com.anthropic.models.beta.messages.BetaInputTransformation;
1084 import com.anthropic.models.beta.messages.BetaMessage;
1085 import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
1086 import com.anthropic.models.beta.messages.MessageCreateParams;
1087 
1088 void main() {
1089 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
1090 
1091 List<String> userTurns = List.of(
1092 "How many positive integers below 500 have exactly 6 positive divisors?",
1093 "How many of those are odd?",
1094 "And how many of the odd ones are below 100?");
1095 
1096 // The builder's message list grows across turns: each assistant turn goes back exactly as returned
1097 MessageCreateParams.Builder conversation = MessageCreateParams.builder()
1098 .model("claude-fable-5-1")
1099 .maxTokens(16000L)
1100 .thinking(BetaThinkingConfigAdaptive.builder().build())
1101 .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01);
1102 
1103 for (int turnIndex = 0; turnIndex < userTurns.size(); turnIndex++) {
1104 if (turnIndex == userTurns.size() - 1) {
1105 // Only the last request adds a system prompt, which changes the prefix on purpose
1106 conversation.system("Answer briefly.");
1107 }
1108 conversation.addUserMessage(userTurns.get(turnIndex));
1109 BetaMessage response = client.beta().messages().create(conversation.build());
1110 conversation.addMessage(response);
1111 long thinkingBlocks = response.content().stream()
1112 .filter(BetaContentBlock::isThinking)
1113 .count();
1114 long flagged = response.inputTransformations().stream()
1115 .flatMap(List::stream)
1116 .filter(BetaInputTransformation::isThinkingMismatchAllowed)
1117 .count();
1118 IO.println("thinking blocks: " + thinkingBlocks + ", flagged: " + flagged);
1119 }
1120 }
1121 ```
1122 
1123 ```php PHP
1124 use Anthropic\Beta\AnthropicBeta;
1125 use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
1126 use Anthropic\Beta\Messages\BetaThinkingMismatchAllowedInputTransformation;
1127 use Anthropic\Client;
1128 
1129 $client = new Client();
1130 
1131 $userTurns = [
1132 'How many positive integers below 500 have exactly 6 positive divisors?',
1133 'How many of those are odd?',
1134 'And how many of the odd ones are below 100?',
1135 ];
1136 
1137 // $messages grows across turns: each assistant turn goes back exactly as returned
1138 $messages = [];
1139 foreach ($userTurns as $turnIndex => $userTurn) {
1140 $messages[] = ['role' => 'user', 'content' => $userTurn];
1141 $response = $client->beta->messages->create(
1142 model: 'claude-fable-5-1',
1143 maxTokens: 16000,
1144 thinking: BetaThinkingConfigAdaptive::with(),
1145 // Only the last request adds a system prompt, which changes the prefix on purpose
1146 system: $turnIndex === array_key_last($userTurns) ? 'Answer briefly.' : null,
1147 messages: $messages,
1148 betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
1149 );
1150 $messages[] = ['role' => 'assistant', 'content' => $response->content];
1151 $thinkingBlocks = array_filter($response->content, fn ($block) => $block->type === 'thinking');
1152 $flagged = array_filter(
1153 $response->inputTransformations ?? [],
1154 fn ($transformation) => $transformation instanceof BetaThinkingMismatchAllowedInputTransformation,
1155 );
1156 echo 'thinking blocks: ', count($thinkingBlocks), ', flagged: ', count($flagged), PHP_EOL;
1157 }
1158 ```
1159 
1160 ```ruby Ruby
1161 client = Anthropic::Client.new
1162 
1163 user_turns = [
1164 "How many positive integers below 500 have exactly 6 positive divisors?",
1165 "How many of those are odd?",
1166 "And how many of the odd ones are below 100?"
1167 ]
1168 
1169 # messages grows across turns: each assistant turn goes back exactly as returned
1170 messages = []
1171 user_turns.each_with_index do |user_turn, turn_index|
1172 messages << {role: "user", content: user_turn}
1173 # Only the last request adds a system prompt, which changes the prefix on purpose
1174 system_param = (turn_index == user_turns.length - 1) ? {system_: "Answer briefly."} : {}
1175 response = client.beta.messages.create(
1176 model: "claude-fable-5-1",
1177 max_tokens: 16_000,
1178 thinking: {type: "adaptive"},
1179 messages: messages,
1180 betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
1181 **system_param
1182 )
1183 messages << {role: "assistant", content: response.content}
1184 thinking_blocks = response.content.count { |block| block.type == :thinking }
1185 flagged = (response.input_transformations || []).count do |transformation|
1186 transformation.type == :thinking_mismatch_allowed
1187 end
1188 puts "thinking blocks: #{thinking_blocks}, flagged: #{flagged}"
1189 end
1190 ```
1191</CodeGroup>
1192 
1193```text Output wrap
1194thinking blocks: 1, flagged: 0
1195thinking blocks: 1, flagged: 0
1196thinking blocks: 1, flagged: 2
1197```
1198 
1199The third response flags every thinking block from the earlier turns, one per turn in this run, because the new system prompt comes before all of them. The model still read them.
1200 
1201Handle these entries as you would `prefix_binding_mismatch` drops. The edit is before the first block listed: diff `system`, `tools`, and `messages` up to that block's `path` against the previous request to find it, then replace it with the matching pattern in [Make changes without editing the prefix](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#replace-prefix-edits). On a new account, or on any request that sets `prefix_mismatch_behavior`, the API instead rejects the request or drops the failing blocks. The entries are a lower bound on what enforcement would remove: with `"drop_block"`, a failing block also takes the rest of that turn's thinking blocks with it, and removing one block can make the next one fail too. When the API only records the check, it judges each block on its own and lists a block only if that block fails.
7831202 
7841203## Make changes without editing the prefix
7851204 
from line 1635
12161635 
12171636<AccordionGroup>
12181637 <Accordion title="Do I need a new account to test preserved thinking?">
1219 No. Send the `thinking-binding-controls-2026-08-01` beta header and set `thinking.block_binding.prefix_mismatch_behavior`. Setting the field opts that request into enforcement regardless of account age. `"error"` rejects an edited history with the same 400 a new account gets, and `"drop_block"` lets the request through and lists what was dropped in `input_transformations`. See [Check whether your code edits the prefix](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#how-to-tell-whether-your-integration-is-impacted).
1638 No. Send the `thinking-binding-controls-2026-08-01` beta header and set `thinking.block_binding.prefix_mismatch_behavior`. Setting the field opts that request into enforcement regardless of account age. `"error"` rejects an edited history with the same 400 a new account gets, and `"drop_block"` lets the request through and lists what was dropped in `input_transformations`. To find prefix edits from an older account without enforcing the check, send the header and leave the field unset: failing blocks still reach the model, and `input_transformations` lists them as `thinking_mismatch_allowed`. See [Check whether your code edits the prefix](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#how-to-tell-whether-your-integration-is-impacted).
12201639 </Accordion>
12211640 
12221641 <Accordion title="If anything before a thinking block changes, even one tool description, is the conversation unusable?">
12231642 

build-with-claude/thinking-steering-and-cost Changed · +9 / -7 lines

from line 43
4343 
4444Effort is the primary steering lever for thinking. Each level sets a different default for how often Claude thinks and how deeply:
4545 
46| Effort level | Thinking behavior |
47| ---------------- | ------------------------------------------------------------------------------------ |
48| `max` | Claude always thinks with no constraints on thinking depth. |
49| `xhigh` | Claude always thinks deeply with extended exploration. |
50| `high` (default) | Claude almost always thinks. Provides deep reasoning on complex tasks. |
51| `medium` | Claude uses moderate thinking. May skip thinking for simple queries. |
52| `low` | Claude minimizes thinking. Skips thinking for simple tasks where speed matters most. |
46| Effort level | Thinking behavior |
47| ---------------- | ------------------------------------------------------------------------------------------------ |
48| `max` | Claude thinks the most readily and at the greatest depth, with no constraint on thinking length. |
49| `xhigh` | Claude thinks more readily and at greater depth than at `high`, suited to extended exploration. |
50| `high` (default) | Claude thinks on most requests that benefit from it. Provides deep reasoning on complex tasks. |
51| `medium` | Claude uses moderate thinking. May skip thinking for simple queries. |
52| `low` | Claude minimizes thinking. Skips thinking for simple tasks where speed matters most. |
53 
54At every level, Claude decides per request whether to think. In a tool-use loop, the first request after new user input typically carries most of the reasoning, and follow-up requests that only process tool results can skip thinking, including at `xhigh` and `max`. Thinking per request also tends to decrease as a conversation grows longer. No level guarantees a thinking block on every request.
5355 
5456This table describes how each level changes thinking behavior. For guidance on which level to choose for a given workload, including per-model recommendations, see [When to adjust the effort parameter](https://platform.claude.com/docs/en/build-with-claude/effort#when-to-adjust-the-effort-parameter) on the effort page.
5557 

managed-agents/quickstart Changed · +2 / -6 lines

from line 391
391391 </MultiFileExample>
392392 
393393 <ForLanguage tab="CLI">
394 `ant apply` prints the environment's ID and records it in `claude-lock.json`. You'll reference it in every session you create.
395 
396 <Tip>
397 [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) accepts more than one file, so you can create the agent and the environment with one command instead: `ant apply coding-assistant.md environment.yaml`.
398 </Tip>
394 [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) records the environment's ID in `claude-lock.json` too. To create the agent and the environment with one command, pass both files: `ant apply coding-assistant.md environment.yaml`.
399395 </ForLanguage>
400396 
401397 ```python Python
from line 476
480476 ```
481477 
482478 <ForLanguage not="CLI">
483 Save the returned `environment.id`. You'll reference it in every session you create.
479 Save the returned `environment.id` too.
484480 </ForLanguage>
485481 </CodeGroup>
486482 

build-with-claude/effort Changed · +1 / -1 lines

from line 342
342342 
343343The `thinking` parameter controls whether Claude thinks in [thinking blocks](https://platform.claude.com/docs/en/build-with-claude/thinking) before answering; the `effort` parameter controls how much work Claude puts into the whole response, which in adaptive mode includes how often and how deeply it thinks. Don't pass `adaptive` as an `effort` value: `adaptive` is a thinking mode, not an effort level.
344344 
345At higher effort levels, Claude thinks on most requests and at greater length. At lower levels, it can skip thinking entirely for simpler problems. See [Thinking and effort](https://platform.claude.com/docs/en/build-with-claude/thinking#thinking-and-effort) for full guidance on how the two controls work together.
345At higher effort levels, Claude thinks more readily and at greater length. In a tool-use loop, follow-up requests that only process tool results can still skip thinking at any level. At lower levels, Claude can skip thinking entirely for simpler problems. See [Thinking and effort](https://platform.claude.com/docs/en/build-with-claude/thinking#thinking-and-effort) for full guidance on how the two controls work together.
346346 
347347On Claude Opus 4.5, the only extended-thinking-only model that supports effort, it works alongside [`budget_tokens`](https://platform.claude.com/docs/en/build-with-claude/extended-thinking): set the effort level for your task, then set the thinking token budget based on how much reasoning depth the task needs.
348348 

build-with-claude/thinking Changed · +1 / -1 lines

from line 1053
10531053* [What counts as an edit](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#what-counts-as-an-edit), and [how to check whether your code makes one](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#how-to-tell-whether-your-integration-is-impacted).
10541054* [The API feature that replaces each common edit](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#replace-prefix-edits): mid-conversation system messages for new instructions and per-turn reminders, `tool_addition` and `tool_removal` blocks for tool changes, per-message `output_config` for effort changes, and server-side compaction and context editing for trimming.
10551055* [Client-side compaction](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#custom-compaction-on-the-client): which patterns keep thinking valid and which don't.
1056* [The `thinking-binding-controls-2026-08-01` beta header](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#preserved-thinking-controls). It adds an `input_transformations` array to every response that lists the blocks the API dropped, and a `block_binding.prefix_mismatch_behavior` field on the thinking configuration that accepts `"error"` or `"drop_block"`.
1056* [The `thinking-binding-controls-2026-08-01` beta header](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#preserved-thinking-controls). It adds a `block_binding.prefix_mismatch_behavior` field (`"error"` or `"drop_block"`) to the thinking configuration and an `input_transformations` array to every response. The array lists each thinking block that the API dropped, or that failed the prefix check and was let through.
10571057 
10581058## Thinking and prompt caching
10591059 

models/fable-5-1/migration-guide Changed · +1 / -1 lines

from line 954
954954 messages.5.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block". That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.
955955 ```
956956 
957 The API enforces the check for new accounts created on or after August 31, 2026. For accounts created earlier, the API records the mismatch but doesn't act on it unless the request sets `thinking.block_binding.prefix_mismatch_behavior`, which opts into enforcement. Anthropic plans to enforce the check for every account on future models, so make your application compatible now: the same patterns keep the prompt cache warm, and you can test against the check from any account by sending `prefix_mismatch_behavior`. If you ship a tool or framework that people run with their own API key, test that way before launch: your key is probably on an older account, and your users on new ones hit the check before you do. To see whether your own account is enforced by default, send a request that edits history without the beta header: a 400 that names the header means it is.
957 The API enforces the check for new accounts created on or after August 31, 2026. For accounts created earlier, the API records the mismatch but doesn't act on it unless the request sets `thinking.block_binding.prefix_mismatch_behavior`, which opts into enforcement. On those accounts, if you send the `thinking-binding-controls-2026-08-01` beta header and leave that field unset, the response lists each block that failed the check in `input_transformations` as a `thinking_mismatch_allowed` entry. Anthropic plans to enforce the check for every account on future models, so make your application compatible now: the same patterns keep the prompt cache warm, and you can test against the check from any account by sending `prefix_mismatch_behavior`. If you ship a tool or framework that people run with their own API key, test that way before launch: your key is probably on an older account, and your users on new ones hit the check before you do. To see whether your own account is enforced by default, send a request that edits history without the beta header: a 400 that names the header means it is.
958958 
959959 The error is permanent for that request body: an automatic retry loop won't clear it. To continue without the invalidated reasoning instead of failing, strip the `thinking` blocks from the history and retry once, or send the `thinking-binding-controls-2026-08-01` [beta header](https://platform.claude.com/docs/en/api/beta-headers) and set `prefix_mismatch_behavior` to `"drop_block"` (the default is `"error"`). With `"drop_block"`, the API drops the mismatched block and every thinking block after it in the conversation, and reports each with `reason: "prefix_binding_mismatch"` in the response's `input_transformations` array:
960960 

release-notes/overview Changed · +1 / -0 lines

from line 19
1919### September 14, 2026
2020 
2121* The Messages API can now [compact a conversation on demand](https://platform.claude.com/docs/en/build-with-claude/compaction-on-demand) on the Claude API, in beta with the `compact-2026-09-04` beta header. Send the top-level `compaction` parameter, and the API returns a signed `compaction` block that summarizes the messages you sent. On later requests, send that block first, in place of those messages. You choose when to compact, the request can run in the background, and you can keep recent turns word for word after the summary. On models with preserved thinking, the thinking in those kept turns can stay valid.
22* With the `thinking-binding-controls-2026-08-01` beta header, the `input_transformations` response field gains a second entry type, `thinking_mismatch_allowed`. It names a thinking block that failed the prefix check on a request where the API doesn't enforce that check: on Claude Fable 5.1, for example, a request from an account created before August 31, 2026, with `prefix_mismatch_behavior` unset. The block still reaches the model unchanged. Log these entries to find history edits in production traffic before you opt into enforcement. See [Set the mismatch behavior and read `input_transformations`](https://platform.claude.com/docs/en/build-with-claude/preserved-thinking#preserved-thinking-controls).
2223 
2324### September 10, 2026
2425