# How to Migrate from OpenAI/Anthropic SDKs to LiteLLM: A Complete Guide

> Effortlessly migrate from OpenAI or Anthropic SDKs to LiteLLM. Achieve zero code changes with the LiteLLM proxy or easily swap SDK calls for LiteLLM's completion function, saving time and resources.

- Repository: [Berri AI/litellm](https://github.com/BerriAI/litellm)
- Tags: migration-guide
- Published: 2026-03-26

---

**To migrate from OpenAI or Anthropic SDKs to LiteLLM, either point your existing SDK client to the LiteLLM proxy URL for zero-code changes, or replace SDK calls with `litellm.completion()` using provider-prefixed model names like `anthropic/claude-3-sonnet`.**

Migrating from proprietary SDKs to **LiteLLM** (BerriAI/litellm) unifies access to over 100 LLM providers behind a single interface. Whether you use OpenAI's `chat.completions.create()` or Anthropic's client libraries, LiteLLM provides drop-in compatibility through pass-through endpoints and a unified Python SDK. This guide covers the exact migration paths, authentication flows, and code transformations needed to switch without breaking existing request payloads.

## Why Migrate from OpenAI/Anthropic SDKs to LiteLLM?

LiteLLM eliminates vendor lock-in while preserving your existing code structure. According to the BerriAI/litellm source code, the migration offers four core advantages:

- **Unified API surface** – One Python SDK or proxy URL handles OpenAI, Anthropic, Azure, and 100+ other providers.
- **Transparent request forwarding** – Pass-through endpoints forward original request bodies unchanged, ensuring zero payload transformation.
- **Centralized governance** – LiteLLM manages provider API keys internally, exposing only a single LiteLLM key to your application while enforcing budgets and rate limits.
- **Future-proof architecture** – Adding new providers requires only updating the provider registry in [`get_llm_provider_logic.py`](https://github.com/BerriAI/litellm/blob/main/get_llm_provider_logic.py), not changing your application code.

The core migration logic resides in [`litellm/litellm_core_utils/get_llm_provider_logic.py`](https://github.com/BerriAI/litellm/blob/main/litellm/litellm_core_utils/get_llm_provider_logic.py), which resolves model strings to internal drivers, and [`litellm/main.py`](https://github.com/BerriAI/litellm/blob/main/litellm/main.py), where the unified `completion()` entry point orchestrates requests.

## Migration Paths

### Proxy-First Migration (Zero Code Changes)

The fastest migration path requires no code modifications. By using **pass-through endpoints**, LiteLLM forwards OpenAI/Anthropic requests unchanged to the original provider.

1. Deploy the LiteLLM proxy (Docker or Poetry) at `http://localhost:4000`.
2. Replace the `base_url` in your existing SDK client with the proxy endpoint.
3. Swap your provider API key for a LiteLLM API key.

As documented in [`docs/my-website/docs/pass_through/intro.md`](https://github.com/BerriAI/litellm/blob/main/docs/my-website/docs/pass_through/intro.md), "No translation is done" – the proxy forwards the exact JSON payload to the provider.

```python
import openai

# Change only the base URL and API key

openai.base_url = "http://localhost:4000/openai"
openai.api_key = "sk-lite-llm"  # LiteLLM key, not OpenAI

client = openai.OpenAI()
resp = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Explain quantum tunneling"}]
)

```

### Python SDK Migration

Replace proprietary SDK imports with `litellm.completion()`. This method accepts provider-prefixed model names (e.g., `anthropic/claude-3-sonnet-20240229`) and automatically routes to the correct internal driver.

```python
import litellm

response = litellm.completion(
    model="anthropic/claude-3-sonnet-20240229",  # provider prefix

    messages=[{"role": "user", "content": "Write a haiku"}],
    api_key="sk-lite-llm"  # LiteLLM API key

)
print(response.choices[0].message.content)

```

The `completion` function in [`litellm/main.py`](https://github.com/BerriAI/litellm/blob/main/litellm/main.py) (lines 49-61) validates parameters and delegates to the provider-specific implementation based on the model string prefix.

### Explicit Provider Specification

When model names lack a provider prefix (e.g., `gpt-4o` instead of `openai/gpt-4o`), use the `custom_llm_provider` parameter to specify the driver explicitly.

```python
import litellm

response = litellm.completion(
    model="gpt-4o-mini",
    custom_llm_provider="openai",  # explicit provider selection

    messages=[{"role": "user", "content": "Summarize this article"}],
    api_key="sk-lite-llm"
)

```

According to [`get_llm_provider_logic.py`](https://github.com/BerriAI/litellm/blob/main/get_llm_provider_logic.py) (lines 99-110), the resolution algorithm first checks for a `/` delimiter in the model string, then falls back to the `custom_llm_provider` argument if no prefix exists.

## Authentication and API Key Handling

LiteLLM abstracts provider authentication through a two-tier key system:

| Client Action | LiteLLM Processing |
| --- | --- |
| Sends `Authorization: Bearer <LITELLM_API_KEY>` | Validates against internal key store |
| LiteLLM proxy lookup | Retrieves provider-specific key (e.g., `OPENAI_API_KEY`) from environment or database |
| Outbound request | Injects provider key into forwarded request headers |

This flow means your application only stores the LiteLLM key. The proxy maps this to the actual OpenAI, Anthropic, or Azure keys internally, as visualized in the pass-through documentation.

## Error Handling Behavior

LiteLLM preserves provider-specific error semantics:

- **Provider errors** – HTTP status codes and JSON error bodies from OpenAI/Anthropic pass through unchanged to your client.
- **LiteLLM errors** – Authentication failures (invalid LiteLLM key) or configuration issues return standard HTTP codes (`401` for unauthorized, `404` for missing models, `500` for internal errors).

## Code Examples: Before and After

### Original OpenAI SDK Implementation

```python
import openai

openai.api_key = "sk-openai-original"
client = openai.OpenAI()

resp = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Explain quantum tunneling"}]
)
print(resp.choices[0].message.content)

```

### Drop-in Proxy Replacement

```python
import openai

# Only base_url and api_key change

openai.base_url = "http://localhost:4000/openai"
openai.api_key = "sk-lite-llm"

client = openai.OpenAI()
resp = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Explain quantum tunneling"}]
)

```

### LiteLLM Python SDK Implementation

```python
import litellm

# Works for OpenAI, Anthropic, Azure, and 100+ providers

response = litellm.completion(
    model="anthropic/claude-3-sonnet-20240229",
    messages=[{"role": "user", "content": "Explain quantum tunneling"}],
    api_key="sk-lite-llm"
)

```

## Summary

- **Pass-through endpoints** in LiteLLM allow zero-code migration by forwarding OpenAI/Anthropic requests unchanged.
- **Provider resolution** uses model string prefixes (`anthropic/`, `openai/`) or the `custom_llm_provider` parameter as implemented in [`get_llm_provider_logic.py`](https://github.com/BerriAI/litellm/blob/main/get_llm_provider_logic.py).
- **Unified authentication** replaces multiple provider keys with a single LiteLLM API key mapped internally.
- **Error transparency** ensures provider-specific status codes and messages pass through without transformation.
- **Future extensibility** means adding providers requires only registry updates, not application code changes.

## Frequently Asked Questions

### Do I need to change my request payload when migrating to LiteLLM?

No. When using pass-through endpoints, LiteLLM forwards the exact JSON payload to the provider without translation. According to the BerriAI/litellm source code, the proxy "does not modify the request body," allowing existing OpenAI/Anthropic SDK calls to work unchanged.

### How does LiteLLM determine which provider to use?

LiteLLM uses the `get_llm_provider()` function in [`litellm/litellm_core_utils/get_llm_provider_logic.py`](https://github.com/BerriAI/litellm/blob/main/litellm/litellm_core_utils/get_llm_provider_logic.py) to parse the model string. If the string contains a prefix like `anthropic/claude-3-sonnet`, it extracts the provider. Otherwise, it uses the `custom_llm_provider` parameter or falls back to environment-based defaults.

### Can I keep using the OpenAI SDK after migrating?

Yes. By setting `openai.base_url` to your LiteLLM proxy endpoint (e.g., `http://localhost:4000/openai`) and using a LiteLLM API key, you can continue using the official OpenAI Python SDK while routing through LiteLLM's unified infrastructure.

### What happens to provider-specific errors?

Provider errors pass through unchanged. If Anthropic returns a 429 rate limit error, your client receives the identical 429 status code and error body. LiteLLM only returns its own error codes (401, 404, 500) for proxy-specific issues like invalid LiteLLM keys or missing configurations.