LiteLLM

One key, every model: model openai/<id> with api_base in the SDK, or a config.yaml model_list for the proxy. Pay per token, no subscription.

Checked 2026-10-28

·All guides·Models

At the end you have LiteLLM, the SDK or the proxy, calling https://api.uplinkswitch.com/v1 with one API key from the console. One key, every one of the 337 chat models on the list, billed per token from prepaid credit with no subscription. The config below is copied from LiteLLM's own docs (read 2026-10-28); the price table is live.

Before you start

You need Python 3.10 or newer, an account on the console with credit on it, and one key created there. Create the key for LiteLLM alone, so its requests sit apart from any other tool on the Usage page. Nothing is installed on the UplinkSwitch side: the base URL and the key are the whole configuration.

Base URL: https://api.uplinkswitch.com/v1. Keep the /v1 on the end; LiteLLM adds /chat/completions itself.

The SDK: openai/<id> with api_base

LiteLLM treats any model named openai/<id> as an OpenAI-compatible endpoint and sends it to api_base with api_key (docs, read 2026-10-28). The openai/ prefix is LiteLLM's routing word, not the developer of the model: openai/claude-sonnet-5-5 is Claude, reached over the OpenAI format at this base URL.

shell
pip install litellm
litellm_call.py
import os
import litellm

response = litellm.completion(
    model="openai/claude-sonnet-5-5",   # openai/ prefix = OpenAI-compatible endpoint
    api_base="https://api.uplinkswitch.com/v1",
    api_key=os.environ["UPLINKSWITCH_API_KEY"],
    extra_headers={
        "HTTP-Referer": "https://uplinkswitch.ai",
        "X-Title": "LiteLLM",
    },
    messages=[{"role": "user", "content": "Say ok."}],
)
print(response.choices[0].message.content)

extra_headers is LiteLLM's parameter for custom request headers. HTTP-Referer and X-Title name the client in the gateway's request log; they change nothing about the answer. base_url is an alias for api_base if you prefer the OpenAI spelling.

The proxy: config.yaml model_list

The proxy reads a config.yaml. Each entry in model_list has a model_name, the alias your clients send, and litellm_params with the real target: model, api_base and api_key. os.environ/UPLINKSWITCH_API_KEY reads the key from the environment so it never sits in the file.

shell
uv tool install 'litellm[proxy]'
config.yaml
model_list:
  - model_name: claude-sonnet-5-5
    litellm_params:
      model: openai/claude-sonnet-5-5
      api_base: https://api.uplinkswitch.com/v1
      api_key: os.environ/UPLINKSWITCH_API_KEY
      extra_headers: {"HTTP-Referer": "https://uplinkswitch.ai", "X-Title": "LiteLLM"}
  - model_name: claude-opus-5-5
    litellm_params:
      model: openai/claude-opus-5-5
      api_base: https://api.uplinkswitch.com/v1
      api_key: os.environ/UPLINKSWITCH_API_KEY
      extra_headers: {"HTTP-Referer": "https://uplinkswitch.ai", "X-Title": "LiteLLM"}
  - model_name: gpt-6.1-sol
    litellm_params:
      model: openai/gpt-6.1-sol
      api_base: https://api.uplinkswitch.com/v1
      api_key: os.environ/UPLINKSWITCH_API_KEY
      extra_headers: {"HTTP-Referer": "https://uplinkswitch.ai", "X-Title": "LiteLLM"}
  - model_name: gemini-3.1-pro-preview
    litellm_params:
      model: openai/gemini-3.1-pro-preview
      api_base: https://api.uplinkswitch.com/v1
      api_key: os.environ/UPLINKSWITCH_API_KEY
      extra_headers: {"HTTP-Referer": "https://uplinkswitch.ai", "X-Title": "LiteLLM"}
  - model_name: deepseek-v4-pro-0813
    litellm_params:
      model: openai/deepseek-v4-pro-0813
      api_base: https://api.uplinkswitch.com/v1
      api_key: os.environ/UPLINKSWITCH_API_KEY
      extra_headers: {"HTTP-Referer": "https://uplinkswitch.ai", "X-Title": "LiteLLM"}
  - model_name: kimi-k3
    litellm_params:
      model: openai/kimi-k3
      api_base: https://api.uplinkswitch.com/v1
      api_key: os.environ/UPLINKSWITCH_API_KEY
      extra_headers: {"HTTP-Referer": "https://uplinkswitch.ai", "X-Title": "LiteLLM"}

litellm_settings:
  drop_params: true

The aliases match the ids on the Models page on purpose, so a client that already knows claude-sonnet-5-5 needs no change. drop_params makes the proxy drop an OpenAI parameter a model does not take instead of raising. Start it and point any OpenAI client at port 4000:

shell
export UPLINKSWITCH_API_KEY="sk-uplink-live-..."
litellm --config config.yaml
# Proxy running on http://0.0.0.0:4000
client.py
import openai

client = openai.OpenAI(api_key="anything", base_url="http://0.0.0.0:4000")
response = client.chat.completions.create(
    model="claude-sonnet-5-5",   # the model_name alias from config.yaml
    messages=[{"role": "user", "content": "Say ok."}],
)
print(response.choices[0].message.content)

The api_key in the client is whatever the proxy expects (anything, until you set a master_key under general_settings). The UplinkSwitch key stays on the proxy side.

Which model ids to use

Any chat id on the Models page, with openai/ in front for LiteLLM. Tool calling and streaming work on every chat model here, so an agent framework on top of LiteLLM can use any of them. The 6 in the config above cover the usual coding and agent picks: claude-sonnet-5-5 and claude-opus-5-5 for planning and hard edits, gpt-6.1-sol and gemini-3.1-pro-preview as the other flagships, deepseek-v4-pro-0813 and kimi-k3 where input volume is high.

The uncensored builds take the same form: one more model_list entry with their id after openai/. Copy ids from the Models page rather than typing them; a dot or a date suffix out of place is a 404.

Price per token

ModelInput / 1MOutput / 1MCached input / 1MList inputList outputUnder list
Claude Sonnet 5.5$1.20$3.00$0.075$2.00$10.0040% on input
Claude Opus 5.5$2.80$10.00$0.15$4.00$20.0030% on input
GPT-6.1 Sol$0.60$3.00$0.06$2.00$10.0070% on input
Gemini 3.1 Pro Preview$1.20$7.20$0.12$2.00$12.0040% on input
DeepSeek V4 Pro 0813$0.792$1.188$0.0625$1.32$3.9640% on input
Kimi K3$0.90$4.50$0.12$3.00$15.0070% on input

USD per million tokens, live from GET /v1/catalog. List: the developer’s own published price. Cached input bills at the cache-read rate where the model has one; LiteLLM needs no switch for it.

LiteLLM's own cost tracking uses its bundled price map, which knows the developers' list prices and not this base URL. For the real charge read the Usage page, or x-uplink-charge on a non-streamed response. Every price on this page is held for 30 days from each top-up.

Check it

Confirm the key before the first LiteLLM call:

shell
curl https://api.uplinkswitch.com/v1/models -H "Authorization: Bearer $UPLINKSWITCH_API_KEY"

Then run the SDK script, or start the proxy and run the client. The request shows on the console Usage page within seconds, with its tokens and its charge.

Errors you will see

  • 401 invalid_api_key: the key is wrong or revoked, or the variable behind os.environ/UPLINKSWITCH_API_KEY was not exported in the shell that started the proxy. Copy the key again from the console and export it.
  • 402 insufficient_balance: the balance does not cover the request. Top up in the console.
  • 402 monthly_limit_reached: the key hit the monthly spend limit you set on it. Raise it in the console, or wait for the first of the month.
  • 404 model_not_found: the id after openai/ is not on the Models page at this base URL. Copy it from the page rather than typing it.
  • 404 with no model code, or LiteLLM's NotFoundError: api_base is missing /v1, or carries an extra path. Set it to exactly https://api.uplinkswitch.com/v1.
  • BadRequestError: LLM Provider NOT provided: the openai/ prefix is missing from model. LiteLLM uses it to pick the OpenAI-compatible path.
  • 429 rate_limited: the key hit its requests-per-minute or concurrency limit. The response carries retry-after in seconds. Wait that long and resend.

Good to know

  • Several model_list entries may share one model_name; LiteLLM then load-balances across them. One entry per id is enough here, since one base URL already covers every model.
  • litellm.embedding takes the same openai/<id>, api_base and api_key for embedding ids on the list.
  • Streaming is stream=True on completion or the client; nothing changes on this side.
  • A key per tool keeps the spend apart on the Usage page. The LangChain, OpenCode and Claude Code guides give each tool its own settings on the same balance.
  • LiteLLM's docs for the compatible provider are at docs.litellm.ai; the config on this page was read from them on 2026-10-28.

Questions

Yes. Put openai/ in front of the model id and pass api_base and api_key to litellm.completion, or the same three fields under litellm_params in the proxy config.yaml (LiteLLM docs, read 2026-10-28). With api_base set to https://api.uplinkswitch.com/v1, every chat model on the Models page answers, Claude and Gemini included.

https://api.uplinkswitch.com/v1, ending at /v1. LiteLLM's docs say a Not Found error on a compatible endpoint usually means the /v1 postfix is missing, and that no further path belongs on api_base because the client appends /chat/completions itself.

Yes. The Claude ids answer the OpenAI chat completions format here, so model="openai/claude-sonnet-5-5" with this api_base is the whole setup. No anthropic/ prefix and no ANTHROPIC_API_KEY are involved.

Set api_key to os.environ/UPLINKSWITCH_API_KEY under litellm_params and export the variable before you start the proxy. LiteLLM reads the variable from the environment (docs, read 2026-10-28); the file carries only the variable name.

Whatever the model page says per million tokens, live from the catalog; the table above has today's input and output rate for 6 common picks. Claude Sonnet 5.5 is $1.20 in and $3.00 out right now. Each request shows on the console Usage page within seconds with its tokens and charge, and a non-streamed response carries x-uplink-charge in its headers.

401 invalid_api_key means the key is wrong or revoked: copy it again from the console. 402 insufficient_balance means the prepaid balance does not cover the request: top up in the console. 402 monthly_limit_reached means the key hit the monthly spend limit you set on it.

Get a key in the console: prepaid credit, no subscription, 30-day price lock.