- 2026-10-21 に Claude API の新しい API バージョン
2026-10-21と、それを既定で送る Python SDK 2.0.0 が出た。v1.17.0 と v2.5.0 で同じコードを 1 回ずつ動かし、7 つの書き方を比べた - v2 では、API キーの送り方(
x-api-key→Authorization: Bearer)、MessageParam(...)の呼び出し、models.list(betas=...)、api_keyとauth_tokenの併用で動きが変わった。Sonnet 4.6 にextra_bodyで送ったtemperature=0.2は、v1 では通り、v2 では API 側で 400 になった - v2 から API バージョン
2023-06-01を指定すると、同じtemperatureは通った。どれも各 1 回の結果なので、移行するときは自分のコードを v2 で実際に動かして確かめる必要がある
背景
2026-10-21 に、Claude API の API バージョン 2026-10-21 が出ました(リリースノート)。API バージョンは、リクエストの anthropic-version ヘッダーで指定する値です。これまでは 2023-06-01 が使われてきました。
同じ日に、2026-10-21 を既定で送る SDK も出ました。Python では anthropic 2.0.0 です(CHANGELOG)。ライセンスも、2.0.0 から MIT ではなく Apache 2.0 になりました(移行ガイド)。
移行ガイド の変更点のうち、Python で書いたふつうのアプリに関係しそうなものを抜き出すと、次のとおりです。
| 変更 | どちらの変更か | 内容(移行ガイドより) |
|---|---|---|
| サンプリングのパラメーター | API |
temperature・top_p・top_k を送ると、既定値でも 400 になる |
アシスタントの document ブロック |
API |
assistant メッセージに直接 document ブロックを入れると 400 になる |
ユーザーメッセージの citations
|
API |
user メッセージの text ブロックに空でない citations があると 400 になる |
MessageParam |
SDK | 役割ごとの型の union(「どれか 1 つの型」を表す型)になる。MessageParam(...) と呼ぶと TypeError
|
| ベータでない Models のメソッド | SDK |
client.models.list() などが betas を受け付けない。client.beta.models を使う |
| API キーのヘッダー | SDK |
X-Api-Key ではなく Authorization: Bearer <key> で送る |
| 認証情報は 1 つ | SDK |
api_key と auth_token などを 2 つ以上渡すと ValueError
|
「API」の行は、API バージョン 2026-10-21 を送ったときに API が返す結果の変更です。「SDK」の行は、SDK を上げると変わることです。
この記事では、v1 の最後の版(1.17.0)と、執筆時点の最新版(2.5.0、2026-11-04 公開)に同じコードを渡して、表のうち 5 つの変更を確かめます。API の 3 つのうちは「サンプリングのパラメーター」だけ(それも temperature を extra_body で送る場合だけ)で、SDK の 4 つはすべてです。
試してみる
やること
同じ main.py を、anthropic 1.17.0 の環境(.venv-v1)と 2.5.0 の環境(.venv)で 1 回ずつ実行します。7 つの書き方を順に試し、成功するか、どんなエラーになるかを記録します。
API を呼ぶのは 1・3・4・5・7 番です(4 番は、v2 では API を呼ぶ前に SDK がエラーにします)。モデルはふだんは安い claude-haiku-5-5 にしました。temperature の確認(3 番と 7 番)だけは、temperature の値を変えられる claude-sonnet-4-6 を使います。費用は 1 セント未満の見込みです(料金)。
動作環境
- OS: macOS 27.2(Apple M3 / 24GB)
- Python: 3.12.15
- 主要ライブラリ: anthropic==1.17.0(
.venv-v1)と anthropic==2.5.0(.venv)、python-dotenv==1.2.4 - モデル:
claude-haiku-5-5(3 番と 7 番だけclaude-sonnet-4-6) - 実行日: 2026-11-07
セットアップ
cd code
uv venv --python 3.12 .venv-v1
uv pip install --python .venv-v1 -r requirements-v1.txt
uv venv --python 3.12 .venv
uv pip install --python .venv -r requirements.txt
./run.sh # ANTHROPIC_API_KEY はリポジトリルートの .env から読む
run.sh は、main.py を 2 つの環境で順に実行し、outputs/run.log に保存します。
コード
main.py の全体です。7 つの書き方を check() で 1 つずつ実行し、例外が出たら種類とメッセージを表示します。送ったヘッダーは、HTTP クライアントのイベントフック(リクエストを送る直前に呼ばれる関数)で記録します(API キーの値は表示しません)。extra_body は、渡した dict をそのままリクエストの JSON に足す SDK の仕組みです。SDK の引数にない項目も送れます。
"""v1 で書いたよくあるコードを、anthropic v1 と v2 の両方で動かして、どこが変わるか確かめる。
同じファイルを .venv-v1(anthropic 1.17.0)と .venv(anthropic 2.5.0)で実行する。
確かめる変更は、公式の移行ガイドに載っているもの:
https://platform.claude.com/docs/en/api/migration-2026-10-21
"""
import os
import platform
from pathlib import Path
import anthropic
from anthropic.types import MessageParam
from dotenv import load_dotenv
# API キーはリポジトリルートの .env から読む(code/ → 記事 → posts → ルート)
load_dotenv(Path(__file__).resolve().parents[3] / ".env")
MODEL = "claude-haiku-5-5"
OLD_MODEL = "claude-sonnet-4-6" # temperature の値を変えられるモデル
API_KEY = os.environ["ANTHROPIC_API_KEY"]
# 送ったリクエストのヘッダーを記録する(キーの値は表示しない)
sent = {}
def on_request(request) -> None:
sent.clear()
sent.update(request.headers)
client = anthropic.Anthropic(
http_client=anthropic.DefaultHttpxClient(event_hooks={"request": [on_request]}),
max_retries=0,
)
def show_auth_headers() -> None:
auth = "authorization" in sent and sent["authorization"].startswith("Bearer ")
print(f" anthropic-version: {sent.get('anthropic-version')}")
print(f" x-api-key ヘッダー: {'あり' if 'x-api-key' in sent else 'なし'}")
print(f" Authorization: Bearer: {'あり' if auth else 'なし'}")
def check(title: str, fn) -> None:
print(f"\n## {title}")
try:
fn()
except Exception as e: # 何が起きたかを記録したいので、種類を問わず表示する
msg = str(e).replace(API_KEY, "***")
print(f" -> {type(e).__name__}: {msg[:200]}")
def plain_request() -> None:
msg = client.messages.create(
model=MODEL,
max_tokens=64,
messages=[{"role": "user", "content": "「こんにちは」とだけ返してください。"}],
)
print(f" -> 成功: {msg.content[-1].text!r}")
show_auth_headers()
def message_param_call() -> None:
m = MessageParam(role="user", content="Hello")
print(f" -> 成功: {m}")
def temperature_extra_body() -> None:
# SDK の引数には temperature がないので、MIGRATION.md の案内どおり extra_body で送る。
# temperature を下げる意味がある古いモデル(Sonnet 4.6)に、既定値以外の 0.2 を送る
msg = client.messages.create(
model=OLD_MODEL,
max_tokens=64,
extra_body={"temperature": 0.2},
messages=[{"role": "user", "content": "「こんにちは」とだけ返してください。"}],
)
print(f" -> 成功: {msg.content[-1].text!r}")
print(f" anthropic-version: {sent.get('anthropic-version')}")
def temperature_old_api_version() -> None:
# 3 と同じ内容を、anthropic-version だけ 2023-06-01 にして送る(SDK の版と API バージョンを切り分ける)
msg = client.messages.create(
model=OLD_MODEL,
max_tokens=64,
extra_body={"temperature": 0.2},
extra_headers={"anthropic-version": "2023-06-01"},
messages=[{"role": "user", "content": "「こんにちは」とだけ返してください。"}],
)
print(f" -> 成功: {msg.content[-1].text!r}")
print(f" anthropic-version: {sent.get('anthropic-version')}")
def models_list_betas() -> None:
page = client.models.list(limit=1, betas=["message-threads-2026-08-12"])
print(f" -> 成功: {page.data[0].id}")
def beta_models_list() -> None:
page = client.beta.models.list(limit=1, betas=["message-threads-2026-08-12"])
print(f" -> 成功: {page.data[0].id}")
def two_credentials() -> None:
c = anthropic.Anthropic(api_key=API_KEY, auth_token="dummy-token")
print(f" -> 成功: クライアントを作れた({type(c).__name__})")
def main() -> None:
print(f"Python {platform.python_version()} / {platform.system()} {platform.machine()}")
print(f"anthropic {anthropic.__version__}")
check("1. ふつうのリクエスト(送ったヘッダーも見る)", plain_request)
check("2. MessageParam(role=..., content=...) で作る", message_param_call)
check("3. temperature=0.2 を extra_body で送る(Sonnet 4.6)", temperature_extra_body)
check("4. client.models.list(betas=...)", models_list_betas)
check("5. client.beta.models.list(betas=...)", beta_models_list)
check("6. api_key と auth_token を両方渡す", two_credentials)
check("7. 3 を anthropic-version: 2023-06-01 で送る", temperature_old_api_version)
if __name__ == "__main__":
main()
実行結果
outputs/run.log の全体です。
# run at: 2026-11-07 09:52:07 JST
################ main.py with .venv-v1
Python 3.12.15 / Darwin arm64
anthropic 1.17.0
## 1. ふつうのリクエスト(送ったヘッダーも見る)
-> 成功: 'こんにちは'
anthropic-version: 2023-06-01
x-api-key ヘッダー: あり
Authorization: Bearer: なし
## 2. MessageParam(role=..., content=...) で作る
-> 成功: {'role': 'user', 'content': 'Hello'}
## 3. temperature=0.2 を extra_body で送る(Sonnet 4.6)
-> 成功: 'こんにちは'
anthropic-version: 2023-06-01
## 4. client.models.list(betas=...)
-> 成功: claude-haiku-5-5
## 5. client.beta.models.list(betas=...)
-> 成功: claude-haiku-5-5
## 6. api_key と auth_token を両方渡す
-> 成功: クライアントを作れた(Anthropic)
## 7. 3 を anthropic-version: 2023-06-01 で送る
-> 成功: 'こんにちは'
anthropic-version: 2023-06-01
################ main.py with .venv
Python 3.12.15 / Darwin arm64
anthropic 2.5.0
## 1. ふつうのリクエスト(送ったヘッダーも見る)
-> 成功: 'こんにちは'
anthropic-version: 2026-10-21
x-api-key ヘッダー: なし
Authorization: Bearer: あり
## 2. MessageParam(role=..., content=...) で作る
-> TypeError: Cannot instantiate typing.Union
## 3. temperature=0.2 を extra_body で送る(Sonnet 4.6)
-> BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'temperature: Extra inputs are not permitted'}, 'request_id': 'req_011Cgneo3rW4Jy7myJQa8MvM'}
## 4. client.models.list(betas=...)
-> TypeError: Models.list() got an unexpected keyword argument 'betas'
## 5. client.beta.models.list(betas=...)
-> 成功: claude-haiku-5-5
## 6. api_key と auth_token を両方渡す
-> ValueError: Pass at most one of `api_key=`, `auth_token=`, `credentials=`, `config=`, or `profile=`. Received `api_key=`, `auth_token=`.
## 7. 3 を anthropic-version: 2023-06-01 で送る
-> 成功: 'こんにちは'
anthropic-version: 2023-06-01
結果
7 つの書き方の結果をまとめると、次のとおりです(各 1 回)。
| # | 書き方 | v1.17.0 | v2.5.0 |
|---|---|---|---|
| 1 | ふつうのリクエスト | 成功。anthropic-version: 2023-06-01、キーは x-api-key で送る |
成功。anthropic-version: 2026-10-21、キーは Authorization: Bearer で送る |
| 2 | MessageParam(role=..., content=...) |
成功(dict ができる) | TypeError: Cannot instantiate typing.Union |
| 3 | Sonnet 4.6 に temperature=0.2 を extra_body で送る |
成功 | API が 400(temperature: Extra inputs are not permitted) |
| 4 | client.models.list(betas=...) |
成功 |
TypeError(betas を受け付けない) |
| 5 | client.beta.models.list(betas=...) |
成功 | 成功 |
| 6 |
api_key と auth_token を両方渡す |
成功(クライアントを作れた) | ValueError: Pass at most one of ... |
| 7 | 3 と同じものを anthropic-version: 2023-06-01 で送る |
成功 | 成功 |
気づいたこと
v1 で extra_body を使って送っていた temperature は、v2 では API に止められた。 Python SDK は、1.0.0(2026-08-20)で temperature・top_p・top_k の引数を外しています。そのとき SDK の MIGRATION.md は、これらをまだ使う古いモデルのために、extra_body で渡す書き方を案内しています。3 番は、その例と同じ形(claude-sonnet-4-6 に temperature=0.2)です。2023-06-01 を送る v1 では成功し、2026-10-21 を送る v2 では 400 になりました。
SDK の引数ではないので、v2 に上げても型エラーにはならず、実行して初めて止まります。この 400 が SDK の版によるものか、API バージョンによるものかを分けるため、7 番では v2 から anthropic-version: 2023-06-01 を指定して同じものを送りました。こちらは成功しました。今回の 1 回の結果では、400 を決めていたのは API バージョンでした。移行ガイドの説明とも合っています(Sampling parameters are removed)。今回の結果と移行ガイドからは、v1 で extra_body を使って temperature を下げていたコードは、v2 に上げると止まると考えられます。移行ガイドでは、これらのパラメーターを外すか、そのリクエストだけ 2023-06-01 のまま送るように書かれています(7 番で確かめた形です)。
API キーのヘッダーが変わる。 1 番では、v2 の SDK が API キーを Authorization: Bearer で送っていました。SDK だけを使うなら、コードを変える必要はありませんでした。ただし、間にプロキシやゲートウェイを置いて X-Api-Key を読んでいる場合は、そちらを直す必要があります(移行ガイド)。
2・4・6 番はガイドのとおりに直せる。 2 番は dict で書く、4 番は client.beta.models を使う(5 番で成功を確認)、6 番は認証情報を 1 つにする、という直し方が移行ガイドに載っています。
まとめ
-
anthropic1.17.0 と 2.5.0 で同じコードを 1 回ずつ動かすと、7 つの書き方のうち 5 つ(1・2・3・4・6 番)で結果が変わった。1 番はエラーにはならず、送るヘッダー(API バージョンと API キーの送り方)だけが変わった - 一番気をつけたいのは
temperatureまわりだった。Sonnet 4.6 にextra_bodyで送ったtemperature=0.2は、v1(2023-06-01)では通り、v2(2026-10-21)では 400 になった。型エラーにならないので、実行するまで気づけない - 今回試したのは移行ガイドの変更の一部で、各 1 回だけだった。移行するときは、自分のコードを v2 で実際に動かして確かめる必要がある
参考
公式ドキュメント・一次情報
- Migrating to API version 2026-10-21 — Anthropic
- Claude Platform release notes — Anthropic(API バージョン 2026-10-21 と SDK の項目は 2026-10-21)
- anthropic-sdk-python CHANGELOG.md — Anthropic(GitHub。2.0.0 は 2026-10-21、2.5.0 は 2026-11-04)
- anthropic-sdk-python MIGRATION.md — Anthropic(GitHub)
- anthropic(PyPI) — PyPI
- Pricing — Anthropic