DeepSeek API Calls

Official source

Based on DeepSeek API Docs and Create Chat Completion. DeepSeek uses an OpenAI-compatible Chat Completions shape and commonly uses the openai Python package.

Legacy model migration has a fixed deadline

The official home page checked on 2026-07-22 scheduled deepseek-chat and deepseek-reasoner for deprecation at 2026-07-24 15:59 UTC. During compatibility, they correspond respectively to non-thinking and thinking modes of deepseek-v4-flash. Do not use legacy names as new defaults. A controlled migration explicitly sets and evaluates thinking / reasoning_effort, tool calls, context, and cost—not just a model string.

Main capabilities

FormUse
client.chat.completions.create()Text, multi-turn history, thinking mode, JSON, and function calls.
stream=TrueStream text and thinking content.
response_format={"type": "json_object"}JSON mode.
tools=[...]Function Calling.

Client, text, and history

python -m pip install --upgrade openai
$env:DEEPSEEK_API_KEY = Read-Host 'DEEPSEEK_API_KEY' -MaskInput
import os
from openai import OpenAI
 
client = OpenAI(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com",
)
 
messages = [
    {"role": "system", "content": "You are a concise technical teacher."},
    {"role": "user", "content": "Explain an API call in three points."},
]
response = client.chat.completions.create(
    model="deepseek-v4-flash", messages=messages
)
assistant_text = response.choices[0].message.content
print(assistant_text, response.usage)
 
messages.extend([
    {"role": "assistant", "content": assistant_text},
    {"role": "user", "content": "Give an append example."},
])
second = client.chat.completions.create(
    model="deepseek-v4-flash", messages=messages
)
print(second.choices[0].message.content)

The API is stateless: preserve and resend ordered history. deepseek-v4-flash is the teaching default; select a stronger model only after checking current model documentation. Do not guess API model IDs from a chat-product display name.

Thinking, streaming, and JSON

thoughtful = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=[{"role": "user", "content": "Compare merge sort and quicksort."}],
    reasoning_effort="high",
    extra_body={"thinking": {"type": "enabled"}},
)
 
stream = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "Write a Python API study plan."}],
    stream=True,
)
for chunk in stream:
    if chunk.choices:
        delta = chunk.choices[0].delta
        if delta.content:
            print(delta.content, end="", flush=True)

Thinking configuration, supported effort levels, and returned fields are model-specific. Use extra_body for DeepSeek-specific extensions rather than treating them as standard OpenAI SDK arguments. A streaming reasoning model can expose reasoning_content through the SDK; do not display internal reasoning to an end user or feed it into subsequent conversation unless the current model documentation explicitly requires it.

import json
 
response = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "Return a JSON study plan with topic, days, and tasks."}],
    response_format={"type": "json_object"},
)
data = json.loads(response.choices[0].message.content)
print(data["tasks"])

JSON mode still requires a prompt that explicitly requests JSON plus local json.loads() and business-field validation.

Function Calling

import json
 
 
def get_weather(city: str) -> dict:
    return {"city": city, "temperature": 25, "unit": "celsius"}
 
 
tools = [{"type": "function", "function": {
    "name": "get_weather",
    "description": "Look up weather for a city.",
    "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
}}]
messages = [{"role": "user", "content": "What is the temperature in Shanghai now?"}]
first = client.chat.completions.create(
    model="deepseek-v4-pro", messages=messages, tools=tools
)
assistant_message = first.choices[0].message
messages.append(assistant_message)
for tool_call in assistant_message.tool_calls or []:
    if tool_call.function.name != "get_weather":
        raise ValueError("unknown tool")
    arguments = json.loads(tool_call.function.arguments)
    result = get_weather(**arguments)
    messages.append({
        "role": "tool", "tool_call_id": tool_call.id,
        "content": json.dumps(result, ensure_ascii=False),
    })
if assistant_message.tool_calls:
    final = client.chat.completions.create(
        model="deepseek-v4-pro", messages=messages, tools=tools
    )
    print(final.choices[0].message.content)

Validate tool arguments, authorization, and side-effect approval before execution. Process every returned call, return one tool_call_id-matched tool message per call, then request a final answer. A missing history, an unreturned tool result, or unvalidated JSON breaks the protocol.

Parameters, failures, and sources

ParameterMeaning
temperatureRandomness; not all thinking models recommend changing it.
max_tokensMaximum output length.
streamStream response chunks.
response_formatRequest JSON output.
tools / tool_choiceOffer and control tools.
extra_bodyPass DeepSeek-specific extensions.

Capture openai.AuthenticationError, RateLimitError, APITimeoutError, APIConnectionError, and APIStatusError; typical causes are key/quota, rate limit, stale model ID, and incorrect base_url. Do not omit base_url, treat DeepSeek extensions as universal SDK parameters, drop multi-turn history, skip JSON validation, or fail to return tool results.

Return to Vendor AI API Reference Index; use API Learning Path for HTTP reliability.