Claude API 2026-10-21 と新しい Anthropic SDK: API キーは Authorization: Bearer に移り、X-Api-Key を読むゲートウェイはキーを見失う
API を直接呼ぶクライアントなら、ヘッダーの変更に対応する必要はありません。一方、ゲートウェイは両方の形式を読めるようにする必要があります。Claude Code やバージョンを固定したサービスは古い形式を送り続けるうえ、SDK クライアントはゲートウェイのトークンとアップストリームのキーを同時に持つことを拒否するようになったからです。
目次
10 月 21 日、Anthropic は API バージョン 2026-10-21 をリリースし、7 つの SDK すべてと ant CLI の新しいメジャーバージョンも公開しました。どれもデフォルトで新しいバージョンを送ります。移行ガイドの大半は型の整理です。その中の 1 行だけが、ネットワークを流れる内容を変えます。SDK は API キーを X-Api-Key ではなく Authorization: Bearer で送るようになりました。
API を直接呼ぶクライアントなら、この変更に対応する必要はありません。API はどちらのヘッダーからでもキーを読むからです。壊れるのは中間にいるものです。X-Api-Key を読むゲートウェイ、プロキシ、自作のミドルウェアはキーを見つけられなくなり、ゲートウェイのトークンとアップストリームのキーを両方持っていたクライアントは、コンストラクタの時点でエラーになります。元の挙動に戻すフラグはありません。しかも古い形式は消えません。Claude Code 2.1.307 は今も古い形式で送るので、ゲートウェイには同じ日に両方が届きます。ゲートウェイに何が届くのかを確かめるため、両世代の SDK と Claude Code を、ヘッダーを記録するローカルのリスナーに向けて動かしました。キーはダミーで、外部には何も転送していません。
新しい Anthropic SDK はゲートウェイに何を送るのか
認証情報のヘッダーとバージョン文字列が変わります。記録したのは以下のヘッダーで、ボディのトップレベルのキーは両世代で同じでした。api_key を設定して同じ messages.create を呼んだとき、リスナーが記録した内容です。
anthropic 1.17.0 x-api-key: sk-ant-FAKE-key anthropic-version: 2023-06-01
anthropic 2.1.0 authorization: Bearer sk-ant-FAKE-key anthropic-version: 2026-10-21
sdk (JS) 0.137.0 x-api-key: sk-ant-FAKE-key anthropic-version: 2023-06-01
sdk (JS) 1.1.0 authorization: Bearer sk-ant-FAKE-key anthropic-version: 2026-10-21新しい側には X-Api-Key がまったくありません。このヘッダーで自分のユーザーを認証しているゲートウェイには、認証情報のないリクエストが届きます。そうしたリクエストを拒否する作りなら、デプロイ当日に 401 が出ます。これはまだ良いほうです。危ないのは、自分の認証情報がなくてもリクエストを転送してしまう設計です。その場合、X-Api-Key に紐づけていたユーザーごとの帰属が失われることがあり、リクエストはクライアントが Authorization に入れたものを持ったまま出ていきます。これは自分のゲートウェイで確認すべき設計上のリスクで、私が実際に観測したものではありません。
リスナーの考え方は Claude Code ゲートウェイの解説 のものと同じですが、1 点だけ変えています。503 を返す代わりにスタブの message オブジェクトを返すので、SDK は応答をパースして正常に終了します。base_url= と偽のキーでクライアントをこのリスナーに向ければ、2 つのメジャーバージョンを 1 分で比べられます。
Anthropic SDK 2.x のクライアントがゲートウェイのトークンと API キーの併用を拒否する理由
キーと認証トークンが同じヘッダーを使うようになったので、クライアントが持てる認証情報は 1 つだけになりました。1.x では、両方を渡して作ったクライアントは両方を送っていました。キーは X-Api-Key、トークンは Authorization です。この組み合わせはゲートウェイでよく使われる構成でした。トークンでゲートウェイに認証し、キーはアップストリームに渡します。2.1.0 では、同じコンストラクタがリクエストの前に失敗します。
ValueError: Pass at most one of `api_key=`, `auth_token=`, `credentials=`, `config=`, or `profile=`. Received `api_key=`, `auth_token=`.TypeScript 1.1.0 は apiKey と authToken を両方渡すと、同じ文言の TypeError を投げます。ガイドには各言語の対応が載っています。C# は ArgumentException、Java は build() 時の IllegalStateException、PHP は InvalidArgumentException、Ruby は ArgumentError です。Go だけは違います。NewClient はエラーを返さず、そのクライアントのリクエストがすべて失敗します。
この組み合わせを残すためにドキュメントが示す方法は、ゲートウェイのトークンを認証情報として渡し、キーを普通のヘッダーとして追加することです。2.1.0 では、これで実際のリクエストに両方のヘッダーが付きました。トークンは Authorization、キーは X-Api-Key です。
client = anthropic.Anthropic(
auth_token=gateway_token,
default_headers={"X-Api-Key": upstream_key},
base_url=gateway_url,
)残り半分はゲートウェイの仕事です。ガイドは、ゲートウェイが転送前に自分宛ての Authorization ヘッダーを削除すべきだと明記しています。理由は "the Claude API expects one credential per request." です。すべてをそのまま通すゲートウェイは、今後は 2 つ送ることになります。
環境変数にも、同じ問題のもっと気づきにくい形があります。ガイドによると、コードで何も渡さず、ANTHROPIC_API_KEY と ANTHROPIC_AUTH_TOKEN の両方が設定されている場合、新しいクライアントはキーを使い、警告を 1 回だけログに出します。両方がゲートウェイに届くことを前提にしたデプロイなら、片方が届かなくなります。
Anthropic SDK 2.x のクライアントに X-Api-Key を再び送らせる方法
言語ごとに対応が必要で、全体を切り替えるスイッチはありません。Python では、ガイドの対処法は HTTP クライアントに auth フックを付けることです。このフックはリトライを含むすべてのリクエストで動きます。2.1.0 ではこれでキーが元に戻り、リスナーには x-api-key が届き、authorization はありませんでした。import するのは httpx ではなく httpx2 です。SDK は 1.17.0 の時点ですでにこちらを使っています。
import httpx2
from anthropic import Anthropic, DefaultHttpxClient
def send_x_api_key(request: httpx2.Request) -> httpx2.Request:
if request.headers.get("Authorization") == f"Bearer {api_key}":
del request.headers["Authorization"]
request.headers["X-Api-Key"] = api_key
return request
client = Anthropic(
api_key=api_key,
base_url=gateway_url,
http_client=DefaultHttpxClient(auth=send_x_api_key),
)TypeScript ではデフォルトヘッダーを 2 つ指定します。キーが二重に送られないようにしているのは Authorization: null です。1.1.0 では、これで x-api-key だけが送られました。
const client = new Anthropic({
apiKey,
baseURL: gatewayUrl,
defaultHeaders: { "X-Api-Key": apiKey, Authorization: null },
});Go は option. と option.、Java は apiKey の代わりに putHeader、PHP と Ruby はミドルウェアを使います。ガイドには見落としやすい点が 2 つあります。PHP ではこの用途に extraHeaders を使わないでください。リクエスト側が独自の extraHeaders を持つとクライアントの設定が置き換えられ、ベータのエンドポイントはすべて独自の extraHeaders を付けます。また、ant CLI にはヘッダーを追加する手段がないので、ant の前に置くゲートウェイは Authorization を読めるようにするしかありません。クライアント側での回避策はありません。
リクエストごとにヘッダーを設定するコードも、2 つの点で意味が変わります。ガイドによると、Python、TypeScript、Go、PHP では、リクエストごとに指定した X-Api-Key がクライアントのキーを置き換えなくなりました。両方が送られるので、上書きは Authorization で行う必要があります。そして、認証トークンだけを送るために X-Api-Key を削除していた処理は、削除対象を Authorization に書き換えるのではなく、処理ごと取り除いてください。Authorization を削除すると、トークンまで消えてしまいます。
Claude Code も Authorization: Bearer に移るのか
2.1.307 では移っていません。Claude Code は SDK の一覧に入っていません。2.1.307 はコードを 2026-10-21 に移行するための /claude-api api-version を追加したリリースですが、ANTHROPIC_API_KEY を設定してリスナーに向けると、古い形式のままでした。
POST /v1/messages?beta=true
user-agent: claude-cli/2.1.307 (external, sdk-cli)
anthropic-version: 2023-06-01
x-api-key: sk-ant-FAKE-keyつまり API キーについては、ゲートウェイの記事の対応関係が今も有効です。ANTHROPIC_API_KEY は x-api-key で送られます(ANTHROPIC_AUTH_TOKEN は再検証していません。ゲートウェイのドキュメントによれば Authorization: Bearer で送られます)。SDK のクライアントにも、挙動がまったく変わらないものがあります。ガイドによると、Foundry のクライアントは引き続き x-api-key を送り、Bedrock Mantle のクライアントは以前から Bearer トークンを送っていました。Claude Code を使う開発者と新しい SDK のサービスの両方を受けるゲートウェイには、同じ日に両方の形式が届きます。Python を 2.0 未満、TypeScript を 1.0 未満に固定しているものが残る限り、この状態が続きます。
Claude API 2026-10-21 は Sonnet 4.6 の temperature をどう扱うか
拒否します。2026-10-21 では、temperature、top_p、top_k を含む Messages や Batch のリクエストは、デフォルト値であっても 400 を返します。Claude 4.7 以降では、もともとデフォルト値しか受け付けないので、サンプリング自体は変わりません。この点は Opus 5.5 の移行メモ で扱いました。ただし、デフォルト値を明示的に書いているリクエストは、その指定を外す必要があります。Sonnet 4.6 のように他の値も受け付けるモデルでは、分類や採点に使っていた低い temperature が使えなくなり、ガイドによれば代わりになるものもありません。
SDK 側の変化は、思ったより早く起きていました。私が試した範囲では、Python 1.17.0 の時点で temperature はすでに messages.create のキーワード引数ではなく、2.1.0 も同じで、どちらも TypeError を出します。それでも temperature を送っているコードは extra_body を使っており、両バージョンともそれをそのまま通しました。2.1.0 ではデフォルトのバージョンにより、これがサーバー側で 400 になります。
ガイドが示す選択肢は、パラメータを外すか、そのリクエストだけ 2023-06-01 に残すかです。2.1.0 なら SDK 全体を固定せずに、リクエスト単位で残せます。リスナーには anthropic-version: 2023-06-01 が届き、ボディに temperature が入っていました。
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=256,
messages=messages,
extra_headers={"anthropic-version": "2023-06-01"},
extra_body={"temperature": 0.0},
)この固定が生きるのは、ゲートウェイ互換性ガイドが求めるとおり、anthropic-version をそのまま転送するゲートウェイを通る場合だけです。自前の SDK でリクエストを組み立て直すゲートウェイや、アップストリームに 1 つのバージョンを一律に付けるゲートウェイは、背後のすべてのクライアントの API バージョンを決めてしまいます。そのゲートウェイがアップグレードした日に、古いクライアントの temperature: 0 は 400 になります。また、この固定はクライアント側の変化を何も元に戻しません。認証情報のヘッダーは SDK の変更であって、API バージョンの変更ではないからです。
この固定は、期限付きのつなぎと考えるべきです。私の考えでは、スコアやラベルが本当に temperature 0 に依存しているなら、両方を比べられる今のうちに同じサンプルを 1.0 で測り、数字で判断すべきです。
Anthropic SDK のアップグレードで他に壊れるもの
後から失敗するもの、エラーが出ないもの、一部のトラフィックでしか起きないものがいくつかあります。
- Go の import パス。 SDK は
github.になったので、すべての import が変わり、古いパスのままのコードは v1 に留まります。さらに厄介なのがcom/ anthropics/ anthropic-sdk-go/ v2 antCLI です。モジュールパスがやはり/v2で終わり、古いgo installのパスはエラーも警告もなく v1 の最新版をインストールし続けます。「アップグレードした」はずのビルドスクリプトが、まだ古い形式で送っていることがあります。 - 会話履歴。 ガイドによると、
2026-10-21ではassistantメッセージに直接置いたdocumentブロックと、userメッセージのtextブロックにある空でないcitationsは、どちらも 400 を返します。トークンカウントとバッチでも同じです。ブロックをロール間で移しながら履歴を組み立て直すゲートウェイやアプリで表に出ます。 - TypeScript のプラットフォームパッケージ。
@anthropic-ai/、bedrock-sdk vertex-sdkなどのプラットフォームパッケージは、対応するコアのメジャーバージョンが必要です。合っていないと、パッケージマネージャーが@anthropic-ai/sdkを 2 つインストールします。 - Claude 4.7 より前の Bedrock。 Amazon Bedrock では、
2026-10-21は Claude 4.7 以降でしか使えません。そのため、Bedrock で Opus 4.6 以前を呼ぶ処理は、古い SDK のままにするか、古いバージョンを送り続ける必要があります。
新しい Anthropic SDK に向けて、ゲートウェイの運用者がまず直すべきもの
直すべきはクライアントではなくゲートウェイです。クライアントを新しいメジャーバージョン未満に固定して稼げる時間は、自分で管理しているコードの分だけで、すべてを管理できていることはまずありません。別のチームの依存関係ボットがアップグレードの PR を出したり、新しいサービスが最初から最新の SDK で動き始めたりします。その間も Claude Code は x-api-key を送り続けます。こうしたクライアントすべてが見える場所はゲートウェイだけなので、両方の形式を受け付けるのもゲートウェイの役目です。
「両方を受け付ける」の中身は、アップストリームに誰のキーが渡るかで変わります。ゲートウェイがアップストリームの認証情報を持っているなら、呼び出し元のゲートウェイ用認証情報を X-Api-Key から、なければ Authorization の Bearer の後ろから読んで検証し、両方のヘッダーを削除してから自分の認証情報を付けて転送します。呼び出し元がゲートウェイのトークンと一緒に自分のアップストリームキーを持ってくるなら、ドキュメントの分け方はトークンが Authorization、キーが X-Api-Key です。トークンを認証し、Authorization を削除してキーを転送します。どちらの場合も、両方のヘッダーが届いて内容が食い違うときにどうするかを決めておき、ヘッダーの順番に任せないでください。anthropic-version は届いたまま転送し、各リクエストがどちらのヘッダーを使ったかをログに残します。そうすれば古い形式が減っていく様子がわかり、認証情報なしでも転送してしまう経路を、帰属が失われる前に見つけられます。そのうえで、最初のサービスが勝手にアップグレードする前に、各世代のクライアントを 1 つずつ、ヘッダーを記録するリスナーに向けて試してください。
01 / ディスカッション
コメント欄はありません。議論は X で行っています。
02 / ほかの記事
tmux で動かす Claude Code: send-keys には権限プロンプトが見えず、claude agents --json には見える
tmux のペインは Claude Code エージェントを置いておく場所としては優秀ですが、エージェントを操作するインターフェースとしては不向きです。私のテストでは、権限プロンプトを表示中のペインに打ち込んだタスクは消え、続けて送った Enter が保留中のコマンドを承認しました。ステータスも、待機の理由も、終了イベントも、今は Claude Code 自身が報告してくれます。画面は、人間が見るためのものに戻せます。
Claude Code の /auto-mode-setup: auto mode の分類器に環境を教え、実際にどのモデルが判定しているかを確かめる
このセットアップは、リポジトリとエージェントの最近のコマンドから信頼リストの下書きを作ります。そしてその下書きは、同梱の environment テキストに追記されず、それを置き換えます。デフォルトとの差分として読んでください。モデル選びに時間をかける前に、アクションを判定しているのがどのモデルかも確認しましょう。
LLM ゲートウェイ経由の Claude Code:誰が支払うかはクレデンシャルで決まり、クレデンシャルがなければプロキシに claude.ai のログイン情報が渡る
サブスクリプションでログインしていればリクエストごとに 12 個、ゲートウェイトークンなら 10 個の beta 値が付きます。消える 2 つの値は、ドキュメントの表よりも多くを語ります。ゲートウェイがそのまま通すべきもの、気づかないうちに高くつくデフォルト、そして allowedProviders で固定すると開発者が自分のデバッグ用リスナーまで使えなくなる理由を扱います。