Sam Austinon October 27, 202616 min read

How to Share One LiteLLM API Endpoint Across Your Team

How to Share One LiteLLM API Endpoint Across Your Team
Contents

Figure 1: How to Share One LiteLLM API Endpoint Across Your Team — one URL, many keys, and a budget attached to each

One developer pastes the company's OpenAI key into a notebook. Another commits it to a repo. A third runs a test loop over the weekend and burns through the monthly budget. Sound familiar?

A shared LiteLLM gateway fixes all three problems. This guide shows you how to share one LiteLLM API endpoint across your team, with separate keys, budgets, rate limits, and model access for each person and group. It builds on the proxy setup from my earlier LiteLLM guide, so run that quickstart first if you have no gateway yet.

The Big Idea: Nobody Touches the Provider Keys

Your team never sees your real OpenAI, Anthropic, or Azure keys. Only the gateway holds them. Everyone else gets a virtual key that works against one shared URL.

Here is the cast of characters [1]:

Piece What it is Who holds it
Master key The root credential for every management call The platform owner only
Teams Groups that share a budget, rate limits and a model list One per squad or purpose
Users People with a role and a login Every teammate
Virtual keys The credentials apps and developers actually use One per person or app

The docs describe a simple budget model with three levels [2]. Personal budgets come from keys created without a team. Team budgets come from keys that carry a team_id. Team member budgets set individual limits inside a team's shared budget.

One rule catches people out: if a key belongs to a team, only the team and team-member budgets are enforced, and the key owner's personal budget does not apply [2]. Version 1.94.0 briefly enforced both behind a skip_user_budget_on_team_key opt-out, and 1.95.0 removed both the enforcement and the flag.

Step 1: Put the Gateway Where Your Team Can Reach It

A gateway on your laptop helps nobody else. Deploy it to a server, a container platform, or Kubernetes, and give it a stable internal URL.

Three requirements matter most:

  1. A database. The docs state plainly that budgets are unavailable without one, because every budget is enforced against spend read from the database and keys cannot resolve without one [2]. Run Postgres.
  2. TLS in front. Terminate HTTPS at a load balancer or reverse proxy.
  3. Restricted network access. Keep the gateway on your VPN or internal network unless you truly need public access.

The official docs cover production deployments with Helm, Kubernetes, and a reference topology where the serving deployment and the background worker share one database and one Redis [5]. Pin a reviewed release tag, because the March 2026 supply chain incident in LiteLLM's PyPI package showed what an unpinned install can cost.

If you run more than one gateway instance, rate limits need a shared store such as Redis to count correctly across instances. The docs are blunt about the failure mode: without Redis each instance keeps its own counters, so a key with rpm_limit: 2 is admitted "up to 2 requests per instance, N times the limit across N instances" [3]. The same docs list fail_closed_rate_limit_enforcement, which rejects unverifiable requests with a 503 instead of admitting them [3].

Step 2: Decide Who Gets Which Role

LiteLLM ships with roles that limit what each person can do. Match them to real jobs [1]:

Role Permissions Who should have it
proxy_admin Full control over every organization, team and user Two or three platform owners, no more
proxy_admin_viewer View all keys and all spend, change nothing Finance and auditors
internal_user Create, view and delete their own keys, see their own spend Most engineers
internal_user_viewer View own keys and spend only Deprecated — use team or org roles

The docs mark internal_user_viewer as deprecated in favour of team and org specific roles [1]. The docs also describe team admins, who add members and manage team permissions, with a proxy admin choosing which fields they may edit, and org admins for organization-level control [1]. Some team member permissions are marked as a premium feature, so check the current licensing page before you plan around them.

Give out proxy_admin like you give out root access. Two or three people is plenty.

Step 3: Onboard Your Teammates

You have three ways to bring people in.

  1. In the Admin UI, go to Internal Users.
  2. Click + Invite User, enter their email, and set the role.
  3. Open the invitation link it generates and share it — the user sets a password from that link [4].

The UI shows the link once, and the docs warn that with SSO configured the link only signs the user in through SSO, so a password reset is a separate action [4].

Single Sign-On

The self-serve docs label SSO as a LiteLLM Enterprise feature, with a carve-out: from v1.76.0 SSO is free for up to five users [4]. Where you have it, the docs include a Microsoft Entra ID tutorial and SAML guidance for providers such as Okta. Both can map identity provider attributes to LiteLLM roles and team IDs. In the Entra flow, signing in even creates teams from your directory groups automatically, and syncs memberships [4].

You can set defaults for new SSO users with default_internal_user_params, which the config reference describes as the default params (role, models, budgets) applied to internal users auto-created on first SSO login [4]. That is what stops a stranger who signs in from landing with admin rights.

general_settings:
  default_internal_user_params:
    user_role: internal_user
    models: ["fast-chat"]

Default Settings for New Users

Set those defaults before you invite anyone. An invited user with no role and no model list is either useless or dangerous, and fixing it later means auditing every key they already created.

Step 4: Create Teams With Budgets and Limits

Teams are where cost control happens. Create one team per group that shares a purpose, like a product squad or a research group [3].

curl --location 'http://localhost:4000/team/new' \
  --header 'Authorization: Bearer <your-master-key>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "team_alias": "research",
    "max_budget": 500,
    "budget_duration": "30d",
    "rpm_limit": 120,
    "models": ["fast-chat", "smart-chat"]
  }'

The docs show team_alias, rpm_limit, max_budget, budget_duration, models, and member roles as team fields [2]. budget_duration resets the budget on a schedule, and you can write it as seconds, minutes, hours, or days, such as 30s, 30m, 30h or 30d [2]. Check the Swagger reference for the full, current field list, since fields change between releases.

Give Individuals Their Own Limits Inside a Team

A team budget can still vanish in one afternoon if one person runs wild. Team member budgets fix that [2]:

  1. Create or invite the user.
  2. Add them to the team with max_budget_in_team set.
  3. Update that value later with /team/member_update — the new limit takes effect on the member's next request [2].

Two details the docs spell out. Setting a member budget detaches that person from the team's team_member_budget default, so later /team/update changes to the default leave them untouched. To move everyone still on the default, update team_member_budget on /team/update instead [2]. There is also POST /team/{team_id}/member/{user_id}/reset_budget to reset one member's cycle spend without touching their limit [2].

Step 5: Issue Virtual Keys the Right Way

Now create keys. Pick the key type that matches the use case [1]:

Key type Created with Spend lands on
Personal key No team The user's personal budget
Team key A team_id The team's shared budget
Service key A team_id, no user The team, for production apps and pipelines
curl -X POST 'http://localhost:4000/key/generate' \
  -H 'Authorization: Bearer <your-master-key>' \
  -H 'Content-Type: application/json' \
  -d '{"team_id": "<team-id>", "key_alias": "research-notebook", "models": ["fast-chat"]}'

Two details from the docs deserve attention. First, a key owner's tpm_limit and rpm_limit apply whenever the owner has them set. Second, when a key carries a team_id, the team budget replaces the user's personal budget for that key [2].

Teammates can also create their own keys in the UI when the team permits it. That self-serve option saves you from becoming a key vending machine.

Step 6: Control Which Models Each Team Can Use

Not every team needs your most expensive model. Restrict the models list on a team or a key, and you cap both cost and risk. A prototype team might get only fast-chat, while a production team gets smart-chat as well.

This also makes migrations painless. Teams call model aliases, not provider model names, so you can swap the model behind smart-chat without touching anyone's code.

Team Allowed aliases Why
Prototype fast-chat Cheap iteration, no surprise invoices
Product fast-chat, smart-chat Quality where users see it
Research smart-chat only Depth over volume

Step 7: Watch Spend Before It Becomes a Problem

Budgets stop disasters, but visibility prevents surprises. The Admin UI shows usage, and you can pull details through the /user/info and /team/info endpoints [2]. Give finance the proxy_admin_viewer role, and the monthly invoice conversation gets much shorter.

Set a routine:

  1. Check spend weekly by team and by key.
  2. Investigate spikes the day you see them.
  3. Review key lists monthly and delete keys nobody uses.
  4. Compare gateway totals with provider invoices to catch gaps.

Step 8: Tell Your Team How to Use It

A gateway nobody understands becomes a support burden. Send teammates one short message with three facts: the base URL, how to get a key, and the model aliases they may call.

Because the gateway speaks the OpenAI format, existing code needs almost no changes. The standard OpenAI SDK reads these environment variables:

export OPENAI_BASE_URL='https://llm.yourcompany.internal'
export OPENAI_API_KEY='sk-<your-virtual-key>'
from openai import OpenAI

client = OpenAI()   # reads the two variables above
reply = client.chat.completions.create(
    model='fast-chat',
    messages=[{'role': 'user', 'content': 'Hello from the team gateway'}],
)
print(reply.choices[0].message.content)

I could not run these snippets here, so test them against your own gateway before you share them.

Test Your Limits Like a Normal User

Here is a trap that fools many admins. The docs say rate limits apply to any key, user or team that has tpm_limit, rpm_limit or max_parallel_requests set, regardless of role — but the master key has no limits unless you configure them [2]. Test every limit with a virtual key that carries an explicit limit, or you will believe your throttling works when it does not [2].

Two more ways the enforcement silently misses:

  • Multiple instances without Redis. Each instance keeps its own counters, so your limit becomes N times the number you set [3].
  • Budgets without Postgres. Nothing is enforced at all, and litellm_settings.max_budget fails open instead of erroring [2].

Security Habits for a Shared Gateway

Shared infrastructure raises the stakes. Follow these habits:

  1. Guard the master key. Keep it out of repos, chat messages, and shared docs.
  2. Back up the salt key. Changing it makes stored provider keys unreadable.
  3. Give keys expiry dates when people use them for short experiments.
  4. Revoke keys when people leave. SSO helps here, since removing someone from your directory cuts their access.
  5. Pin the gateway version and update on purpose.
  6. Set provider-side spending caps too. A second limit catches mistakes the gateway misses.
  7. Keep the audit trail. Budget and role changes are the first thing you will want after an incident.

Common Pitfalls

I see teams trip over the same problems:

  1. Running without a database. Budgets and virtual keys silently stop working.
  2. Handing out the master key. One leaked message then gives away full admin access.
  3. Using one shared key for everyone. You lose per-person and per-app tracking.
  4. Making everyone an admin. The role list exists for a reason.
  5. Skipping model restrictions. Anyone can then call your priciest model.
  6. Testing limits with the master key. The limits look like they do nothing.
  7. Setting a team budget with no member budgets. One runaway notebook can consume the quarter.
  8. Assuming SSO is free at any team size. It is Enterprise beyond five users, so budget for the licence before you standardise on it.

Best Book to Read

CoverBookDescriptionGet it
Cover of “Site Reliability Engineering” Site Reliability Engineeringby Betsy Beyer, Chris Jones, Jennifer Petoff and Niall Richard Murphy the Google SRE volume, and the clearest treatment of shared infrastructure, quotas and on-call that a gateway owner inherits the moment teammates depend on it. View on Amazon

As an Amazon Associate I earn from qualifying purchases. Links on this page are affiliate links, and I may earn a commission at no extra cost to you.

Wrapping Up

Sharing one LiteLLM endpoint comes down to roles, teams, keys, and budgets. Keep provider keys inside the gateway, give each team a budget and a model list, issue one key per person or application, and watch the spend. Your team gets one simple URL, and you get control.

So set up one test team today. Give it a small budget, create a key with a short expiry, and ask a teammate to call it. That ten-minute exercise will show you exactly how the pieces fit.

If you have not built the gateway yet, the LiteLLM proxy guide covers the Docker Compose quickstart, the two keys, and the March 2026 PyPI incident in full. For where a gateway sits in the wider stack, LLMOps vs MLOps draws the boundary.

Frequently Asked Questions

How do I give my team access to one LiteLLM endpoint without sharing provider keys?

Only the gateway holds the real OpenAI, Anthropic or Azure keys. Everyone else gets a virtual key pointed at the shared base URL, and the proxy resolves that key to a user, a team budget and an allowed model list. Create the keys with /key/generate or the Admin UI under Virtual Keys, hand out the base URL plus the key, and never send the master key to an application or a teammate.

Do budgets work without Postgres in LiteLLM?

No. The docs state that every budget is enforced against spend read from the database, so on a DB-less deployment none of them cap anything, and litellm_settings.max_budget fails open rather than erroring. Virtual keys cannot resolve without a database either. If cost control is the reason you are running a gateway, run Postgres with it.

What happens to a personal budget when a key belongs to a team?

The team budget wins. If a key carries a team_id, only the team and team-member budgets are enforced and the key owner's personal budget does not apply. Version 1.94.0 briefly enforced both behind a skip_user_budget_on_team_key opt-out, and 1.95.0 removed both the enforcement and the flag. Plan budgets per team, then per member inside the team.

How do team member budgets work in LiteLLM?

A team carries a shared max_budget plus an optional team_member_budget default that applies to members without their own limit. To give one person a separate cap, set max_budget_in_team for that member, either when adding them with /team/member_add or later with /team/member_update, and the new limit applies on their next request. Raising the team default afterwards leaves that member untouched.

Why do my rate limits seem to do nothing when I test them?

Because you are usually testing with the master key. It has no limits unless you configure them, which makes throttling look broken. The docs say rate limits apply to any key, user or team that has tpm_limit, rpm_limit or max_parallel_requests set, regardless of role, so create a virtual key with explicit limits and test with that. And if you run several instances without Redis, each instance keeps its own counters, so the effective limit is N times what you set.

Is SSO available in the open-source LiteLLM proxy?

SSO is labelled an Enterprise feature, with one exception: from v1.76.0 it is free for up to five users, and beyond that a licence is required. Where you have it, the Microsoft Entra ID tutorial can auto-create LiteLLM teams from your directory groups and sync memberships, which makes offboarding a directory change rather than a support ticket. Without SSO, invitation links from Internal Users are the self-serve path.

Sources

  • [1] LiteLLM, access control and roles — the proxy_admin, proxy_admin_viewer, internal_user and deprecated internal_user_viewer roles, team and org admins, the key types with and without user_id and team_id, and the premium team member permissions: docs.litellm.ai/docs/proxy/access_control
  • [2] LiteLLM, budgets, rate limits and users — the personal, team and team-member budget levels, the rule that a team key ignores the personal budget, /team/new, /team/member_add, /team/member_update, team_member_budget on /team/update, the member budget reset endpoint, budget_duration formats, and the note that limits apply regardless of role while the master key has none: docs.litellm.ai/docs/proxy/users
  • [3] LiteLLM, team budgets and Redis coordination — setting monthly team budgets with Postgres, the budget_duration reset values, and the multi-instance counter behaviour where each instance admits up to its own limit without Redis, plus fail_closed_rate_limit_enforcement: team budgets · redis requirements
  • [4] LiteLLM, SSO for the Admin UI — SSO as an Enterprise feature with the free tier up to five users from v1.76.0, the Entra ID group-to-team auto-creation and membership sync tutorial, the invitation link flow, and default_internal_user_params in the config reference: admin_ui_sso · Microsoft SSO tutorial · config settings
  • [5] LiteLLM, production guide — the Helm and Kubernetes deployment guidance, the one-worker-per-pod recommendation, and the reference topology where the serving deployment and background worker share one Postgres and one Redis: docs.litellm.ai/docs/proxy/prod

What are You Looking For?

esc