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.
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 }'Reasoning effort
Section titled “Reasoning effort”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 reasonupstage/solar-pro4:low -> reasoning starts hereupstage/solar-pro4:high -> high effortupstage/solar-pro4:max -> highest effortupstage/solar-mini4:low -> reasoning starts here on Mini 4 as wellupstage/solar-pro3:medium -> reasoning starts here on Pro 3upstage/solar-pro2:medium -> reasoning starts here on Pro 2curl "$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.
The reasoning trace
Section titled “The reasoning trace”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.
Interaction with max_tokens
Section titled “Interaction with max_tokens”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.
Tool calling
Section titled “Tool calling”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.
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.
Structured outputs
Section titled “Structured outputs”Every Solar model supports both JSON object output and schema-conforming structured output through response_format.
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 } } } }'Prompt caching
Section titled “Prompt caching”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.
Pricing
Section titled “Pricing”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.
Language support
Section titled “Language support”Upstage officially states English, Korean, and Japanese support for these models. Turkish prompts work in practice but are not on the official support list.
Not supported
Section titled “Not supported”- Image input: an
image_urlcontent part is rejected with400. - Audio input: an
input_audiocontent part is rejected with400. 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
reasoningfield in the request body: do not use it, usereasoning_effortinstead. The gateway accepts areasoning: { "effort": ... }object and converts it toreasoning_effort, so it never leaks upstream.
Data handling
Section titled “Data handling”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.
Solar Pro 3 and Solar Pro 2 shutdown
Section titled “Solar Pro 3 and Solar Pro 2 shutdown”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,lowreturned a non-reasoning answer; on Pro 4 the same result comes fromminimal. If you do not sendreasoning_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.