How to Migrate from Older Versions of the Anthropic Python SDK to the Modern Messages API

Upgrade to the latest SDK version and replace all client.completions.create calls with client.messages.create, converting legacy LegacyAPIResponse objects to the modern APIResponse type to access Claude 3 features and avoid deprecation warnings.

The Anthropic Python SDK has evolved significantly from its early releases, moving from the legacy Text Completion endpoint to the modern Messages API. If you are looking to migrate from older versions of the Anthropic Python SDK, you will need to update your code to use client.messages.create instead of client.completions.create and handle the new response types defined in the current codebase. This guide provides concrete steps, code examples, and source file references from the anthropics/anthropic-sdk-python repository to ensure a smooth transition.

Identify Legacy Usage in Your Codebase

Legacy constructs typically appear as calls to client.completions.create and references to LegacyAPIResponse. Search your project for these patterns to locate all migration targets.

Key legacy symbols and their locations:

Example legacy code pattern:

import anthropic

client = anthropic.Anthropic()
response = client.completions.create(
    model="claude-2.1",
    prompt="Human: Hello\nAssistant:",
    max_tokens_to_sample=512,
)

# response is a LegacyAPIResponse

content = response.content  # property, not method

Upgrade the Anthropic Python SDK Package

Before migrating your code, ensure you have the latest SDK version installed:

pip install --upgrade anthropic

The latest release ships with the new APIResponse and AsyncAPIResponse types, along with deprecation warnings for legacy endpoints.

Switch from Text Completions to the Messages API

The Messages API is the recommended interface for all new development. Replace every client.completions.create call with client.messages.create.

Before (Legacy)

response = client.completions.create(
    model="claude-2.1",
    prompt="Human: Hello\nAssistant:",
    max_tokens_to_sample=512,
)
print(response.content)

After (Modern)

response = client.messages.create(
    model="claude-3-sonnet-20240229",
    max_tokens=512,
    messages=[
        {"role": "user", "content": "Hello"},
    ],
)
print(response.content)

Implementation reference: The new endpoint is implemented in [src/anthropic/resources/messages/messages.py](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/resources/messages/messages.py). The legacy completions.py file includes a migration note in its docstring pointing to the official migration guide.

Update Response Handling from LegacyAPIResponse to APIResponse

The new response class lives in src/anthropic/_response.py. Key differences between the legacy and modern implementations:

Feature LegacyAPIResponse APIResponse
.content / .text Properties (eagerly read) Properties (eagerly read, with .read() and .json() available)
Streaming Returns Stream wrapper via stream=True Returns unified Stream/AsyncStream types
Future support Will be removed in next major version Current class

Remove any explicit imports of LegacyAPIResponse and rely on the client's return type inference:


# Old

from anthropic._legacy_response import LegacyAPIResponse

# New - rely on implicit return types or import if needed

from anthropic._response import APIResponse

# The client automatically returns APIResponse when calling messages.create()

response = client.messages.create(...)

Migrate Streaming Implementations

Legacy streaming overloads returned Stream[Completion]. The modern implementation returns Stream[Message] for the Messages API.

Legacy streaming:

stream = client.completions.create(
    model="claude-2.1",
    prompt="Human: Tell me a story\nAssistant:",
    max_tokens_to_sample=512,
    stream=True,
)
for event in stream:
    print(event.type)  # event is a Completion chunk

Modern streaming:

stream = client.messages.create(
    model="claude-3-sonnet-20240229",
    max_tokens=512,
    messages=[{"role": "user", "content": "Tell me a story"}],
    stream=True,
)
for event in stream:
    print(event.type)  # event is a Message chunk

Reference: Streaming handling is defined in [src/anthropic/_streaming.py](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_streaming.py).

Handle Model Deprecation Warnings

The SDK emits warnings when you use models slated for deprecation. For example, the Messages API implementation includes logic to warn about legacy model usage (see lines 984‑1062 in [src/anthropic/resources/messages/messages.py](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/resources/messages/messages.py)).

When you encounter warnings like:

"The model 'claude‑2.1' is deprecated and will reach end‑of‑life on … Please migrate to a newer model."

Update your model parameter to a supported version (e.g., claude-3-sonnet-20240229 or claude-3-5-sonnet-20241022).

Verify Your Migration

After completing the code changes:

  1. Run your test suite to ensure functional parity:

    pytest -q
  2. Smoke-test production code by invoking a simple request using the new Messages API.

  3. Check logs for deprecation warnings and update any remaining outdated model names.

Summary

  • Upgrade the package with pip install --upgrade anthropic to access the modern APIResponse types.
  • Replace client.completions.create with client.messages.create and restructure prompts into the messages format ([{"role": "user", "content": "..."}]).
  • Remove LegacyAPIResponse imports; the client now returns APIResponse objects automatically.
  • Update streaming code to handle Stream[Message] instead of Stream[Completion].
  • Address model deprecation warnings by switching to Claude 3 or newer model identifiers.

Frequently Asked Questions

How do I know if my code is using the legacy API?

Search your codebase for client.completions.create or imports of LegacyAPIResponse from anthropic._legacy_response. If you find either pattern, you are using the legacy Text Completion endpoint that returns LegacyAPIResponse objects instead of the modern APIResponse type used by the Messages API.

What is the difference between LegacyAPIResponse and APIResponse?

LegacyAPIResponse, defined in src/anthropic/_legacy_response.py, is a legacy wrapper that exposes .content and .text as properties for the Text Completion endpoint. APIResponse, defined in src/anthropic/_response.py, is the modern response class used by the Messages API that provides the same properties plus additional methods like .read() and .json(). LegacyAPIResponse will be removed in the next major version.

Can I still use streaming with the new Messages API?

Yes. Pass stream=True to client.messages.create to receive a Stream[Message] object. Iterate over this stream to process Message chunks instead of the legacy Completion chunks. The streaming implementation is defined in src/anthropic/_streaming.py and works identically for both synchronous and asynchronous clients.

Which models should I use after migrating?

Replace deprecated models like claude-2.1 with modern Claude 3 or Claude 3.5 series models such as claude-3-sonnet-20240229, claude-3-opus-20240229, or claude-3-5-sonnet-20241022. The SDK emits deprecation warnings when you invoke legacy models, directing you to the model deprecation documentation for specific end-of-life dates.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →