MiniMax Models
Scenario-based examples for minimax-m3: thinking switch, streaming, tool calls, image and video input, caching, Anthropic format
MiniMax models are called through /v1/chat/completions or /v1/messages. The platform passes the request body through and the upstream model decides whether a parameter takes effect. This page is organised by scenario, following MiniMax's official docs (the OpenAI-compatible page, the Anthropic-compatible page and the text generation guide: thinking, tool calls, image and video input). What is supported is decided by the upstream we actually connect to, not by the official site.
Every scenario carries an evidence label:
- Tested (live test account, 2026-10-19): called for real on production; responses come from real output (
idand timestamps replaced with placeholders). - Per official docs (not tested): checked against the official documentation only, no real request.
Supported models
| Model id | Description | Context window | Max output | Capability tags |
|---|---|---|---|---|
minimax-m3 | MiniMax-M3, coding and agent scenarios, natively multimodal (text, image and video input; no audio) | 1,000,000 | Not stated officially | chat, streaming, vision, tools, thinking |
The official docs say M3 supports a 1M context; a request whose input exceeds 512K tokens is billed at the higher tier. The official model page gives no maximum output for M3 and the platform catalog does not set one either, so control output length with max_completion_tokens; thinking tokens count toward the output cap, and a value that is too small can leave only reasoning and no answer (in the Anthropic format this shows up as stop_reason: "max_tokens" with no text).
The platform never switches thinking on or off for you. It does not inject thinking, reasoning_effort or temperature by default. The one exception is reasoning_split: when you do not send it the platform adds reasoning_split: true, so the reasoning appears in the reasoning_content field instead of being mixed into content as a think tag; it only changes where the reasoning goes and never turns thinking on. In testing minimax-m3 thinks by default when thinking is omitted.
Scenario overview
| Scenario | Official docs cover it | Our status | Example |
|---|---|---|---|
| Basic chat | Yes | Supported | Thinking switch and basic chat |
Thinking: on by default, returns reasoning_content | Yes | Supported | Responses in Tool calls and Anthropic format |
Thinking: off (thinking: disabled) | Yes (M3 can be switched off) | Supported | Thinking switch and basic chat |
Thinking: thinking: adaptive | Yes | Partly supported: depends on an update that is not released yet, not tested | Notes in Thinking switch and basic chat |
| Streaming | Yes | Partly supported: same pipeline, not tested on MiniMax specifically | Streaming |
| Tool calls and interleaved thinking | Yes | Supported: first round tested, the second round that sends tool results back is per official docs (not tested) | Tool calls |
| Image input | Yes | Supported | Image and video input |
| Video input | Yes | Partly supported: per official docs, not tested | Image and video input |
| Caching | The official pricing page has a cache-hit price, the guides say nothing | Partly supported: hits happen automatically in testing, but the platform capability tags do not include cache and nothing is promised | Caching |
| Anthropic-format calls | Yes (the officially recommended endpoint) | Supported; thinking accepts only adaptive / disabled, and enabled returns 400 | Anthropic format |
Token counting (/v1/messages/count_tokens) | Yes | Partly supported: the platform has the endpoint, not tested on MiniMax | See the Messages page |
Thinking effort reasoning_effort / output_config.effort | Officially only for M3.1-Flash | Not applicable: do not use on minimax-m3 | None |
| Structured output (JSON mode) | Not offered officially | Unverified: do not rely on response_format | None |
| Audio input | Not supported officially | Not supported | None |
File API (mm_file://) | Yes | Not integrated | None |
Priority tier (service_tier: priority) | Yes (1.5x price) | Not supported: the platform does not forward the field upstream, so it has no effect | None |
| M3.1-Flash and other MiniMax models | Yes | Not integrated: the platform connects only minimax-m3 | None |
Thinking switch and basic chat
Evidence: tested (live test account, 2026-10-19), minimax-m3, OpenAI format, thinking: disabled.
When to use: turn thinking off for simple Q&A when you want low latency and fewer tokens. Officially thinking takes adaptive or disabled; with disabled M3 answers directly without thinking. Without thinking M3 thinks by default (see the response in Tool calls). thinking is not an OpenAI standard field: put it in extra_body with the Python SDK.
Request
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
# Disable thinking
resp = client.chat.completions.create(
model="minimax-m3",
messages=[{"role": "user", "content": "用一句话解释量子纠缠"}],
max_tokens=300,
extra_body={"thinking": {"type": "disabled"}},
)
print(resp.choices[0].message.content)
# Without thinking: thinking is on by default, the reasoning is in reasoning_content
resp = client.chat.completions.create(
model="minimax-m3",
messages=[{"role": "user", "content": "用一句话解释量子纠缠"}],
max_tokens=1500,
)
msg = resp.choices[0].message
print(getattr(msg, "reasoning_content", None)) # the reasoning
print(msg.content) # the final answerResponse (thinking off): no reasoning_content, reasoning_tokens is 0.
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "量子纠缠是指两个或多个粒子在某种特殊状态下,即使相隔很远,它们的量子属性也会瞬间关联,测量其中一个会立即决定另一个的状态。",
"refusal": null
},
"finish_reason": "stop"
}
],
"created": 1760000000,
"id": "xxxxxxxx",
"model": "minimax-m3",
"object": "chat.completion",
"output_sensitive_int": 0,
"service_tier": "standard",
"usage": {
"completion_tokens": 30,
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
},
"prompt_tokens": 168,
"prompt_tokens_details": {
"cached_tokens": 128
},
"total_tokens": 198
}
}Notes
thinking: {"type": "adaptive"}(depends on an update that is not released yet, not tested): officially this is how thinking is switched on explicitly. Production currently drops theadaptivevalue and will forward it to MiniMax only after the update ships; until then omitthinkingto get the default thinking.reasoning_split: officiallytrueputs the reasoning inreasoning_contentandfalsekeeps it incontentas think tags. The platform addstruefor you; if you sendfalseyourself the platform respects it but does not parse the think tags in the response, so they appear incontentas they are.reasoning_detailsin the response is structured reasoning added by this upstream, from the same source asreasoning_content.- Sampling:
temperatureranges over [0, 2], default and recommended 1, and the upstream errors outside the range;top_pranges over [0, 1], default 0.95 for M3;nsupports only 1;presence_penalty,frequency_penaltyandlogit_biasare ignored. The platform does not range-check. max_completion_tokensis the officially recommended new form andmax_tokensthe legacy one; thinking tokens count toward both.
Streaming
Evidence: per official docs (not tested); the streaming pipeline matches the real responses on the DeepSeek and GLM pages.
When to use: show output as it is generated. Pass stream: true; reasoning arrives in delta.reasoning_content, the answer in delta.content.
Request
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
stream = client.chat.completions.create(
model="minimax-m3",
messages=[{"role": "user", "content": "数到五,用逗号分隔。"}],
max_tokens=1000,
stream=True,
)
reasoning, content = "", ""
for chunk in stream:
if not chunk.choices:
continue
d = chunk.choices[0].delta
if getattr(d, "reasoning_content", None):
reasoning += d.reasoning_content
elif d.content:
content += d.content
print(content)Response: the SSE chunk structure is the same as for other models (see the streaming response on the DeepSeek page), with usage at the end.
Notes
- If
stream_optionsis not set the gateway addsinclude_usage. - MiniMax historically inlines reasoning as think tags in
contentby default; the platform's defaultreasoning_split: trueavoids that, and it applies to streaming as well.
Tool calls
Evidence: tested (live test account, 2026-10-19), minimax-m3, first round only (the model returning a tool call, default thinking); the second round that sends tool results back is per official docs (not tested).
When to use: agents, letting the model decide to call functions you define. The model does not run functions: it returns tool_calls, your code runs them and puts each result back as a role: "tool" message (with the matching tool_call_id) before the next request.
First request
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather of a location, the user should supply a location first.",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "The city and state, e.g. San Francisco, CA"}},
"required": ["location"],
},
},
}]
messages = [{"role": "user", "content": "How is the weather in Hangzhou?"}]
resp = client.chat.completions.create(
model="minimax-m3", messages=messages, tools=tools, max_tokens=1500,
)
msg = resp.choices[0].message
messages.append(msg) # put the assistant message with tool_calls back into historyFirst response: finish_reason is tool_calls; the reasoning appears in both reasoning_content and reasoning_details, and content is null.
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"refusal": null,
"tool_calls": [
{
"id": "call_xxxx",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"Hangzhou, Zhejiang\"}"
}
}
],
"reasoning_content": "The user is asking about the weather in Hangzhou. The tool requires both location (as city and state format) and unit parameters. Hangzhou is a city in China, in Zhejiang province. I'll call the weather function for Hangzhou.",
"reasoning_details": [
{
"type": "reasoning.text",
"text": "The user is asking about the weather in Hangzhou. The tool requires both location (as city and state format) and unit parameters. Hangzhou is a city in China, in Zhejiang province. I'll call the weather function for Hangzhou.",
"id": "reasoning-text-1",
"format": "MiniMax-response-v1",
"index": 0
}
]
},
"finish_reason": "tool_calls"
}
],
"created": 1760000000,
"id": "xxxxxxxx",
"model": "minimax-m3",
"object": "chat.completion",
"output_sensitive_int": 0,
"service_tier": "standard",
"usage": {
"completion_tokens": 81,
"completion_tokens_details": {
"reasoning_tokens": 48,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
},
"prompt_tokens": 435,
"prompt_tokens_details": {
"cached_tokens": 203
},
"total_tokens": 516
}
}Second round (per official docs, not tested): for multi-round tool calls the official docs require appending the complete assistant reply (including the reasoning) that contains tool_calls back to the history, with the reasoning kept intact, followed by the role: "tool" results.
for call in msg.tool_calls:
messages.append({"role": "tool", "tool_call_id": call.id, "content": "24°C, cloudy"})
resp = client.chat.completions.create(
model="minimax-m3", messages=messages, tools=tools, max_tokens=1500,
)
print(resp.choices[0].message.content)Notes
- The platform forwards
reasoning_content(andreasoning_details) of assistant messages in history to the upstream unchanged; in the Anthropic format athinkingcontent block in history is converted toreasoning_content. Your client must put the previous round's complete assistant message back; the platform cannot supply content you did not keep. toolsis officially supported; fortool_choicethe official Anthropic-compatible page says full support while the OpenAI-compatible page says nothing, so whether it takes effect in the OpenAI format is unverified; the deprecatedfunction_callis not supported.- Anthropic-format
tool_choice: {"type": "none"}becomestool_choice: "none", anddisable_parallel_tool_use: truebecomesparallel_tool_calls: false.
Image and video input
Evidence: images tested (live test account, 2026-10-19), minimax-m3; video per official docs (not tested).
When to use: visual Q&A and screenshot analysis. Put images in the content array as image_url blocks whose url is a public URL or a Base64 data URL. The official docs say text, image and video input are supported, audio is not.
Image request (a solid red 64x64 PNG)
import base64
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
b64 = base64.b64encode(open("red.png", "rb").read()).decode()
resp = client.chat.completions.create(
model="minimax-m3",
messages=[{"role": "user", "content": [
{"type": "text", "text": "这张图是什么颜色?一句话。"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
]}],
max_tokens=1500,
)
print(resp.choices[0].message.content)Response (the model described pure red as "dark red"; do not treat visual descriptions as exact values)
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "这张图是深红色(暗红/酒红色)的纯色背景。",
"refusal": null,
"reasoning_content": "The user is asking about the color in the image. The image appears to be a solid dark red/maroon color. I need to answer in one sentence in Chinese.",
"reasoning_details": [
{
"type": "reasoning.text",
"text": "The user is asking about the color in the image. The image appears to be a solid dark red/maroon color. I need to answer in one sentence in Chinese.",
"id": "reasoning-text-1",
"format": "MiniMax-response-v1",
"index": 0
}
]
},
"finish_reason": "stop"
}
],
"created": 1760000000,
"id": "xxxxxxxx",
"model": "minimax-m3",
"object": "chat.completion",
"output_sensitive_int": 0,
"service_tier": "standard",
"usage": {
"completion_tokens": 54,
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
},
"prompt_tokens": 201,
"prompt_tokens_details": {
"cached_tokens": 128
},
"total_tokens": 255
}
}Video input (per official docs, not tested): use a video_url content block; officially MP4, AVI, MOV and MKV are supported, up to 50 MB each by URL or Base64, fps from 0.2 to 5 (default 1). The official file API mm_file:// is not integrated on the platform. The platform has not verified how video is passed or its size limits, so try a short sample first.
Notes
- Official image limits: JPEG, PNG, GIF and WEBP, at most 10 MB per image;
image_urltakes an optionaldetail(low/default/high) andmax_long_side_pixel; request body at most 64 MB. The token costs the official docs give are rough; rely onusagein the response. - Image and video input apply to M3 / M3.1-Flash only; the platform and the upstream gateway have their own request-body size limits, so try large images on a small scale first.
Caching
Evidence: tested (live test account, 2026-10-19): hits showed up in the usage of several requests.
When to use: multi-round chat, repeated system prompts or long documents. There is no request parameter for caching; hits are automatic and not guaranteed.
How to see a hit: in the OpenAI format look at usage.prompt_tokens_details.cached_tokens, in the Anthropic format at usage.cache_read_input_tokens. In the "thinking off" request above prompt_tokens is 168, of which cached_tokens is 128:
{
"usage": {
"completion_tokens": 30,
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
},
"prompt_tokens": 168,
"prompt_tokens_details": {
"cached_tokens": 128
},
"total_characters": 0,
"total_tokens": 198
}
}Notes
- The official pricing page has a cache-hit price and the platform price table has a cache-hit item too; but the platform model catalog has no cache capability tag, so hits are judged only by
cached_tokensin the response, anything that does not hit is billed at the normal input price, and you must not assume a hit. - A
cache_controlmarker on content blocks is stripped by the platform; do not use it.
Anthropic format
Evidence: tested (live test account, 2026-10-19), minimax-m3.
When to use: the client is the Anthropic SDK or something like Claude Code that only speaks /v1/messages; this is also the endpoint MiniMax officially recommends. See the Messages page for usage and authentication (the SDK needs auth_token, not api_key).
Request (no thinking)
from anthropic import Anthropic
client = Anthropic(base_url="https://api.modelsite.ai", auth_token="sk-ms-xxxxxxxx")
resp = client.messages.create(
model="minimax-m3",
max_tokens=1500,
messages=[{"role": "user", "content": "用一句话解释量子纠缠"}],
)
for block in resp.content:
if block.type == "thinking":
print("thinking:", block.thinking)
elif block.type == "text":
print("answer:", block.text)Response: thinking is on by default and comes back as a thinking content block; usage.reasoning_tokens is the number of thinking tokens and usage.cache_read_input_tokens is the cache hit.
{
"content": [
{
"type": "thinking",
"thinking": "The user is asking me to explain quantum entanglement in one sentence, in Chinese. Let me craft a concise yet accurate explanation.\n\n量子纠缠是指两个或多个粒子在相互作用后,它们的量子态会变得相互关联,即使相隔很远,测量其中一个粒子的状态会瞬间决定另一个粒子的状态。\n\nLet me make it more concise and clear as a single sentence."
},
{
"type": "text",
"text": "量子纠缠是指两个或多个粒子在相互作用后,其量子态紧密关联在一起,无论相隔多远,对其中一个粒子的测量都会瞬间决定另一个粒子的状态,这种关联不受距离限制,体现了量子世界非经典的关联性。"
}
],
"id": "msg_xxxx",
"model": "minimax-m3",
"output_sensitive_int": 0,
"role": "assistant",
"stop_reason": "end_turn",
"stop_sequence": null,
"type": "message",
"usage": {
"cache_read_input_tokens": 128,
"input_tokens": 53,
"output_tokens": 119,
"reasoning_tokens": 72,
"total_characters": 0
}
}Do not send thinking: {"type": "enabled", ...}: it is not an official value (adaptive / disabled). A request with "thinking": {"type": "enabled", "budget_tokens": 1024} is rejected by the platform with 400 (the upstream used to return 200 with an empty reply; this is now blocked):
{"type":"error","error":{"type":"invalid_request_error","message":"thinking.type \"enabled\" is not supported for this model; use \"adaptive\" or \"disabled\"."}}To control thinking, omit thinking (thinking by default) or send {"type": "disabled"} to turn it off.
Notes
- Per the official Anthropic-compatible page,
top_k,stop_sequences,mcp_servers,context_managementandcontainerare ignored; for theadaptivevalue ofthinkingsee the note under Thinking switch. - For multi-round use the official docs require putting the complete
thinking,textandtool_usecontent blocks back into the history unchanged.
Parameter quick reference
| Parameter | Notes |
|---|---|
thinking | Use only disabled (tested); adaptive depends on an unreleased update; enabled returns 400 in the Anthropic format |
reasoning_split | The platform adds true by default; your value wins |
reasoning_effort, output_config.effort | Officially only for M3.1-Flash, do not use on minimax-m3 |
temperature, top_p, n | temperature [0, 2]; top_p [0, 1]; n supports only 1 |
max_completion_tokens / max_tokens | Thinking tokens count; minimax-m3 has no official max output |
presence_penalty, frequency_penalty, logit_bias | Ignored |
stop / stop_sequences | The Anthropic-compatible page says stop_sequences is ignored; stop in the OpenAI format is not documented, unverified |
service_tier | Not forwarded upstream; has no effect |
tool_choice, function_call | Whether tool_choice takes effect in the OpenAI format is unverified; function_call is not supported |
Unknown top-level fields, keys in extra_body | Forwarded flat, unchanged |
developer role | Converted to system |
Also: the reasoning object (OpenRouter style) is handled by the platform itself, and the reasoning_effort it produces does not apply to minimax-m3, so use thinking directly; reasoning.exclude: true or include_reasoning: false removes the reasoning from the response, thinking tokens are still billed.
Official docs