Skip to content

Upstage Solar

Solar is Upstage's model family tuned for agentic workflows. All three rows are called through /v1/chat/completions. All three accept text input only; image and audio input are not supported.

ModelContextMax output
upstage/solar-pro4524,288131,072
upstage/solar-pro3131,072shared with the context window
upstage/solar-pro265,536shared with the context window

Only Solar Pro 4 has an output ceiling separate from its context window. On Pro 3 and Pro 2 generated tokens come out of the same window, so a long prompt shrinks the output budget that remains.

Terminal window
curl "$LLMTR_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer llmtr-your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "upstage/solar-pro4",
"messages": [
{ "role": "user", "content": "Find the bug in this function." }
],
"max_tokens": 2048
}'

On all three models reasoning is off by default. If you do not send reasoning_effort, the model answers directly and produces no reasoning tokens.

The important part: the accepted set of levels differs per model.

ModelAccepted levels
upstage/solar-pro4none, minimal, low, medium, high, xhigh, max
upstage/solar-pro3none, minimal, low, medium, high
upstage/solar-pro2minimal, low, medium, high

Solar Pro 2 has no none level. Solar Pro 3 and Pro 2 have no xhigh or max. Sending an unsupported level to those models is rejected with 400, and the error message lists that model's real set of levels.

Selecting a level is not the same as enabling reasoning

Section titled “Selecting a level is not the same as enabling reasoning”

Not every level triggers reasoning. Below a per-model threshold the level is accepted, returns 200, and produces no reasoning tokens at all:

ModelLevels that produce no reasoningReasoning starts at
upstage/solar-pro4none, minimallow
upstage/solar-pro3none, minimal, lowmedium
upstage/solar-pro2minimal, lowmedium

So sending reasoning_effort: "low" to Solar Pro 3 looks like it enables reasoning but actually returns a non-reasoning answer. If you want reasoning, use at least medium on Pro 3 and Pro 2.

Effort can also be given as a suffix on the model id:

upstage/solar-pro4 -> default (reasoning off)
upstage/solar-pro4:none -> accepted, does not reason
upstage/solar-pro4:low -> reasoning starts here
upstage/solar-pro4:high -> high effort
upstage/solar-pro4:max -> highest effort
upstage/solar-pro3:medium -> reasoning starts here on Pro 3
upstage/solar-pro2:medium -> reasoning starts here on Pro 2
Terminal window
curl "$LLMTR_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer llmtr-your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "upstage/solar-pro4",
"messages": [{ "role": "user", "content": "What is 17 * 23?" }],
"reasoning_effort": "medium",
"max_tokens": 2048
}'

For the general behavior of reasoning effort, see the reasoning effort page.

When reasoning is on, Solar Pro 4 and Solar Pro 3 return the trace separately in the response's reasoning field and stream it incrementally.

Solar Pro 2 does not return the trace. The reasoning tokens are still produced, counted in usage.completion_tokens_details.reasoning_tokens, and billed as output - so on this model you see the cost of the reasoning without seeing its content.

Reasoning tokens are counted inside completion_tokens, so they consume the max_tokens budget too. With reasoning on and a small budget, the budget runs out before the model produces the actual answer:

max_tokensfinish_reason
16length
64length
256stop

Keep max_tokens at 200-250 or above whenever reasoning is on. Expecting a short answer does not change this; the budget is spent on reasoning first. If you do not need reasoning, simply do not send reasoning_effort — it is off by default and small budgets work fine.

All three models support tool/function calling and accept every value of tool_choice: the default (auto), required, none, and a named function choice.

Terminal window
curl "$LLMTR_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer llmtr-your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "upstage/solar-pro4",
"messages": [{ "role": "user", "content": "Weather in Istanbul?" }],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Returns the current weather for a city",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}],
"tool_choice": "required"
}'

When you return the tool result in a second turn as a role: "tool" message, the model turns it into prose. For the general flow, see the tool calling page.

All three models support both JSON object output and schema-conforming structured output through response_format.

Terminal window
curl "$LLMTR_BASE_URL/v1/chat/completions" \
-H "Authorization: Bearer llmtr-your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "upstage/solar-pro3",
"messages": [{ "role": "user", "content": "Which country is Ankara in?" }],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "city_info",
"strict": true,
"schema": {
"type": "object",
"properties": {
"city": { "type": "string" },
"country": { "type": "string" }
},
"required": ["city", "country"],
"additionalProperties": false
}
}
}
}'

Repeating the same prompt prefix engages the cache, and those tokens are billed at the discounted cache rate. The number of cached tokens is returned in prompt_tokens_details.cached_tokens. The cache is a discount, not a guarantee; the hit rate depends on prompt length and traffic.

Current unit prices are shown on each model's own page; the table below is for reference.

For upstage/solar-pro3 and upstage/solar-pro2, in USD per 1M tokens:

Metric$/1M
Input0.15
Input (cached)0.015
Output0.60

For upstage/solar-pro4, Upstage is running a launch discount. The discount ends on 2026-09-11 UTC, and standard pricing applies from that instant. The switch happens by itself; nothing has to be changed on the gateway side:

MetricBefore 2026-09-11 UTCFrom 2026-09-11 UTC
Input0.030.30
Input (cached)0.0060.06
Output0.121.20

No platform margin is added to model prices; the margin applies to credit top-ups only.

Upstage officially states English, Korean, and Japanese support for these models. Turkish prompts work in practice but are not on the official support list.

  • Image input: an image_url content part is rejected with 400.
  • Audio input: an input_audio content part is rejected with 400.
  • A reasoning field in the request body: do not use it, use reasoning_effort instead. The gateway accepts a reasoning: { "effort": ... } object and converts it to reasoning_effort, so it never leaks upstream.

Solar requests are processed on Upstage's infrastructure; this is not a Turkey-hosted LLMTR model. Upstage states that it does not use or store prompts and completions from this API for training.