Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Azure OpenAI reasoning models are designed to tackle reasoning and problem-solving tasks with increased focus and capability. These models spend more time processing and understanding the user's request, making them exceptionally strong in areas like science, coding, and math compared to previous iterations.
Key capabilities of reasoning models:
- Complex Code Generation: Capable of generating algorithms and handling advanced coding tasks to support developers.
- Advanced Problem Solving: Ideal for comprehensive brainstorming sessions and addressing multifaceted challenges.
- Complex Document Comparison: Perfect for analyzing contracts, case files, or legal documents to identify subtle differences.
- Instruction Following and Workflow Management: Particularly effective for managing workflows requiring shorter contexts.
Prerequisites
An Azure OpenAI reasoning model deployed.
If you use the REST examples:
Install the Azure CLI. For more information, see Install the Azure CLI.
Sign in with
az login, then generate a bearer token and store it in theAZURE_OPENAI_AUTH_TOKENenvironment variable.az account get-access-token --resource https://cognitiveservices.azure.com --query accessToken -o tsv
Usage
These models don't currently support the same set of parameters as other models that use the chat completions API.
Chat completions API
using Azure.Identity;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;
#pragma warning disable OPENAI001 //currently required for token based authentication
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ChatClient client = new(
model: "o4-mini",
authenticationPolicy: tokenPolicy,
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1")
}
);
ChatCompletionOptions options = new ChatCompletionOptions
{
MaxOutputTokenCount = 100000
};
ChatMessage[] messages =
[
new DeveloperChatMessage("You are a helpful assistant"),
new UserChatMessage("Tell me about the bitter lesson")
];
ChatCompletion completion = client.CompleteChat(messages, options);
Console.WriteLine($"[ASSISTANT]: {completion.Content[0].Text}");
How reasoning works
Reasoning models generate reasoning tokens in addition to the input and output tokens you're already familiar with. The model uses those tokens to work through your prompt: breaking the problem apart, weighing approaches, and abandoning paths that don't hold up. Reasoning tokens never appear in the message content, but they occupy space in the context window and are billed as output tokens.
To see how many reasoning tokens a request consumed, check completion_tokens_details.reasoning_tokens in a Chat Completions API response, or output_tokens_details.reasoning_tokens in a Responses API response.
The gpt-5.4 and gpt-5.5 models support interleaved thinking with the Responses API. They can produce visible output before and between periods of reasoning, and reason between tool calls.
Across a multi-turn conversation, input and output tokens carry forward from each turn. What happens to the reasoning from earlier turns depends on the model and on the reasoning.context value you set.
To choose a mode, see Preserve reasoning across calls.
Manage the context window
Reasoning tokens share the context window with your input and the visible output. A single request can spend anywhere from a few hundred to tens of thousands of reasoning tokens depending on how hard the problem is, so leave room for them when you size a request.
The usage object reports the exact count for each request:
{
"usage": {
"input_tokens": 75,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 1186,
"output_tokens_details": {
"reasoning_tokens": 1024
},
"total_tokens": 1261
}
}
Context window sizes differ by model. For the limits that apply to your deployment, see API & feature support.
Control costs
Reasoning tokens are billed as output tokens, so a request that thinks longer costs more even when the visible answer is short. To cap the total the model generates, set max_output_tokens with the Responses API or max_completion_tokens with the Chat Completions API. Both limits cover reasoning tokens, visible output tokens, and formatting tokens.
Capping output addresses only half of a multi-turn workload. Reasoning models also resend a growing conversation on every turn, and all_turns adds earlier reasoning items on top of that. To reduce what you pay for those repeated input tokens, see Prompt caching.
Allocate space for reasoning
If generation reaches the context window limit or the token cap you set, the response comes back incomplete:
{
"status": "incomplete",
"incomplete_details": {
"reason": "max_output_tokens"
}
}
This condition can occur before the model produces any visible output. You pay for input and reasoning tokens but receive no answer. Check status on every response so your application handles this case instead of treating it as an empty result.
To avoid running out of room, reserve at least 25,000 tokens for reasoning and output while you're getting a feel for a workload. Once you know how many reasoning tokens your prompts typically consume, tune the buffer to match.
Keep reasoning items in context
When a reasoning model calls functions through the Responses API, pass the reasoning items from the previous response back along with your function output. If the model called several functions in a row, send every reasoning item, function call item, and function call output item since the last user message. The model then continues the same line of reasoning instead of starting over, which reaches a good answer in fewer tokens.
The simplest approach is to pass all output items from the previous response into the next request, either with previous_response_id or by copying the items into the next input array. Reasoning items that aren't relevant to your functions are ignored, and the relevant ones are retained.
If you trim or reorder context before sending it, keep everything between the last user message and your function call output intact.
Reasoning effort
The reasoning_effort parameter tells the model how much to think before it answers. Supported values vary by model and include none, minimal, low, medium, high, xhigh, and max. Defaults vary by model as well. For the values each model accepts, see API & feature support.
| Effort | Best for |
|---|---|
none |
Latency-critical work that doesn't benefit from reasoning or chained tool calls, such as voice, fast information retrieval, and classification. |
low |
Efficient reasoning with a modest latency increase. Suits tool use, planning, search, and multistep decisions where speed and cost matter. |
medium |
A balanced starting point for most workloads, especially when the task involves planning, complex reasoning, or judgment. |
high |
Hard reasoning, complex debugging, deep planning, and high-value tasks where quality matters more than latency. |
xhigh |
Deep research, asynchronous workflows, and agentic tasks with long runs. Use it when your evaluations show a gain that justifies the extra latency and cost. |
max |
Your most complex tasks. If you currently use xhigh, compare both settings before you switch. |
Reasoning models adapt within a setting, spending fewer tokens on simple tasks and thinking harder on complex ones. The higher the effort, the longer the model spends on the request, which generally produces more reasoning tokens.
Note
o1-mini doesn't support reasoning_effort.
For a faster first visible token in latency-sensitive applications, prompt the model to produce a short preamble before it reasons more deeply.
Developer messages
Developer messages ("role": "developer") are functionally the same as system messages.
Adding a developer message to the previous code example would look as follows:
using Azure.Identity;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;
#pragma warning disable OPENAI001 //currently required for token based authentication
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ChatClient client = new(
model: "o4-mini",
authenticationPolicy: tokenPolicy,
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1")
}
);
ChatCompletionOptions options = new ChatCompletionOptions
{
ReasoningEffortLevel = ChatReasoningEffortLevel.Low,
MaxOutputTokenCount = 100000
};
ChatMessage[] messages =
[
new DeveloperChatMessage("You are a helpful assistant"),
new UserChatMessage("Tell me about the bitter lesson")
];
ChatCompletion completion = client.CompleteChat(messages, options);
Console.WriteLine($"[ASSISTANT]: {completion.Content[0].Text}");
Tool calling with reasoning models
Use the Responses API when you combine reasoning with function or custom tools. The gpt-5.6 and later models support the Chat Completions API and they support tools, but the Chat Completions API doesn't support the two together. A Chat Completions request that includes tools fails with the following error:
Function tools with reasoning_effort are not supported for gpt-5.6-sol in /v1/chat/completions. To use function tools, use /v1/responses or set reasoning_effort to 'none'.
The request fails even when you don't send reasoning_effort, because these models default to medium. Sending tools is enough to trigger the error. An application that calls tools through Chat Completions can start failing after you upgrade its deployment from an earlier reasoning model.
You have two ways to resolve it:
- Recommended: Send tool-calling requests to the Responses API. This path supports the full range of
reasoning_effortvalues, returns reasoning items you can carry across turns, and is the surface where new reasoning features ship first. For a migration walkthrough, see Upgrade your Azure OpenAI app from Chat Completions to the Responses API. - If you must stay on Chat Completions, set
reasoning_efforttononeon every request that sendstools. The model then calls tools without reasoning, which loses the planning quality that reasoning provides.
The following request shows the Chat Completions workaround:
curl -X POST "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AZURE_OPENAI_AUTH_TOKEN" \
-d '{
"model": "gpt-5.6-sol",
"messages": [
{"role": "user", "content": "What is the weather in Seattle?"}
],
"reasoning_effort": "none",
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
}
]
}'
In .NET, set the same value through ChatCompletionOptions.ReasoningEffortLevel:
using OpenAI.Chat;
ChatTool getWeatherTool = ChatTool.CreateFunctionTool(
functionName: "get_weather",
functionDescription: "Get the current weather for a city.",
functionParameters: BinaryData.FromString("""
{
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
"""));
ChatCompletionOptions options = new ChatCompletionOptions
{
ReasoningEffortLevel = ChatReasoningEffortLevel.None,
MaxOutputTokenCount = 100000
};
options.Tools.Add(getWeatherTool);
For the full type surface, see the OpenAI .NET library.
Note
ChatReasoningEffortLevel is marked experimental in the OpenAI .NET library, so it emits the OPENAI001 diagnostic. Suppress it with #pragma warning disable OPENAI001 as shown in the earlier samples, or add <NoWarn>$(NoWarn);OPENAI001</NoWarn> to your project file. Token-based authentication uses the same diagnostic.
Reasoning mode
The gpt-5.6 models support two execution modes in the Responses API. Standard mode is the default on Azure OpenAI. Set reasoning.mode to pro for difficult tasks that justify more model work and can absorb the extra latency.
Mode and effort are independent controls. The mode selects standard or pro execution, and reasoning_effort controls how much reasoning the model applies within that mode.
{
"model": "gpt-5.6",
"reasoning": {
"mode": "pro",
"effort": "medium"
},
"input": "Review this database migration plan and identify potential failure modes."
}
Pro mode aggregates the work it performs into a single answer and bills those tokens at the model's standard rates. Because it performs more work than standard mode, expect higher token usage and higher cost. Existing pro model deployments keep their current behavior and pricing.
Reasoning summary
When using the latest reasoning models with the Responses API you can use the reasoning summary parameter to receive summaries of the model's chain of thought reasoning.
Important
Attempting to extract raw reasoning through methods other than the reasoning summary parameter are not supported, may violate the Acceptable Use Policy, and may result in throttling or suspension when detected.
using OpenAI;
using OpenAI.Responses;
using System.ClientModel.Primitives;
using Azure.Identity;
#pragma warning disable OPENAI001 //currently required for token based authentication
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
OpenAIResponseClient client = new(
model: "o4-mini",
authenticationPolicy: tokenPolicy,
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1")
}
);
OpenAIResponse response = await client.CreateResponseAsync(
userInputText: "What's the optimal strategy to win at poker?",
new ResponseCreationOptions()
{
ReasoningOptions = new ResponseReasoningOptions()
{
ReasoningEffortLevel = ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = ResponseReasoningSummaryVerbosity.Auto,
},
});
// Get the reasoning summary from the first OutputItem (ReasoningResponseItem)
Console.WriteLine("=== Reasoning Summary ===");
foreach (var item in response.OutputItems)
{
if (item is ReasoningResponseItem reasoningItem)
{
foreach (var summaryPart in reasoningItem.SummaryParts)
{
if (summaryPart is ReasoningSummaryTextPart textPart)
{
Console.WriteLine(textPart.Text);
}
}
}
}
Console.WriteLine("\n=== Assistant Response ===");
// Get the assistant's output
Console.WriteLine(response.GetOutputText());
Note
Even when enabled, reasoning summaries are not guaranteed to be generated for every step/request. This is expected behavior.
Preserve reasoning across calls
Conversation state and reasoning state aren't the same thing. Passing messages across calls gives the model the visible conversation history. Persisted reasoning goes a step further: on models that support it, the model can also render its own reasoning items from earlier turns into the current context.
Persisted reasoning is about continuity, not transparency. The reasoning items stay opaque, and the API never returns their reasoning text. Set reasoning.context to control which of the available reasoning items the model can draw on.
| Value | Behavior |
|---|---|
auto |
Uses the model's default. Omitting reasoning.context has the same effect. |
current_turn |
Makes the active turn's reasoning available to the model, but doesn't render reasoning from earlier turns into the next sample. |
all_turns |
Renders available, compatible reasoning items from earlier turns into the next sample. Only the gpt-5.6 models support this value. |
The gpt-5.6 models support all_turns and use it by default. Earlier reasoning models default to current_turn.
Important
Because all_turns renders more reasoning items into context, it increases the tokens billed for a request. If you upgrade an existing workload to a gpt-5.6 model, expect higher token consumption on multi-turn conversations even when your code doesn't change. Set reasoning.context to current_turn to keep the earlier behavior.
Keep these behaviors in mind:
- Setting
reasoning.contextdoesn't create reasoning items that aren't already available. It only controls which existing items the model renders. all_turnshas an effect only when the request can reach earlier response items. Useprevious_response_id, attach the response to a conversation, or replay the complete response history yourself.- On the first request in a conversation,
current_turnandall_turnsbehave the same way, because no earlier reasoning exists yet. - Each response reports the mode it actually used in its
reasoning.contextfield, as eithercurrent_turnorall_turns. Check that field to confirm the effective mode.
Continue reasoning with stored responses
When you store responses, previous_response_id is the shortest way to make earlier reasoning available to the model.
A C# example for reasoning.context isn't available yet. Select the Python or REST tab to see how to set the mode and read the effective value back from the response.
Use current_turn when you replay older response items that the model no longer needs. Those items can stay in the request payload for continuity, but the service doesn't render them into the new sample, which reduces the rendered context in long-running workflows.
Preserve reasoning without stored responses
In stateless mode, reasoning items in the response's output array include an encrypted_content property by default. Stateless mode applies when you set store to false, and when your organization uses Zero Data Retention. You don't need to request the property: the API still accepts reasoning.encrypted_content in the include parameter for compatibility, but no longer requires it.
To use all_turns in this mode, keep every output item, append the next user message, and replay the complete history.
A C# example for stateless persisted reasoning isn't available yet. Select the Python or REST tab to see how to replay encrypted reasoning items across turns.
For more information about encrypted reasoning items, see Encrypted reasoning items.
Phase parameter
In long-running or tool-heavy workflows that use gpt-5.5 and gpt-5.4 in the Responses API, mark each assistant message with a phase value. The parameter is optional, but omitting it can cause the model to treat a preamble as the final answer and stop early.
Use commentary for intermediate assistant updates, such as the preamble a model produces before a tool call, and final_answer for the completed response. Don't add phase to user messages.
{
"model": "gpt-5.5",
"input": [
{
"role": "assistant",
"phase": "commentary",
"content": "I'll inspect the logs, then summarize the root cause and the fix."
},
{
"role": "assistant",
"phase": "final_answer",
"content": "Root cause: a cache invalidation race."
},
{
"role": "user",
"content": "Now give me a rollout-safe fix plan."
}
]
}
When you continue a conversation by using previous_response_id, the service preserves the earlier assistant state for you. If you replay assistant history yourself, keep each message's original phase value.
Python lark
GPT-5 series reasoning models have the ability to call a new custom_tool called lark_tool. This tool is based on Python lark and can be used for more flexible constraining of model output.
Responses API
{
"model": "gpt-5-2025-08-07",
"input": "please calculate the area of a circle with radius equal to the number of 'r's in strawberry",
"tools": [
{
"type": "custom",
"name": "lark_tool",
"format": {
"type": "grammar",
"syntax": "lark",
"definition": "start: QUESTION NEWLINE ANSWER\nQUESTION: /[^\\n?]{1,200}\\?/\nNEWLINE: /\\n/\nANSWER: /[^\\n!]{1,200}!/"
}
}
],
"tool_choice": "required"
}
Microsoft Entra ID:
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
response = client.responses.create(
model="gpt-5", # replace with your model deployment name
tools=[
{
"type": "custom",
"name": "lark_tool",
"format": {
"type": "grammar",
"syntax": "lark",
"definition": "start: QUESTION NEWLINE ANSWER\nQUESTION: /[^\\n?]{1,200}\\?/\nNEWLINE: /\\n/\nANSWER: /[^\\n!]{1,200}!/"
}
}
],
input=[{"role": "user", "content": "Please calculate the area of a circle with radius equal to the number of 'r's in strawberry"}],
)
print(response.model_dump_json(indent=2))
API Key:
import os
from openai import OpenAI
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=os.getenv("AZURE_OPENAI_API_KEY")
)
response = client.responses.create(
model="gpt-5", # replace with your model deployment name
tools=[
{
"type": "custom",
"name": "lark_tool",
"format": {
"type": "grammar",
"syntax": "lark",
"definition": "start: QUESTION NEWLINE ANSWER\nQUESTION: /[^\\n?]{1,200}\\?/\nNEWLINE: /\\n/\nANSWER: /[^\\n!]{1,200}!/"
}
}
],
input=[{"role": "user", "content": "Please calculate the area of a circle with radius equal to the number of 'r's in strawberry"}],
)
print(response.model_dump_json(indent=2))
Output:
{
"id": "resp_689a0cf927408190b8875915747667ad01c936c6ffb9d0d3",
"created_at": 1754926332.0,
"error": null,
"incomplete_details": null,
"instructions": null,
"metadata": {},
"model": "gpt-5",
"object": "response",
"output": [
{
"id": "rs_689a0cfd1c888190a2a67057f471b5cc01c936c6ffb9d0d3",
"summary": [],
"type": "reasoning",
"encrypted_content": null,
"status": null
},
{
"id": "msg_689a0d00e60c81908964e5e9b2d6eeb501c936c6ffb9d0d3",
"content": [
{
"annotations": [],
"text": ""strawberry" has 3 r's, so the radius is 3.\nArea = πr<sup>2</sup> = π × 3<sup>2</sup> = 9π ≈ 28.27 square units.",
"type": "output_text",
"logprobs": null
}
],
"role": "assistant",
"status": "completed",
"type": "message"
}
],
"parallel_tool_calls": true,
"temperature": 1.0,
"tool_choice": "auto",
"tools": [
{
"name": "lark_tool",
"parameters": null,
"strict": null,
"type": "custom",
"description": null,
"format": {
"type": "grammar",
"definition": "start: QUESTION NEWLINE ANSWER\nQUESTION: /[^\\n?]{1,200}\\?/\nNEWLINE: /\\n/\nANSWER: /[^\\n!]{1,200}!/",
"syntax": "lark"
}
}
],
"top_p": 1.0,
"background": false,
"max_output_tokens": null,
"max_tool_calls": null,
"previous_response_id": null,
"prompt": null,
"prompt_cache_key": null,
"reasoning": {
"effort": "medium",
"generate_summary": null,
"summary": null
},
"safety_identifier": null,
"service_tier": "default",
"status": "completed",
"text": {
"format": {
"type": "text"
}
},
"top_logprobs": null,
"truncation": "disabled",
"usage": {
"input_tokens": 139,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 240,
"output_tokens_details": {
"reasoning_tokens": 192
},
"total_tokens": 379
},
"user": null,
"content_filters": null,
"store": true
}
Chat Completions
{
"messages": [
{
"role": "user",
"content": "Which one is larger, 42 or 0?"
}
],
"tools": [
{
"type": "custom",
"name": "custom_tool",
"custom": {
"name": "lark_tool",
"format": {
"type": "grammar",
"grammar": {
"syntax": "lark",
"definition": "start: QUESTION NEWLINE ANSWER\nQUESTION: /[^\\n?]{1,200}\\?/\nNEWLINE: /\\n/\nANSWER: /[^\\n!]{1,200}!/"
}
}
}
}
],
"tool_choice": "required",
"model": "gpt-5-2025-08-07"
}
Availability
Region availability
| Model | Region | Limited access |
|---|---|---|
gpt-5.6-sol |
Model availability | No access request needed. Quota request required depending on quota tier. Tier 5 and Tier 6 subscriptions have quota by default. |
gpt-5.6-terra |
Model availability | No access request needed. Quota request required depending on quota tier. Tier 5 and Tier 6 subscriptions have quota by default. |
gpt-5.6-luna |
Model availability | No access request needed. Quota request required depending on quota tier. Tier 5 and Tier 6 subscriptions have quota by default. |
gpt-chat-latest |
Model availability | No access request needed. |
gpt-5.5 |
Model availability | No access request needed. Quota request required depending on quota tier. Tier 5 and Tier 6 subscriptions have quota by default. |
gpt-5.4-mini |
Model availability | No access request needed. |
gpt-5.4-nano |
Model availability | No access request needed. |
gpt-5.4-pro |
Model availability | Access is no longer restricted for this model. |
gpt-5.4 |
Model availability | Access is no longer restricted for this model. |
gpt-5.3-codex |
Model availability | Access is no longer restricted for this model. |
gpt-5.2-codex |
Model availability | Access is no longer restricted for this model. |
gpt-5.2 |
Model availability | Access is no longer restricted for this model. |
gpt-5.1-codex-max |
Model availability | Access is no longer restricted for this model. |
gpt-5.1 |
Model availability | Access is no longer restricted for this model. |
gpt-5.1-chat |
Model availability | No access request needed. |
gpt-5.1-codex |
Model availability | Access is no longer restricted for this model. |
gpt-5.1-codex-mini |
Model availability | No access request needed. |
gpt-5-pro |
Model availability | Access is no longer restricted for this model. |
gpt-5-codex |
Model availability | Access is no longer restricted for this model. |
gpt-5 |
Model availability | Access is no longer restricted for this model. |
gpt-5-mini |
Model availability | No access request needed. |
gpt-5-nano |
Model availability | No access request needed. |
o3-pro |
Model availability | Access is no longer restricted for this model. |
codex-mini |
Model availability | No access request needed. |
o4-mini |
Model availability | Access is no longer restricted for this model. |
o3 |
Model availability | Access is no longer restricted for this model. |
o3-mini |
Model availability | Access is no longer restricted for this model. |
o1 |
Model availability | Access is no longer restricted for this model. |
API & feature support
Input and output limits share the available context budget and aren't additive. For details and a GPT-5.5 calculation example, see Understand model token limits and Responses API token budget.
| Feature | gpt-5.6-sol, 2026-06-25 | gpt-5.6-terra, 2026-06-25 | gpt-5.6-luna, 2026-06-25 | gpt-5.5, 2026-04-24 | gpt-5.4-nano, 2026-03-17 | gpt-5.4-mini, 2026-03-17 | gpt-5.4-pro | gpt-5.4, 2026-03-05 | gpt-5.3-codex, 2026-02-24 | gpt-5.2-codex, 2026-01-14 | gpt-5.2, 2025-12-11 | gpt-5.1-codex-max, 2025-12-04 | gpt-5.1, 2025-11-13 | gpt-5.1-chat, 2025-11-13 | gpt-5.1-codex, 2025-11-13 | gpt-5.1-codex-mini, 2025-11-13 | gpt-5-pro, 2025-10-06 | gpt-5-codex, 2025-09-011 | gpt-5, 2025-08-07 | gpt-5-mini, 2025-08-07 | gpt-5-nano, 2025-08-07 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Developer Messages | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Structured Outputs | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
| Context Window | 1,050,000 Input: 922,000 Output: 128,000 |
1,050,000 Input: 922,000 Output: 128,000 |
1,050,000 Input: 922,000 Output: 128,000 |
1,050,000 Input: 922,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
1,050,000 Input: 922,000 Output: 128,000 |
1,050,000 Input: 922,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
128,000 Input: 111,616 Output: 16,384 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
400,000 Input: 272,000 Output: 128,000 |
| Reasoning effort7 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅6 | ✅4 | ✅ | ✅ | ✅ | ✅5 | ✅ | ✅ | ✅ | ✅ |
| Image input | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Chat Completions API | ✅9 | ✅9 | ✅9 | ✅ | ✅ | ✅ | - | ✅ | - | - | ✅ | - | ✅ | ✅ | - | - | - | - | ✅ | ✅ | ✅ |
| Responses API | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
| Functions/Tools | ✅9 | ✅9 | ✅9 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
| Parallel Tool Calls1 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ |
max_completion_tokens 2 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | - | - | ✅ | - | ✅ | ✅ | - | - | - | - | ✅ | ✅ | ✅ |
| System Messages 3 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Reasoning summary | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Persisted reasoning8 | ✅ | ✅ | ✅ | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| Streaming | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ |
1 Parallel tool calls are not supported when reasoning_effort is set to minimal
2 Reasoning models will only work with the max_completion_tokens parameter when using the Chat Completions API. Use max_output_tokens with the Responses API.
3 The latest reasoning models support system messages to make migration easier. You should not use both a developer message and a system message in the same API request.
4 gpt-5.1 reasoning_effort defaults to none. When upgrading from previous reasoning models to gpt-5.1 keep in mind that you may need to update your code to explicitly pass a reasoning_effort level if you want reasoning_effort to occur.
5 gpt-5-pro only supports reasoning_effort high, this is the default value even when not explicitly passed to the model.
6 gpt-5.1-codex-max adds support for a new reasoning_effort level of xhigh which is the highest level that reasoning effort can be set to.
7 gpt-5.6, gpt-5.5, gpt-5.4, gpt-5.2, gpt-5.1, gpt-5.1-codex, gpt-5.1-codex-max, and gpt-5.1-codex-mini support 'None' as a value for the reasoning_effort parameter. To use these models to generate responses without reasoning, set reasoning_effort='None'. This setting can increase speed.
8 The gpt-5.6 models support all_turns for the reasoning.context parameter and use it by default. Earlier reasoning models support only auto and current_turn.
9 The gpt-5.6 and later models support the Chat Completions API and function tools, but not both at the same time unless reasoning_effort is none. Use the Responses API for tool calling. For details and workarounds, see Tool calling with reasoning models.
NEW GPT-5 reasoning features
| Feature | Description |
|---|---|
reasoning_effort |
max is only supported with gpt-5.6 and Responses API xhigh is only supported with gpt-5.6, gpt-5.5, gpt-5.4, and gpt-5.1-codex-max minimal is only supported with the original GPT-5 reasoning models. minimal isn't supported with gpt-5.1 or greater * With gpt-5.6 and later models on the Chat Completions API, none is the only value you can combine with function tools. See Tool calling with reasoning models. Options: none, minimal, low, medium, high, xhigh, max |
verbosity |
A new parameter providing more granular control over how concise the model's output will be. Options: low, medium, high. |
reasoning.context |
Controls which available reasoning items the model renders into its next context. all_turns is only supported with gpt-5.6, which uses it by default.Options: auto, current_turn, all_turns. |
reasoning.mode |
Selects standard or pro execution for gpt-5.6 with the Responses API. Pro mode performs more model work on a request before returning a single answer, which increases latency and token usage. Azure OpenAI uses standard as the default.Options: standard, pro. |
preamble |
GPT-5 series reasoning models have the ability to spend extra time "thinking" before executing a function/tool call. When this planning occurs the model can provide insight into the planning steps in the model response via a new object called the preamble object.Generation of preambles in the model response is not guaranteed though you can encourage the model by using the instructions parameter and passing content like "You MUST plan extensively before each function call. ALWAYS output your plan to the user before calling any function" |
| allowed tools | You can specify multiple tools under tool_choice instead of just one. |
| custom tool type | Enables raw text (non-json) outputs |
lark_tool |
Allows you to use some of the capabilities of Python lark for more flexible constraining of model responses |
* gpt-5-codex also does not support reasoning_effort minimal.
Note
- To avoid timeouts background mode is recommended for
o3-pro. o3-prodoes not currently support image generation.
Not Supported
The following are currently unsupported with reasoning models:
temperature,top_p,presence_penalty,frequency_penalty,logprobs,top_logprobs,logit_bias,max_tokens
Prompting guidance
Reasoning models work best when you give them a clear goal, firm constraints, and an explicit output contract. Unlike non-reasoning models, they don't need you to prescribe every intermediate step.
- State the task, the constraints, and the output format you expect.
- Treat
reasoning_effortas a tuning knob rather than the first thing you reach for when quality drops. - For agentic or research-heavy workflows, define what counts as done and how the model should verify its own work.
Markdown output
By default the o3-mini and o1 models will not attempt to produce output that includes markdown formatting. A common use case where this behavior is undesirable is when you want the model to output code contained within a markdown code block. When the model generates output without markdown formatting you lose features like syntax highlighting, and copyable code blocks in interactive playground experiences. To override this new default behavior and encourage markdown inclusion in model responses, add the string Formatting re-enabled to the beginning of your developer message.
Adding Formatting re-enabled to the beginning of your developer message does not guarantee that the model will include markdown formatting in its response, it only increases the likelihood. We have found from internal testing that Formatting re-enabled is less effective by itself with the o1 model than with o3-mini.
To improve the performance of Formatting re-enabled you can further augment the beginning of the developer message which will often result in the desired output. Rather than just adding Formatting re-enabled to the beginning of your developer message, you can experiment with adding a more descriptive initial instruction like one of the examples below:
Formatting re-enabled - please enclose code blocks with appropriate markdown tags.Formatting re-enabled - code output should be wrapped in markdown.
Depending on your expected output you may need to customize your initial developer message further to target your specific use case.