LiteLLM Free code examples in Python and JavaScript
A proxy that normalises a hundred providers to one API, with budgets and keys.
Try it without writing code: Prompt Testing Kit — free in the browser.
WHAT THIS PAGE COVERS
Per-team spend limits, which is the feature teams actually adopt it for.
fast
litellm
Model ids change. If a sample returns a 404 on the model, that is the first thing to check against the official docs.
The proxy extra, and a Postgres instance. The database is not optional if you intend to enforce anything.
pip install 'litellm[proxy]'
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=dev postgres:17
export LITELLM_MASTER_KEY="sk-master-dev" # generate a long random one
export DATABASE_URL="postgresql://postgres:dev@localhost:5432/postgres"
model_name is the alias callers ask for; litellm_params says what it really is. That indirection is the point — swapping a model for every caller is one line here and no change anywhere else.
# config.yaml
model_list:
- model_name: fast # what callers request
litellm_params:
model: openai/gpt-5.4-mini # what it actually is
api_key: os.environ/OPENAI_API_KEY
- model_name: smart
litellm_params:
model: anthropic/claude-sonnet-4.6
api_key: os.environ/ANTHROPIC_API_KEY
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
database_url: os.environ/DATABASE_URL # REQUIRED for budgets
litellm_settings:
max_budget: 500 # proxy-wide ceiling
budget_duration: 30d
Provider keys stay in the proxy's environment. Everyone else gets a LiteLLM key with a budget and an allow-list — and revoking one is an API call rather than a rotation across every repository that had it.
litellm config.yaml
# A team with a monthly ceiling.
curl -sX POST 'http://localhost:4000/team/new' \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{
"team_alias": "search-squad",
"max_budget": 100,
"budget_duration": "30d",
"rpm_limit": 99
}'
# A key inside that team, with its own smaller budget and a
# restricted model list.
curl -sX POST 'http://localhost:4000/key/generate' \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{
"team_id": "<team-id-from-above>",
"max_budget": 10,
"budget_duration": "30d",
"models": ["fast"]
}'
An OpenAI client against the proxy. The application never sees a provider key, and the model name is the alias from the config rather than a vendor's id.
import os
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:4000",
api_key=os.environ["LITELLM_VIRTUAL_KEY"], # not the provider key
)
completion = client.chat.completions.create(
model="fast", # the alias, not openai/gpt-5.4-mini
messages=[{"role": "user", "content": "Explain a database index."}],
)
print(completion.choices[0].message.content)
The proxy returns 400 with a budget message — not 429, and not a silent downgrade. Handle it explicitly, because a retry loop written for rate limits will hammer a spent budget forever.
import openai
try:
completion = client.chat.completions.create(
model="fast",
messages=[{"role": "user", "content": "Explain a database index."}],
)
except openai.BadRequestError as error:
message = str(error)
# Budget exhaustion arrives as a 400, so generic 429 retry logic
# will not catch it and generic 400 handling will call it a bug.
if "budget" in message.lower():
raise RuntimeError("Team budget exhausted — raise it or wait.") from error
raise
# Check spend before it bites:
# curl http://localhost:4000/key/info \
# -H "Authorization: Bearer $LITELLM_VIRTUAL_KEY"
The proxy is Python and runs as a service. Nothing LiteLLM-specific is installed in Node.
# On the proxy host:
# pip install 'litellm[proxy]'
# litellm config.yaml
npm install openai
export LITELLM_VIRTUAL_KEY="sk-..." # from /key/generate
The base URL is the proxy and the model is the alias. The provider key is not present in this process at all, which is the security argument for the whole arrangement.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://localhost:4000",
apiKey: process.env.LITELLM_VIRTUAL_KEY, // not a provider key
});
const completion = await client.chat.completions.create({
model: "fast", // the alias from config.yaml
messages: [{ role: "user", content: "Explain a database index." }],
});
console.log(completion.choices[0].message.content);
Tags and a user id turn one aggregate bill into per-feature numbers. Without them the monthly figure is a single line item nobody can do anything about.
const completion = await client.chat.completions.create(
{
model: "fast",
messages: [{ role: "user", content: "Explain a database index." }],
// Rides along in the body; the proxy records it against the spend.
user: "tenant-acme",
metadata: {
tags: ["feature:search", "env:production"],
},
},
{
// Or as headers, which survives a typed client that strips
// unknown body fields.
headers: { "x-litellm-tags": "feature:search,env:production" },
},
);
A spent budget is a 400 with a budget message, not a 429. Generic retry logic aimed at rate limits will retry it forever and get nowhere.
async function ask(messages) {
try {
return await client.chat.completions.create({ model: "fast", messages });
} catch (error) {
const message = String(error?.message ?? "");
if (error?.status === 400 && /budget/i.test(message)) {
// Not transient. Do not retry.
throw new Error("Team budget exhausted — raise it or wait for the reset.");
}
throw error;
}
}
// Current spend for this key:
// GET http://localhost:4000/key/info
// Authorization: Bearer $LITELLM_VIRTUAL_KEY
QUESTIONS
Which languages are the LiteLLM examples in?
Python and JavaScript. Every sample runs as pasted and reads its credentials from an environment variable — no key is ever written into the code.
Which package do I install for LiteLLM?
The samples use litellm. The install step on each language tab gives the exact command.
Which LiteLLM model do these examples use?
fast, checked against the official documentation on 26 September 2026. Model ids change often; if a call returns a model-not-found error, check the current list in the official docs.
Where is the official LiteLLM documentation?
https://docs.litellm.ai/ — it is linked at the bottom of this page, and it is the authority whenever it disagrees with a sample here.
ALSO IN HOSTING, GATEWAYS & LOCAL
The authority
Official LiteLLM documentation
Model names, pricing and rate limits change faster than any page here can. When this page and the official docs disagree, the official docs are right.
https://docs.litellm.ai/