Claude API LiteLLM Proxy Setup Guide
If you're searching for a way to call Claude through an OpenAI-compatible interface, route multiple models through one endpoint, or add basic usage tracking without writing it yourself, LiteLLM's proxy server is the standard tool for the job. This guide walks through the actual setup: installing LiteLLM, configuring it for Claude, running the proxy, and the gotchas that trip people up the first time.
The short version: LiteLLM proxy is a lightweight server you run (locally, in Docker, or on a VM) that translates OpenAI-format requests into Anthropic's Messages API format and back. You configure it with your ANTHROPIC_API_KEY, define model aliases in a YAML file, and your app talks to http://localhost:4000/v1/chat/completions instead of directly to Anthropic. This is useful if you're migrating code that already speaks OpenAI's SDK, or if you want to proxy several providers (Claude, GPT, local models) through one URL.
What the LiteLLM Proxy Actually Does
LiteLLM sits between your application and Anthropic's API. It handles:
- Format translation — your code sends OpenAI-style
messagesarrays, LiteLLM converts them to Claude's Messages API schema - Model routing — map a friendly name like
claude-maintoclaude-3-5-sonnet-20241022in config, swap models without touching app code - Key management — store the real Anthropic key server-side, issue virtual keys to different services or teams
- Basic logging — request/response logs, optional cost tracking if you configure a database backend
It does not give you a hosted dashboard, billing, or team seat management out of the box — that part you build or bolt on yourself.
Prerequisites
- An Anthropic API key with Claude access
- Python 3.9+ (for the pip install path) or Docker
- A place to run the proxy: a VM, a container host, or your laptop for local dev
Step 1: Install LiteLLM
pip install 'litellm[proxy]'
Or run it via Docker if you'd rather not manage a Python environment:
docker run -p 4000:4000 \
-e ANTHROPIC_API_KEY=sk-ant-xxxx \
ghcr.io/berriai/litellm:main-latest \
--config /app/config.yaml
Step 2: Write the Config File
LiteLLM reads a config.yaml to know which models to expose and how to reach them. A minimal Claude-only setup:
model_list:
- model_name: claude-main
litellm_params:
model: anthropic/claude-3-5-sonnet-20241022
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: claude-fast
litellm_params:
model: anthropic/claude-3-5-haiku-20241022
api_key: os.environ/ANTHROPIC_API_KEY
general_settings:
master_key: sk-litellm-master-123
model_name is what your app will request. litellm_params.model is the real Anthropic model string, prefixed with anthropic/ so LiteLLM knows which provider adapter to use. The master_key protects the proxy itself — requests without it get rejected.
Step 3: Run the Proxy
export ANTHROPIC_API_KEY=sk-ant-xxxx
litellm --config config.yaml --port 4000
You should see LiteLLM confirm it loaded both models and is listening on port 4000.
Step 4: Call It From Your App
Once running, you talk to it exactly like the OpenAI Chat Completions endpoint:
curl http://localhost:4000/v1/chat/completions \
-H "Authorization: Bearer sk-litellm-master-123" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-main",
"messages": [{"role": "user", "content": "Summarize this changelog."}]
}'
Any OpenAI SDK client works unmodified — just point base_url at your proxy:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "sk-litellm-master-123",
baseURL: "http://localhost:4000/v1",
});
const res = await client.chat.completions.create({
model: "claude-main",
messages: [{ role: "user", content: "Summarize this changelog." }],
});
Common Pitfalls
- Streaming inconsistencies. LiteLLM translates streamed chunks between formats, and occasionally a field (like stop reason) doesn't map cleanly. Test streaming specifically before shipping it.
- Tool/function calling schema mismatches. Claude's tool_use blocks and OpenAI's function_call format aren't identical. Complex multi-tool workflows sometimes need manual adjustment in the config or your parsing code.
- No built-in billing per app key. LiteLLM can track spend if you wire up a Postgres database for its usage logs, but there's no dashboard for issuing per-customer API keys with individual rate limits unless you build that layer yourself.
- Running it in production means running it. You're now responsible for uptime, scaling, and patching the proxy — it's another service in your stack, not a managed endpoint.
When You Want the Proxy Without Running the Proxy
If what you actually need is a stable HTTPS endpoint with Claude behind it, application-level API keys, and basic usage visibility — without hosting and maintaining a LiteLLM instance yourself — that's the gap SubToAPI fills. You get a sub_live_... key per app, streaming and tool use support, and team seats, without a config.yaml or a server to patch.
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize this changelog."}]
}'
Check the quickstart and messages API reference for the full request format, or start a free trial at signup if you'd rather skip the proxy maintenance entirely. Pricing is on /pricing — Solo at €9, Team at €19/seat, Scale at €49/seat.
LiteLLM is the right call if you're already deep into multi-provider routing and want that flexibility. If you just need Claude behind a clean API with less operational overhead, a hosted layer is the simpler path.
Questions
Does LiteLLM change what Claude outputs, or just the request/response format? Just the format. LiteLLM translates between OpenAI-style and Anthropic-style schemas — the model, its outputs, and its behavior are unchanged.
Can I run LiteLLM proxy with multiple Claude models and switch between them per request? Yes — define each model under model_list in config.yaml with a distinct model_name, then pass that name in the model field of your request to route to it.
Is LiteLLM proxy suitable for production traffic? It can be, but you need to handle its uptime, scaling, and database for logging yourself — it's self-hosted infrastructure, not a managed service, so plan for that operational cost.