DeepSeek: DeepSeek V3.1 Terminus
DeepSeek V3.1 Terminus refines the V3.1 text model’s language consistency and code/search agent behaviour. It retains the hybrid thinking and direct-response profile, with a 128K context and an updated search-agent template kept separate from later V3.2 formats.
- Ailoot Ultra · OpenAI Chat
POST /v1/chat/completionsdeepseek/deepseek-v3.1-terminus - Ailoot Ultra · Anthropic Messages
POST /v1/messagesdeepseek/deepseek-v3.1-terminus
About the model
This description covers the model’s capabilities. Available in Ailoot inputs, outputs and options are listed for the selected method below.
DeepSeek V3.1 Terminus is DeepSeek’s update to the V3.1 text-model profile. It retains the original capabilities while addressing unwanted Chinese-English mixing, occasional abnormal characters and the behaviour of code and search agents. The input is a written task and source context; the output is text, which can include an explanation, proposed code or agent-related content. The named Terminus edition remains distinct from original V3.1 and the later sparse-attention releases.
The inherited V3.1 profile is hybrid: one model can respond in thinking or non-thinking mode through its chat template. V3.1’s published model table lists 671 billion total parameters, 37 billion active parameters and a 128K context. Terminus describes the same model structure as V3 and points to V3.1 for the conversation template outside its revised search-agent workflow. These references connect the update to the underlying family while preserving its own changes.
For a direct coding assistant, the inherited template supports standard tool calls in non-thinking mode, with named functions and JSON arguments based on the supplied tool definitions. The model proposes the operation, the application performs it and returns the observation. Thinking-mode search follows a specialised search-agent format. Terminus updates that search template and tool set, so the search trajectory should use the Terminus reference rather than an unrelated template from another release.
Language consistency is a practical edition difference. For a Chinese or English document task, specify the answer language, the terms that must retain their original spelling and the source passages to use. An illustrative brief is: “Write the explanation in English, preserve the supplied variable names and avoid translating the API field names. Base each finding on the provided specification.” The update targets unwanted language switching, while your brief still defines what mixed-language material is intentional.
The model can use a user-supplied search tool for questions requiring external or current information. Provide the research question, the criteria for useful sources and the final deliverable. A coding task should include the relevant fragment, observed behaviour and expected result. Keep tool returns associated with the operation that produced them, and ask the final answer to identify the evidence behind a proposed change or conclusion.
The producer records a checkpoint-specific precision detail: the attention output-projection parameters do not conform to the UE8M0 FP8 scale format used in the V3.1 release. That is a reference implementation consideration, not a change to the task’s language, modality or answer format. It is a reason to retain Terminus as its own edition and avoid treating all V3.1 checkpoints as identical precision profiles.
For longer work, budget the source material, conversation and generated response within the 128K family context. Label document sections and code fragments so a result can refer back to the right evidence. In a multi-step task, define the allowed actions, the required artifact and the criterion for completion. The useful result is a consistent textual answer, code proposal or source-supported analysis that can be reviewed against the input and the actual tool observations.
Practical task
Explain a field rule in English
Technical example in English
Explain a field rule in English
Write an English explanation of this validation rule for an integration guide: "retry_count must be a nonnegative integer; retry_after_ms may be omitted; when present, it must be a positive integer." Preserve the field names exactly. Add one valid and one invalid example as plain text, explaining the invalid field without translating identifiers.Expected result
An English paragraph plus two labelled examples and a specific validation explanation.Check the result
Check that retry_count accepts zero while retry_after_ms does not.Ailoot Ultra · OpenAI Chat POST /v1/chat/completions deepseek/deepseek-v3.1-terminus
deepseek/deepseek-v3.1-terminus
deepseek/deepseek-v3.1-terminusOverview
DeepSeek V3.1 Terminus refines the V3.1 text model’s language consistency and code/search agent behaviour. It retains the hybrid thinking and direct-response profile, with a 128K context and an updated search-agent template kept separate from later V3.2 formats.
- Accepted inputs
- Text
- Results
- Text
Available in Ailoot · inputs & methods
Ailoot Ultra · OpenAI Chat POST /v1/chat/completions
- Input types
text- Output types
text- Output format
- json or SSE
| Field | Type | Requirement | Values & limits | Default |
|---|---|---|---|---|
Fieldmodel | Typestring | RequirementRequired | Values & limits deepseek/deepseek-v3.1-terminus | Default— |
Fieldmessages | Typemessage[] | RequirementRequired | Values & limits Minimum items: 1 | Default— |
Fieldmessages[].role | Typestring | RequirementRequired | Values & limits Examples: system, user, assistant, tool, function Conditions: These roles are explicitly represented by Source compatibility types; the exact model role set remains model-specific. Model-specific | Default— |
Fieldmessages[].content | Typestring|content_part[]|null | RequirementOptional | Values & limits | Default— |
Fieldmessages[].tool_calls | Typetool_call[] | RequirementOptional | Values & limits | Default— |
Fieldmessages[].tool_call_id | Typestring | RequirementOptional | Values & limits Applies when: role=tool; use actual returned ID | Default— |
Fieldmessages[].name | Typestring | RequirementOptional | Values & limits | Default— |
Fieldmessages[].reasoning_content | Typestring | RequirementOptional | Values & limits Applies when: Round-trip actual returned reasoning where this model uses it | Default— |
Fieldmessages[].reasoning_details | Typeobject|array | RequirementOptional | Values & limits Model-specific | Default— |
Fieldmax_tokens | Typeinteger | RequirementOptional | Values & limits Minimum: 1 Model-specific | Default— |
Fieldmax_completion_tokens | Typeinteger | RequirementOptional | Values & limits Minimum: 1 Model-specific | Default— |
Fieldstream | Typeboolean | RequirementOptional | Values & limits | Defaultfalse |
Fieldstream_options.include_usage | Typeboolean | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtemperature | Typenumber | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtop_p | Typenumber | RequirementOptional | Values & limits Model-specific | Default— |
Fieldstop | Typestring|string[] | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtools | Typefunction_tool[] | RequirementOptional | Values & limits Model-specific | Default— |
Fieldtools[].type | Typestring | RequirementOptional | Values & limits function Model-specific | Default— |
Fieldtools[].function.name | Typestring | RequirementRequired | Values & limits Applies when: function tool supplied | Default— |
Fieldtools[].function.description | Typestring | RequirementOptional | Values & limits | Default— |
Fieldtools[].function.parameters | TypeJSON_schema | RequirementOptional | Values & limits | Default— |
Fieldtool_choice | Typestring|object | RequirementOptional | Values & limits Model-specific | Default— |
Fieldparallel_tool_calls | Typeboolean | RequirementOptional | Values & limits Model-specific | Default— |
Fieldresponse_format | Typeobject | RequirementOptional | Values & limits Model-specific | Default— |
Fieldreasoning_effort | Typestring | RequirementOptional | Values & limits Model-specific | Default— |
Fieldreasoning | Typeobject | RequirementOptional | Values & limits Model-specific | Default— |
Fieldservice_tier | Typestring | RequirementOptional | Values & limits Model-specific | Default— |
Fieldinstructions | Typestring | RequirementOptional | Values & limits Compatibility field | Default— |
Fieldfunctions | Typefunction[] | RequirementOptional | Values & limits Model-specific | Default— |
Fieldfunction_call | Typestring|object | RequirementOptional | Values & limits Model-specific | Default— |
Fieldprompt_cache_options | Typeobject | RequirementOptional | Values & limits Model-specific | Default— |
Fieldmodalities | Typestring[] | RequirementOptional | Values & limits text | Default— |
Fieldprovider | Typeobject | RequirementOptional | Values & limits Conditions: provider.options is rejected on this Ultra text route | Default— |
Fieldcache_control.ttl | Typestring | RequirementOptional | Values & limits Conditions: 1h is rejected in actual prompt-cache locations | Default— |
Input material combinations
Text · UTF8 text
messages[].content
Method parameters and lifecycle
| Parameter | Contract |
|---|---|
Parametercontent_type | Contractapplication/json |
Parameterrequired | Contractmodel, messages |
Parametermaterial_types | Contracttext |
Parametermessages | Contractmessage array with role/content shape |
Parameterfile_material | Contractactual UTF-8 document inserted as literal text; no file ID inferred |
Parameteroptional_controls | Contractstream, temperature, top_p, stop, max_tokens, max_completion_tokens, reasoning, response_format, tools, tool_choice |
Parametercontrol_scope | Contractmodel-specific; user function tools differ from hosted tools |
Parameteroutput_modalities | Contracttext |
Parameterhosted_operations | Contractfalse |
Parametermultimodal_input_binding | Contractnull |
Lifecycle: synchronous_or_streamed
Send exact model ID with messages.
Context length is not an output cap.
A text file may supply literal text; image/audio/file-object inputs need exact binding.
Pricing
Tariff references do not add request options. Supported parameters are listed for the selected method.
- Fast mode
- Not specified When fast mode is selected
- Flex mode
- Not specified When flex mode is selected
- Maximum reasoning effort
- Not specified When maximum reasoning effort uses the default adjustment
Ailoot rates
Prices by configuration
| Configuration | Rate schedule | Charge |
|---|---|---|
| ConfigurationBase token rates | Rate scheduleBase rate | Charge Input · Input tokens $0.001144 / 1K tokens Output · Output tokens $0.00343 / 1K tokens Input · Cache read $0 / 1K tokens Input · Cache write $0 / 1K tokens Input · Cache write, 1 hour — / 1K tokens |
Ailoot reserves an estimated amount before a request. After the result, it settles the final charge from measured usage. Streaming settlement uses the final usage record. How reservation and settlement work →
Example requests
Ailoot Ultra · OpenAI Chat
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
p=json.loads('{"model": "deepseek/deepseek-v3.1-terminus", "messages": [{"role": "user", "content": "Explain the difference between an observation and a hypothesis in three sentences."}]}')
Path("request.json").write_text(json.dumps(p,ensure_ascii=False))
PY_REQUEST
curl --fail-with-body --silent --show-error https://api.ailoot.ai/v1/chat/completions \
-H "Authorization: Bearer $AILOOT_API_KEY" -H 'Content-Type: application/json' \
--data-binary @request.json -D response-headers.txt -o result.json
python3 - <<'PY_RESULT'
import json
from pathlib import Path
r=json.loads(Path("result.json").read_text())
for x in r.get("choices",[]):
if x.get("message",{}).get("content"): print(x["message"]["content"])
PY_RESULT
from openai import OpenAI
import os
if not os.environ.get("AILOOT_API_KEY", "").strip(): raise SystemExit("Set AILOOT_API_KEY before making a request")
client=OpenAI(base_url="https://api.ailoot.ai/v1",api_key=os.environ["AILOOT_API_KEY"],max_retries=0)
result=client.chat.completions.create(model='deepseek/deepseek-v3.1-terminus',messages=[{"role":"user","content":"Explain observations and hypotheses in three sentences."}])
import base64, json
from pathlib import Path
def save_result(data, stem="result"):
# Keep every field, including usage, IDs, reasoning and tool requests.
Path(stem + ".json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(data, ensure_ascii=False, indent=2))
def save_blob(encoded, suffix, label):
raw = base64.b64decode(encoded, altchars=b"-_", validate=True)
ext = "png" if raw.startswith(b"\x89PNG\r\n\x1a\n") else "jpg" if raw.startswith(b"\xff\xd8") else "webp" if raw[:4] == b"RIFF" and raw[8:12] == b"WEBP" else suffix
file = Path(stem + "-" + label + "." + ext)
file.write_bytes(raw)
print("Saved", file)
for index, block in enumerate(data.get("content") or []):
print("Content", index, json.dumps(block, ensure_ascii=False))
for choice in data.get("choices") or []:
print("Choice", choice.get("index"), json.dumps(choice.get("message", choice.get("delta", {})), ensure_ascii=False))
for index, item in enumerate(data.get("output") or []):
print("Output", index, json.dumps(item, ensure_ascii=False))
if item.get("type") == "image_generation_call" and item.get("result"):
save_blob(item["result"], item.get("output_format") or "bin", "output-" + str(index))
for ci, candidate in enumerate(data.get("candidates") or []):
for pi, part in enumerate((candidate.get("content") or {}).get("parts") or []):
print("Candidate/part", ci, pi, json.dumps(part, ensure_ascii=False))
blob = part.get("inlineData") or part.get("inline_data")
if blob and blob.get("data"):
mime = blob.get("mimeType") or blob.get("mime_type")
suffix = {"image/png":"png", "image/jpeg":"jpg", "image/webp":"webp", "audio/wav":"wav", "audio/mpeg":"mp3", "video/mp4":"mp4"}.get(mime, "bin")
save_blob(blob["data"], suffix, "candidate-" + str(ci) + "-part-" + str(pi))
save_result(result.to_dict(mode="json"))
from openai import OpenAI
import os
from pathlib import Path
if not os.environ.get("AILOOT_API_KEY", "").strip(): raise SystemExit("Set AILOOT_API_KEY before making a request")
client=OpenAI(base_url="https://api.ailoot.ai/v1",api_key=os.environ["AILOOT_API_KEY"],max_retries=0)
import base64, json
from pathlib import Path
def save_result(data, stem="result"):
# Keep every field, including usage, IDs, reasoning and tool requests.
Path(stem + ".json").write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(data, ensure_ascii=False, indent=2))
def save_blob(encoded, suffix, label):
raw = base64.b64decode(encoded, altchars=b"-_", validate=True)
ext = "png" if raw.startswith(b"\x89PNG\r\n\x1a\n") else "jpg" if raw.startswith(b"\xff\xd8") else "webp" if raw[:4] == b"RIFF" and raw[8:12] == b"WEBP" else suffix
file = Path(stem + "-" + label + "." + ext)
file.write_bytes(raw)
print("Saved", file)
for index, block in enumerate(data.get("content") or []):
print("Content", index, json.dumps(block, ensure_ascii=False))
for choice in data.get("choices") or []:
print("Choice", choice.get("index"), json.dumps(choice.get("message", choice.get("delta", {})), ensure_ascii=False))
for index, item in enumerate(data.get("output") or []):
print("Output", index, json.dumps(item, ensure_ascii=False))
if item.get("type") == "image_generation_call" and item.get("result"):
save_blob(item["result"], item.get("output_format") or "bin", "output-" + str(index))
for ci, candidate in enumerate(data.get("candidates") or []):
for pi, part in enumerate((candidate.get("content") or {}).get("parts") or []):
print("Candidate/part", ci, pi, json.dumps(part, ensure_ascii=False))
blob = part.get("inlineData") or part.get("inline_data")
if blob and blob.get("data"):
mime = blob.get("mimeType") or blob.get("mime_type")
suffix = {"image/png":"png", "image/jpeg":"jpg", "image/webp":"webp", "audio/wav":"wav", "audio/mpeg":"mp3", "video/mp4":"mp4"}.get(mime, "bin")
save_blob(blob["data"], suffix, "candidate-" + str(ci) + "-part-" + str(pi))
with client.chat.completions.stream(model='deepseek/deepseek-v3.1-terminus',messages=[{"role":"user","content":"Explain observations and hypotheses in three sentences."}]) as stream:
with Path("stream-events.jsonl").open("w",encoding="utf-8") as log:
for event in stream:
payload=event.to_dict(mode="json")
log.write(json.dumps(payload,ensure_ascii=False)+"\n"); log.flush()
print(json.dumps(payload,ensure_ascii=False))
final=stream.get_final_completion()
save_result(final.to_dict(mode="json"),"stream-result")
Receive and save results
Ailoot Ultra · OpenAI Chat
json or SSE
Keep all completed results
Keep every complete returned response, file and content part.
Keep every choice and its content/tool calls/reasoning. In SSE assemble deltas by choice/tool index, retain the final finish reason and usage.
If the original response needs checking
Keep request/response IDs and headers. No generic text job retrieval URL is supplied.
Response fields
| Field | Type |
|---|---|
Fieldchoices[].index | Typeinteger |
Fieldchoices[].message.content | Typestring|null |
Fieldchoices[].message.tool_calls | Typetool_call[] |
Fieldchoices[].message.reasoning_content | Typestring |
Fieldchoices[].message.reasoning_details | Typeobject|array |
Fieldchoices[].finish_reason | Typestring|null |
Fieldusage | Typeobject |
Errors and next steps
| Response | Condition | Next step |
|---|---|---|
Response400 · invalid_request_error | ConditionInvalid required fields, material representation or parameter value | Next stepCorrect the indicated fields before a new creation request. |
Aliases
Model aliases
Ailoot Ultra deepseek/deepseek-v3.1-terminus
Method path aliases
Use the method paths shown above.
Related caller IDs
Ailoot Ultra · Anthropic Messages POST /v1/messages deepseek/deepseek-v3.1-terminus
deepseek/deepseek-v3.1-terminus
deepseek/deepseek-v3.1-terminusOverview
DeepSeek V3.1 Terminus refines the V3.1 text model’s language consistency and code/search agent behaviour. It retains the hybrid thinking and direct-response profile, with a 128K context and an updated search-agent template kept separate from later V3.2 formats.
- Accepted inputs
- Text
- Results
- json · sse
Available in Ailoot · inputs & methods
Ailoot Ultra · Anthropic Messages POST /v1/messages
- Input types
text- Output types
json,sse- Output format
- JSON or SSE
| Field | Type | Requirement | Values & limits | Default |
|---|---|---|---|---|
Fieldmodel | Typestring | RequirementRequired | Values & limits deepseek/deepseek-v3.1-terminus | Default— |
Fieldmessages | Typemessage[] | RequirementRequired | Values & limits | Default— |
Fieldmessages[].role | Typestring | RequirementRequired | Values & limits user, assistant | Default— |
Fieldmessages[].content | Typestring | RequirementRequired | Values & limits | Default— |
Fieldmax_tokens | Typeinteger | RequirementRequired | Values & limits | Default— |
Fieldstream | Typeboolean | RequirementOptional | Values & limits | Defaultfalse |
Input material combinations
Text · UTF-8 text
messages[].content string
Method parameters and lifecycle
| Parameter | Contract |
|---|---|
Parametercontent_type | Contractapplication/json |
Parameterrequired | Contractmodel, messages, max_tokens |
Parameteroptional_controls | Contractstream |
Parametermaterial_types | Contracttext |
Parametertext_file_material | ContractRead the actual UTF-8 document and put its text in the indicated input or message content string. |
Lifecycle: synchronous_or_streamed
Pricing
Tariff references do not add request options. Supported parameters are listed for the selected method.
- Fast mode
- Not specified When fast mode is selected
- Flex mode
- Not specified When flex mode is selected
- Maximum reasoning effort
- Not specified When maximum reasoning effort uses the default adjustment
Ailoot rates
Prices by configuration
| Configuration | Rate schedule | Charge |
|---|---|---|
| ConfigurationBase token rates | Rate scheduleBase rate | Charge Input · Input tokens $0.001144 / 1K tokens Output · Output tokens $0.00343 / 1K tokens Input · Cache read $0 / 1K tokens Input · Cache write $0 / 1K tokens Input · Cache write, 1 hour — / 1K tokens |
Ailoot reserves an estimated amount before a request. After the result, it settles the final charge from measured usage. Streaming settlement uses the final usage record. How reservation and settlement work →
Example requests
Ailoot Ultra · Anthropic Messages
{
"model": "deepseek/deepseek-v3.1-terminus",
"max_tokens": 128,
"messages": [
{
"role": "user",
"content": "Summarize the incident report."
}
],
"stream": false
}set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_TEXT_FILE:?Set your actual UTF-8 document}"
export AILOOT_TEXT_FILE
python3 - <<'PY_REQUEST'
import json, os
from pathlib import Path
source_file = Path(os.environ['AILOOT_TEXT_FILE'])
if not source_file.is_file():
raise SystemExit('Set AILOOT_TEXT_FILE to your actual UTF-8 document')
text = source_file.read_text(encoding='utf-8')
if not text.strip():
raise SystemExit('Choose a document containing text')
payload = {'model': 'deepseek/deepseek-v3.1-terminus', 'max_tokens': 128, 'messages': [{'role': 'user', 'content': 'Summarize the incident report.'}]}
payload['messages'][0]['content'] = 'Summarize this material and quote supporting source passages.\n\n' + text
Path('request.json').write_text(json.dumps(payload, ensure_ascii=False), encoding='utf-8')
PY_REQUEST
curl --fail-with-body --silent --show-error https://api.ailoot.ai/v1/messages \
-H "x-api-key: $AILOOT_API_KEY" -H 'anthropic-version: 2023-06-01' -H 'Content-Type: application/json' \
--data-binary @request.json -D response-headers.txt -o result.json
python3 - <<'PY_RESULT'
import json
from pathlib import Path
result = json.loads(Path('result.json').read_text(encoding='utf-8'))
print(json.dumps(result, ensure_ascii=False, indent=2))
PY_RESULT
import json, os
from pathlib import Path
source_file = Path(os.environ['AILOOT_TEXT_FILE'])
if not source_file.is_file():
raise SystemExit('Set AILOOT_TEXT_FILE to your actual UTF-8 document')
text = source_file.read_text(encoding='utf-8')
if not text.strip():
raise SystemExit('Choose a document containing text')
payload = {'model': 'deepseek/deepseek-v3.1-terminus', 'max_tokens': 128, 'messages': [{'role': 'user', 'content': 'Summarize the incident report.'}]}
payload['messages'][0]['content'] = 'Summarize this material and quote supporting source passages.\n\n' + text
from urllib.request import Request, urlopen
from urllib.error import HTTPError
api_key = os.environ['AILOOT_API_KEY']
if not api_key.strip():
raise SystemExit('Set AILOOT_API_KEY before making a request')
headers = {'x-api-key': 'PLACEHOLDER_KEY', 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json'}
headers['x-api-key'] = api_key
request = Request('https://api.ailoot.ai/v1/messages', data=json.dumps(payload, ensure_ascii=False).encode('utf-8'), headers=headers, method='POST')
try:
with urlopen(request, timeout=120) as response:
raw = response.read()
Path('response-headers.txt').write_text(str(response.headers), encoding='utf-8')
except HTTPError as error:
Path('result.json').write_bytes(error.read())
Path('response-headers.txt').write_text(str(error.headers), encoding='utf-8')
raise
Path('result.json').write_bytes(raw)
import json
from pathlib import Path
result = json.loads(Path('result.json').read_text(encoding='utf-8'))
print(json.dumps(result, ensure_ascii=False, indent=2))
Receive and save results
Ailoot Ultra · Anthropic Messages
JSON or SSE
Keep all completed results
Keep every complete returned response, file and content part.
Keep all content blocks, thinking signatures and actual tool-use IDs. Assemble all SSE block deltas; a first text block is not the complete output.
If the original response needs checking
Keep request/response IDs and headers. No generic text job retrieval URL is supplied.
Response fields
| Field | Type |
|---|---|
Fieldid | Typestring |
Fieldmodel | Typestring |
Fieldcontent[] | Typetext|thinking|tool_use|other content block |
Fieldstop_reason | Typestring|null |
Fieldusage | Typeobject |
Errors and next steps
| Response | Condition | Next step |
|---|---|---|
Response400 · invalid_request_error | ConditionInvalid required fields, material representation or parameter value | Next stepCorrect the indicated fields before a new creation request. |
Aliases
Model aliases
Ailoot Ultra deepseek/deepseek-v3.1-terminus
Method path aliases
Use the method paths shown above.
Related caller IDs
FAQ · DeepSeek: DeepSeek V3.1 Terminus
- What inputs and results are available?
POST /v1/chat/completions·deepseek/deepseek-v3.1-terminus:text→textPOST /v1/messages·deepseek/deepseek-v3.1-terminus:text→json,sse- Which fields does the request use?
POST /v1/chat/completions·deepseek/deepseek-v3.1-terminus:model,messages,stream,modalities,providerPOST /v1/messages·deepseek/deepseek-v3.1-terminus:model,messages,max_tokens,stream- What limits apply?
POST /v1/chat/completions·deepseek/deepseek-v3.1-terminus:messages.min_items:1