Remove temperature and top_p — and logprobs and top_logprobs with them — from requests to reasoning models. OpenAI's model guidance allows sampling on GPT-5.1, 5.2 and 5.4, and on GPT-6 Sol and Luna, only with reasoning effort none; gpt-5, gpt-5-mini and gpt-5-nano reject them at any setting, and GPT-6 Astra has no none setting to use. Output is steered with reasoning effort, verbosity and the prompt instead.
The error
{
"error": {
"message": "Unsupported value: 'temperature' does not support 0.2 with this model. Only the default (1) value is supported.",
"type": "invalid_request_error",
"param": "temperature",
"code": "unsupported_value"
}
}
# 0.2 is whatever your code sent; reports show 0 and 0.7 too.
# Some models reject the field at any value instead:
# "Unsupported parameter: 'temperature' is not supported with this model."
# "Unsupported parameter: 'top_p' is not supported with this model."
# (code "unsupported_parameter")Causes and fixes at a glance
| Cause | Fix |
|---|---|
| A reasoning model running with reasoning effort above none | Remove temperature, top_p, logprobs and top_logprobs from the request. |
| A model with no none setting — gpt-5, gpt-5-mini, gpt-5-nano, GPT-6 Astra | Never send it sampling parameters; steer it with effort and verbosity. |
| A default in your stack you never set (0.7 from LangChain, 0 in Cline) | Override or strip the default per model before the request leaves. |
| Sending the default value 1 to be safe | Omit the field instead — some models reject the parameter at any value. |
Remove the sampling parameters
It is a deletion, not a new value. Leave temperature and top_p out of reasoning-model calls entirely, together with logprobs and top_logprobs, which the same rule covers. If you want to change how much the model works, reasoning effort is the knob that is left.
from openai import OpenAI
client = OpenAI(base_url="https://api.kunavo.com/v1", api_key="sk-kn-...")
msgs = [{"role": "user", "content": "Summarize this diff as three changelog bullets."}]
# Before — sampling parameters on a reasoning model
resp = client.chat.completions.create(
model="gpt-6-astra", temperature=0.2, top_p=0.9, messages=msgs)
# After — removed; reasoning effort is the control that remains
resp = client.chat.completions.create(
model="gpt-6-astra", reasoning_effort="low", messages=msgs)Check which models accept sampling at all
OpenAI states the rule per model family, and it turns on reasoning effort. This is its model guidance as read on September 23, 2026. The GPT-5.5 and GPT-5.6 pages do not restate the rule, so treat the silence as a reason to test, not as permission; the o-series rows come from error reports rather than documentation.
gpt-5, gpt-5-mini, gpt-5-nano error, whatever the reasoning setting
GPT-5.1, GPT-5.2, GPT-5.4 accepted only with reasoning effort "none"
GPT-6 Sol, GPT-6 Luna remove them unless reasoning effort is "none"
GPT-6 Astra remove them: Astra has no "none" effort
GPT-5.5, GPT-5.6 not stated on their guidance pages
o1-preview, o3-mini rejected (reported errors, not docs)Steer with the controls that replaced it
OpenAI's guidance names three substitutes when reasoning is on: reasoning depth (reasoning.effort, whose values are model-dependent and run from none and minimal up to xhigh and max), output verbosity (text.verbosity: low, medium or high, medium by default) and output length (max_output_tokens, which counts reasoning tokens as well as visible ones). Chat Completions spells the first two reasoning_effort and verbosity. The guidance offers no sampling-level stand-in for temperature 0; if you used it to keep output repeatable, pin the shape instead, with Structured Outputs for a schema and the prompt for the rest.
# client as in fix.py above
resp = client.responses.create(
model="gpt-5-6-sol",
input="Summarize this diff as three changelog bullets.",
reasoning={"effort": "low"}, # how much it thinks
text={"verbosity": "low"}, # how much it says
max_output_tokens=2000, # hard cap, reasoning tokens included
)
print(resp.output_text)Put the rule in one helper
Branching at every call site is how the next model family turns into another round of edits. Filter the sampling parameters once, keyed on the model and the effort you are about to send; on a model that supports effort none, they pass through when you ask for none.
SAMPLING = ("temperature", "top_p", "logprobs", "top_logprobs")
REASONING = ("gpt-5", "gpt-6", "o1", "o3", "o4") # extend as you adopt models
def sampling_params(model: str, effort: str | None, **params) -> dict:
"""Keep sampling parameters only where they are accepted: effort "none"."""
if model.startswith(REASONING) and effort != "none":
return {k: v for k, v in params.items() if k not in SAMPLING}
return params
effort = "low" # client and msgs as in fix.py above
resp = client.chat.completions.create(
model="gpt-5-6-terra",
messages=msgs,
reasoning_effort=effort,
**sampling_params("gpt-5-6-terra", effort, temperature=0.2, top_p=0.9),
)If you’re calling through Kunavo
Kunavo does not strip or rewrite temperature or top_p for GPT models, on either endpoint. On /v1/chat/completions it rebuilds the request for the Responses upstream: temperature and top_p are copied across unchanged, reasoning_effort becomes reasoning.effort, and either token-cap spelling becomes max_output_tokens, while fields outside that mapping — verbosity, logprobs, top_logprobs, seed and stop among them — are not forwarded at all, so set verbosity through /v1/responses. There your sampling and text fields pass through exactly as sent, text.verbosity included. If the model rejects a value, the 400 carries its message word for word inside Kunavo's envelope (type upstream_error, code upstream_400), so match on the status or the message rather than on code "unsupported_value"; the failed call is not billed. A call that succeeds with temperature set proves nothing about whether the value was applied. Kunavo strips temperature, top_p and top_k itself only on the six Claude models Anthropic removed them from — claude-fable-5-1, claude-fable-5, claude-opus-5, claude-opus-4-8, claude-opus-4-7 and claude-sonnet-5 — and does so on every endpoint. The other half of the same migration, max_tokens versus max_completion_tokens, is covered in the max_tokens guide.
FAQ
Can I set temperature on GPT-5?
Not on gpt-5, gpt-5-mini or gpt-5-nano: OpenAI says requests that include it raise an error. GPT-5.1, 5.2 and 5.4 accept temperature, top_p and logprobs only with reasoning effort set to none, and OpenAI's GPT-6 guidance says to remove them whenever reasoning effort is not none.
What replaces temperature on reasoning models?
Reasoning effort for how much the model thinks, text.verbosity (verbosity in Chat Completions) for how much it says, and max_output_tokens as a hard cap. Through Kunavo, set verbosity on /v1/responses: the chat endpoint does not forward it to GPT models. For repeatable structure, use Structured Outputs and explicit format rules in the prompt.
Should I just send temperature=1?
Omit it. The Unsupported value message says the default of 1 is accepted on the model that produced it, but other models reject the parameter at any value ("Unsupported parameter: 'temperature' is not supported with this model"), and OpenAI's guidance is to remove the fields.
Why do I get this error when my code never sets temperature?
Something in your stack set it. A jupyter-ai user's o1-preview calls carried 0.7, the default of LangChain's ChatOpenAI class underneath jupyter-ai, and a Cline contributor put the 0 a GPT-5 user hit down to a hard-coded default. Check what your SDK or framework actually puts on the wire, then override or remove it per model.
Does Kunavo remove temperature for me?
Not for GPT models: Kunavo forwards temperature and top_p exactly as you send them, on /v1/chat/completions and /v1/responses alike. It does remove temperature, top_p and top_k on the six Claude models Anthropic removed them from.
Related guides
- “Unsupported parameter: 'max_tokens' is not supported with this model” — use max_completion_tokens
- “`temperature` and `top_p` cannot both be specified for this model” — send one, and on newer Claude models neither
- OpenAI-compatible API guide — from Ollama's local endpoint to hosted frontier models
- OpenAI API rate limits — which limit you hit, how to read it, and the retry that fixes it
More error semantics live in the error reference; getting a key takes a minute via sign up and the authentication docs.