DeepSeek Models
Scenario-based examples for deepseek-v4.1-flash / deepseek-v4-flash-0731 / deepseek-v4-pro: chat, thinking, tool calls, JSON output, prefix completion, caching, image input
DeepSeek models are called through /v1/chat/completions or /v1/messages. The platform passes the request body through: vendor-specific parameters are forwarded unchanged and the upstream model decides whether they take effect. This page is organised by scenario, following the scenarios in DeepSeek's official documentation (thinking mode, tool calls, JSON output, chat prefix completion, FIM completion, context caching, multi-round chat). 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 |
|---|---|---|---|---|
deepseek-v4.1-flash | V4.1 Flash, thinking / non-thinking | 1,000,000 | 384,000 | chat, streaming, tools, thinking, cache |
deepseek-v4-flash-0731 | V4 Flash (0731 build) | 1,000,000 | 384,000 | chat, streaming, tools, thinking, cache |
deepseek-v4-pro | V4 Pro, stronger reasoning | 1,000,000 | 384,000 | chat, streaming, tools, thinking, cache |
- DeepSeek's own API names the models
deepseek-flashanddeepseek-v4-pro; on ModelSite use the model ids in the table. - Capability tags are whatever
GET /v1/modelsreturns. None of the three has thevisiontag; see Image input.
The platform never turns thinking on for you. It does not inject thinking, reasoning_effort, a thinking budget or temperature by default. If you omit them the upstream default applies (officially thinking is on and reasoning_effort defaults to high). Pass thinking explicitly on every request when you need deterministic behaviour.
Scenario overview
| Scenario | Official docs cover it | Our status | Example |
|---|---|---|---|
| Basic and multi-round chat | Yes | Supported | Basic chat |
| Streaming | Yes | Supported | Streaming |
| Thinking mode (switch, effort, reading the reasoning) | Yes | Supported | Thinking mode |
| Tool calls (non-thinking) | Yes | Supported | Tool calls |
| Tool calls in thinking mode | Yes | Partly supported: tested on deepseek-v4.1-flash, not on the other two | Thinking + tool calls |
| JSON output | Yes | Supported | JSON output |
| Chat prefix completion (Beta) | Yes | Partly supported: tested on deepseek-v4-pro, no Beta endpoint needed; other two models not tested | Prefix completion |
| Context caching | Yes | Supported (automatic, no parameter) | Context caching |
| Image input | The official pricing page lists Flash as supporting it | Partly supported: deepseek-v4.1-flash read an image in testing, but the platform does not list it as a vision model and makes no promise | Image input |
| Anthropic-format calls | Yes (official Anthropic compatibility page) | Supported | Anthropic format |
FIM completion (Beta, /completions) | Yes | Not integrated: the platform has no /v1/completions endpoint | None |
Strict-mode tool calls (strict, Beta) | Yes | Not integrated: the official feature depends on a Beta endpoint that the platform does not offer; we have not verified whether the upstream recognises strict | None |
Basic chat
Evidence: tested (live test account, 2026-10-19), deepseek-v4-flash-0731.
When to use: a single question, or multi-round chat by sending the history along. The API is stateless, so append each assistant reply to messages before the next round.
Request
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
messages = [{"role": "user", "content": "Which is the highest mountain in the world? Answer in one short sentence."}]
resp = client.chat.completions.create(
model="deepseek-v4-flash-0731",
messages=messages,
max_tokens=200,
extra_body={"thinking": {"type": "disabled"}},
)
print(resp.choices[0].message.content)
# Multi-turn: append the reply to history, then ask the next question
messages.append({"role": "assistant", "content": resp.choices[0].message.content})
messages.append({"role": "user", "content": "And the second highest?"})
resp = client.chat.completions.create(
model="deepseek-v4-flash-0731",
messages=messages,
max_tokens=200,
extra_body={"thinking": {"type": "disabled"}},
)Response
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Mount Everest, at 8,848.86 meters (29,031.7 feet) above sea level, is the highest mountain in the world.",
"refusal": null
},
"finish_reason": "stop"
}
],
"created": 1760000000,
"id": "chatcmpl-xxxx",
"model": "deepseek-v4-flash-0731",
"object": "chat.completion",
"system_fingerprint": "fp_xxxx",
"usage": {
"prompt_tokens": 19,
"completion_tokens": 32,
"total_tokens": 51,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
}
}Notes
- When
max_tokensis omitted the default and the counting rule come from the upstream and differ by model: fordeepseek-v4.1-flashthe upstream default is 128K, thinking is counted, and overflow is truncated without an error; the other two are unverified. The official API defaults to 8K non-thinking, 64K thinking, and errors on overflow. Always passmax_tokensexplicitly, and leave room for thinking on thinking models. - A longer history means more input tokens; repeated prefixes hit the cache automatically, see Context caching.
Streaming
Evidence: tested (live test account, 2026-10-19), deepseek-v4-pro.
When to use: show output as it is generated. Pass stream: true and read SSE chunks; reasoning arrives in delta.reasoning_content, the answer in delta.content; accumulate them separately.
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="deepseek-v4-pro",
messages=[{"role": "user", "content": "数到五,用逗号分隔。"}],
max_tokens=100,
stream=True,
extra_body={"thinking": {"type": "disabled"}},
)
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 (middle chunks elided with ...)
data: {"choices":[{"index":0,"delta":{"role":"assistant","content":"1"}}],"created":1760000000,"id":"chatcmpl-xxxx","model":"deepseek-v4-pro","object":"chat.completion.chunk","service_tier":"default"}
data: {"choices":[{"index":0,"delta":{"role":"assistant","content":","}}],"created":1760000000,"id":"chatcmpl-xxxx","model":"deepseek-v4-pro","object":"chat.completion.chunk","service_tier":"default"}
...
data: {"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":"stop"}],"created":1760000000,"id":"chatcmpl-xxxx","model":"deepseek-v4-pro","object":"chat.completion.chunk","service_tier":"default","usage":{"prompt_tokens":13,"completion_tokens":13,"total_tokens":26,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}}
data: {"choices":[],"created":1760000000,"id":"chatcmpl-xxxx","model":"deepseek-v4-pro","object":"chat.completion.chunk","service_tier":"default","usage":{"prompt_tokens":13,"completion_tokens":13,"total_tokens":26,"prompt_tokens_details":{"cached_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}}
data: [DONE]Notes
- If
stream_optionsis not set the gateway addsinclude_usageitself and usage appears at the end of the stream; both the last chunk that haschoicesand the following chunk with emptychoicescarryusage, so check whetherchoicesis empty before reading it. - Reasoning and answer are separate fields in the stream; do not concatenate
reasoning_contentinto the answer.
Thinking mode
Evidence: tested (live test account, 2026-10-19), deepseek-v4.1-flash (OpenAI format).
When to use: maths, reasoning and complex coding that benefit from step-by-step thought. For simple Q&A, translation and tool loops, turn thinking off: faster and cheaper.
All three models have a thinking and a non-thinking mode: thinking switches it, reasoning_effort sets the depth. thinking is not an OpenAI standard field, so the Python SDK takes it in extra_body; reasoning_effort is standard and is passed directly.
Request
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
# Enable thinking explicitly and set the effort
resp = client.chat.completions.create(
model="deepseek-v4.1-flash",
messages=[{"role": "user", "content": "9.11 和 9.9 哪个大?一句话回答。"}],
max_tokens=1500,
reasoning_effort="low",
extra_body={"thinking": {"type": "enabled"}},
)
msg = resp.choices[0].message
print(getattr(msg, "reasoning_content", None)) # the reasoning
print(msg.content) # the final answer
# Disable thinking
resp = client.chat.completions.create(
model="deepseek-v4.1-flash",
messages=[{"role": "user", "content": "用一句话解释量子纠缠"}],
extra_body={"thinking": {"type": "disabled"}},
)Response: the reasoning is in message.reasoning_content, the answer in message.content; the number of thinking tokens is usage.completion_tokens_details.reasoning_tokens and is included in completion_tokens.
{
"id": "xxxxxxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4.1-flash",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "按数值比较,9.9 比 9.11 大。",
"refusal": null,
"reasoning_content": "我们需要回答中文问题:“9.11 和 9.9 哪个大?一句话回答。” 需要注意可能是版本号? 一般数字比较:9.11 < 9.9? 因为 9.11 = 9.11,9.9=9.90,所以 9.9 大。但如果像软件版本号,9.11 > 9.9 因为 minor 11 > 9。问题没指定。通常数学数字比较:9.9 大。一句话回答。需要简洁。问“9.11 和 9.9 哪个大?” 应该回答“按数值比较,9.9 比 9.11 大。” 一句话。注意如果版本号则 9.11 更大,但通常直接问哪个大,按十进制。可以加“按数值”。一句话。最终。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 46,
"completion_tokens": 200,
"total_tokens": 246,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 183,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default"
}Notes
- Use only
low,highandmaxforreasoning_effort; the default ishigh. Other values (none,minimal,medium,xhigh,ultra) map differently across models, do not depend on them: the upstream docs fordeepseek-v4.1-flashsaynonedisables thinking,minimalmaps tolow,mediumandxhighmap tohigh,ultramaps tomax; fordeepseek-v4-prothey saynoneandminimaldisable thinking,mediummaps tolow,xhighmaps tohigh;deepseek-v4-flash-0731is unverified. To turn thinking off usethinking: {"type": "disabled"}. - Sampling:
temperaturehas no effect in thinking mode (no error); ondeepseek-v4.1-flashtop_pbelow 0.95 is raised to 0.95 in thinking mode and fixed at 1.0 otherwise; do not sendfrequency_penaltyorpresence_penalty.top_kis ignored upstream. The platform does not range-check, so out-of-range values go to the upstream unchanged. thinkingaccepts onlyenabled/disabled;adaptive(a Claude-only value) is not forwarded.reasoning_contentin history: in multi-round chat withouttoolsthe upstream ignores it; for the case withtoolssee Thinking + tool calls.
Tool calls
Evidence: tested (live test account, 2026-10-19), deepseek-v4-pro, thinking off.
When to use: let the model decide to call functions you define. The model does not run functions: it returns tool_calls, your code runs them, puts each result back as a role: "tool" message (with the matching tool_call_id) and you call the model once more for the final answer.
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="deepseek-v4-pro", messages=messages, tools=tools, max_tokens=300,
extra_body={"thinking": {"type": "disabled"}},
)
msg = resp.choices[0].message
messages.append(msg) # put the assistant message with tool_calls back into historyFirst response: finish_reason is tool_calls; function.arguments is a JSON string that you must parse yourself.
{
"id": "xxxxxxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4-pro",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "I'll check the current weather in Hangzhou for you.\n\n",
"refusal": null,
"tool_calls": [
{
"id": "call_xxxx",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"Hangzhou, China\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 306,
"completion_tokens": 59,
"total_tokens": 365,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default"
}Second round: run the function, put the result into the history and request again (keep sending tools).
for call in msg.tool_calls:
result = "24℃, cloudy" # the real result of your function
messages.append({"role": "tool", "tool_call_id": call.id, "content": result})
resp = client.chat.completions.create(
model="deepseek-v4-pro", messages=messages, tools=tools, max_tokens=300,
extra_body={"thinking": {"type": "disabled"}},
)
print(resp.choices[0].message.content)Second response
{
"id": "xxxxxxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4-pro",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The weather in Hangzhou is currently **24℃ and cloudy**.",
"refusal": null
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 381,
"completion_tokens": 13,
"total_tokens": 394,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default"
}Notes
tool_choiceacceptsnone,auto,requiredor a named function. Whether a forced call works in thinking mode depends on the model (next section); when you must force a tool, turning thinking off is the safest option.- Only
functiontools are supported. - The Chat Completions format cannot insert tool-call messages in the middle of a conversation (official note; use the Anthropic format for that).
- Anthropic-format
tool_choice:automaps toauto,anytorequired,toolto a named function;nonemaps tonone;disable_parallel_tool_use: truemaps toparallel_tool_calls: false.
Thinking + tool calls
Evidence: tested (live test account, 2026-10-19) on deepseek-v4.1-flash only; deepseek-v4-pro and deepseek-v4-flash-0731 per official docs (not tested).
When to use: agent flows that should reason before deciding which function to call. Enable thinking, pass tools, and loop until the response has no more tool_calls.
Request (first round)
resp = client.chat.completions.create(
model="deepseek-v4.1-flash",
messages=messages, # same as above: the user asks about Hangzhou weather
tools=tools,
max_tokens=1500,
reasoning_effort="low",
extra_body={"thinking": {"type": "enabled"}},
)
msg = resp.choices[0].message # contains reasoning_content and tool_calls
messages.append(msg) # put the whole assistant message (with reasoning_content) backFirst response: both reasoning_content and tool_calls are present.
{
"id": "xxxxxxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4.1-flash",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "",
"refusal": null,
"tool_calls": [
{
"id": "call_xxxx",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"Hangzhou\"}"
}
}
],
"reasoning_content": "The user wants to know the weather in Hangzhou. Let me call the get_weather function."
},
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 321,
"completion_tokens": 61,
"total_tokens": 382,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 20,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default"
}Second response: put the whole assistant message above (with reasoning_content) and the role: "tool" result back into the history and request again.
{
"id": "xxxxxxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4.1-flash",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The weather in Hangzhou is currently **24℃ and cloudy** — mild and comfortable, with no precipitation expected. It's a good day to be outside, though you might want a light layer if it gets breezy.",
"refusal": null,
"reasoning_content": "The tool returned 24℃, cloudy. Let me report that."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 378,
"completion_tokens": 60,
"total_tokens": 438,
"prompt_tokens_details": {
"cached_tokens": 256
},
"completion_tokens_details": {
"reasoning_tokens": 14,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default"
}Notes
- Passing back
reasoning_content: DeepSeek officially requires the history's assistantreasoning_contentto be passed back in full whenevertoolsis present, and returns 400 otherwise. Thedeepseek-v4.1-flashupstream we connect to did not error when we left it out in testing (the second round returned normally without it). That is lenient upstream behaviour, not a promise: always pass it back. The platform forwardsreasoning_contentin history unchanged, and in the Anthropic format athinkingcontent block in history is converted toreasoning_content. - Forced tool calls: the official API returns 400 for
tool_choice: "required"and named functions in thinking mode; the upstream docs fordeepseek-v4.1-flashsayrequiredis supported in thinking mode; the other two models are unverified. - In this scenario the second response shows
usage.prompt_tokens_details.cached_tokensof 256: the prefix hit the automatic cache.
JSON output
Evidence: tested (live test account, 2026-10-19), deepseek-v4.1-flash, thinking off.
When to use: stable, directly parseable JSON, for example information extraction. Set response_format: {"type": "json_object"}; the prompt must contain the word "json" and an example of the expected format.
Request
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
system_prompt = """Parse the question and answer from the exam text and output them as JSON.
Example input: "Which is the highest mountain? Mount Everest."
Example JSON: {"question": "Which is the highest mountain?", "answer": "Mount Everest"}"""
resp = client.chat.completions.create(
model="deepseek-v4.1-flash",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": "Which is the longest river in the world? The Nile River."},
],
response_format={"type": "json_object"},
max_tokens=512,
extra_body={"thinking": {"type": "disabled"}},
)
print(json.loads(resp.choices[0].message.content))Response
{
"id": "xxxxxxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4.1-flash",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"question\": \"Which is the longest river in the world?\", \"answer\": \"The Nile River\"}",
"refusal": null
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 89,
"completion_tokens": 21,
"total_tokens": 110,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default"
}Notes
- Set
max_tokenshigh enough, otherwise the JSON may be cut off; the official docs warn that empty content is occasionally returned, so handle an empty result in code. - Use
json_objectonly.json_schemais marked Beta in the upstream docs and per-model support is unverified.
Prefix completion
Evidence: tested (live test account, 2026-10-19) on deepseek-v4-pro only; deepseek-v4.1-flash and deepseek-v4-flash-0731 per official docs (not tested).
When to use: make the model continue from a beginning you supply, for example forcing a code block to start the output. Officially this is a Beta feature that needs the https://api.deepseek.com/beta endpoint; on ModelSite you do not change the endpoint, use the same /v1/chat/completions: the last message has role assistant and "prefix": true, and content is the beginning to continue.
Request
from openai import OpenAI
client = OpenAI(base_url="https://api.modelsite.ai/v1", api_key="sk-ms-xxxxxxxx")
resp = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[
{"role": "user", "content": "Please write quick sort code"},
{"role": "assistant", "content": "```python\n", "prefix": True},
],
stop=["```"],
max_tokens=400,
extra_body={"thinking": {"type": "disabled"}},
)
print(resp.choices[0].message.content)Response (content truncated; max_tokens ran out this time so finish_reason is length)
{
"id": "xxxxxxxx",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4-pro",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "def quick_sort(arr):\n \"\"\"\n Quick sort implementation using Lomuto partition scheme.\n \n Args:\n arr: List of comparable elements\n \n Retur…",
"refusal": null
},
"finish_reason": "length"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 400,
"total_tokens": 412,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0,
"accepted_prediction_tokens": 0,
"rejected_prediction_tokens": 0
}
},
"service_tier": "default"
}Notes
- How we know the prefix was used: asked the same question without a prefix, the model opens with explanatory prose ("Here's a clean implementation..."); with the prefix it starts directly with code, and the input token count grows by the prefix. The response contains only the continuation, not the prefix you sent.
- The last message must be an assistant message with
prefix: true.stopis optional and cuts the output at a delimiter. - This is a DeepSeek Beta capability and may change; it has been tested on
deepseek-v4-proonly.
Context caching
Evidence: tested (live test account, 2026-10-19), deepseek-v4.1-flash.
When to use: multi-round chat, or repeated questions over the same long document. Caching is automatic, has no request parameter, is best-effort rather than guaranteed, and only the input prefix is cached. Put stable content (system prompt, document) first and changing content last so that it can hit.
How to see a hit: usage.prompt_tokens_details.cached_tokens. For example in the second response of "Thinking + tool calls" above, prompt_tokens is 378 and cached_tokens is 256.
Notes
- The upstream docs for
deepseek-v4.1-flashgive a 256-token minimum for implicit caching, and building a cache takes a few seconds. - DeepSeek's official API also returns
prompt_cache_hit_tokens/prompt_cache_miss_tokens; these two fields did not appear in the real responses, so rely oncached_tokens. - A
cache_controlmarker on content blocks has no effect on DeepSeek; the platform strips it before forwarding, so do not use it.
Image input
Evidence: tested (live test account, 2026-10-19) on deepseek-v4.1-flash only; the other two models were not tested.
None of the three models has the vision capability tag, so the platform has not opened DeepSeek as a vision model, and this scenario can only be "partly supported":
deepseek-v4.1-flash: tested with a solid red 64x64 PNG; the model answered the colour correctly and returned normally with no error. This is upstream behaviour, not a platform commitment, and image-input billing has not been checked separately, so do not use it in production.deepseek-v4-pro: officially no image support; not tested.deepseek-v4-flash-0731: the model catalog marks vision as unsupported; not tested.
For stable image understanding choose a model whose capability tags include vision (see the Qwen page).
Anthropic format
Evidence: tested (live test account, 2026-10-19), deepseek-v4-pro.
When to use: your client is the Anthropic SDK or something like Claude Code that only speaks /v1/messages. See the Messages page for usage and authentication (the SDK needs auth_token, not api_key).
Request
from anthropic import Anthropic
client = Anthropic(base_url="https://api.modelsite.ai", auth_token="sk-ms-xxxxxxxx")
resp = client.messages.create(
model="deepseek-v4-pro",
max_tokens=1500,
thinking={"type": "enabled", "budget_tokens": 1024},
messages=[{"role": "user", "content": "9.11 和 9.9 哪个大?一句话回答。"}],
)
for block in resp.content:
if block.type == "thinking":
print("thinking:", block.thinking)
elif block.type == "text":
print("answer:", block.text)Response
{
"id": "msg_xxxx",
"type": "message",
"role": "assistant",
"content": [
{
"type": "thinking",
"thinking": "我们需要回答用户中文问题“9.11 和 9.9 哪个大?一句话回答。”需要一句话。注意陷阱?9.11和9.9作为数字比较,9.9大。但要注意可能是日期?但通常数字。用户要求一句话回答。我们可以说“9.9更大。”需要一句话。确保不要解释太多。用中文。"
},
{
"type": "text",
"text": "9.9 更大。"
}
],
"model": "deepseek-v4-pro",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 20,
"output_tokens": 84,
"reasoning_tokens": 77
}
}Notes
budget_tokensis not a hard budget: the official Anthropic compatibility doc says it is ignored. To control depth add the top-level fieldreasoning_effortto the body (extra_bodyin the Python SDK); the platform forwards it unchanged. Disable thinking withthinking: {"type": "disabled"}.- The reasoning comes back as a
thinkingcontent block;usage.reasoning_tokensis the number of thinking tokens. top_kis forwarded and ignored upstream;stop_sequencesmaps tostop;metadata.user_idmaps touser.
Parameter quick reference
| Parameter | Notes |
|---|---|
thinking | enabled / disabled; auto is forwarded but DeepSeek only recognises the first two; adaptive is not forwarded |
reasoning_effort | Use only low / high / max |
max_tokens / max_completion_tokens | Not rewritten and no default injected; when both are sent only max_completion_tokens is forwarded |
temperature, top_p | Mostly ineffective in thinking mode, see Thinking mode |
frequency_penalty, presence_penalty | Do not send (the deepseek-v4.1-flash upstream says unsupported) |
stop | Up to 16 strings (upstream docs for deepseek-v4.1-flash; the others per official docs, unverified) |
logprobs, top_logprobs | Upstream docs say supported, top_logprobs up to 20; not tested |
stream_options.include_usage | Added by the gateway when a streaming request omits it |
response_format | text / json_object; json_schema unverified |
n (above 1), service_tier, store, metadata, user_id, etc. | Forwarded unchanged; whether the upstream recognises them is unverified |
Unknown top-level fields, keys in extra_body | Forwarded flat, unchanged |
developer role | Converted to system |
Also: the reasoning object (OpenRouter style, reasoning.effort, reasoning.exclude, ...) is handled by the platform itself; reasoning.exclude: true or include_reasoning: false removes the reasoning from the response, thinking tokens are still billed.
Official docs