Get API key
Get startedComing from OpenRouter
Get started

Coming from OpenRouter

llm.buzz speaks OpenRouter's API, so most OpenRouter code works after you change the base URL and the key. This page lists what else differs, with links to the pages that explain more.

On this page

Switch your client

Create a key on the console's Keys page. It starts exp_vk_. There is no OAuth key exchange: you create a key in the console, and every client sends it as its API key: as a bearer token, or on Messages in x-api-key, the header the Anthropic SDK sends (Authentication).

ClientSettingValue
OpenRouter Pythonserver_urlhttps://api.llm.buzz/api/v1
OpenRouter TypeScriptserverURLhttps://api.llm.buzz/api/v1
OpenAIbase_url (baseURL in TypeScript)https://api.llm.buzz/api/v1
Anthropicbase_url (baseURL in TypeScript)https://api.llm.buzz/api
curlthe URLhttps://api.llm.buzz/api/v1/chat/completions

The Anthropic address has no /v1: the SDK adds /v1/messages itself (Base URL and SDKs). The OpenRouter SDKs call decisions through a server URL of their own: Decisions. Any other client of these APIs needs only the base URL and the key.

What works the same

The routes you call are OpenRouter's: Chat Completions, Responses, Messages, Embeddings, Images, speech to text and text to speech, GET /models and GET /models/{author}/{slug}/endpoints with the same shapes, GET /generation, and the key and credits routes GET /key, GET /credits and /keys (Endpoints). The provider object takes order, only, ignore, allow_fallbacks, sort, zdr and data_collection (Provider preferences), and :nitro and :floor change the order on a model's name (Suffixes). Errors come in OpenRouter's envelope with metadata.error_type, and add metadata.gateway_code, llm.buzz's own code to branch on; Messages answers Anthropic's error body (The envelope). A page can call the API from a browser with its visitor's own key (Browser access), and X-Title and HTTP-Referer name your app (App attribution).

Request fields that differ

On Chat Completions, Responses and Messages, llm.buzz drops a field it does not know instead of refusing it, and names each dropped field in x-sgr-ignored-parameters. That is a key in the response body, never a header: in a Chat Completions body and in the content and finish chunks of its stream, in the Responses object, and in Messages in message_start and the final message. Embeddings and Images drop unknown fields without naming them, and Decisions refuse them. A field llm.buzz deliberately refuses is a 400 before any provider is called. On Chat Completions and Responses its metadata.gateway_code is unsupported_parameter (the field is refused), invalid_parameter (only some values are) or unsupported_capability, and metadata.param names it. Messages renders every field refusal as Anthropic's invalid_request_error, with (param: NAME) at the end of the message. The same field can be refused on one API and dropped on another:

FieldWhat llm.buzz does
models, route, transforms, usage, trace, debugDropped and named on all three APIs.
plugins entries other than webChat Completions and Responses: dropped, named plugins.<id>. Messages: plugins dropped whole and named.
:online, web_search_options, the web pluginChat Completions: served without a search. Responses: :online and the web plugin are served without a search, and web_search_options, not a Responses field, is dropped and named. Messages: :online is named model:online, plugins and web_search_options are dropped and named, and nothing is searched.
seed, logit_biasChat Completions: 400 unsupported_parameter. Responses and Messages: dropped and named.
audio, modalities, functions, function_call, predictionChat Completions: 400 unsupported_parameter. Responses and Messages: dropped and named.
moderationChat Completions and Responses: 400 unsupported_parameter. Messages: dropped and named.
stream_optionsChat Completions: dropped and named when the request does not stream; on a stream include_usage changes nothing, because the last chunk carries usage whenever the counts are known. Responses and Messages: dropped and named.
n other than 1Chat Completions: 400 invalid_parameter. Responses and Messages: dropped and named.
storeChat Completions: true is 400 invalid_parameter. Responses: used, and store: false keeps the turn out of continuation. Messages: dropped and named.
previous_response_idChat Completions: dropped and named. Responses: used, and it continues a kept turn. Messages: dropped and named.
service_tierChat Completions and Responses: flex, priority and fast are 400 unsupported_capability; auto and default are served at the standard tier and not sent on. Messages: 400, naming service_tier.
background, conversation, max_tool_calls, promptChat Completions: dropped and named. Responses: 400 unsupported_parameter. Messages: dropped and named.
context_managementChat Completions: dropped and named. Responses: 400 unsupported_parameter. Messages: sent where the provider takes it, dropped and named elsewhere.
betas, container, fallbacks, fallback_credit_token, mcp_servers, thread, user_profile_idChat Completions and Responses: dropped and named. Messages: 400, naming the field; send betas as the anthropic-beta header.

Responses refuses a few more values with 400 invalid_parameter: a truncation other than "disabled", any reasoning.mode, a text.format.type other than text or json_schema (json_object included: ask for JSON with a json_schema format), and any include selector other than reasoning.encrypted_content and message.output_text.logprobs. Chat Completions takes response_format: {"type": "json_object"}. Chat Completions, Responses and Messages list every field of their API. Tools and structured output covers the tool and format fields.

What happens in place of these fields:

  • Fallback models. A model's own providers fail over through its routing preset in place of models: How a provider is chosen. Usage counts and usage.cost come back whether or not you send usage.
  • Web search is not available on llm.buzz today. A request that asks for one is still served, without the search; nothing is sent to a search service and nothing is billed for one. x-sgr-ignored-parameters names it web_search->dropped(search_unavailable). For an organization whose requests llm.buzz keeps in the EU, such a request is 400 web_search_unavailable_in_region. Suffixes.
  • Other provider keys. require_parameters, quantizations, max_price and sort.partition are accepted on all three APIs and do not change which provider serves. provider.sort takes price, latency, throughput and smart; throughput ranks like latency, by recent time to first token. exacto, :exacto and any other sort string leave the model's routing preset in place. The provider object.
  • Suffixes. A suffix such as :free, :extended or :thinking is part of the model's name, which is matched exactly, and no model is listed under such a name today. A name that is not listed answers 404 model_not_found. Model names.
  • Service tiers. llm.buzz does not sell a priority tier, and no model has a price for flex, priority or fast today, so on Chat Completions and Responses a request for one is refused with 400 unsupported_capability, naming service_tier, before any provider is called. auto and default are served at the standard tier.
  • Conversations. Responses keeps each finished turn for up to 24 hours: Continue a conversation.

Routes llm.buzz does not serve

Apart from batches, files, decisions and the two model routes below, an OpenRouter route that is missing from the Endpoints table answers 404 unknown_route ("Unknown route"). Among them:

  • /completions, /rerank and /videos;
  • /providers, /endpoints/zdr, /activity, /analytics/*, /generation/content and /generation/feedback;
  • /presets, /guardrails, /workspaces, /organization/*, /byok, /auth/keys, /tools, /observability/* and /private-endpoints.

llm.buzz does not enable batch jobs: /batches and /files answer 404 with a key, "batches are not enabled on this gateway": send a large job as single requests, as the batch jobs guide shows. /models/count and /models/user read their last segment as a model name and answer 404 model_not_found: read total_count on GET /models for a count, and list the models your key can call with GET /models and your key. Decisions are served, but no public model answers them today: Decisions.

In their place: a model's endpoints route lists its providers (/providers), provider.zdr keeps a request on zero-retention providers, and your organization's data policy narrows the endpoints route the same way (/endpoints/zdr), the console's Activity page and GET /generation cover activity and analytics, and the console's Prompt logs page shows logged prompts (/generation/content).

Features llm.buzz does not offer

  • Router models. openrouter/auto and OpenRouter's other router models name no model on llm.buzz: a request for one answers 404 model_not_found. Name a model, and choose its provider order with provider.sort.
  • Saved presets. There is no /presets route. llm.buzz's own routing presets (smart, cheapest, fastest and order) order one model's providers, and provider.sort or a :floor or :nitro suffix picks one of them for a single request: How a provider is chosen.
  • Server tools. Tool search is the one tool llm.buzz runs for you: Tool search. Web search is not available, as above, and OpenRouter's other server tools are not offered.
  • Plugins. No plugin runs. On Chat Completions and Responses an entry in plugins is dropped and named plugins.<id>, and the web plugin is the web search above; Messages drops plugins whole.
  • A response cache. Replay is opt-in, on Chat Completions and Responses only: a retry that carries the same Idempotency-Key returns the first answer, and no other request is answered from a stored one. Messages reads no Idempotency-Key, so a Messages retry runs and is billed again (Idempotency-Key).
  • Workspaces. Your keys, the people you invite with their roles and one prepaid balance belong to an organization: Organizations.
  • Guardrails. There is no /guardrails route.
  • Bring your own key. The hosted service has no bring-your-own-key: is_byok is false on every generation record.
  • Broadcast to observability tools. There is no /observability route. Read your traffic on the console's Activity and Logs pages.
  • SAML single sign-on and SCIM. Neither is offered. People sign in to the console with an email and a password, Google or GitHub.
  • Regional base URLs. There is no regional base URL. To keep a request in the EU, list the EU tags in provider.only: EU. GET /models?region=eu lists only the models with an EU provider: The model list.
  • Video generation. /videos answers 404.
  • openrouter_metadata. Read the provider key of a Chat Completions or Embeddings answer and the x-gateway-* headers of every answer: Answer fields and headers.
  • Other attribution headers. llm.buzz reads X-Title and HTTP-Referer. A header such as X-OpenRouter-Title is not read, and a browser preflight that asks for it does not allow it, so the browser refuses to send it.

Answers that differ

  • Endpoint metrics. uptime_last_5m, uptime_last_30m, uptime_last_1d, latency_last_30m and throughput_last_30m come from your organization's own traffic. A minute counts as observed with 1 attempt or more, where OpenRouter needs 10. status is always 0. Each window ends at the last computed 5-minute bucket, so the values run 2 to 8 minutes behind, and a field is null when its window has no sample. Without a key only uptime_last_1d can be set. Endpoints.
  • Key objects. GET /key and the key objects of /keys carry fixed values where llm.buzz has no counterpart: the byok_usage figures are 0, include_byok_in_limit is false and workspace_id is "default", and a /keys object has external_user null. GET /key also has is_provisioning_key false, organization_id null, a free_model_daily_requests object whose limit, remaining and used are 0, and a deprecated rate_limit. Check your key and credit.
  • Creating keys. POST /keys takes name, limit, limit_reset and expires_at, and accepts and ignores include_byok_in_limit, workspace_id and external. external.api_key is 400, because llm.buzz issues its own keys. Management keys are created only in the console.
  • Reasoning efforts. A model object has no reasoning, knowledge_cutoff or benchmarks key. The model list names a model's efforts in reasoning_efforts, from none to max, when the model's lead provider's listing names them; the key is left out otherwise, including where llm.buzz knows a model's efforts only from its own rules for the model's family, and no public model names reasoning in supported_parameters today. A model without the key can still reason: Reasoning.
  • Image models. An image model's supported_parameters.size lists the sizes it takes, and allowed_passthrough_parameters is always empty, because llm.buzz checks every field and passes none through. The image model routes need a key: Find an image model.
  • Audio endpoints. A text-to-speech endpoint's max_completion_tokens is null, and OpenRouter's endpoint flags supports_voice_cloning, supports_diarization, supports_image_reference and supports_multiple_audio_references are left out, because no provider here offers those features: Find an audio model.
  • The provider in the answer. The request's provider object works on Chat Completions, Responses and Messages. The answer carries a provider key, the name of the provider that answered, only on Chat Completions (every body and stream chunk) and Embeddings. Every answer names its provider in x-gateway-provider.
  • Retries. On Chat Completions and Responses, a retry with the same Idempotency-Key returns the first answer, or answers 409 idempotency_replay_unavailable when its answer is not stored where the retry arrived. Send the same key again only when the first call got no answer, or after an answer carrying x-gateway-admission-refused: true; after any other error answer send a new key. What to send next has the cases.

Prompt logs

llm.buzz keeps the prompts and answers of your organization's Chat Completions, Responses and Messages requests in prompt logs, and logging is on by default. An admin turns it off, or deletes the logged prompts, on the console's Prompt logs page. provider.zdr and provider.data_collection work as on OpenRouter, and a request with either demand is never logged. Prompt logs explains the rest.

Billing

  • You pay from prepaid credit that your organization buys on the console's Credits page, with a service fee added when you buy: Prepaid credit.
  • A provider that fails or sends an empty answer and is replaced by another adds nothing to the cost; you pay the provider that answered. Retries and idempotency.
  • A free offer is a provider discount with an allowance, not a :free model: Free offers.
Docs