Skip to content

Chat Completions

The LLMTR gateway is compatible with the OpenAI Chat Completions API. All requests POST to https://llmtr.com/v1/chat/completions.

POST /v1/chat/completions
Authorization: Bearer llmtr-your_key
Content-Type: application/json
FieldTypeRequiredDescription
modelstringyesCanonical model ID (e.g. openai/gpt-4o)
messagesarrayyesOpenAI messages format
streambooleannotrue enables SSE stream
temperaturenumberno0-2 range, model-specific default
max_tokensintegernoOutput token cap
top_pnumbernoNucleus sampling
frequency_penaltynumberno-2 to 2
presence_penaltynumberno-2 to 2
stopstring/arraynoStop sequences
response_formatobjectno{ "type": "json_object" } on supported models
toolsarraynoFunction calling (supported models)
tool_choicestring/objectnoauto, none or specific tool
Terminal window
curl https://llmtr.com/v1/chat/completions \
-H "Authorization: Bearer llmtr-your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is LLMTR?"}
],
"temperature": 0.3,
"max_tokens": 200
}'

Successful response mirrors OpenAI's format exactly:

{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1739200000,
"model": "openai/gpt-4o",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "LLMTR is a unified gateway..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 52,
"total_tokens": 76
}
}

Models are always referenced as provider/model:

  • openai/gpt-4o
  • anthropic/claude-sonnet-4.5
  • google/gemini-3.6-flash
  • deepseek/deepseek-v4-flash
  • mistral/mistral-large-latest

Use the dashboard model list or GET /v1/models for the full catalog.

When a provider discontinues a model, LLMTR does not silently forward the request to a different one. After the retirement date the request is rejected with 410 and the response names the model to move to:

{
"error": {
"type": "model_retired",
"message": "Model \"google/gemini-2.5-flash\" was retired on 2026-10-16. Use \"google/gemini-3.6-flash\" instead.",
"details": {
"model": "google/gemini-2.5-flash",
"retirement_date": "2026-10-16",
"replacement_model": "google/gemini-3.6-flash",
"status": "retired"
}
}
}

The model page and the catalog card warn ahead of the cutoff as well, while /v1/models never lists retired models.

Google is discontinuing the Gemini 2.5 text models on Gemini Enterprise Agent Platform. LLMTR closes these three identifiers on 2026-10-16:

Retired modelSuggested replacement
google/gemini-2.5-flashgoogle/gemini-3.6-flash
google/gemini-2.5-flash-litegoogle/gemini-3.5-flash-lite
google/gemini-2.5-progoogle/gemini-3.1-pro-preview

The other google/gemini-2.5-* models (image, TTS, native audio, computer use) are not part of this retirement.

Some providers support extra body fields or custom options. You can include supported fields directly in the request body.

tencent/hy3 keeps thinking disabled by default. Enable it with either a canonical suffix or the standard body field:

{ "model": "tencent/hy3:low", "messages": [{ "role": "user", "content": "Analyze this code." }] }
{ "model": "tencent/hy3", "reasoning": { "effort": "high" }, "messages": [{ "role": "user", "content": "Analyze this code." }] }

Only low and high are supported. Low requests that contain tools run as high upstream because of Hy3's adaptive-thinking behavior. Responses may include reasoning_content, usage.completion_tokens_details.reasoning_tokens, and usage.prompt_tokens_details.cached_tokens after a cache hit. Reasoning tokens are already included in completion_tokens and are not billed twice.

During multi-step tool calling, append the returned assistant message with its tool_calls, content, and reasoning_content fields intact. Dropping the field breaks the reasoning context for the next turn.

The model is advertised with a 256K window, but a single request accepts at most 192K tokens (196,608) of input. Above that limit the provider does not return an error: it silently drops the leading part of the prompt, answers from what is left, and does not report the loss. /v1/models therefore reports context_length as 196608 for this model, so clients that size their context from that field stay under the limit automatically. If you size prompts by hand, keep long documents under it or chunk them.

tencent/hy4-preview reasons by default, unlike Hy3, and uses a different field: instead of Hy3’s effort rungs it offers a single off switch.

{ "model": "tencent/hy4-preview:none", "messages": [{ "role": "user", "content": "What is 2+2? Number only." }] }
{ "model": "tencent/hy4-preview", "reasoning_effort": "none", "messages": [{ "role": "user", "content": "What is 2+2? Number only." }] }

Only none is supported. The provider accepts the other levels, but they were measured not to change reasoning length in any ordered way; offered as a selector they would bill reasoning tokens while changing nothing. An unsupported level is refused with a 400 before the request reaches the upstream.

Responses carry reasoning_content and usage.completion_tokens_details.reasoning_tokens; those tokens are already inside completion_tokens and are not billed twice. The model supports prompt caching, and cached tokens arrive in usage.prompt_tokens_details.cached_tokens, billed at the lower cache-read price.

It produces schema-enforced JSON through json_schema. It has two tool-calling limits — tool_choice: "required" is not honoured, and a named choice mislabels finish_reason — see Tool Calling for details.

The model is text only. An image sent to it is dropped without an error: the request returns 200, prompt_tokens counts the text alone, and the model says it cannot see images. Do not send images to this model.

llmtr/qwen3-5-4b is hosted in Turkey: requests are never forwarded to a third-party provider. It offers a 128K context window (prompt and completion together), reads image input, and supports tool calling.

Thinking is on by default. The model produces a reasoning pass before answering and returns it in message.reasoning_content. That reasoning is spent from the max_tokens budget: if the budget is small it is consumed entirely by reasoning, content comes back empty, and finish_reason is length. Set max_tokens to at least 2048 on a default call.

Turn thinking off with the canonical suffix or the body field:

{ "model": "llmtr/qwen3-5-4b:fast", "messages": [{ "role": "user", "content": "Summarize this product in one sentence." }], "max_tokens": 256 }
{ "model": "llmtr/qwen3-5-4b", "reasoning": false, "messages": [{ "role": "user", "content": "Summarize this product in one sentence." }], "max_tokens": 256 }

With thinking off, no extra reasoning tokens are spent, the response carries no reasoning_content, and answers are noticeably faster. Prefer this mode for classification, labeling, and summarization flows that expect short answers.

The model supports prompt caching. Re-sending the same prompt prefix (for example a fixed system prompt) hits the cache; the number of tokens served from it is returned in usage.prompt_tokens_details.cached_tokens and those tokens are billed at the discounted cache-read rate. To lower cost in RAG and chatbot flows with long system prompts, keep the fixed content at the start of the message array and the varying content at the end.

Image input is accepted only as a base64 data URL; a remote https:// image address returns 400 unsupported_input. See LLMTR Qwen 3.5 4B for details. Audio and video input are not supported.

The following models run at fixed sampling settings and do not accept temperature or top_p:

openai/o1, openai/o3, openai/o3-mini, openai/o4-mini, openai/gpt-5.5, openai/gpt-5.5-pro, openai/gpt-5.6-sol, openai/gpt-5.6-sol-pro, openai/gpt-5.6-terra, openai/gpt-5.6-terra-pro, openai/gpt-5.6-luna, openai/gpt-5.6-luna-pro, openai/gpt-6-astra

Sending temperature or top_p to these models does not fail the request: LLMTR removes the field from the body and runs the request. The response reports which fields were removed:

{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"choices": [],
"usage": {},
"llmtr_dropped_parameters": ["temperature", "top_p"]
}

The llmtr_dropped_parameters field is present only when something was actually removed; every other response matches the OpenAI schema exactly. In streaming mode the same field arrives on the final chunk.

These models do not list temperature or top_p under supported_parameters in /v1/models, so agent frameworks that read that field will not send them in the first place.

Note: not every reasoning model belongs to this group. openai/gpt-5.3-codex reasons and does accept temperature. We measure this per model rather than assuming it per family.

openai/o1, openai/o3, openai/o3-mini, and openai/o4-mini accept a thinking depth through reasoning_effort. The supported levels are low, medium, and high. You can also write the level as a suffix on the model identifier:

{ "model": "openai/o4-mini:high", "messages": [{ "role": "user", "content": "Analyze the complexity of this algorithm." }] }
{ "model": "openai/o4-mini", "reasoning_effort": "high", "messages": [{ "role": "user", "content": "Analyze the complexity of this algorithm." }] }

When no level is given the field is not sent and OpenAI applies its own default.

xhigh is deliberately unsupported. The provider accepts the value and returns 200, but in our measurements it produced no reasoning tokens on any of the four models: offering it would be a choice that changes nothing. Requesting an unsupported level is refused with a 400 before the request reaches the upstream, and the error names the levels that do work.

Reasoning tokens are reported in usage.completion_tokens_details.reasoning_tokens; they are already part of completion_tokens and are not billed twice.

moonshot/kimi-k2.5 was retired on 5 September 2026 (model_retired, HTTP 410); use moonshot/kimi-k2.6 for new and existing integrations.

moonshot/kimi-k3, moonshot/kimi-k2.7-code, and moonshot/kimi-k2.6 run with thinking enabled by default. moonshot/kimi-k2.7-code does not support non-thinking mode; omit thinking or use { "type": "enabled" }. thinking: { "type": "disabled" } returns 400 invalid_request.

For moonshot/kimi-k3, thinking can be turned off: send "reasoning": false in the request body or append the :fast suffix to the model name (moonshot/kimi-k3:fast). The :think suffix keeps thinking on; without a suffix or reasoning field the default is thinking on. With thinking off, the response carries no reasoning_content and no reasoning tokens are produced. Reasoning tokens are billed as output, so keep max_tokens generous even for short answers (at least 1024 recommended).

Kimi K3, K2.7 Code, and K2.6 have fixed sampling values: temperature=1, top_p=0.95, n=1, presence_penalty=0, and frequency_penalty=0. Unsupported n, presence/frequency penalties, or unsupported Kimi tool_choice forms are rejected with 400 before the upstream call. The K2 family accepts only auto or none for tool_choice; kimi-k3 additionally supports required. The {"type": "function", ...} form that forces a specific function is not supported on any Kimi model.

kimi-k3 does not support web search; requests containing $web_search return 400. Use kimi-k2.7-code or kimi-k2.6 for flows that need web search.

During multi-step tool calling, Kimi may return reasoning_content on the assistant tool-call message. Preserve that assistant message with both tool_calls and reasoning_content before sending the following tool-result turn. LLMTR preserves this provider-specific field across the round trip.

For media input, use base64 data URLs instead of remote URLs. Image and video parts must be sent as data: URLs; remote media URLs return 400 unsupported_input.

Active chat model identifiers: mimo/mimo-v2.5-pro, mimo/mimo-v2.5.

Legacy MiMo V2 model identifiers return model_retired (HTTP 410) after 2026-06-30 00:00 Beijing time. The endpoint and API key do not change; update only the model ID to the replacement below.

Legacy model IDReplacement model IDTransition behavior
mimo/mimo-v2-promimo/mimo-v2.5-proAutomatically forwarded by LLMTR starting 2026-06-01
mimo/mimo-v2-omnimimo/mimo-v2.5Automatically forwarded by LLMTR starting 2026-06-01
mimo/mimo-v2-flashmimo/mimo-v2.5Automatically routed by MiMo upstream starting 2026-06-18; the legacy ID is no longer accepted after 2026-06-30

MiMo TTS is not currently exposed through LLMTR. TTS/ASR support will be documented separately when those operations are available.

Enabling web search. Both forms are accepted:

// Option 1: Via the tools field
{ "tools": [{ "type": "web_search" }] }
// Option 2: Via the body field
{ "webSearchEnabled": true }

Search-enabled requests may carry extra provider-side charges. Check the current model pricing before sending production traffic.

Thinking control. On supported models, add thinking to the body to control this behavior:

{ "thinking": { "type": "enabled" } } // or "disabled"
HTTPerror.typeMeaning
400invalid_request_errorInvalid parameter / missing field
401auth_errorInvalid or expired API key
403forbiddenNo access to the model
410model_retiredModel retired; use the replacement model ID from the error message
429rate_limit_exceededRate limit hit
500internal_errorGateway internal error
502provider_errorUpstream provider failure

See Errors for the full list.