How routing works
One key reaches both providers. We route on the request path, not on anything you have to configure:
/v1/messages→ the Anthropic Messages API./v1/chat/completionsand/v1/responses→ OpenAI./v1/embeddings→ OpenAI.
This means you keep using each provider’s official SDK in its native shape. We deliberately do not offer a unified abstraction layer over both. A lowest-common-denominator wrapper would cost you the features you are paying for, and there are good open-source options if you want one.
One key, two SDKs
import os
from anthropic import Anthropic
from openai import OpenAI
key = os.environ["LOWCOSTLLM_API_KEY"]
claude = Anthropic(base_url="https://api.lowcostllm.com", api_key=key)
gpt = OpenAI(base_url="https://api.lowcostllm.com/v1", api_key=key)
# Route by cost: cheap model first, escalate only when it matters.
draft = gpt.chat.completions.create(
model="gpt-5.6-luna",
messages=[{"role": "user", "content": prompt}],
)
review = claude.messages.create(
model="claude-sonnet-5",
max_tokens=2048,
messages=[{"role": "user", "content": f"Critique this draft:\n{draft}"}],
)Note the /v1 on the OpenAI base URL and not on the Anthropic one. That asymmetry is the SDKs’, not ours. Each expects a different convention, and we accept both so you do not have to fight either.
Billing and limits
Spend across both providers draws from one balance and one set of tier limits. The usage endpoint groups by model, so a mixed workload still gives you a clean per-provider breakdown at the end of the month.