Upgrade the SDK

Su Suriya Ravichandran Updated 10 Nov 2026
12 min read ·Lesson 5 of 200

What Upgrading Means

Upgrading the SDK means replacing the installed version of the anthropic package with a newer release from PyPI. Anthropic releases new versions frequently. Each one adds support for new models and API features, fixes bugs, or improves performance.

Before upgrading, you need to understand what kind of release you are moving to, because some upgrades are routine and others require code changes.


Understanding Version Numbers

SDK versions follow the MAJOR.MINOR.PATCH pattern of Semantic Versioning (SemVer):

  2  .  4  .  1
  │     │     └── PATCH: bug fixes; no new features
  │     └──────── MINOR: new features, backward-compatible
  └────────────── MAJOR: breaking changes are allowed
Upgrade typeExampleWhat to expectRisk
Patch2.4.0 → 2.4.1Bug fixesVery low
Minor2.4.1 → 2.5.0New features and new models; existing code keeps workingLow
Major1.x → 2.0.0Breaking changes; code may need updatesRequires review and testing

The SDK's Own Versioning Rules

The SDK generally follows SemVer, with one documented caveat. Certain backward-incompatible changes can appear in minor releases when they:

  1. affect only static types, not runtime behavior;
  2. change library internals that are technically public but not meant for external use; or
  3. are not expected to affect the vast majority of users in practice.

In practice, minor upgrades are safe for normal code that uses documented features. Code that relies on private attributes (names starting with _, other than the documented _request_id) can break at any time.

SDK Major Versions and API Versions

Each SDK major version is tied to one API version, sent in the anthropic-version header (Lessons 1 and 2):

SDK versionAPI version sent
Before 2.0.02023-06-01
2.0.0 and later2026-10-21

A major SDK upgrade can therefore also change the API behavior your code receives, not just the Python interface. That is the main reason major upgrades need deliberate testing.


Why Upgrade, and Why Not Blindly

Reasons to upgrade:

  • New models and features. New request parameters and response types arrive in new SDK releases. Older versions may not know about them.
  • Bug fixes and security fixes, in the SDK and in its dependencies.
  • Compatibility with documentation. Official examples are written for the current SDK.

Reasons to upgrade deliberately, not automatically:

  • A major version can remove parameters or change behavior.
  • Your application's behavior should change only when you have tested the change.
  • Production systems must match the versions you tested.

The goal is regular, controlled upgrades: routine for minor and patch versions, planned for major versions.


Check Your Current Version

From the Terminal

python -m pip show anthropic
Name: anthropic
Version: 1.8.0
...

From Python

import anthropic

print(anthropic.__version__)

Find Out Whether Newer Versions Exist

List all outdated packages in the environment:

python -m pip list --outdated
Package   Version Latest Type
--------- ------- ------ -----
anthropic 1.8.0   2.0.0  wheel

List every available version of the SDK:

python -m pip index versions anthropic

Note: pip index is marked experimental by pip, but it is widely used and works with current pip versions. You can also check the release history on the package's PyPI page or the GitHub repository's releases.


Upgrade with pip

Upgrade to the Latest Version

python -m pip install --upgrade anthropic

--upgrade (short form -U) tells pip to replace the installed version with the newest compatible release. Without it, pip install anthropic does nothing when any version is already installed.

By default, pip upgrades the SDK's dependencies only if the new SDK version requires it. Other packages in your environment are left alone.

Upgrade Within a Major Version

To get all minor and patch updates but not the next major version:

python -m pip install --upgrade "anthropic>=2.0,<3"

This is the safe routine-upgrade command for a project on SDK 2.x.

Install an Exact Version

python -m pip install "anthropic==2.0.0"

Verify

python -c "import anthropic; print(anthropic.__version__)"

Update Your Requirements File

Upgrading the environment does not change requirements.txt. If you use frozen versions, regenerate the file:

python -m pip freeze > requirements.txt

If you use ranges, edit the range by hand, for example from anthropic>=1.0,<2 to anthropic>=2.0,<3. Then commit the change, so every machine and deployment uses the same version.


Upgrade with Other Tools

uv

uv lock --upgrade-package anthropic   # Update the lock file to the newest allowed version
uv sync                               # Install the locked versions into .venv

To move to a new major version, change the constraint:

uv add "anthropic>=2.0,<3"

Poetry

poetry update anthropic               # Newest version allowed by the constraint
poetry add anthropic@latest           # Change the constraint to the latest release

Jupyter

%pip install --upgrade anthropic

Then restart the kernel. A running kernel has already imported the old version and keeps using it until restarted.


Upgrading Across a Major Version: 1.x to 2.0.0

Version 2.0.0 is the first SDK release that uses API version 2026-10-21. It includes breaking changes in both the API and the SDK. If your code was written for 1.x, check each item below.

1. temperature, top_p, and top_k Are Removed

API version 2026-10-21 rejects these sampling parameters, even at their default values, and SDK 2.x no longer has them.

# SDK 1.x: worked
message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=500,
    temperature=0.2,
    messages=[{"role": "user", "content": "Summarize this report."}],
)

# SDK 2.x: remove the parameter
message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=500,
    messages=[{"role": "user", "content": "Summarize this report."}],
)

Without these parameters, requests use the default sampling behavior. Models that already accept only the defaults (Claude 4.7 and later) behave exactly as before. On older models that accepted other values, code that lowered temperature for more consistent output loses that effect, and no other setting replaces it. If a workload truly depends on a non-default value, it must stay on SDK 1.x (API version 2023-06-01) for now.

2. The API Key Is Sent as Authorization: Bearer

SDK 2.x sends the key as Authorization: Bearer <key> instead of in the X-Api-Key header. The Claude API accepts either, so ordinary code needs no change.

It matters if anything in your infrastructure reads X-Api-Key, such as a proxy, API gateway, logging filter, middleware, or test stub. Update those components to read Authorization. Alternatively, follow the migration guide's instructions for moving the key back to X-Api-Key with a custom HTTP client.

Per-request key overrides also change:

# SDK 1.x
extra_headers={"X-Api-Key": other_key}

# SDK 2.x
extra_headers={"Authorization": f"Bearer {other_key}"}

3. A Client Holds Exactly One Credential

Passing more than one credential, such as both api_key and auth_token, now raises ValueError:

client = Anthropic(api_key=key, auth_token=token)   # SDK 2.x: ValueError

Pass only one. When none is passed, the client uses the first credential it finds, starting with ANTHROPIC_API_KEY (Lesson 7).

4. MessageParam Is Now a Union of Role-Specific Types

Messages written as dictionaries need no change:

messages = [{"role": "user", "content": "Hello"}]   # Works in 1.x and 2.x

Code that called MessageParam like a constructor must change, because that now raises TypeError:

from anthropic.types import MessageParam

# SDK 1.x
message = MessageParam(role="user", content="Hello")

# SDK 2.x
message: MessageParam = {"role": "user", "content": "Hello"}

MessageParam still works as a type annotation, as in list[MessageParam]. The new role-specific types are UserMessageParam, AssistantMessageParam, and SystemMessageParam.

5. betas Moved from client.models to client.beta.models

# SDK 1.x
page = client.models.list(betas=["some-beta"])

# SDK 2.x
page = client.beta.models.list(betas=["some-beta"])

6. The License Changed to Apache 2.0

SDK 2.x is licensed under Apache License 2.0. Earlier versions remain under MIT. No code changes are needed, but update your dependency-license records if your organization tracks them.

7. Amazon Bedrock Caveat

On Amazon Bedrock, API version 2026-10-21 is available only for Claude 4.7 and later models. If you call older models through Bedrock, stay on your current SDK version for those calls until you move to a newer model.

Note: If you are upgrading from a 0.x release, there is an additional set of breaking changes from 0.x to 1.x, described in the v1 migration guide (MIGRATION.md) in the SDK's GitHub repository. Upgrade one major version at a time, and test after each step.

The complete, authoritative list is in the official guide, Migrating to API version 2026-10-21, in the Claude Platform documentation. Always read it before a major upgrade.


Practical Example: Scanning Your Code Before a Major Upgrade

Before upgrading from 1.x to 2.x, it helps to find every place in your code that the breaking changes might affect. This script scans a project for the patterns described above:

"""scan_for_v2_changes.py: find code that may need updates for anthropic 2.x."""

import re
import sys
from pathlib import Path

# Each pattern maps to an explanation of what to change.
CHECKS = {
    r"\btemperature\s*=": "temperature is removed in 2.x: delete the argument",
    r"\btop_p\s*=": "top_p is removed in 2.x: delete the argument",
    r"\btop_k\s*=": "top_k is removed in 2.x: delete the argument",
    r"MessageParam\(": "MessageParam can no longer be called: use a dict literal",
    r"models\.(list|retrieve)\([^)]*betas": "betas moved: use client.beta.models",
    r"[Xx]-[Aa]pi-[Kk]ey": "the SDK now sends Authorization: Bearer, not X-Api-Key",
    r"auth_token\s*=": "check that each client receives only one credential",
}

SKIP_DIRS = {".venv", "venv", ".git", "__pycache__", "node_modules"}


def scan(root: Path) -> int:
    findings = 0
    for path in root.rglob("*.py"):
        if SKIP_DIRS.intersection(path.parts) or path.name == Path(__file__).name:
            continue
        lines = path.read_text(encoding="utf-8", errors="ignore").splitlines()
        for line_number, line in enumerate(lines, start=1):
            for pattern, advice in CHECKS.items():
                if re.search(pattern, line):
                    findings += 1
                    print(f"{path}:{line_number}: {advice}")
                    print(f"    {line.strip()}")
    return findings


if __name__ == "__main__":
    project_root = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(".")
    total = scan(project_root)
    print(f"\n{total} potential issue(s) found.")

Run it from your project folder:

python scan_for_v2_changes.py .

Example output:

app/summarizer.py:14: temperature is removed in 2.x: delete the argument
    temperature=0.3,
app/proxy.py:22: the SDK now sends Authorization: Bearer, not X-Api-Key
    api_key = request.headers.get("X-Api-Key")

2 potential issue(s) found.

How the Script Works

  • CHECKS maps regular expressions to advice. For example, \btemperature\s*= matches temperature= or temperature = as a whole word (\b), so it finds keyword arguments but not unrelated words that merely contain "temperature".
  • root.rglob("*.py") walks the project recursively and yields every Python file.
  • SKIP_DIRS excludes the virtual environment and other generated folders. Without this, the script would scan the SDK's own source code inside .venv and report hundreds of irrelevant matches. The script also skips its own file, whose patterns would otherwise match themselves.
  • errors="ignore" prevents a crash on files with unusual encodings.
  • For each match, the script prints the file, line number, advice, and the line itself, the familiar path:line format that most editors and terminals turn into clickable links.

The script reports potential issues. A match can be a false positive, such as a variable named temperature in a weather app. Review each finding instead of changing code blindly.


A Safe Upgrade Workflow

For a minor or patch upgrade:

  1. Upgrade in your development environment (pip install --upgrade "anthropic>=2.0,<3").
  2. Run your tests and try the main features.
  3. Update requirements.txt or the lock file, and commit.
  4. Deploy.

For a major upgrade, add preparation and review:

  1. Read the migration guide and release notes for the new major version.
  2. Create a Git branch for the upgrade.
  3. Scan the code for affected patterns, as in the script above.
  4. Upgrade the package and update the version constraint.
  5. Fix each breaking change, then run the full test suite.
  6. Test against the real API in a development or staging workspace, because API behavior changes too.
  7. Check infrastructure: proxies, gateways, and log filters that read headers.
  8. Deploy, and monitor errors, stop_reason values, and token usage after release.

Rolling Back

If an upgrade causes problems, reinstall the previous version:

python -m pip install "anthropic<2"          # Back to the latest 1.x
python -m pip install "anthropic==1.8.0"     # Or an exact known-good version

Then restore the previous requirements.txt or lock file from Git. This is easy because the old versions were recorded.


Common Mistakes

Upgrading the Wrong Environment

What happens: pip install --upgrade anthropic reports success, but anthropic.__version__ still shows the old version.

Why: the upgrade went into a different Python installation than the one running your code.

Fix: activate the project's virtual environment and use python -m pip. Confirm with pip show anthropic that the Location is inside .venv.

Not Restarting Running Processes

What happens: the package is upgraded, but a running web server, worker, or Jupyter kernel keeps the old behavior.

Why: Python imports a module once, when the process starts. Upgrading the files on disk does not change modules already loaded in memory.

Fix: restart the server, worker, or kernel after upgrading.

Upgrading Without Updating the Requirements File

What happens: your machine runs 2.x, but the deployed application still installs 1.x from requirements.txt, or the reverse.

Fix: treat the requirements file as the source of truth. Update it in the same commit as any code changes the upgrade requires.

Unbounded Version Constraints in Production

What happens: requirements.txt contains just anthropic, with no version. A routine deployment silently installs a new major version, and features break.

Fix: use a range that blocks the next major version (anthropic>=2.0,<3), or pin exact versions with a lock file.

Skipping the Migration Guide for a Major Version

What happens: code that sends temperature fails, or a proxy that expects X-Api-Key rejects every request.

Fix: read the migration guide before every major upgrade, and test against the real API before deploying.


Best Practices

  • Upgrade minor and patch versions regularly, for example monthly, to stay current with models, features, and fixes.
  • Plan major upgrades as a separate task with a branch, the migration guide, a code scan, and testing.
  • Constrain the major version in your dependency file (>=2.0,<3), and pin exact versions or use lock files for deployments.
  • Upgrade one major version at a time (0.x → 1.x → 2.x) and test after each step.
  • Restart every process that uses the SDK after upgrading.
  • Log anthropic.__version__ at application startup, so logs show exactly which SDK version produced a given behavior.
  • Use official documentation for your version. When behavior differs from the documentation, check anthropic.__version__ first.

Exercise

  1. Run python -m pip list --outdated in your tutorial environment. Is the SDK up to date?
  2. Install an older 2.x release with an exact version specifier, verify the version, then upgrade back to the newest 2.x release with a range that blocks 3.x.
  3. Create a file containing client.messages.create(..., temperature=0.5, ...) and a call to MessageParam(role="user", content="Hi"). Run scan_for_v2_changes.py and confirm that both are reported.
  4. Rewrite both lines so they are compatible with SDK 2.x.
Show answers for steps 2 and 4

Step 2:

python -m pip install "anthropic==2.0.0"
python -c "import anthropic; print(anthropic.__version__)"   # 2.0.0
python -m pip install --upgrade "anthropic>=2.0,<3"
python -c "import anthropic; print(anthropic.__version__)"   # newest 2.x release

Step 4:

from anthropic.types import MessageParam

# temperature removed
message = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=200,
    messages=[{"role": "user", "content": "Hi"}],
)

# dict literal instead of calling MessageParam
first_message: MessageParam = {"role": "user", "content": "Hi"}

0 Comments

Reviewed before they appear

No comments yet.

Anthropic SDK Using Python
Anthropic SDK Intro Claude API Intro SDK Requirements Install Anthropic SDK Upgrade the SDK Create an API Key Set API Keys Use Environment Variables Import Anthropic Create a Client Send Your First Message Choose a Claude Model Set Max Tokens Read a Response Print Response Text Understand Message Blocks Use System Prompts Send User Messages Set Temperature Handle Stop Reasons Messages API Intro Create Messages Use Message Roles Send Conversation History Continue a Conversation Build a Chat Loop Reset Chat History Use Multiple Turns Inspect Message IDs Read Usage Data Write Clear Prompts Set a System Prompt Add Context to Prompts Use Prompt Templates Add Examples to Prompts Request JSON Output Use XML Tags Control Response Length Improve Prompt Quality Avoid Prompt Injection Read Text Blocks Read Content Blocks Check Stop Reasons Count Input Tokens Count Output Tokens Count Tokens Before Sending Limit Output Tokens Use Stop Sequences Read Request IDs Parse API Responses Streaming Intro Stream Text Output Use Stream Events Use Stream Helpers Get Final Messages Stream Async Responses Handle Stream Errors Build a Live Chat Stream Long Responses Close Streams Safely Build a Chatbot Keep Chat History Manage Chat Sessions Add Chat Memory Build a CLI Chatbot Build a Web Chatbot Use Flask with Claude Use FastAPI with Claude Return JSON from an API Add Chat Error Messages Async SDK Intro Create an Async Client Send Async Messages Use asyncio Run Parallel Requests Stream Async Text Handle Async Errors Set Async Timeouts Close Async Clients Choose Sync or Async Tool Use Intro Define a Tool Create Tool Schemas Send Tools to Claude Read Tool Calls Run Python Tools Return Tool Results Continue After Tool Use Control Tool Choice Handle Tool Errors Use the beta_tool Decorator Create a Tool Runner Add Tool Docstrings Validate Tool Inputs Use Multiple Tools Limit Tool Calls Log Tool Activity Build a Weather Tool Build a Search Tool Build a Calculator Tool Structured Output Intro Request JSON Data Validate JSON Output Use Pydantic Models Handle Invalid JSON Extract Fields from Text Generate Typed Data Use Image URLs Send Base64 Images Read PDFs with Claude Use Output Schemas Build Data Extraction Test Structured Responses Send Image Inputs Upload Files Use File IDs Process Text Files Summarize Documents Extract Table Data Handle File Errors Read Cache Usage Reduce Repeated Input Costs Debug Cache Misses Prompt Caching Intro Enable Prompt Caching Cache System Prompts Cache Long Context Test Cache Performance Use Cache Breakpoints Cache Best Practices Message Batches Intro Create a Message Batch Set Batch IDs Check Batch Status List Message Batches Get Batch Results Process Batch Outputs Handle Failed Batch Items Use Batches for Bulk Tasks Compare Batches and Requests Handle API Errors Handle Rate Limits Retry Failed Requests Set Request Timeouts Handle Network Errors Use Exponential Backoff Build Reliable API Calls Use Extended Thinking Log API Errors Track Request IDs Paginate API Results Set Thinking Budgets Read Thinking Blocks Use Tool Search Use Web Search Tools Use Computer Tools Use Citations Use Token Counting Read Raw Responses Set Custom Headers Use Claude on AWS Bedrock Use Claude on Vertex AI Use Claude on Microsoft Foundry Configure Cloud Credentials Choose a Cloud Provider Compare API Integrations Configure Provider Clients Handle Cloud Errors Use Cloud SDK Extras Deploy Cloud Apps Protect API Keys Use a .env File Ignore Secrets in Git Validate User Input Reduce Prompt Injection Limit Tool Permissions Avoid Unsafe Tool Calls Sanitize Tool Results Set Usage Limits Review Security Logs Test SDK Functions Mock API Responses Test Error Handling Test Streaming Code Measure Token Usage Track API Costs Configure Logging Deploy with Docker Deploy a FastAPI App Monitor Production Apps Build a Claude Chatbot Build a Text Summarizer Build a Code Explainer Build a JSON Extractor Build a PDF Assistant Build a Streaming Chat App Build a Tool-Calling Agent Build a Batch Processor Build a Research Assistant Build a Claude API Dashboard
Ask about this post
AI Ask about this post

Ask questions about Upgrade the SDK and get answers drawn from it.

Signed-in readers only.