Skip to content

Upstage Solar

Solar is Upstage's model family tuned for agentic workflows. Every row in the table below is called through /v1/chat/completions and accepts text input only; image and audio input are not supported. Solar Mini 4 is the compact member (35B total, 3B active parameters) for high-volume, cost-sensitive agent work.

Model Context Max output
upstage/solar-pro4 524,288 131,072
upstage/solar-mini4 524,288 shared with the context window
upstage/solar-pro3 131,072 shared with the context window
upstage/solar-pro2 65,536 shared with the context window

For Solar Decide, see Structured Decisions.

Only Solar Pro 4 enforces an output ceiling separate from its context window: max_tokens above 131,072 is refused. On the other three rows generated tokens come out of the same window, so a long prompt shrinks the output budget that remains. Upstage states an output size of up to 128K tokens for Solar Mini 4; that figure is not enforced with a request refusal, so check finish_reason on long outputs.

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 every Solar model 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.

Model Accepted levels
upstage/solar-pro4 none, minimal, low, medium, high, xhigh, max
upstage/solar-mini4 none, minimal, low, medium, high, xhigh, max
upstage/solar-pro3 none, minimal, low, medium, high
upstage/solar-pro2 minimal, 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:

Model Levels that produce no reasoning Reasoning starts at
upstage/solar-pro4 none, minimal low
upstage/solar-mini4 none, minimal low
upstage/solar-pro3 none, minimal, low medium
upstage/solar-pro2 minimal, low medium

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-mini4:low -> reasoning starts here on Mini 4 as well
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, Solar Mini 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_tokens finish_reason
16 length
64 length
256 stop

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.

That floor is not enough for Solar Mini 4: give max_tokens 2,000 or more while reasoning is on. A large budget is no guarantee either, since reasoning length varies on the same prompt. If you get finish_reason: "length" with empty content, repeat the request at a lower level, or without reasoning_effort at all.

Every Solar model supports tool/function calling and accepts every value of tool_choice: the default (auto), required, none, and a named function choice.

One response can carry several tool calls, but that is not guaranteed and varies by model. Handle both shapes: answer every call you receive and take a second turn for whatever is still missing.

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.

Every Solar model supports 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-pro4",
"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
Input 0.15
Input (cached) 0.015
Output 0.60

For upstage/solar-pro4, Upstage runs a discount in three steps. The 50% discount in effect from 2026-10-11 UTC has no announced end date; list pricing is 0.30 / 0.06 / 1.20 and applies from whatever date Upstage publishes. Each switch happens by itself; nothing has to be changed on the gateway side:

Metric Before 2026-09-11 UTC 2026-09-11 to 2026-10-11 UTC From 2026-10-11 UTC
Input 0.03 0.09 0.15
Input (cached) 0.006 0.018 0.03
Output 0.12 0.36 0.60

For upstage/solar-mini4, the launch discount runs in two steps and ends on 2026-10-23 00:00 UTC; standard pricing applies from that instant:

Metric Before 2026-10-11 00:00 UTC 2026-10-11 00:00 UTC to 2026-10-23 00:00 UTC From 2026-10-23 00:00 UTC
Input 0.03 0.05 0.10
Input (cached) 0.003 0.005 0.01
Output 0.12 0.20 0.40

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.
  • stop: the upstream accepts the field but does not apply it; generation continues past the stop sequence. Trim the output on your side if you need a cut-off.
  • 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.

Upstage shuts down upstage/solar-pro3 and upstage/solar-pro2 on 2026-10-30 (Korea time). From 2026-10-29 15:00 UTC (18:00 in Turkey) both models return 410 model_retired; the error response names the model to move to (upstage/solar-pro4). Until then both keep working at today's price and behaviour.

Moving to upstage/solar-pro4 changes two things besides the model id:

  • Reasoning starts at low. On Pro 3 and Pro 2, low returned a non-reasoning answer; on Pro 4 the same result comes from minimal. If you do not send reasoning_effort, nothing changes: reasoning stays off.
  • Cached input costs more. See the table above for the other prices.

upstage/solar-mini4 is cheaper on every metric, but it is a compact model; try it on your own workload before switching.