Get API key
API reference

Overview

The llm.buzz model API speaks the OpenAI, Anthropic and OpenRouter request and response formats under https://api.llm.buzz/api/v1. This page covers what every route shares: the base URL, authentication, the provider object, request fields and errors. Each endpoint has its own page, with its fields and examples.

On this page

Base URL and SDKs

Every model route is under https://api.llm.buzz/api/v1. Point an SDK at it and change nothing else:

SDKSetting
OpenAIbase_url="https://api.llm.buzz/api/v1"
OpenRouterserver_url="https://api.llm.buzz/api/v1" (Python), serverURL: "https://api.llm.buzz/api/v1" (TypeScript)
Anthropicbase_url="https://api.llm.buzz/api", without /v1: the SDK adds /v1/messages itself

Authentication

Send an inference key as a bearer token:

curl https://api.llm.buzz/api/v1/models \
  -H "Authorization: Bearer $LLM_BUZZ_KEY"

The Messages API also takes the key in x-api-key, the header the Anthropic SDK sends. A management key calls only the key routes below: create one on the console's Keys page, as you create an inference key, and send it the same way. The samples for those routes read it from $LLM_BUZZ_MANAGEMENT_KEY. Authentication covers keys, expiry and spending limits.

Endpoints

Method and pathWhat it does
POST /chat/completionsChat Completions. Streams with stream: true.
POST /responsesResponses. The same path also takes a WebSocket upgrade on GET.
POST /messagesThe Anthropic Messages API.
POST /messages/count_tokensAn estimate of a Messages request's input tokens, {"input_tokens": N}. Costs nothing.
POST /embeddingsEmbeddings, for embeddings models. Never streamed. Embeddings covers it.
POST /imagesOpenRouter's Image API: images from a text prompt, each as base64. Never streamed. Images covers it.
POST /images/generationsThe OpenAI Images API (generations), serving the same image models. Never streamed.
POST /audio/transcriptionsSpeech to text: one audio file in, its text out. Never streamed. Audio covers both audio routes.
POST /audio/speechText to speech: one text in, the whole audio out as MP3 or PCM.
GET /generation?id=What a finished request cost, below.
GET /modelsThe models your key can call, in OpenRouter's shape. Without a key, the public models.
GET /models/{author}/{slug}One model. A model whose name has no / is GET /models/{name}.
GET /model/{author}/{slug}The same model, wrapped as {"data": ...}.
GET /models/{author}/{slug}/endpointsOne model's providers, each with its prices, context length, tag and recent uptime, latency and throughput. GET /models/{name}/endpoints for a name with no /.
GET /embeddings/modelsThe embeddings models, as GET /models?output_modalities=embeddings lists them. Without a key, the public ones.
GET /images/modelsThe image models your key can call, each with the sizes and values its fields take. Key required.
GET /images/models/{author}/{slug}/endpointsOne image model's providers, each with the values its fields take and its price per token or per image. GET /images/models/{name}/endpoints for a name with no /. Key required.
GET /keyThe key you send: its kind, its limit, what is left and its spend.
GET /creditsYour organization's prepaid credit and usage. Management key.
GET, POST /keys; GET, PATCH, DELETE /keys/{hash}List, create, change and revoke inference keys. Management key.

Paths are relative to https://api.llm.buzz/api/v1. Model routes outside it, such as /v1/chat/completions on the bare host, answer 404.

Decisions are served on POST /systemone and on POST https://api.llm.buzz/api/alpha/decisions, and no listed model answers them today. Choosing an API says which API each kind of model takes, and Decisions covers the two routes.

Note:

llm.buzz does not enable batch jobs: with a key, /batches and /files answer 404, "batches are not enabled on this gateway". Send a large job as single requests; the batch jobs guide shows how.

The keyless public catalog under /public/v1 (the site facts, every public model and provider) is what the llm.buzz website is built from, and the API reference lists it too. It needs no key, but it is the website's data, not a stable API: its fields can change without notice. Build on GET /models and the endpoints route instead.

The model list

GET /models returns data, total_count and links. Prices are decimal strings in US dollars per token. An audio model's prompt price is per second of audio or per character of input, and an image model lists its output price in image_output (Images explains image prices). Its query parameters:

ParameterEffect
output_modalitiestext by default; all lists every model, and a comma list such as text,embeddings lists models that produce any of them. The values are text, image, embeddings, transcription (speech to text) and speech (text to speech).
limit, offsetPage the list.
region=euOnly models with an EU provider, priced over those providers. It changes the listing, never how a call routes.

A model whose lead provider's listing names its reasoning efforts carries them as reasoning_efforts, in order from none to max. The key is left out otherwise, including for a model whose efforts llm.buzz knows only from its own rules for the model's family, so a model without it can still reason: Reasoning. A speech-to-text model carries verbose_json, and a text-to-speech model supported_voices, default_voice and speech_speed; Audio explains them.

Without an Authorization header the list, a model and its endpoints answer the public catalog, at most 1,000 models, priced at each model's first-ranked public provider.

On the endpoints route, llm.buzz's own provider is one endpoint, provider_name llm.buzz and tag llm-buzz, priced at the lowest live direct price of each component. The llm.buzz provider explains it.

The provider object

Send provider in the request body (with the OpenAI SDK, in extra_body) to steer one request. Chat Completions, Responses, Messages, Embeddings and the image routes read every field; the audio routes read only zdr and data_collection. Every field accepts null.

FieldTypeMeaning
orderlist of stringsTry these providers first, in this order, then the others.
onlylist of stringsUse only these providers.
ignorelist of stringsNever use these providers.
allow_fallbacksbooleanfalse stops moving to other providers: without order only the first provider is tried, with order only the listed ones.
sortstringprice tries the cheapest provider first, throughput and latency the fastest, smart weighs price and speed. Ignored when order is set.
zdrbooleantrue keeps the request on providers that declare 0 days of retention.
data_collectionstringdeny keeps the request on providers that declare no training and 0 days of retention. allow demands nothing.

order, only and ignore take at most 64 names. A name matches a provider's display name, its tag, or the tag's first part, ignoring case; an EU provider's tag ends in /eu. llm.buzz or llm-buzz names llm.buzz's own provider, and llm-buzz/eu only its capacity in the EU. Models and routing explains the order a model's providers are tried in.

extra_body={"provider": {"only": ["scaleway/eu"], "zdr": True}}

Model suffixes

A suffix on the model's name changes one request: :floor tries the cheapest provider first, :nitro the fastest, and :exacto is accepted and ignored. :online asks for a web search on Chat Completions and Responses; on Messages it does nothing and is named in x-sgr-ignored-parameters as model:online.

llm.buzz runs no web search today. A request that asks for one, with :online, web_search_options or plugins: [{"id": "web"}], is still served, without the search: nothing is sent to a search service, no search is billed, and x-sgr-ignored-parameters names it as web_search->dropped(search_unavailable). For an organization whose requests llm.buzz keeps in the EU, such a request answers 400 web_search_unavailable_in_region instead.

Request fields

Each API's page lists every field and what llm.buzz does with it: Chat Completions, Responses and Messages. Fields the surface does not know are dropped instead of refused, and Chat Completions, Responses and Messages name them in x-sgr-ignored-parameters in the response body. A field llm.buzz refuses answers 400 before any provider is called: Errors. These fields do something on llm.buzz:

FieldSurfacesMeaning
toolsChat Completions, Responses, MessagesFunctions the model can call, in each API's own shape.
response_formatChat Completionsjson_schema asks for an answer in a JSON schema; json_object for any JSON object.
reasoningChat Completions, Messageseffort or max_tokens, plus enabled and exclude. Each provider receives it in its own terms. Where a model's efforts are known, an effort it does not take becomes the nearest one it does, named in x-sgr-ignored-parameters; a provider that refuses the setting answers 400 naming the field. exclude: true keeps the reasoning text out of the answer while the model still reasons. Responses takes reasoning.effort, and Chat Completions also takes OpenRouter's include_reasoning: true is reasoning: {}, false is reasoning: {exclude: true}.
cache_controlChat Completions, ResponsesAnthropic's prompt-cache marker, {"type": "ephemeral"} with an optional ttl of "5m" or "1h". llm.buzz passes it on and never adds one. Messages takes Anthropic's own markers. Prompt caching says when to send it.
prompt_cache_breakpoint, prompt_cache_options, prompt_cache_retentionChat Completions, ResponsesOpenAI's explicit caching controls, for OpenAI's GPT-5.6 and later models. Prompt caching explains them.
session_idChat Completions, Responses, MessagesA name for the conversation, 1 to 256 characters, so its turns stay on the provider that holds its cache. The x-session-id header works too.
web_search_options, plugins: [{"id": "web"}]Chat Completions, ResponsesAsk for a web search, as :online does. llm.buzz runs none today: see Model suffixes.
providerEvery model routeThe provider object above.
gatewayChat Completions, Responses, MessagesPer-request retries and fallbacks, below.
defer_loadingChat Completions, Responses, MessagesOn a tool, keeps it out of the prompt until a tool search finds it, below.

On Chat Completions and Responses, send an Idempotency-Key header. A retry with the same key and the same body never runs the request twice: it returns the first answer, or 409 idempotency_replay_unavailable when that 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. A retry without the key, or with a new one, runs the request again and is billed again. Retries and idempotency says which key to send after each answer, and Errors lists the codes.

Sampling settings a model does not take

Some models refuse sampling settings. The Claude models that only think adaptively (Opus 4.7 onward, Sonnet 5, Haiku 5, Fable 5, Mythos 5) take no temperature, top_p or top_k, and OpenAI's reasoning models take temperature and top_p only where OpenAI does: some never, others only at reasoning effort none. llm.buzz drops such a value instead of failing the request, and names it in x-sgr-ignored-parameters, as temperature->dropped(unsupported_by_provider), or temperature->dropped(set_reasoning_effort_none) where setting the effort to none keeps it.

Two more rules follow the model or the provider:

  • Claude models that always think. Claude Opus 5.5, Sonnet 5.5 and the Fable models take no none effort: reasoning_effort: none and thinking.type: disabled answer 400 before any provider is called, whichever provider would serve the model. Leave thinking out, or choose an effort: How an effort is mapped. Claude Opus 5.5, Sonnet 5.5 and Fable 5.1 also cannot be forced to call a tool: a tool_choice that forces one is served as auto and named as tool_choice->auto, so the answer may come without a tool call.
  • Moonshot AI's own API, one provider of the Kimi models such as moonshotai/kimi-k3, takes no temperature, top_p, top_k, frequency_penalty or presence_penalty: llm.buzz drops them there, names them in x-sgr-ignored-parameters, and the model answers at its fixed settings. A tool_choice that names one function goes to another provider of the model that takes it, or is served as auto and named as tool_choice->auto. To force a tool call there, send tool_choice: "required". The Kimi models' other providers keep these settings.

Retries and fallbacks per request

The gateway object sets bounds for one request. Every field is optional.

extra_body={"gateway": {
    "retry": {"max_attempts_per_route": 2, "max_total_attempts": 3,
              "backoff": {"type": "exponential", "base_delay_ms": 500, "max_delay_ms": 8000}},
    "routing": {"allow_fallbacks": False},
}}
FieldMeaning
retry.max_attempts_per_route1 to 4 calls to one provider, the first included. A cap, not extra retries: a provider that failed is not called again for an ordinary failure.
retry.max_total_attempts1 to 8 calls in all, every fallback included. 8 when omitted.
retry.backoff{"type": "none"}, or {"type": "exponential"} with base_delay_ms (default 500), max_delay_ms (default 8000) and multiplier (default 2): the wait before calling a throttled provider again.
routing.allow_fallbacksfalse keeps the request on the first provider, as provider.allow_fallbacks: false does.

These are ceilings: the request's time limit, your spending limits and a provider's health can stop it sooner. Once output has reached you, the request stays on the provider that sent it.

With many tools, mark most of them defer_loading: true and declare a tool search tool. The model then sees only the other tools and a search; the tools a search finds join the request. Where every provider of the model searches natively, the provider does it; otherwise llm.buzz runs the search, up to 3 rounds per request.

SurfaceDeclareMark
Messages{"type": "tool_search_tool_bm25"} or {"type": "tool_search_tool_regex"}defer_loading: true on the tool
Responses{"type": "tool_search"}defer_loading: true on the function tool
Chat Completions{"type": "openrouter:tool_search"}defer_loading: true beside function

Usage counts the searches in server_tool_use_details.tool_search_requests (server_tool_use.tool_search_requests on Messages).

Responses

  • usage.cost is the request's cost in US dollars, on every surface, when every part of it is known.
  • Chat Completions and Embeddings bodies, and every Chat stream chunk, carry provider: the name of the provider that answered, llm.buzz for llm.buzz's own provider.
  • Cached input shows in usage.prompt_tokens_details.cached_tokens on Chat Completions and usage.input_tokens_details.cached_tokens on Responses, and cache writes in cache_write_tokens beside it, with cache_write_1h_tokens for the one-hour part when the provider reports it. Messages keeps Anthropic's fields, cache_read_input_tokens and cache_creation_input_tokens. Prompt caching lists them.
  • Every answer carries the headers x-request-id, x-gateway-alias (the model that served), x-gateway-canonical-model, x-gateway-provider (the provider that answered), x-gateway-route-depth and x-gateway-route-reason. Image and audio answers add X-Generation-Id.
  • Readable reasoning comes back beside the answer: message.reasoning (delta.reasoning in a stream) on Chat Completions, a thinking block on Messages, and a reasoning item's summary_text on Responses. reasoning.exclude: true turns it off.
  • A Chat Completions model that makes images returns them in message.images[].image_url.url (delta.images in a stream), each a complete base64 image. Send one back as an assistant image_url content part to continue the conversation.

Cost of a finished request

GET /generation?id= answers the record and cost of any finished request of your organization. A request's generation ID is gen- and the 32 hex digits of its x-request-id, which is request- and the same digits. Image and audio answers also name it in X-Generation-Id, and a text-to-speech answer, which has no JSON body, has its cost only here.

curl "https://api.llm.buzz/api/v1/generation?id=gen-..." \
  -H "Authorization: Bearer $LLM_BUZZ_KEY"

The answer is OpenRouter's {"data": {...}}. total_cost and usage are what you were charged, in US dollars at your rate; api_type is completions (Chat Completions, Responses and Messages), embeddings, image, stt, tts or decisions; provider_name is the provider that served it. An ID of another organization, a malformed one, and one whose request has not finished all answer 404; a request without id answers 400. Audio lists every key.

Time limit

A request may run for 600 seconds. A stream still generating then ends with a timeout error chunk and the stream terminator, and is billed for the prompt and the output you received, not for its whole reservation. Any other request past the limit answers 504 deadline_exceeded. Usage and limits collects the limits of every API.

Browser access

A web page can call the model API from the browser with its visitor's own key, as on OpenRouter. The key travels in Authorization or x-api-key, never in a cookie, so every answer under /api/ allows any origin and none allows credentials.

  • A preflight answers 204 without a key, and a browser keeps its answer for a day. It allows the headers the API reads: authorization, content-type, accept, x-api-key, anthropic-version, anthropic-beta, x-title, http-referer, idempotency-key, x-session-id, x-client-request-id, originator, openai-organization, openai-project, and any x-sgr- or x-stainless- header (the OpenAI and Anthropic SDKs send the latter). The browser refuses to send any other header.
  • Every answer, errors included, lets the page read the headers x-request-id, x-generation-id, retry-after, x-ratelimit-* and x-gateway-*, and, in the body, the x-sgr-ignored-parameters key. No answer sends that name as a header.
  • The keyless catalog under /public/v1 sends no CORS headers.
  • A key used from a page is visible to that page's visitors. Give a browser app a key with a spending limit, or let each visitor bring their own.

App attribution

Coding agents and apps that llm.buzz recognizes get their usage counted under their own name on Rankings and their app page. Most are recognized by their User-Agent. An app can also name itself with OpenRouter's headers:

-H "X-Title: Cline" -H "HTTP-Referer: https://cline.bot"

A title or a site llm.buzz does not know counts as other usage. Neither header is ever published.

Errors

Errors on the model routes come in one envelope; metadata.gateway_code is the code to branch on. The Messages API keeps Anthropic's error body.

{"error": {"code": 404, "message": "...", "metadata": {"error_type": "not_found", "gateway_code": "model_not_found", "param": "model"}}}
StatusCodeMeaning
400invalid_parameterA request field fails validation, such as a missing messages or input, an out-of-range temperature or n other than 1; metadata.param names it, or body when the fault spans fields.
400invalid_jsonThe body is not JSON.
400unsupported_parameterA field llm.buzz refuses; metadata.param names it. The pages of Chat Completions, Responses and Messages list the fields each refuses.
400invalid_requestllm.buzz read the body and refused the request: a provider's own 400, whose sentence follows provider rejected the request:, or another refusal the message explains.
400unsupported_capabilityThe model or its providers cannot do what the request asks, such as a service_tier of flex, priority or fast on Chat Completions and Responses.
400context_length_exceededThe prompt fits no provider's context window.
400web_search_unavailable_in_regionThe request asked for a web search, and your organization's requests are kept in the EU.
401invalid_keyNo key, or the key is unknown, expired, revoked or disabled.
402insufficient_creditsYour balance is spent and the model is not free.
403key_limit_exceededThe key's spend in its period has reached its limit.
403management_key_not_allowedA management key called a model route.
404model_not_foundNo model has this name, or your key may not call it.
404model_unavailableNo provider of the model can serve it right now.
404no_allowed_providersYour provider preferences leave no provider. Nothing was sent.
404model_not_available_under_data_policyNo provider meets zdr, data_collection or your organization's data policy. Nothing was sent.
409idempotency_conflictAn Idempotency-Key was reused with a different body.
409idempotency_replay_unavailableA request with this Idempotency-Key was already accepted, and its answer is not stored where this retry arrived, so it was not run again. Retry with the same key after a short backoff first, when the first call got no answer; a new key runs the request again and bills it again, and after an error answer a new key is the only way.
413request_too_largeThe request body is over the size limit, such as an audio file over 25 MiB.
429unavailable_routeProviders are throttling. Retry after Retry-After seconds.
429free_allowance_exceededA free offer's allowance is used: your organization's tokens, or your key's requests per minute. Choose a paid model, or retry after Retry-After seconds for the per-minute limit.
502all_routes_failedEvery provider tried failed. Retry with backoff.
503unavailable_routeNo provider could answer just now. Retry with backoff.
504deadline_exceededThe request passed its 600-second limit.

Errors lists every code with what to do.

Docs