본문으로 건너뛰기

Chat Completions

Creates a chat completion. Compatible with the OpenAI Chat Completions API.

POST/v1/chat/completions
For AI SDK, Messages, Responses, and Images, see the Quickstart method tabs.
chat.ts

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);

Request body#

ParameterTypeRequiredDescription
modelstringRequiredModel 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.
messagesarrayRequiredArray of {role, content}. role is system | user | assistant.
temperaturenumberOptional0.0 to 2.0.
max_tokensintegerOptional1 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.
streambooleanOptionalIf true, returns an SSE streaming response. Default false.
top_pnumberOptional0.0 to 1.0. Nucleus sampling.
stopstring | string[]OptionalSequences that stop generation.
toolsarrayOptionalFunction-calling tool definitions (OpenAI format). See Tool Calling.
tool_choicestring | objectOptional"auto" · "none", or an object forcing a specific tool.
response_formatobjectOptionalE.g. {"type": "json_object"}. See Structured Outputs.
seedintegerOptionalDeterministic sampling seed. Support varies by model.
frequency_penaltynumberOptional-2.0 to 2.0.
presence_penaltynumberOptional-2.0 to 2.0.
parallel_tool_callsbooleanOptionalWhether parallel tool calls are allowed.
logit_biasobjectOptionalMap from token ID to bias value.
reasoning_effortstringOptionalminimal | none | low | medium | high | xhigh | max. Automatically translated to each provider's format. See Reasoning Models.
thinkingbooleanOptionalConvenience alias for reasoning_effort — true means medium, false means none. If both are sent, reasoning_effort wins.
reasoningobjectOptionalOpenRouter-compatible object {effort|enabled, max_tokens}. Folded into reasoning_effort (priority: effort > enabled > max_tokens bucket ≥6000 high / ≥2500 medium / else low).
service_tierstringOptionalauto | 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_modestringOptionalstandard | pro. GPT-5.6 Sol/Terra/Luna quality-first (pro) mode.
pluginsarrayOptional[{"id": "web", ...}] web search plugin. See Web Search.
providerobjectOptional{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_idstringOptionalMax 128 chars. Sticky seed for the weighted routing policy — the same trace_id always routes to the same model.
modelstringRequired

Model ID to route to. Also accepts model@provider.

messagesobject[]Required

Conversation turns. Minimum length 1.

rolestringRequired

system | user | assistant | tool | function

contentstring | ContentPart[] | nullOptional

Plain text, multimodal parts, or null when tool_calls is set.

namestringOptional

Tool or function name for tool/function roles.

tool_callsobject[]Optional

OpenAI-format tool calls from the assistant.

tool_call_idstringOptional

Id referenced by a role=tool result message.

reasoning_detailsobject[]Optional

Opaque prior-turn reasoning blocks passed through to the provider.

temperaturenumberOptional

Sampling temperature.

range: 0.0–2.0

max_tokensintegerOptional

Minimum 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_tokensintegerOptional

OpenAI reasoning alias; copied onto max_tokens when set. Minimum 1, capped per model like max_tokens.

streambooleanOptional

default: false

stream_optionsobjectOptional

Accepted but ignored. A final usage chunk is always sent on a stream.

modalities("text" | "audio")[]Optional

Include "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.

voicestringRequired
formatstringRequired

enum: wav mp3 flac opus pcm16

top_pnumberOptional

range: 0.0–1.0

stopstring | string[]Optional
toolsobject[]Optional

OpenAI-format function tools.

typestringOptional

example: function

functionobjectOptional
namestringOptional
descriptionstringOptional
parametersobjectOptional
tool_choicestring | objectOptional
response_formatobjectOptional
seedintegerOptional
frequency_penaltynumberOptional

range: -2.0–2.0

presence_penaltynumberOptional

range: -2.0–2.0

parallel_tool_callsbooleanOptional
logit_biasobjectOptional
reasoning_effortstringOptional

enum: minimal none low medium high xhigh max

thinkingbooleanOptional

Alias absorbed into reasoning_effort (true means medium, false means none).

service_tierstringOptional

enum: auto default flex background priority fast ultrafast

reasoning_modestringOptional

enum: standard pro

pluginsobject[]Optional
providerobjectOptional

Routing-only; stripped before upstream.

orderstring[]Optional
onlystring[]Optional
ignorestring[]Optional
sortstringOptional

Ignored when order is set.

enum: price latency throughput ttft tps

max_pricenumber | objectOptional
hasstring[]Optional

enum: implicit-caching

require_zdrbooleanOptional
disallow_prompt_trainingbooleanOptional
quantization_onlystring[]Optional

Cannot be sent together with quantization_exclude (400).

quantization_excludestring[]Optional

Cannot be sent together with quantization_only (400).

min_contextintegerOptional
require_no_trainingbooleanOptional

Keep only providers whose training use is 'no'. Providers marked 'yes' or unknown are excluded.

residency_instring[]Optional

Keep only providers whose data residency is in this list. Providers with unknown residency are excluded.

modelsstring[]Optional

Cross-model fallback list; routing-only. Max 10.

trace_idstringOptional

Sticky seed for weighted policies. Max 128 chars. Routing-only.

userstringOptional
tagsstring[]Optional

The 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.

request body
{
  "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.

200 OK
{
  "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.

SSE stream
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.

request body (explicit caching)
{
  "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 (cache hit)
"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.

Transient provider failures are retried automatically or switched to another provider. If the call still fails, an error is returned, and no credits are charged for a failure that happens before the response starts.