On Wednesday 21 October Anthropic released API version 2026-10-21, the first new version of the Claude API since 2023-06-01, and with it a new major version of every official SDK: Python 2.0.0, TypeScript 1.0.0, Go 2.0.0, Java 3.0.0, C# 13.0.0, PHP 1.0.0, Ruby 2.0.0 and the ant CLI 2.0.0. The new SDKs send the new version by default. On that version a Messages request that carries temperature, top_p or top_k returns a 400, even at the parameter's default value. The old version is not deprecated, and the migration guide gives it no end date.

The change I would check first is the one that does not depend on the API version. The new SDKs send your API key as Authorization: Bearer <key> instead of in X-Api-Key. I pointed the Python 2.1.0 and TypeScript 1.1.0 clients at a local server that records headers. With a key alone, that header move is the whole difference. With a gateway token set in Authorization through default_headers, the pattern for putting a token on a proxy and a key on the API behind it, the token went out and the key did not. There was no warning and no error. The header holds one value, and the token had it.

The guide has a fix for that case: pass the gateway token as auth_token, put the key back in X-Api-Key yourself, and have the gateway strip its own Authorization header before it forwards. It also has a gap. It tells you that a request which relies on a lower temperature should "keep that request on 2023-06-01," and the new SDKs have no temperature argument and no documented way to send the old version. Both work through plumbing the guide does not mention, default_headers for the version and extra_body for the parameter. I checked what goes out on the wire. I did not have a key in this environment to check what comes back.

What the new clients send

The test was a 25-line HTTP server on 127.0.0.1:8765 that logs every header and body and answers with a canned Messages response. I pointed clients at it with base_url and a fake key.

The old Python client, 0.86.0, sent anthropic-version: 2023-06-01, the key in x-api-key, and temperature: 0.2 in the body without complaint. The 2.1.0 client, published at 22:00 UTC on 21 October, six hours after 2.0.0, sent anthropic-version: 2026-10-21, authorization: Bearer <key>, and no x-api-key header at all. TypeScript 1.1.0 did exactly the same.

Anthropic's guide says the API itself takes either header: "The Claude API accepts a key in either header, so a program that talks to the API directly needs no change." The sentence before it is the one that matters: "change any proxy or gateway that reads or sets X-Api-Key to use Authorization." Anything between your code and the API that looks for the key in the old header now sees a request with no credential in the place it is looking.

One header, two credentials

Until yesterday a client could hold two credentials and they travelled apart. Anthropic(api_key=key, default_headers={"Authorization": "Bearer <gateway token>"}) sent the gateway's token in Authorization and the key in X-Api-Key. The gateway checked its token, forwarded the rest, and Anthropic found the key.

With the 2.1.0 client that same constructor sends Authorization: Bearer <gateway token> and nothing else. The header you set wins and the key has nowhere left to go. TypeScript with defaultHeaders behaves the same way. Pass both as credentials, api_key and auth_token, and the constructor refuses: ValueError: Pass at most one of api_key=, auth_token=, credentials=, config=, or profile=. The guide puts it in one line: "An API key and an authentication token now share a header, so an SDK client holds one credential."

The fix in the guide works. Anthropic(auth_token="<gateway token>", default_headers={"X-Api-Key": key}) sent both headers on my server, the token in Authorization and the key in X-Api-Key. Then comes the part you cannot fix in the client: "Have the gateway remove its Authorization header before it forwards the request. The Claude API expects one credential for each request." If your gateway forwards headers untouched, Anthropic now gets two credentials where it got one before.

For a gateway that only reads X-Api-Key, the guide shows an auth function on the Python HTTP client that moves the key back. Two details from running it. The 2.x SDK depends on a package called httpx2, version 2.16.0 in my install, not httpx, and the guide's function is typed against httpx2.Request. An Auth object from the httpx package is rejected with TypeError: Invalid "auth" argument. In TypeScript the fix is defaultHeaders: { "X-Api-Key": apiKey, Authorization: null }, and on the wire that produced x-api-key and no Authorization. The ant CLI has no fix: "ant has no flag or environment variable for adding a header of your own, so it can't send X-Api-Key."

Several write-ups this week say LiteLLM-style gateways are the likeliest to break. I read LiteLLM's proxy auth code as of its 20 October commit. It takes the virtual key from x-litellm-api-key if you configured one, then from Authorization, then from API-Key, and only then from x-api-key, the one its source describes as "If anthropic client used." A LiteLLM key arrives either way. The products to check are the ones with their own token in Authorization and the Anthropic key in X-Api-Key, and anything that reads only the second.

Two smaller per-request changes, both confirmed on the wire and both in the guide. extra_headers={"X-Api-Key": other_key} no longer swaps the key, it adds a second one, so both keys go out. And extra_headers={"Authorization": omit} now sends a request with no credential at all, where the old idiom used X-Api-Key.

temperature fails in two different places

The three sampling parameters are gone from the SDKs as well as the API. In Python that is a client-side failure: Messages.create() raises TypeError: got an unexpected keyword argument 'temperature' before any request leaves the process, and temperature, top_p and top_k are absent from the method signature. In TypeScript the parameter is gone from the SDK's types. In plain JavaScript there is nothing to reject it, and when I passed temperature: 0 the 1.1.0 client sent it in the body. The 400 comes back from the API. Code that builds request bodies dynamically, or passes them through from a config file, is in the same position.

The guide says what the removal costs. The default is a temperature of 1.0. Models that already accept only the defaults, Claude 4.7 and later, "sample as before." On earlier models such as Claude Sonnet 4.6, "a request that lowered temperature for more consistent output loses that effect. No other setting replaces it." The advice is to "either stop sending the parameter, or keep that request on 2023-06-01."

How you keep one request on the old version with the new SDK is not in the guide. The word "pin" does not appear on the page. The version header is a client default, ANTHROPIC_API_VERSION = "2026-10-21" in the Python package's constants, and default_headers={"anthropic-version": "2023-06-01"} overrode it on my server. extra_body={"temperature": 0.2} put the parameter back in the body. A client built with both sent anthropic-version: 2023-06-01 and temperature: 0.2 together. That is the request the guide tells you to keep making, built from two features the guide does not mention. I saw it leave. I did not see the API accept it.

What pulls you onto the new version

A version range does. anthropic>=1.14 resolved to 2.1.0 when I compiled it this morning, and anthropic~=1.17 stayed on 1.17.0, the last 1.x release, published the evening of 20 October. On npm, ^0.137.0 resolved to 0.137.0, because a caret on a 0.x version holds the minor, so TypeScript projects move only when someone changes the range. The TypeScript platform packages, for Bedrock, Vertex, Foundry, AWS and Google Cloud, need the 1.0 SDK and must move in the same upgrade, or "your package manager installs a second, older copy of @anthropic-ai/sdk for it."

Claude Code 2.1.307, published at 20:47 UTC on 21 October, added /claude-api api-version, a command that moves Claude API code in a repository to 2026-10-21. It does not touch your gateway.

On Amazon Bedrock, 2026-10-21 "is available only for Claude 4.7 and later models." The guide tells you to stay on the SDK you use today for anything older. The Foundry clients still send x-api-key, and Bedrock Mantle already used a bearer token, so those two are unchanged.

The rest of the version-dependent list is short. A document block placed directly in an assistant message returns a 400. A user text block with a non-empty citations array returns a 400. The Admin API drops old field names, and workspace_id on API keys becomes scope. Text Completions is removed from the TypeScript, Go, Java and Ruby SDKs and the CLI. MessageParam is a union of one type per role, so MessageParam(role="user", content="hi") in Python now raises TypeError: Cannot instantiate typing.Union. And the SDKs move from the MIT license to Apache 2.0, which the PyPI and npm metadata already show.

What to do

Grep for the two headers before you grep for temperature. In code, look for default_headers, defaultHeaders, extra_headers and putHeader that set Authorization or X-Api-Key. In gateway configuration, find out which header it reads for its own token, which header it reads for the upstream key, and whether it strips its own header before forwarding.

Pin until you have tested. anthropic<2 and @anthropic-ai/sdk@^0.137 hold the old behaviour. When you move, move the SDK and the gateway rule in the same change, as the guide's third step says: "Release the upgrade together with your fixes."

If a request needs a lowered temperature on a pre-4.7 model, stay on the 1.x SDK for that request, or test the undocumented pin against the live API before you depend on it.

And read your gateway's response for a request with no credential. A key that stops arriving does not fail in the SDK. It fails with whatever your gateway returns for a request that has no key.