Create Chat Completion
Create Chat Completion on a specified text generation model.
Continuation: If the final message has the assistant role, the model continues that message instead of starting a new turn (the same convention as Anthropic and OpenRouter). Send a response that ended with finish_reason length back as the final assistant message to resume it. The message must be non-empty text without tool_calls, trailing whitespace is trimmed, thinking is disabled for the continuation, and only the new text is returned.
Response shape: Responses follow OpenRouter's chat completion shape whichever engine serves the model. Reasoning is always in reasoning (never reasoning_content), usage always has prompt_ and completion_, ids start with chatcmpl- and tool call ids with call_, finish_reason is one of stop, length, tool_calls, content_filter or error with the engine's own value in native_finish_reason, and engine-specific fields are removed. A -normalize model suffix is accepted for compatibility and ignored.
Errors: Errors use OpenRouter's envelope, {"error": {"code", "message", "type", "metadata": {"error_type"}}}. A streaming request that fails before the first token gets the real HTTP status; one that fails later receives a final chunk carrying error.
Reasoning budget: Set reasoning.max_tokens to limit thinking tokens. This limit must be below max_ (or the effective context-clipped limit). Models with reasoning.supports_max_tokens: true in /v1/models?format=openrouter (a max_tokens property under the reasoning parameter in the default list) enforce the budget; other models accept the field without enforcing it. Requested effort maps through the model's reasoning_config when configured. The :express model variant derives a budget for models with enforced budget support when no budget is supplied.
Body
application/jsonChat Completion Request Payload
-
model string
The model to use. If omitted, the gateway resolves its default model. A
-normalizesuffix is accepted for compatibility and ignored; every response is normalized. A:<variant>suffix is parsed separately from the model ID;:expressderives a thinking budget when the model supports enforced budgets and no explicit budget is supplied. -
messages array of objects required
The message context to use for the chat completion request, separated by system, user, assistant, tool, and developer roles. A final
assistantmessage is treated as a prefill and continued (seecontinue_).final_ message at least 1 items -
continue_final_message boolean
Continue the final message instead of starting a new assistant turn. Implied whenever the final message has the
assistantrole, so it only makes the intent explicit. The final message must carry non-empty text and notool_calls; trailing whitespace is trimmed, thinking is disabled for the continuation, and only the newly generated text is returned. Use it to resume a response that ended withfinish_reasonlength.default false -
stream boolean
Indicates whether the response should be streamed.
-
max_tokens integer
Deprecated name for
max_. If both are sent,completion_ tokens max_takes precedence. A value below 1 returns 400.completion_ tokens at least 1 -
max_completion_tokens integer
Maximum completion tokens, including reasoning and visible output. A value below 1 returns 400; omit the field to get the default. A value that does not fit the model's context window with the prompt is not refused. It is cut to the window less the prompt and a 32 token margin, and
finish_reasonreportslengthif the answer reaches the cut. A prompt that alone fills the window returns 400.default 32768at least 1 -
reasoning_effort string
Shorthand for
reasoning.effort. When both are supplied,reasoning.efforttakes precedence. Configured models map this level to their supported reasoning control; unsupported levels return 400.ultramaxxhighhighmediumlowminimalnone -
reasoning object
Reasoning controls. Configured models map effort through their database profile. Models advertising
reasoning.supports_max_tokens: truein/v1/models?format=openrouter(amax_tokensproperty under thereasoningparameter in the default list) enforce the budget; other models accept it without enforcing it. -
n integer
The number of chat completion choices to generate for each input message.
default 1at least 1 -
seed integer
If you would like a different response from the same message, changing the seed will change the response. A null value generates a random seed.
-
top_k integer
Sample only from the k most likely tokens at each step. 0 disables it. Passed to the engine; a model's default is the
top_kindefault_parametersof the public model list.at least 0 -
repetition_penalty number (float)
Penalises tokens already in the prompt or the answer. 1.0 is no penalty and above 1.0 discourages repetition. Passed to the engine, which also reads it as a model default.
range 0–2 -
response_format object
Constrains the answer's format.
json_objectmakes the model answer with a JSON object;json_schemamakes it answer with JSON that matches the schema.textis the default. -
temperature number (float)
A value between 0.0 and 2.0 that controls the randomness of the model's output. When set closer to 1, such as 0.8, the outcome is more unpredictable and creative. Values nearing 0, like 0.2, produce more predictable and less creative results. A temperature of zero requests greedy decoding; exact reproducibility depends on the model engine.
default 1range 0–2 -
top_p number (float)
A value between 0.0 and 1.0 that controls the probability of the model generating a particular token. A higher value will result in more diverse outputs, while a lower value will result in more repetitive outputs.
default 1range 0–1 -
frequency_penalty number (float)
A value between -2.0 and 2.0 that controls how much the model penalizes generating repetitive responses.
default 0range -2–2 -
presence_penalty number (float)
A value between -2.0 and 2.0 that controls how much the model penalizes generating responses that contain certain words or phrases.
default 0range -2–2 -
stop string or array of strings
The strings the model stops generating at, up to 4. A single string is accepted as shorthand for a one-item array.
-
logprobs boolean
Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the content of message.
-
top_logprobs integer
An integer between 0 and 20 specifying the number of most likely tokens to return at each token position, each with an associated log probability. Optional:
logprobs: truealone returns the sampled token's log probability. Requireslogprobsto be true.range 0–20 -
tool_choice string or object
Controls which (if any) tool is called by the model. A tool choice other than
nonerequirestools. -
tools array of objects
A list of function tools the model may call.
Responses
OK
application/json, text/event-stream · chat-completion-response-payload
Bad Request, including context_
application/json · error-payload
The API key is missing, unknown or not active. Send it as Authorization: Bearer <key>.
application/json · error-payload
Rate limit exceeded
application/json · error-payload
The model could not be reached
application/json · error-payload
The model timed out
application/json · error-payload
No model by that name exists, or its row is missing
application/json · error-payload
The list of models being served could not be read, so the request's model could not be resolved. Retry shortly.
application/json · error-payload
curl https://api.vultrinference.com/v1/chat/completions \
-H "Authorization: Bearer $VULTR_INFERENCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash",
"messages": [
{
"role": "system",
"content": "Answer in one sentence."
},
{
"role": "user",
"content": "Why is the sky blue?"
}
],
"max_completion_tokens": 512
}'import os
import requests
response = requests.post(
"https://api.vultrinference.com/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['VULTR_INFERENCE_API_KEY']}"},
json={
"model": "deepseek-v4.1-flash",
"messages": [
{
"role": "system",
"content": "Answer in one sentence.",
},
{
"role": "user",
"content": "Why is the sky blue?",
},
],
"max_completion_tokens": 512,
},
)
print(response.json())const response = await fetch("https://api.vultrinference.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VULTR_INFERENCE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "deepseek-v4.1-flash",
"messages": [
{
"role": "system",
"content": "Answer in one sentence."
},
{
"role": "user",
"content": "Why is the sky blue?"
}
],
"max_completion_tokens": 512
}),
});
console.log(await response.json());{
"id": "string",
"object": "string",
"created": 0,
"model": "string",
"choices": [
{
"index": 0,
"message": {
"role": "system",
"content": null,
"reasoning": null,
"tool_calls": []
},
"logprobs": {
"content": []
},
"finish_reason": "stop",
"native_finish_reason": "string"
}
],
"usage": {
"completion_tokens": 0,
"prompt_tokens": 0,
"total_tokens": 0,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0
}
}
}