Claude Messages API compaction: two beta paths, the signed block and the billing line
compacting is not automatically cheaper
Anthropic put the compaction API in beta on 2026-02-05 (summarise once a threshold is hit) and added on-demand compaction on 2026-09-14: send the top-level compaction parameter and the API returns a signed compaction block. This page answers four things: how each path is sent, how the block goes back (the wrong position is a 400, in the vendor's own words), why usage.iterations changes what you bill, and how compaction really relates to prompt caching.
Updated 2026-09-21
Four key points
Two different beta headers
Threshold compaction uses compact-2026-01-12, configured inside context_management.edits with entry type compact_20260112; on-demand uses compact-2026-09-04 with the top-level compaction parameter. Official wording: You can't send compaction and context_management on the same request.
Default trigger for the threshold path
The official parameter table: trigger defaults to {"type": "input_tokens", "value": 150000}, input_tokens is the only supported trigger type, and value must be at least 50,000 tokens. Once it fires, the API writes a summary, puts it in a compaction block and continues the response with the compacted context.
A misplaced signed block is a 400
The on-demand path returns one signed compaction block. Official: Leaving the summarized messages in front of a signed block is a 400 error. Send the block first in messages, in place of the turns it summarises, and keep it byte-for-byte including its signature. The threshold block sits after the content it summarised instead.
Why it bills separately
Official wording: Compaction requires an additional sampling step, which contributes to rate limits and billing. The response adds an entry of type compaction to usage.iterations; the top-level input_tokens and output_tokens do not include it, so the vendor asks you to sum across iterations for the real cost of the call.
What it is
Server-side compaction: when a request reaches your configured threshold, Claude summarises the conversation itself, returns the summary inside a compaction block, and on later requests the API drops every content block before that block and continues from the summary. The docs position it as the replacement for client-side summarisation code (Server-side compaction is the recommended strategy) and name two use cases: long single-thread chats, and task-oriented prompts that need lots of follow-up work, usually tool use, that might exceed the context window.
What happened
Both dates are verbatim in the official API release notes: 2026-02-05, We've launched the compaction API in beta, providing server-side context summarization for effectively infinite conversations. Available on Opus 4.6.; and, re-checked 2026-09-21, the September 14, 2026 entry, The Messages API can now compact a conversation on demand ... in beta with the compact-2026-09-04 beta header. The on-demand path produces one signed block and no reply (stop_reason is compaction); that request can run in the background while the conversation continues on full history, and recent turns can be kept word for word after the summary.
Timeline
2026-02-05: the official release notes say We've launched the compaction API in beta ... Available on Opus 4.6. - the first server-side compaction beta.
2026-09-14: the same page adds on-demand compaction (beta header compact-2026-09-04): the top-level compaction parameter, a signed block, background summarisation and word-for-word recent turns kept after the summary.
2026-09-21: this page captured both official .md documents and checked every parameter, default and error code quoted above; catalog and 30-day priced usage checked the same day.
Confirmed vs watch out
Confirmed by the docs
Verbatim in the pages captured 2026-09-21: trigger defaults to 150000 with value at least 50,000; input_tokens is the only supported trigger type; a non-blank instructions string replaces the default summarisation prompt entirely (up to 16,384 characters on the on-demand path); pause_after_compaction defaults to false; Compaction requires an additional sampling step, which contributes to rate limits and billing; top-level usage excludes the compaction iteration and you must sum iterations; Leaving the summarized messages in front of a signed block is a 400 error; compaction cannot be combined with context_management on one request; the token counting endpoint ignores the compaction parameter; images, documents, container_upload blocks and fetched URLs inside the summarised range are gone once the block replaces them.
⚠️ Watch out
The community line compaction makes every later request dearer cannot be stated as fact. The vendor says compaction adds a billed sampling step, and in the same document says Compaction works well with prompt caching, showing a cache_control breakpoint on the block and recommending a breakpoint at the end of the system prompt so the system prompt cache stays valid; it also says re-applying a previous compaction block incurs no additional compaction cost. The accurate version: compaction is not free, and whether it pays depends on where your cache breakpoints sit. Also: the whole surface is beta; a failed summary still returns HTTP 200 with empty content and that call is still billed; a transient server problem returns a retryable 529 overloaded_error with error.details.error_code compaction_unavailable; and sending a task budget's remaining value alongside compaction is a 400. (the four points above were checked against the docs on 2026-09-21; rewrite this section if they move)
Same and different
What they share
Both summarise server-side, both return a compaction block, both use the model in your request to write the summary (Current limitations says there is no option to use a different, cheaper model), both add a sampling step that counts against rate limits and billing, and both are still beta.
What differs
Triggering differs: the threshold path fires mid-request and can fire several times in one call (with server tools the trigger is re-checked at the start of each sampling iteration), while the on-demand path is one request you spend on writing the summary, which generates no reply. Block placement differs: a threshold block follows the content it summarised, a signed block replaces those messages. Platforms differ too: the docs say on-demand compaction is available on the Claude API but not on Amazon Bedrock or Google Cloud.
How to use it
Five steps. 1) Pick a path: threshold compaction if you want the API to manage context inside ordinary requests; the compaction parameter if your app must control when it happens, cannot pause while a summary is written, or must keep recent turns and their thinking. 2) Send the header right: on-demand needs compact-2026-09-04 on the request that asks for the summary and on every later request carrying the signed block - and the docs note that omitting it fails with a generic validation error (compaction: Extra inputs are not permitted) that never mentions the header. 3) Put the block back first in messages and delete the summarised turns. 4) Fix your cost tracking: sum usage.iterations instead of reading only the two top-level fields. 5) Handle the no-summary case: with tools defined the model sometimes calls a tool instead of writing a summary and the block comes back with content: null; the documented fix is instructions that explicitly forbid tool calls.
On QCode
Compaction is a Messages API parameter and beta header, not a switch we expose. We have not sent a real billed request down our own relay to test it (test accounts here are read-only), so this page only says which layer owns the behaviour: upstream Anthropic interprets the parameter, and we make no promise on its behalf. Checked against our catalog on 2026-09-19: claude-opus-5, claude-sonnet-5, claude-fable-5, claude-fable-5-1, claude-opus-4-8 and claude-sonnet-4-6 from the beta's supported list are all in the public /models list, with 59,161 / 222,137 / 12,904 / 15,728 / 22,007 / 151,645 priced calls over the last 30 days; claude-mythos-5 and claude-mythos-5-1 are listed too with 0 priced calls in that window. Beta surfaces change without notice, so this page promises no stability for any tier.
FAQ
Can both betas be on at once?
No. In How it fits with the rest of the API the docs state You can't send compaction and context_management on the same request, and add that threshold compaction (compact_20260112) can't run on a request that carries a signed block. Pick one path.
Does enabling compaction save money?
Not by itself. The vendor says compaction requires an additional sampling step that contributes to rate limits and billing, and that the top-level input_tokens / output_tokens exclude it, so you have to sum usage.iterations. What shrinks is the context of later requests; whether the net is cheaper depends on cache breakpoints and on the fact that re-applying an old block costs no extra compaction.
Where does the signed block go?
First in messages, with the summarised turns removed, and the block kept exactly as returned including its signature. The docs state that leaving the summarised messages in front of a signed block is a 400 error. Every later request must carry the compact-2026-09-04 header.
Why did the block come back empty?
Most often the tool conflict: Current limitations says that when a request includes tools, the model occasionally calls a tool during the internal summarisation step instead of writing a summary, and the response then carries a compaction block with content: null. The documented fix is instructions that explicitly say not to call tools and to answer with text only. Note also that a failed summary is still HTTP 200 with empty content, still billed and still reported in usage.iterations.
Which models can I try this on at QCode?
On the beta's supported list, claude-opus-5, claude-sonnet-5, claude-fable-5, claude-fable-5-1, claude-opus-4-8 and claude-sonnet-4-6 are all in our public /models list (checked 2026-09-19; 59,161 / 222,137 / 12,904 / 15,728 / 22,007 / 151,645 priced calls over 30 days). Compaction is an API parameter, not something we toggle for you, and beta surfaces can change - this page promises no stability.
Can a cheaper model write the summary, or skip it?
No swap. The docs state The model specified in your request is used for summarization. There is no option to use a different (for example, cheaper) model for the summary. What you can change is instructions (a custom summarisation prompt that fully replaces the default) and the trigger threshold. Full control means turning server-side compaction off and summarising client-side, which is a different design.
Sources
Anthropic, Compaction, https://platform.claude.com/docs/en/build-with-claude/compaction (captured 2026-09-21 as the official .md, HTTP 200; Compatibility, Parameters, Understanding usage, Prompt caching, Current limitations and Compact on demand sections) and Claude release notes, https://platform.claude.com/docs/en/release-notes/overview (same capture; the 2026-02-05 and September 14, 2026 entries are quoted verbatim). Catalog listing and 30-day priced calls are our own checks (public /models snapshot plus the priced-call ledger).
Fix the usage accounting before deciding to compact
Headers, block placement and billing wording here follow the official documents captured 2026-09-21; the parameter is interpreted upstream and we promise no behaviour on its behalf. Prices on /pricing, current catalog on /models.
Related reading
Context Engineering Complete Guide 2026
Compaction is one technique inside context engineering; that page covers the method, not the API parameters.
Adding and Removing Tools Mid-Conversation
How mid-conversation instructions and tool changes survive summarisation is covered there.
effort is not supported when thinking is disabled
The thinking-block and history-change error family: the kept turns' thinking must stay consistent too.
This page transcribes public Anthropic documentation and is not affiliated with Anthropic. Parameter names, defaults, error codes and quoted sentences are as of the capture on 2026-09-21; beta surfaces change without notice. This page makes no claim that compaction is cheaper - the vendor documents an extra billed sampling step and specific cache-breakpoint behaviour, nothing more. QCode provides API access and does not change the beta status of upstream interfaces.