Chat Completions
Creates a chat completion. Compatible with the OpenAI Chat Completions API.
OpenAI Chat Completions API
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "plm_xxxxxxxxxxxxxxxx",
baseURL: "https://apirouter.pleum.ai/v1",
});
const response = await client.chat.completions.create({
model: "gpt-5.5",
messages: [{ role: "user", content: "Why is the sky blue?" }],
});
console.log(response.choices[0].message.content);OpenAI Chat Completions API
from openai import OpenAI
client = OpenAI(
api_key="plm_xxxxxxxxxxxxxxxx",
base_url="https://apirouter.pleum.ai/v1",
)
response = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Why is the sky blue?"}],
)
print(response.choices[0].message.content)OpenAI Chat Completions API
curl https://apirouter.pleum.ai/v1/chat/completions \
-H "Authorization: Bearer plm_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}'Request body#
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | Required | Model ID. See the full list at GET /v1/models. You can also pin a specific provider with the model@provider syntax (e.g. claude-sonnet-4-6@anthropic). A <family>-latest spelling (e.g. mistral-medium-latest) automatically resolves to the newest release of that family. |
| messages | array | Required | Array of {role, content}. role is system | user | assistant. |
| temperature | number | Optional | 0.0 to 2.0. |
| max_tokens | integer | Optional | 1 or greater (no global cap). Default 4096. A value above the model's maximum output (the catalog's max_output) is lowered to that maximum instead of failing. A 400 is returned only when input plus output cannot fit the context window. Used to estimate the credit pre-hold amount, so set only as much as you need. |
| stream | boolean | Optional | If true, returns an SSE streaming response. Default false. |
| top_p | number | Optional | 0.0 to 1.0. Nucleus sampling. |
| stop | string | string[] | Optional | Sequences that stop generation. |
| tools | array | Optional | Function-calling tool definitions (OpenAI format). See Tool Calling. |
| tool_choice | string | object | Optional | "auto" · "none", or an object forcing a specific tool. |
| response_format | object | Optional | E.g. {"type": "json_object"}. See Structured Outputs. |
| seed | integer | Optional | Deterministic sampling seed. Support varies by model. |
| frequency_penalty | number | Optional | -2.0 to 2.0. |
| presence_penalty | number | Optional | -2.0 to 2.0. |
| parallel_tool_calls | boolean | Optional | Whether parallel tool calls are allowed. |
| logit_bias | object | Optional | Map from token ID to bias value. |
| reasoning_effort | string | Optional | minimal | none | low | medium | high | xhigh | max. Automatically translated to each provider's format. See Reasoning Models. |
| thinking | boolean | Optional | Convenience alias for reasoning_effort — true means medium, false means none. If both are sent, reasoning_effort wins. |
| reasoning | object | Optional | OpenRouter-compatible object {effort|enabled, max_tokens}. Folded into reasoning_effort (priority: effort > enabled > max_tokens bucket ≥6000 high / ≥2500 medium / else low). |
| service_tier | string | Optional | auto | default | flex | background | priority/fast | ultrafast. Passed through to OpenAI-family providers (latency/cost tradeoff). Billing follows the tier reported in the response — fast/priority 2x, flex 0.5x, ultrafast 6x. Models that support it list service_tier in supported_parameters on GET /v1/models. |
| reasoning_mode | string | Optional | standard | pro. GPT-5.6 Sol/Terra/Luna quality-first (pro) mode. |
| plugins | array | Optional | [{"id": "web", ...}] web search plugin. See Web Search. |
| provider | object | Optional | {order, only, ignore, sort, max_price, has, require_zdr, disallow_prompt_training, quantization_only, quantization_exclude, min_context, require_no_training, residency_in} provider routing preferences. sort is one of price | latency | throughput | ttft | tps and is ignored when order is set. has accepts only implicit-caching. Sending both quantization_only and quantization_exclude returns 400. See Latency Routing. |
| trace_id | string | Optional | Max 128 chars. Sticky seed for the weighted routing policy — the same trace_id always routes to the same model. |
modelstringRequiredModel ID to route to. Also accepts model@provider.
messagesobject[]Required
Conversation turns. Minimum length 1.
rolestringRequiredsystem | user | assistant | tool | function
contentstring | ContentPart[] | nullOptionalPlain text, multimodal parts, or null when tool_calls is set.
namestringOptionalTool or function name for tool/function roles.
tool_callsobject[]OptionalOpenAI-format tool calls from the assistant.
tool_call_idstringOptionalId referenced by a role=tool result message.
reasoning_detailsobject[]OptionalOpaque prior-turn reasoning blocks passed through to the provider.
temperaturenumberOptionalSampling temperature.
range: 0.0–2.0
max_tokensintegerOptionalMinimum 1. There is no global upper bound. A value above the model's max_output is lowered to that maximum instead of failing; a 400 is returned only when input plus output cannot fit the context window.
default: 4096
max_completion_tokensintegerOptionalOpenAI reasoning alias; copied onto max_tokens when set. Minimum 1, capped per model like max_tokens.
streambooleanOptionaldefault: false
stream_optionsobjectOptionalAccepted but ignored. A final usage chunk is always sent on a stream.
modalities("text" | "audio")[]OptionalInclude "audio" to request audio output. Audio output works only with stream set to false; a streaming request returns 400.
audioobjectOptional
Audio output options. Send it together with "audio" in modalities.
voicestringRequiredformatstringRequiredenum: wav mp3 flac opus pcm16
top_pnumberOptionalrange: 0.0–1.0
stopstring | string[]Optionaltoolsobject[]Optional
OpenAI-format function tools.
typestringOptionalexample: function
functionobjectOptional
namestringOptionaldescriptionstringOptionalparametersobjectOptionaltool_choicestring | objectOptionalresponse_formatobjectOptionalseedintegerOptionalfrequency_penaltynumberOptionalrange: -2.0–2.0
presence_penaltynumberOptionalrange: -2.0–2.0
parallel_tool_callsbooleanOptionallogit_biasobjectOptionalreasoning_effortstringOptionalenum: minimal none low medium high xhigh max
thinkingbooleanOptionalAlias absorbed into reasoning_effort (true means medium, false means none).
service_tierstringOptionalenum: auto default flex background priority fast ultrafast
reasoning_modestringOptionalenum: standard pro
pluginsobject[]OptionalproviderobjectOptional
Routing-only; stripped before upstream.
orderstring[]Optionalonlystring[]Optionalignorestring[]OptionalsortstringOptionalIgnored when order is set.
enum: price latency throughput ttft tps
max_pricenumber | objectOptionalhasstring[]Optionalenum: implicit-caching
require_zdrbooleanOptionaldisallow_prompt_trainingbooleanOptionalquantization_onlystring[]OptionalCannot be sent together with quantization_exclude (400).
quantization_excludestring[]OptionalCannot be sent together with quantization_only (400).
min_contextintegerOptionalrequire_no_trainingbooleanOptionalKeep only providers whose training use is 'no'. Providers marked 'yes' or unknown are excluded.
residency_instring[]OptionalKeep only providers whose data residency is in this list. Providers with unknown residency are excluded.
modelsstring[]OptionalCross-model fallback list; routing-only. Max 10.
trace_idstringOptionalSticky seed for weighted policies. Max 128 chars. Routing-only.
userstringOptionalThe standard sampling / tool parameters (top_p through reasoning_effort) are passed through to the routed provider as-is, without validation — a parameter the model does not support may be ignored by the provider or cause it to return an error. n (multiple choices) is not supported — a single response is always returned.
{
"model": "gpt-5.5",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello"}
],
"temperature": 0.7,
"max_tokens": 4096,
"stream": false
}Response#
Returns OpenAI-style choices / usage. Cost is settled after the reply is sent, so cost (KRW cost, FX rate, markup) is included in the body only once settlement has finished. If it is missing, call GET /v1/generation?id=… with the X-Request-Id response header value, or check dashboard usage. See also Where to find cost.
{
"id": "chatcmpl-9f3c2b7a5e1d4c8a9b0e6d7f1a2b3c4d",
"object": "chat.completion",
"created": 1767225600,
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "Hello! How can I help you?"},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 12,
"total_tokens": 36
},
"cost": {"usd": 0.00048, "krw": 0.7, "fx_rate": 1342.48, "markup_rate": 0.0}
}Streaming#
With stream: true, text chunks are sent as text/event-stream, and the final event carries usage. Look up cost with X-Request-Id.
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":"Hello! "}}]}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"How can I help you?"}}]}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":8,"total_tokens":20}}
data: [DONE]Prompt caching#
PleumRouter supports prompt caching. OpenAI, Google Gemini, and DeepSeek cache automatically with no extra configuration — repeated input prefixes (long system prompts, reference documents, etc.) are cached on the provider side, and cache hits are billed at a discounted rate below the standard input price, lowering your cost.
Anthropic (Claude) uses explicit caching. Add cache_control: {"type": "ephemeral"} to a content part to mark a cache breakpoint; the prefix up to that point is cached. On multi-turn calls, breakpoints are injected automatically even without cache_control; see Auto Prompt Caching for the rules.
{
"model": "claude-sonnet-4-6",
"messages": [
{
"role": "system",
"content": [
{
"type": "text",
"text": "<large reusable context: docs, schema, instructions...>",
"cache_control": {"type": "ephemeral"}
}
]
},
{"role": "user", "content": "Answer based on the context above."}
]
}On a cache hit, the response usage includes prompt_tokens_details.cached_tokens (hit tokens). Anthropic also returns cache-write tokens as cache_creation_input_tokens. The discount applies to models that list a cache-read price in cache_read_usd on GET /v1/models.
"usage": {
"prompt_tokens": 10240,
"completion_tokens": 120,
"total_tokens": 10360,
"prompt_tokens_details": {"cached_tokens": 10000},
"cache_creation_input_tokens": 0
}Billing#
A call that fails before the response starts is not billed. A successful call is settled against actual token usage, with a minimum charge of 0.1 credits. If a stream is cut off midway, the tokens already sent are billed.