llm·yard

Change the model without touching the app.

Your apps hold no provider key. They send one base URL and one virtual key, and ask for a tier — standard, heavy, whatever you named it. llmyard decides which provider and which model answers, screens the content, reserves against a budget that survives a restart, and records what the call actually cost.

Move a route and every app that asks for that tier moves with it. No deploy, no config file in anybody's repository, no code change.

Fig. 1 · one request, end to end

app · inbox app · batch app · agents no provider key on any of them 1 key AX−1 guardrail screen 6 classes, off until you give one an action 403 · blocked nothing spent, no call slot response cache · exact + semantic looked up before the reserve, so a hit is free hit ends here $0.00, no call slot used budget reserve durable · survives a restart · downroutes at 90% router tier → model · failover chain circuit breaker per endpoint · 3.0× price guard cost meter the provider’s own rate, not an estimate openai platform pool anthropic wire, translated openrouter platform pool your own key BYOK, sealed at rest real credentials live only here byte-faithful OpenAI response · real cost recorded per call
  1. Your apps hold no provider keyThey send one base URL and one virtual key.
  2. Guardrail screen6 classes, off until you give one an action. A block costs nothing.
  3. Response cacheExact, then semantic. A hit ends here, at $0.00, using no call slot.
  4. Budget reserveDurable, survives a restart, downroutes at 90% instead of cutting off.
  5. RouterTier to model, with a failover chain, a breaker per endpoint and a 3.0× price guard.
  6. Cost meterThe provider's own rate, not an estimate.
  7. The provideropenai, anthropic, openrouter, or your own key. Real credentials live only here.
  8. Back to your appA byte-faithful OpenAI response, with the real cost recorded per call.

The change to your application

Two lines, and the rest is policy you set once.
client = OpenAI(
    base_url="https://llmyard.cc/v1",
    api_key=os.environ["LLMYARD_KEY"],
)

r = client.chat.completions.create(
    model="standard",     # a tier you named, not a model id
    messages=[...],
)

Ask for a tier and llmyard resolves it. Change which model answers standard and every application that asks for it follows, without a deploy and without a config file in anybody’s repository. Send a concrete provider/model instead and it passes straight through.

What it refuses to do

The limits, on the page rather than in a support ticket.
BehaviourWhenResult
Refuse an expensive fallbackA fallback would cost more than 3.0× the first choiceThe call fails rather than costing more than you expected
Downroute instead of cutting offSpend passes 90% of the ceilingTiers resolve to trivial until the month rolls over
Refuse a project with no routeNo vendor key of its own, and no platform-pool grant400 no models available for route
Charge nothing for a blocked callA guardrail set to block matches403 guardrail_blocked, no call slot used
Charge nothing for a cache hitExact match, or cosine ≥ 0.95 inside the TTL$0.00, and no call slot used

Every endpoint, rating and default →