Find a file
Mateo Wang 250d8d2a96
fix(a2a): forward agent_extra_headers through completion bridge (#28277)
* fix(a2a): forward agent_extra_headers through completion bridge

A2A agents backed by a custom_llm_provider (e.g. langgraph,
bedrock_agentcore) silently dropped any per-request headers rewritten
from the inbound `x-a2a-{agent}-*` convention or admin-configured
`extra_headers`. The headers were correctly extracted in
`a2a_endpoints.py` but never passed into
`_send_message_via_completion_bridge` or the bridge handler, so the
upstream HTTP request reached the agent backend without them.

Thread `agent_extra_headers` through:
  - asend_message / asend_message_streaming -> bridge call sites
  - _send_message_via_completion_bridge
  - A2ACompletionBridgeHandler.handle_non_streaming / handle_streaming
  - Inject as `extra_headers` into the underlying litellm.acompletion()
    call, and forward to provider configs via kwargs (their **kwargs
    signature absorbs it harmlessly today).

* fix(a2a): forward agent_extra_headers through bridge convenience wrappers

Address greptile review on PR #28277:

- handle_a2a_completion / handle_a2a_completion_streaming (the public,
  exported convenience wrappers) now accept agent_extra_headers and
  forward it to the underlying class methods. Without this, callers
  going through the public API would still silently drop per-request
  headers — the exact regression this PR fixes for the class-method
  path.
- Add the missing agent_extra_headers entry to the handle_streaming
  docstring for parity with handle_non_streaming.

Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>

* fix(a2a/bedrock): forward agent_extra_headers to AgentCore HTTP request

Address greptile follow-up on PR #28277:

BedrockAgentCoreA2AConfig was absorbing agent_extra_headers via **kwargs
but never propagating to the underlying HTTP POST, so x-a2a-{agent}-*
rewrites and admin extra_headers were silently dropped on the
bedrock_agentcore path that bypasses the completion bridge.

Thread the parameter through the full Bedrock AgentCore stack:
- config.handle_non_streaming / handle_streaming pull
  agent_extra_headers from kwargs and pass to the handler.
- handler.handle_non_streaming / handle_streaming accept it and forward
  to the transformation layer.
- transformation.get_url_and_signed_request merges agent_extra_headers
  into the headers dict BEFORE signing, so SigV4 covers them in the
  signature. JWT/Bearer path: AgentCore signer always overwrites
  Authorization with api_key, so use api_key (not agent_extra_headers)
  to override the bearer token.

Also fix a pre-existing test assertion that was already broken by the
parent commit ab70ff6 (test_provider_config_receives_litellm_params
didn't include agent_extra_headers in the expected call).

Tests:
- TestTransformation::test_agent_extra_headers_merged_into_signed_headers_jwt
- TestTransformation::test_agent_extra_headers_signed_for_sigv4
- TestNonStreaming::test_agent_extra_headers_forwarded_on_outbound_post

Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>

* fix(a2a/bedrock): drop reserved AWS headers from agent_extra_headers

Per veria-ai security review on PR #28277:

agent_extra_headers carries values rewritten from the client-controlled
x-a2a-{agent}-* convention, so the unconditional 'headers.update(agent_extra_headers)'
in BedrockAgentCoreA2ATransformation.get_url_and_signed_request let any
caller with access to an agent overwrite headers the proxy sets from
trusted server-side config -- most notably
X-Amzn-Bedrock-AgentCore-Runtime-User-Id, which AWS treats as the runtime
identity. Because the merge happened before SigV4 signing, the spoofed
value would also be bound into a valid signature.

Strip reserved AWS/AgentCore headers (authorization, host,
x-amzn-bedrock-agentcore-runtime-*, x-amz-*) from agent_extra_headers
before merging and log a warning when any are dropped. Legitimate
per-request headers (e.g. x-mcp-token, x-tenant) still pass through.

Adds two tests covering both the JWT path (verifies the spoof does not
land on the outbound headers) and the SigV4 path (verifies the signer
never sees the spoofed values).

Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>

* fix(a2a): annotate completion_params dict for mypy

The dict literal initializing completion_params had heterogeneous value
types (str, list, bool), so mypy inferred the value type as a narrow
union that did not accept dict[str, str] when assigning extra_headers.

Annotate completion_params as Dict[str, Any] in both the non-streaming
and streaming bridge handlers so the agent_extra_headers merge
type-checks cleanly.

Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>

* fix(a2a/pydantic_ai): forward agent_extra_headers to upstream HTTP request

* fix(a2a/bridge): admin litellm_params.extra_headers win over caller-rewritten headers

agent_extra_headers contains both admin static_headers and caller-derived
dynamic headers (from the x-a2a-{agent}-* rewrite). Merging it last would
let a caller replace headers that the proxy was configured to send upstream
via litellm_params.extra_headers. Flip the merge order so admin-configured
headers take precedence on conflict.

* fix(a2a/headers): merge_agent_headers compares case-insensitively

HTTP header names are case-insensitive, but the previous merge was a
case-sensitive dict update. That meant an admin-configured
static_headers['Authorization'] (capital A) did not strip a
caller-rewritten x-a2a-{agent}-authorization (lowercase, from the
inbound header normalization in a2a_endpoints) - both ended up on the
outbound request to pydantic_ai / langgraph / etc.

Restore the documented 'static wins on conflict' invariant by comparing
case-insensitively when overlaying static_headers. Static side's casing
is preserved on the output.

* fix(a2a/bridge): merge configured extra_headers case-insensitively over caller headers

A caller-rewritten lowercase header (e.g. authorization from the
x-a2a-{agent}-* convention) could ride alongside an admin-configured
case-variant key in litellm_params.extra_headers, sending duplicate
Authorization headers upstream. The bridge now reuses
merge_agent_headers so configured headers win case-insensitively, in
both the non-streaming and streaming paths. merge_agent_headers moved
to litellm.interactions.agents.utils (re-exported from the proxy utils)
so the SDK-level bridge does not import from litellm.proxy.

https://claude.ai/code/session_017cBvda8Y4CLo8wspB2kfSV

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>
2026-06-11 21:56:18 -07:00
.circleci test(ui): data-driven App Router migration E2E smoke (default + server-root-path) (#29974) 2026-06-09 10:40:01 -07:00
.devcontainer build: migrate packaging, CI, and Docker from Poetry to uv (#25007) 2026-04-09 11:46:23 -07:00
.githooks chore(hooks): enforce Conventional Commits and Conventional Branches (#30174) 2026-06-11 10:00:23 -07:00
.github chore(hooks): enforce Conventional Commits and Conventional Branches (#30174) 2026-06-11 10:00:23 -07:00
.semgrep/rules security: remove .claude/settings.json and add semgrep rule to prevent re-adding 2026-03-25 11:57:43 -07:00
backend fix(docker): use system Node in componentized builders + retry apk add (#28888) 2026-05-26 15:41:38 -07:00
ci_cd Drop dep bumps + black-26 reformat to clear fork CI policy 2026-05-07 23:04:52 +00:00
cookbook chore(cookbook): bump Go directive to 1.26.3 in gollem example (#29234) 2026-05-28 18:12:31 -07:00
db_scripts feat(spend_logs): opt-in native Postgres partitioning for SpendLogs retention (#29466) 2026-06-11 11:02:42 -07:00
deploy feat(proxy): native /health/drain preStop hook for graceful shutdown (#29439) 2026-06-02 16:30:44 -07:00
dist build: update dependencies 2025-11-01 12:58:39 -07:00
docker chore(admin-ui): regenerate static export with trailingSlash: true (#28112) 2026-05-25 21:06:50 -07:00
docs fix(hosted_vllm): normalize custom tools for chat completions (#25763) 2026-05-05 17:27:02 -07:00
enterprise chore(deps): bump deps (#29373) 2026-05-30 20:41:23 -07:00
gateway Litellm OSS Staging 010626 (#29422) 2026-06-01 21:42:51 -07:00
helm/litellm fix(helm): Enable Backend Deployment to mount Gateway config.yaml (#29605) 2026-06-04 12:07:19 -07:00
litellm fix(a2a): forward agent_extra_headers through completion bridge (#28277) 2026-06-11 21:56:18 -07:00
litellm-proxy-extras chore(deps): bump deps (#29860) 2026-06-06 21:44:54 +00:00
migrations fix(docker): use system Node in componentized builders + retry apk add (#28888) 2026-05-26 15:41:38 -07:00
packaging/homebrew feat(cli): per-agent lite claude / codex / opencode commands that wrap coding agents through the proxy (#29850) 2026-06-10 13:52:26 -07:00
scripts feat(rate-limiter): allow opting out of v3 TPM reservation and Redis circuit breaker (#30211) 2026-06-11 10:34:26 -07:00
terraform/litellm fix(terraform/gcp): abandon SQL user on destroy (#29855) 2026-06-06 13:42:35 -07:00
tests fix(a2a): forward agent_extra_headers through completion bridge (#28277) 2026-06-11 21:56:18 -07:00
ui feat(ui): migrate mcp-servers, search-tools, tag-management, vector-stores, and memory to path routes (#30261) 2026-06-11 18:17:06 -07:00
.dockerignore fix critical CVE vulnerabliltes (#20683) 2026-02-07 22:23:01 -08:00
.env.example Add new model provider Novita AI (#7582) (#9527) 2025-05-12 21:49:30 -07:00
.flake8 chore: list all ignored flake8 rules explicit 2023-12-23 09:07:59 +01:00
.git-blame-ignore-revs chore: ignore prettier dashboard reformat in git blame (#29695) 2026-06-04 11:47:04 -07:00
.gitattributes feat(ui): generate dashboard API types from the proxy OpenAPI spec (#29816) 2026-06-05 17:20:01 -07:00
.gitguardian.yaml build: migrate packaging, CI, and Docker from Poetry to uv (#25007) 2026-04-09 11:46:23 -07:00
.gitignore tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
.npmrc [Fix] CI/Tooling: Correct min-release-age value in .npmrc files 2026-04-29 19:49:27 -07:00
AGENTS.md docs: hand-written CLAUDE.md; point GEMINI.md and AGENTS.md at it (#29252) 2026-05-29 00:05:05 -07:00
ARCHITECTURE.md feat(litellm): add models and repository layers (#29686) 2026-06-06 20:59:33 -07:00
CLAUDE.md feat: add conventional commits and coding guidelines (#30159) 2026-06-10 16:34:08 -07:00
codecov.yaml fix(ci): flag codecov uploads, enable carryforward, close coverage gaps (#28028) 2026-05-16 10:56:32 -07:00
CONTRIBUTING.md chore(hooks): enforce Conventional Commits and Conventional Branches (#30174) 2026-06-11 10:00:23 -07:00
cosign.pub [Infra] Add release workflow and cosign public key 2026-03-31 14:30:27 -07:00
docker-compose.hardened.yml [Feature] Download Prisma binaries at build time instead of at runtime for Security Restricted environments (#17695) 2025-12-16 21:25:53 +05:30
docker-compose.yml feat: add read-replica routing for Prisma DB via DATABASE_URL_READ_REPLICA (#27493) 2026-05-08 21:05:50 -07:00
Dockerfile fix(docker): restore npm@11.14.0 lost in merge resolution 2026-05-07 17:25:10 -07:00
GEMINI.md docs: hand-written CLAUDE.md; point GEMINI.md and AGENTS.md at it (#29252) 2026-05-29 00:05:05 -07:00
LICENSE refactor: creating enterprise folder 2024-02-15 12:54:13 -08:00
license_cache.json Add granian as a ASGI compliant web server. Provider better throughput stability, (#26027) 2026-05-21 19:08:37 -07:00
Makefile chore(hooks): enforce Conventional Commits and Conventional Branches (#30174) 2026-06-11 10:00:23 -07:00
mcp_servers.json Add ScrapeGraph MCP server configuration (#18923) 2026-01-11 21:57:46 +05:30
model_prices_and_context_window.json Litellm oss 090626 (#30021) 2026-06-10 10:34:07 -07:00
package-lock.json chore(deps): refresh dependency locks 2026-05-04 11:36:18 -07:00
package.json chore(deps): refresh dependency locks 2026-05-04 11:36:18 -07:00
policy_templates.json feat: Add Canadian PII protection (PIPEDA) (#22951) 2026-03-06 18:27:31 -08:00
prometheus.yml build(docker-compose.yml): add prometheus scraper to docker compose 2024-07-24 10:09:23 -07:00
provider_endpoints_support.json Litellm oss staging 080626 (#29932) 2026-06-08 13:49:52 -07:00
proxy_server_config.yaml Extend the record/replay proxy to chat, embeddings, moderations, rerank, and Anthropic (#29847) 2026-06-06 14:33:42 -07:00
pyproject.toml feat(cli): per-agent lite claude / codex / opencode commands that wrap coding agents through the proxy (#29850) 2026-06-10 13:52:26 -07:00
pyrightconfig.json Agents - support agent registration + discovery (A2A spec) (#16615) 2025-11-14 18:23:30 -08:00
README.md Litellm oss staging 050626 (#29774) 2026-06-05 13:51:51 -07:00
render.yaml build(render.yaml): fix health check route 2024-05-24 09:45:28 -07:00
ruff.toml [Fix] CI: fix 6 more CircleCI job failures from uv migration 2026-04-10 21:06:25 -07:00
schema.prisma feat(mcp): per-server env vars with global + per-user scopes (#28917) 2026-06-05 20:15:11 -07:00
security.md docs(security): require a reproduction video for vulnerability reports (#30048) (#30063) 2026-06-09 14:59:50 -07:00
taplo.toml fix(agentcore): simplify agentcore streaming (#17141) 2026-01-19 05:20:24 -08:00
uv.lock feat(cli): per-agent lite claude / codex / opencode commands that wrap coding agents through the proxy (#29850) 2026-06-10 13:52:26 -07:00

🚅 LiteLLM

LiteLLM AI Gateway

Open Source AI Gateway for 100+ LLMs. Self-hosted. Enterprise-ready. Call any LLM in OpenAI format.

Deploy to Render Deploy on Railway

LiteLLM Proxy Server (AI Gateway) | Hosted Proxy | Enterprise Tier | Website

PyPI Version GitHub Stars Y Combinator W23 Whatsapp Discord Slack CodSpeed

LiteLLM AI Gateway

What is LiteLLM

LiteLLM is an open source AI Gateway that gives you a single, unified interface to call 100+ LLM providers — OpenAI, Anthropic, Gemini, Bedrock, Azure, and more — using the OpenAI format.

Use it as a Python SDK for direct library integration, or deploy the AI Gateway (Proxy Server) as a centralized service for your team or organization.

Jump to LiteLLM Proxy (LLM Gateway) Docs
Jump to Supported LLM Providers


Why LiteLLM

Managing LLM calls across providers gets complicated fast — different SDKs, auth patterns, request formats, and error types for every model. LiteLLM removes that friction:

  • Unified API — one interface for 100+ LLMs, no provider-specific SDK juggling
  • Drop-in OpenAI compatibility — swap providers without rewriting your code
  • Production-ready gateway — virtual keys, spend tracking, guardrails, load balancing, and an admin dashboard out of the box
  • 8ms P95 latency at 1k RPS (benchmarks)

OSS Adopters

Stripe image Google ADK Greptile OpenHands

Netflix

OpenAI Agents SDK

Features

LLMs - Call 100+ LLMs (Python SDK + AI Gateway)

All Supported Endpoints - /chat/completions, /responses, /embeddings, /images, /audio, /batches, /rerank, /a2a, /messages and more.

Python SDK

uv add litellm
from litellm import completion
import os

os.environ["OPENAI_API_KEY"] = "your-openai-key"
os.environ["ANTHROPIC_API_KEY"] = "your-anthropic-key"

# OpenAI
response = completion(model="openai/gpt-4o", messages=[{"role": "user", "content": "Hello!"}])

# Anthropic  
response = completion(model="anthropic/claude-sonnet-4-20250514", messages=[{"role": "user", "content": "Hello!"}])

AI Gateway (Proxy Server)

Getting Started - E2E Tutorial - Setup virtual keys, make your first request

uv tool install 'litellm[proxy]'
litellm --model gpt-4o
import openai

client = openai.OpenAI(api_key="anything", base_url="http://0.0.0.0:4000")
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}]
)

Docs: LLM Providers

Agents - Invoke A2A Agents (Python SDK + AI Gateway)

Supported Providers - LangGraph, Vertex AI Agent Engine, Azure AI Foundry, Bedrock AgentCore, Pydantic AI

Python SDK - A2A Protocol

from litellm.a2a_protocol import A2AClient
from a2a.types import SendMessageRequest, MessageSendParams
from uuid import uuid4

client = A2AClient(base_url="http://localhost:10001")

request = SendMessageRequest(
    id=str(uuid4()),
    params=MessageSendParams(
        message={
            "role": "user",
            "parts": [{"kind": "text", "text": "Hello!"}],
            "messageId": uuid4().hex,
        }
    )
)
response = await client.send_message(request)

AI Gateway (Proxy Server)

Step 1. Add your Agent to the AI Gateway

Step 2. Call Agent via A2A SDK

from a2a.client import A2ACardResolver, A2AClient
from a2a.types import MessageSendParams, SendMessageRequest
from uuid import uuid4
import httpx

base_url = "http://localhost:4000/a2a/my-agent"  # LiteLLM proxy + agent name
headers = {"Authorization": "Bearer sk-1234"}    # LiteLLM Virtual Key

async with httpx.AsyncClient(headers=headers) as httpx_client:
    resolver = A2ACardResolver(httpx_client=httpx_client, base_url=base_url)
    agent_card = await resolver.get_agent_card()
    client = A2AClient(httpx_client=httpx_client, agent_card=agent_card)

    request = SendMessageRequest(
        id=str(uuid4()),
        params=MessageSendParams(
            message={
                "role": "user",
                "parts": [{"kind": "text", "text": "Hello!"}],
                "messageId": uuid4().hex,
            }
        )
    )
    response = await client.send_message(request)

Docs: A2A Agent Gateway

MCP Tools - Connect MCP servers to any LLM (Python SDK + AI Gateway)

Python SDK - MCP Bridge

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from litellm import experimental_mcp_client
import litellm

server_params = StdioServerParameters(command="python", args=["mcp_server.py"])

async with stdio_client(server_params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()

        # Load MCP tools in OpenAI format
        tools = await experimental_mcp_client.load_mcp_tools(session=session, format="openai")

        # Use with any LiteLLM model
        response = await litellm.acompletion(
            model="gpt-4o",
            messages=[{"role": "user", "content": "What's 3 + 5?"}],
            tools=tools
        )

AI Gateway - MCP Gateway

Step 1. Add your MCP Server to the AI Gateway

Step 2. Call MCP tools via /chat/completions

curl -X POST 'http://0.0.0.0:4000/v1/chat/completions' \
  -H 'Authorization: Bearer sk-1234' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Summarize the latest open PR"}],
    "tools": [{
      "type": "mcp",
      "server_url": "litellm_proxy/mcp/github",
      "server_label": "github_mcp",
      "require_approval": "never"
    }]
  }'

Use with Cursor IDE

{
  "mcpServers": {
    "LiteLLM": {
      "url": "http://localhost:4000/mcp/",
      "headers": {
        "x-litellm-api-key": "Bearer sk-1234"
      }
    }
  }
}

Docs: MCP Gateway

Supported Providers (Website Supported Models | Docs)

Provider /chat/completions /messages /responses /embeddings /image/generations /audio/transcriptions /audio/speech /moderations /batches /rerank
Abliteration (abliteration) ✅
AI/ML API (aiml) ✅ ✅ ✅ ✅ ✅
AI21 (ai21) ✅ ✅ ✅
AI21 Chat (ai21_chat) ✅ ✅ ✅
Aleph Alpha ✅ ✅ ✅
Amazon Nova ✅ ✅ ✅
Anthropic (anthropic) ✅ ✅ ✅ ✅
Anthropic Text (anthropic_text) ✅ ✅ ✅ ✅
Anyscale ✅ ✅ ✅
AssemblyAI (assemblyai) ✅ ✅ ✅ ✅
Auto Router (auto_router) ✅ ✅ ✅
AWS - Bedrock (bedrock) ✅ ✅ ✅ ✅ ✅
AWS - Sagemaker (sagemaker) ✅ ✅ ✅ ✅
Azure (azure) ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
Azure AI (azure_ai) ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
Azure Text (azure_text) ✅ ✅ ✅ ✅ ✅ ✅ ✅
Baseten (baseten) ✅ ✅ ✅
Bytez (bytez) ✅ ✅ ✅
Cerebras (cerebras) ✅ ✅ ✅
Clarifai (clarifai) ✅ ✅ ✅
Cloudflare AI Workers (cloudflare) ✅ ✅ ✅
Codestral (codestral) ✅ ✅ ✅
Cohere (cohere) ✅ ✅ ✅ ✅ ✅
Cohere Chat (cohere_chat) ✅ ✅ ✅
CometAPI (cometapi) ✅ ✅ ✅ ✅
CompactifAI (compactifai) ✅ ✅ ✅
Custom (custom) ✅ ✅ ✅
Custom OpenAI (custom_openai) ✅ ✅ ✅ ✅ ✅ ✅ ✅
Dashscope (dashscope) ✅ ✅ ✅ ✅ ✅
Databricks (databricks) ✅ ✅ ✅
DataRobot (datarobot) ✅ ✅ ✅
Deepgram (deepgram) ✅ ✅ ✅ ✅
DeepInfra (deepinfra) ✅ ✅ ✅
Deepseek (deepseek) ✅ ✅ ✅
ElevenLabs (elevenlabs) ✅ ✅ ✅ ✅ ✅
Empower (empower) ✅ ✅ ✅
Fal AI (fal_ai) ✅ ✅ ✅ ✅
Featherless AI (featherless_ai) ✅ ✅ ✅
Fireworks AI (fireworks_ai) ✅ ✅ ✅
FriendliAI (friendliai) ✅ ✅ ✅
Galadriel (galadriel) ✅ ✅ ✅
GitHub Copilot (github_copilot) ✅ ✅ ✅ ✅
GitHub Models (github) ✅ ✅ ✅
Google - PaLM ✅ ✅ ✅
Google - Vertex AI (vertex_ai) ✅ ✅ ✅ ✅ ✅
Google AI Studio - Gemini (gemini) ✅ ✅ ✅
GradientAI (gradient_ai) ✅ ✅ ✅
Groq AI (groq) ✅ ✅ ✅
Heroku (heroku) ✅ ✅ ✅
Hosted VLLM (hosted_vllm) ✅ ✅ ✅
Huggingface (huggingface) ✅ ✅ ✅ ✅ ✅
Hyperbolic (hyperbolic) ✅ ✅ ✅
IBM - Watsonx.ai (watsonx) ✅ ✅ ✅ ✅
Infinity (infinity) ✅
Jina AI (jina_ai) ✅
Lambda AI (lambda_ai) ✅ ✅ ✅
Lemonade (lemonade) ✅ ✅ ✅
LiteLLM Proxy (litellm_proxy) ✅ ✅ ✅ ✅ ✅
Llamafile (llamafile) ✅ ✅ ✅
LM Studio (lm_studio) ✅ ✅ ✅
Maritalk (maritalk) ✅ ✅ ✅
Meta - Llama API (meta_llama) ✅ ✅ ✅
Mistral AI API (mistral) ✅ ✅ ✅ ✅
Moonshot (moonshot) ✅ ✅ ✅
Morph (morph) ✅ ✅ ✅
Nebius AI Studio (nebius) ✅ ✅ ✅ ✅
NLP Cloud (nlp_cloud) ✅ ✅ ✅
Novita AI (novita) ✅ ✅ ✅
Nscale (nscale) ✅ ✅ ✅
Nvidia NIM (nvidia_nim) ✅ ✅ ✅
OCI (oci) ✅ ✅ ✅
Ollama (ollama) ✅ ✅ ✅ ✅
Ollama Chat (ollama_chat) ✅ ✅ ✅
Oobabooga (oobabooga) ✅ ✅ ✅ ✅ ✅ ✅ ✅
OpenAI (openai) ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅
OpenAI-like (openai_like) ✅
OpenRouter (openrouter) ✅ ✅ ✅
OVHCloud AI Endpoints (ovhcloud) ✅ ✅ ✅
Perplexity AI (perplexity) ✅ ✅ ✅
Petals (petals) ✅ ✅ ✅
Predibase (predibase) ✅ ✅ ✅
Recraft (recraft) ✅
Replicate (replicate) ✅ ✅ ✅
Sagemaker Chat (sagemaker_chat) ✅ ✅ ✅
Sambanova (sambanova) ✅ ✅ ✅
Snowflake (snowflake) ✅ ✅ ✅
Text Completion Codestral (text-completion-codestral) ✅ ✅ ✅
Text Completion OpenAI (text-completion-openai) ✅ ✅ ✅ ✅ ✅ ✅ ✅
Together AI (together_ai) ✅ ✅ ✅
Topaz (topaz) ✅ ✅ ✅
Triton (triton) ✅ ✅ ✅
V0 (v0) ✅ ✅ ✅
Vercel AI Gateway (vercel_ai_gateway) ✅ ✅ ✅
VLLM (vllm) ✅ ✅ ✅
Volcengine (volcengine) ✅ ✅ ✅
Voyage AI (voyage) ✅
WandB Inference (wandb) ✅ ✅ ✅
Watsonx Text (watsonx_text) ✅ ✅ ✅
xAI (xai) ✅ ✅ ✅
Xinference (xinference) ✅

Read the Docs


Get Started

You can use LiteLLM through either the Proxy Server or Python SDK. Both give you a unified interface to access multiple LLMs (100+ LLMs). Choose the option that best fits your needs:

LiteLLM AI Gateway LiteLLM Python SDK
Use Case Central service (LLM Gateway) to access multiple LLMs Use LiteLLM directly in your Python code
Who Uses It? Gen AI Enablement / ML Platform Teams Developers building LLM projects
Key Features Centralized API gateway with authentication and authorization, multi-tenant cost tracking and spend management per project/user, per-project customization (logging, guardrails, caching), virtual keys for secure access control, admin dashboard UI for monitoring and management Direct Python library integration in your codebase, Router with retry/fallback logic across multiple deployments (e.g. Azure/OpenAI) - Router, application-level load balancing and cost tracking, exception handling with OpenAI-compatible errors, observability callbacks (Lunary, MLflow, Langfuse, etc.)

Stable Release: Use docker images with the -stable tag. These have undergone 12 hour load tests, before being published. More information about the release cycle here

Support for more providers. Missing a provider or LLM Platform, raise a feature request.

Run in Developer Mode

Services

  1. Setup .env file in root
  2. Run dependent services docker-compose up db prometheus

Backend

  1. (In root) create virtual environment python -m venv .venv
  2. Activate virtual environment source .venv/bin/activate
  3. Install dependencies uv sync --all-extras --group proxy-dev
  4. uv run prisma generate
  5. prisma generate
  6. Start proxy backend python litellm/proxy/proxy_cli.py

Frontend

  1. Navigate to ui/litellm-dashboard
  2. Install dependencies npm install
  3. Run npm run dev to start the dashboard

Verify Docker Image Signatures

All LiteLLM Docker images published to GHCR are signed with cosign. Every release is signed with the same key introduced in commit 0112e53.

Verify using the pinned commit hash (recommended):

A commit hash is cryptographically immutable, so this is the strongest way to ensure you are using the original signing key:

cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
  ghcr.io/berriai/litellm:<release-tag>

Verify using a release tag (convenience):

Tags are protected in this repository and resolve to the same key. This option is easier to read but relies on tag protection rules:

cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/<release-tag>/cosign.pub \
  ghcr.io/berriai/litellm:<release-tag>

Replace <release-tag> with the version you are deploying (e.g. v1.83.0-stable).


Enterprise

For companies that need better security, user management and professional support

Get an Enterprise License Talk to founders

This covers:

  • ✅ Features under the LiteLLM Commercial License:
  • ✅ Feature Prioritization
  • ✅ Custom Integrations
  • ✅ Professional Support - Dedicated discord + slack
  • ✅ Custom SLAs
  • ✅ Secure access with Single Sign-On

Contributing

We welcome contributions to LiteLLM! Whether you're fixing bugs, adding features, or improving documentation, we appreciate your help.

Quick Start for Contributors

This requires uv to be installed.

git clone https://github.com/BerriAI/litellm.git
cd litellm
make install-dev    # Install development dependencies
make format         # Format your code
make lint           # Run all linting checks
make test-unit      # Run unit tests
make format-check   # Check formatting only

For detailed contributing guidelines, see CONTRIBUTING.md.

📖 Contributing to documentation? The LiteLLM docs have moved to a separate repository: BerriAI/litellm-docs. Please open doc PRs there. Docs are served at docs.litellm.ai.

Code Quality / Linting

LiteLLM follows the Google Python Style Guide.

Our automated checks include:

  • Black for code formatting
  • Ruff for linting and code quality
  • MyPy for type checking
  • Circular import detection
  • Import safety checks

All these checks must pass before your PR can be merged.

Support / talk with founders

Contributors