Drop-in from OpenRouter

KhaBot serves every model in OpenRouter's catalog at the provider's own price, under the same model ids, plus KhaBot's own models and services. Moving an OpenRouter integration over is a two-line change: the base URL and the key. Your requests, model ids and response handling stay as they are.

Switch in two lines

OpenRouterKhaBot
Base URLhttps://openrouter.ai/api/v1https://khabot.com/api/v1
Keysk-or-…kb_… — create one under API keys
from openai import OpenAI

client = OpenAI(
    base_url="https://khabot.com/api/v1",   # was https://openrouter.ai/api/v1
    api_key="kb_YOUR_KEY",                  # was sk-or-…
)

r = client.chat.completions.create(
    model="anthropic/claude-opus-4.5",      # any OpenRouter model id, unchanged
    messages=[{"role": "user", "content": "Hello"}],
)
print(r.choices[0].message.content)
curl https://khabot.com/api/v1/chat/completions \
  -H "Authorization: Bearer kb_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "openai/gpt-5.1", "messages": [{"role": "user", "content": "Hello"}]}'

Two kinds of model

KhaBot modelsPass-through models
Idskhabot/<model>OpenRouter's ids, as-is — e.g. openai/gpt-5.1
Served byKhaBotPassed through to OpenRouter
PriceKhaBot's published per-model priceExactly the provider's reported cost — no markup
Billed fromYour plan quota first, then creditCredit only — never covered by a plan
CatalogThe khabot/ setOpenRouter's whole catalog except :free variants and openrouter/* meta-models, synced daily

Both appear in the model list and in GET /models, KhaBot models first.

Model ids on pass-through calls

  • Variant suffixes work on pass-through ids: :online, :nitro, :floor, :thinking and the like — e.g. openai/gpt-5.1:online.
  • models fallback arrays work when every model in the array is in the catalog.
  • Rolling aliases such as ~openai/gpt-latest are real models and work like any other id.
  • Account presets (preset/…, @preset/…) aren't models and aren't available.
  • :free ids and openrouter/* ids are refused with 400 bad_request — they aren't part of the catalog. Use the paid id instead.

The rename

KhaBot's own models now use the khabot/ prefix — for example khabot/glm-5.2. The old ids are gone, with no aliases. Watch out: any id without the khabot/ prefix is treated as a pass-through request. If an old id happens to match an OpenRouter model, the call is served by OpenRouter — billed from credit at the provider's price, not from your plan. Update your ids to the khabot/ ones listed by GET /models.

Billing

  • Every pass-through call is billed at exactly the cost the provider reports for it — no markup — from your credit. Plans never cover pass-through calls, so keep credit on the account.
  • When your credit is short of a call's estimated cost, it is refused with 402 insufficient_credit.
  • Pass-through spend counts toward your monthly spend cap (set in Billing), together with extra usage on KhaBot models.
  • There is also a daily pass-through limit per account, set by KhaBot as a brake against runaway use: it counts what you have spent on pass-through calls since 00:00 UTC, plus calls still running, plus the new call's estimate. Past it, pass-through calls are refused with 402 passthrough_daily_cap_reached until the next UTC day; KhaBot models are unaffected.
  • The usage.cost in a pass-through response is what KhaBot billed you for that call.
  • The cost shows up in your usage log immediately for JSON responses, and within a couple of minutes for streamed and file responses, while the final cost is confirmed.
  • KhaBot models keep their published prices and plan coverage; see Quotas & plans.
  • BYOK applies to KhaBot models' chat only — pass-through calls always use KhaBot's own key.

Errors on pass-through calls

HTTPcodeWhen
400bad_requestThe model id isn't servable. The message names the reason: :free variants not available, openrouter/* meta-routers not available, or unknown or unavailable model — see GET /api/v1/models (unknown ids and ids without a price)
402insufficient_creditYour credit is short of the call's estimated cost — redeem a code in Billing
402passthrough_daily_cap_reached“Daily pass-through spend limit reached — try again tomorrow.” Your account hit today's pass-through limit; it resets at 00:00 UTC

Everything else — authentication, per-key limits, rate limits — works as for any KhaBot call; see Errors.

What passes through

These OpenRouter endpoints work on KhaBot unchanged, for pass-through models. Paths are relative to https://khabot.com/api/v1.

EndpointNotes
POST /chat/completionsAny model without the khabot/ prefix
POST /responses
POST /messagesAnthropic format
POST /embeddings, GET /embeddings/models
POST /imagesOpenRouter's own image API — a different path from KhaBot's /images/generations
Read-only catalog and info routesGET /models/count, /models/{author}/{slug}/endpoints, /model/{author}/{slug}, /images/models, /providers, /benchmarks, /tools

Not available: endpoints that store content on the upstream account — /files, /batches, /videos, /presets and other stored-content routes. They would be shared between KhaBot customers, so they are switched off. POST /rerank and GET /models/user (per-account model preferences) answer 404 not_available. The legacy /completions endpoint is not part of what KhaBot guarantees either — use /chat/completions.

What stays KhaBot's

Where KhaBot has its own endpoint at a path, ours answers — OpenRouter's version of that path isn't reachable through KhaBot:

PathServed by KhaBot as
/images/generations, /images/editsImages
/audio/*Speech to text and text to speech — OpenRouter's audio endpoints are not reachable
/storage/*Object storage
/media/*Media search
/web-searchWeb search
/documents, /documents/{key}Documents storage
/html-to-markdownHTML to Markdown
/key-infoYour key's own limits

Account endpoints

OpenRouter's management endpoints — /keys, /credits, /auth, /generation, /activity, /analytics and the like — are not proxied: your KhaBot account is managed in the dashboard. Three answer with KhaBot's own data, so clients that check them keep working:

  • GET /key — the KhaBot key you called with.
  • GET /credits — your KhaBot credit.
  • GET /generation?id=… — a call's details from your KhaBot usage log, for KhaBot request ids.

Every call's cost and usage is also in your usage log.

GET /key

{
  "data": {
    "label": "laptop",
    "limit": 25.0,
    "usage": 3.42,
    "limit_remaining": 21.58,
    "is_free_tier": false,
    "is_management_key": false,
    "is_provisioning_key": false,
    "expires_at": null,
    "credit_usd": 12.5
  }
}
FieldMeaning
labelThe key's name — "session" when called from a signed-in dashboard session
limit, usage, limit_remainingThe key's binding spending limit — the one with the least left (null = no limits) — what it has counted in its current window, and what is left
is_free_tier, is_management_key, is_provisioning_keyAlways false — kept for OpenRouter clients that read them
expires_atWhen the key expires, or null
credit_usdYour account's credit balance

GET /credits

{ "data": { "total_credits": 40.0, "total_usage": 27.5 } }

total_credits − total_usage is your current credit balance.

The model list: GET /models

GET https://khabot.com/api/v1/models returns the catalog in OpenRouter's shape, so tools that read OpenRouter's model list can read ours. KhaBot models come first. Each entry adds a tier — curated or passthrough — and pass-through entries carry their openrouter_url. Prices are in US dollars per token, as strings, like OpenRouter's.

{
  "data": [
    {
      "id": "khabot/glm-5.2",
      "name": "GLM 5.2",
      "tier": "curated",
      "context_length": 200000,
      "architecture": { "input_modalities": ["text"], "output_modalities": ["text"] },
      "pricing": { "prompt": "0.000003", "completion": "0.000005", "input_cache_read": "0.0000003" }
    },
    {
      "id": "openai/gpt-5.1",
      "name": "OpenAI: GPT-5.1",
      "tier": "passthrough",
      "context_length": 400000,
      "architecture": { "input_modalities": ["text", "image", "file"], "output_modalities": ["text"] },
      "pricing": { "prompt": "0.00000125", "completion": "0.00001" },
      "openrouter_url": "https://openrouter.ai/openai/gpt-5.1"
    }
  ]
}

Trimmed — entries carry more of OpenRouter's metadata than shown, and the prices here are illustrative. For prices per million tokens, see the model list.