DeepSeek API Examples: Copy-Paste Snippets for Flash and V4-Pro
![DeepSeek API examples — five patterns card DeepSeek API examples tutorial card, subtitle 'Five copy-paste patterns covering V4 production calls', listing a minimal POST /chat/completions, streaming with stream=true (SSE), JSON output via response_format, tool calls via tools[] plus JSON Schema, and thinking mode via reasoning_effort.](https://deepseekai.guide/wp-content/uploads/2026/04/deepseek-api-examples-card.png)
You opened the DeepSeek docs, found a quickstart, and now you want the next ten things — streaming, JSON output, tool calls, thinking mode, cost math that survives a code review. This page collects DeepSeek API examples for the two current models, deepseek-flash and deepseek-v4-pro, which replaced the legacy deepseek-chat and deepseek-reasoner IDs. Every snippet targets the OpenAI-compatible endpoint at https://api.deepseek.com and uses only fields documented in DeepSeek’s API reference and guides, with notes on what breaks, what costs more than you think, and which features are still Beta. By the end you will have copy-paste code for the eight most common API patterns, plus a cost helper for both models.
What the DeepSeek API actually is

DeepSeek’s API is an HTTP service that speaks the OpenAI Chat Completions wire format. The canonical chat endpoint is POST /chat/completions against the base URL https://api.deepseek.com. DeepSeek’s official quickstart shows the same shape — a JSON body with model, messages, and the usual sampling knobs.
Two practical points before any code:
- The API is stateless. Unlike the web chat or mobile app, the API does not remember prior turns. Each request must include the full conversation history in
messages. - Two current model IDs.
deepseek-flashis served by DeepSeek-V4.1-Flash-1017 (see DeepSeek V4-Flash for the Flash line) and is the only current model with image input;deepseek-v4-prois served by DeepSeek-V4-Pro-0813 (see DeepSeek V4-Pro). Both publish MIT-licensed weights, both have a 1M-token context with output up to 384K tokens, and both run in thinking mode by default.
The legacy deepseek-chat and deepseek-reasoner IDs were scheduled for retirement on 2026-07-24 at 15:59 UTC (until then they routed to deepseek-v4-flash in non-thinking and thinking mode) and are no longer listed in DeepSeek’s docs. deepseek-v4-flash itself is now a legacy name served by DeepSeek-V4.1-Flash-1017. Migration is a one-line change to your model= argument; base_url stays put. For background on the model family see our DeepSeek V4 overview.
Example 1: Minimal request — curl and Python
The simplest possible call, with the default thinking mode. First in curl:
curl https://api.deepseek.com/chat/completions \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-flash",
"messages": [
{"role": "system", "content": "You are a terse senior engineer."},
{"role": "user", "content": "What is a MoE router, in two sentences?"}
]
}'
Then the equivalent in Python with the OpenAI SDK — no rewrites, just swap the base URL. This version switches thinking off so that the temperature setting takes effect:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ.get("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com",
)
resp = client.chat.completions.create(
model="deepseek-flash",
messages=[
{"role": "system", "content": "You are a terse senior engineer."},
{"role": "user", "content": "What is a MoE router, in two sentences?"},
],
temperature=1.3,
extra_body={"thinking": {"type": "disabled"}},
)
print(resp.choices[0].message.content)
Note temperature=1.3. DeepSeek publishes task-specific recommendations: 0.0 for code and math, 1.0 for data analysis, 1.3 for general chat and translation, 1.5 for creative writing. They apply in non-thinking mode only — thinking mode (the default) accepts temperature but ignores it. The examples below reuse this client.
If your codebase already speaks Anthropic, the API also supports the Anthropic format at a separate base URL, https://api.deepseek.com/anthropic, so the Anthropic SDK works too. More on that in our DeepSeek OpenAI SDK compatibility guide.
Example 2: Multi-turn conversation (resending history)
Because the API is stateless, you maintain the conversation client-side:
history = [
{"role": "system", "content": "You are a Postgres tutor."},
]
def ask(user_msg: str) -> str:
history.append({"role": "user", "content": user_msg})
resp = client.chat.completions.create(
model="deepseek-flash",
messages=history,
temperature=1.3,
extra_body={"thinking": {"type": "disabled"}},
)
answer = resp.choices[0].message.content
history.append({"role": "assistant", "content": answer})
return answer
print(ask("Explain CTEs in one paragraph."))
print(ask("Show a recursive example."))
Every call resends the entire history array. That sounds wasteful, but DeepSeek’s automatic context cache persists a prefix unit at the end of each request’s output, so the next turn — which resends that exact history plus a new question — can bill the older tokens at the cache-hit rate (best-effort). We dig into that further in DeepSeek context caching.
Example 3: Streaming responses
For chat UIs you want tokens as they generate. Set stream=True and iterate:
stream = client.chat.completions.create(
model="deepseek-flash",
messages=[{"role": "user", "content": "Write a haiku about caching."}],
stream=True,
temperature=1.5,
extra_body={"thinking": {"type": "disabled"}},
)
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
print(delta, end="", flush=True)
When thinking mode is on, reasoning streams in a separate delta.reasoning_content field before the final content begins, and the last chunk before data: [DONE] carries the token usage. Detailed patterns live in DeepSeek API streaming.
Example 4: Thinking mode (reasoning_effort)

The current models collapse the old “chat vs reasoner” split into a parameter on either model. Thinking is on by default with effort high; reasoning_effort takes "low", "high" or "max", and the thinking flag goes through extra_body:
resp = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[{"role": "user",
"content": "Plan a zero-downtime migration from MySQL 5.7 to 8.0."}],
reasoning_effort="high",
extra_body={"thinking": {"type": "enabled"}},
max_tokens=8192,
)
msg = resp.choices[0].message
print("REASONING:\n", msg.reasoning_content)
print("ANSWER:\n", msg.content)
The response returns reasoning_content alongside the final content. Use reasoning_effort="max" for the heaviest workloads; per the API reference, max_tokens then defaults to 128K (64K at the other thinking levels), and you can set it up to 393,216. A low max_tokens like the 8192 above can cut a long reasoning run short (finish_reason="length"). Keep thinking off for simple chat: it spends output tokens on reasoning you may not need.
Example 5: JSON mode
For structured extraction set response_format={"type": "json_object"}. JSON mode is designed to return valid JSON, but DeepSeek’s JSON Output guide notes the API may occasionally return empty content — three rules apply:
- Include the word “json” in the system or user prompt.
- Show a small example of the schema you want.
- Set
max_tokenshigh enough that output cannot be truncated mid-object.
import json
SYSTEM = """Extract invoice fields as json.
Example:
{"invoice_no": "INV-001", "total_usd": 42.50, "line_items": 3}
"""
resp = client.chat.completions.create(
model="deepseek-flash",
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": open("invoice.txt").read()},
],
response_format={"type": "json_object"},
max_tokens=2048,
temperature=0.0,
extra_body={"thinking": {"type": "disabled"}},
)
data = json.loads(resp.choices[0].message.content or "{}")
Handle the empty-content case explicitly — that or "{}" exists for a reason. More patterns in DeepSeek API JSON mode.
Example 6: Tool calling (function calling)
Tool calling uses the OpenAI-compatible schema, supported in both thinking and non-thinking modes. This version runs the full round trip; appending the assistant message object (rather than rebuilding it) keeps its reasoning_content, which thinking mode requires you to pass back whenever the request carries tools:
import json
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
def get_weather(city: str) -> str:
return f"14°C and cloudy in {city}" # replace with a real lookup
messages = [{"role": "user", "content": "Weather in Dublin?"}]
resp = client.chat.completions.create(model="deepseek-flash", messages=messages, tools=tools)
msg = resp.choices[0].message
messages.append(msg)
for call in msg.tool_calls or []:
args = json.loads(call.function.arguments) # validate before use
messages.append({"role": "tool", "tool_call_id": call.id,
"content": get_weather(**args)})
if msg.tool_calls:
resp = client.chat.completions.create(model="deepseek-flash", messages=messages, tools=tools)
print(resp.choices[0].message.content)
DeepSeek’s API reference notes that the model does not always generate valid JSON arguments and may invent parameters, so validate them before calling your function. In thinking mode, tool_choice="required" or a named tool returns a 400; leave it at the default auto or disable thinking. See DeepSeek API function calling for strict mode and multi-step loops.
Example 7: FIM completion (Beta)
Fill-In-the-Middle is for code editors and autocomplete. It runs in non-thinking mode only, is currently Beta with a 4K maximum output, and uses the /completions endpoint under the Beta base URL:
beta = OpenAI(api_key=os.environ.get("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com/beta")
resp = beta.completions.create(
model="deepseek-flash",
prompt="def fibonacci(n):\n if n < 2:\n return n\n return ",
suffix="\n\nprint(fibonacci(10))",
max_tokens=64,
)
print(resp.choices[0].text)
Example 8: Chat Prefix Completion (Beta)

When you need the model to continue from a specific opening, make the last message an assistant message with prefix: True and call the Beta base URL (the beta client from Example 7):
messages = [
{"role": "user", "content": "Write quicksort in Python."},
{"role": "assistant", "content": "```python\n", "prefix": True},
]
resp = beta.chat.completions.create(
model="deepseek-v4-pro",
messages=messages,
stop=["```"],
)
print(resp.choices[0].message.content)
Quick parameter reference
| Parameter | Type | Notes |
|---|---|---|
model |
string | deepseek-flash or deepseek-v4-pro |
temperature |
0.0–2.0 (default 1) | 0.0 code/math, 1.0 analysis, 1.3 chat, 1.5 creative; no effect in thinking mode |
top_p |
0–1 (default 1) | Model-specific: on deepseek-flash only in thinking mode (0.95–1.0); on deepseek-v4-pro only in non-thinking mode |
max_tokens |
int | 1–393,216; defaults 8K non-thinking, 64K thinking, 128K at max; set it explicitly in JSON mode |
reasoning_effort |
string | "low", "high" (default) or "max"; "none" disables thinking |
thinking |
object (via extra_body) |
{"type": "enabled"} (default) or {"type": "disabled"} |
stream / stream_options |
bool / object | SSE chunks; reasoning streams separately; usage on the last chunk |
response_format |
object | {"type": "json_object"} for JSON mode |
tools / tool_choice |
array / string or object | OpenAI-shaped function definitions; required or a named tool not supported in thinking mode |
stop |
string or array | Up to 16 stop sequences |
Cost worked example — both models
Prices as of October 2026, from DeepSeek’s official pricing page, per 1M tokens: deepseek-flash $0.006 cache-hit input / $0.30 cache-miss input / $1.20 output at peak and $0.003 / $0.15 / $0.60 off-peak; deepseek-v4-pro $0.044 / $1.32 / $3.96 at peak and $0.022 / $0.66 / $1.98 off-peak. Peak hours are 01:00–04:00 and 06:00–10:00 UTC, Monday through Friday, excluding Chinese public holidays; all other hours are off-peak.
The usage object on every response already splits the input into the two billed buckets, so the cost of a call is a few lines of code:
RATES = { # USD per 1M tokens at peak, October 2026; off-peak is half
"deepseek-flash": {"hit": 0.006, "miss": 0.30, "out": 1.20},
"deepseek-v4-pro": {"hit": 0.044, "miss": 1.32, "out": 3.96},
}
def request_cost(usage, model: str, off_peak: bool = False) -> float:
r = RATES[model]
usd = (usage.prompt_cache_hit_tokens * r["hit"]
+ usage.prompt_cache_miss_tokens * r["miss"]
+ usage.completion_tokens * r["out"]) / 1_000_000
return usd / 2 if off_peak else usd
print(request_cost(resp.usage, "deepseek-flash"))
Worked example: one call with a 2,000-token cached system prompt, a 200-token uncached user message and a 300-token response.
| Token bucket | Tokens | deepseek-flash peak / off-peak |
deepseek-v4-pro peak / off-peak |
|---|---|---|---|
| Cached input | 2,000 | $0.000012 / $0.000006 | $0.000088 / $0.000044 |
| Uncached input | 200 | $0.000060 / $0.000030 | $0.000264 / $0.000132 |
| Output | 300 | $0.000360 / $0.000180 | $0.001188 / $0.000594 |
| Total per call | $0.000432 / $0.000216 | $0.001540 / $0.000770 |
Two things people get wrong: skipping the uncached-input row (each new user message misses the cache against the system prefix), and mixing models inside one estimate. Pick one and stick with it. In thinking mode, reasoning tokens count as output (completion_tokens_details.reasoning_tokens), so the output row grows. For interactive estimates use the DeepSeek pricing calculator.
Error handling pattern
The API returns OpenAI-compatible error envelopes. The codes and finish reasons you will hit most often, per DeepSeek’s Error Codes page and API reference:
400 Invalid Format/422 Invalid Parameters— fix the request using the hints in the error message.401 Authentication Fails— wrong or missing API key.402 Insufficient Balance— top up the account.429 Rate Limit Reached— requests too fast or over the per-account concurrency limit (2,500 fordeepseek-flash, 500 fordeepseek-v4-pro); back off and retry with jitter.500 Server Error/503 Server Overloaded— retry after a brief wait.finish_reason="length"— output was truncated; raisemax_tokens.finish_reason="content_filter"— content was omitted by the content filter.finish_reason="insufficient_system_resource"— generation was interrupted for lack of inference resources; retry.
import random
import time
from openai import APIConnectionError, APIStatusError, RateLimitError
def call_with_retry(**kw):
for attempt in range(5):
try:
return client.chat.completions.create(**kw)
except (RateLimitError, APIConnectionError):
pass # 429 or network error: retry
except APIStatusError as e:
if e.status_code < 500:
raise # other 4xx: fix the request
time.sleep((2 ** attempt) + random.random())
raise RuntimeError("exhausted retries")
For a complete code-by-code playbook see DeepSeek API error codes.
Where to go next

If you are still wiring up authentication, start with our walk-through on how to get a DeepSeek API key, then the DeepSeek API getting started tutorial. For broader context on every endpoint, parameter and rate limit, the DeepSeek API docs and guides hub indexes the lot. If you need a JavaScript counterpart to the snippets above, see DeepSeek Node.js integration.
Frequently asked questions
How do I make my first DeepSeek API call?
Get an API key from the DeepSeek platform console, install the OpenAI SDK (pip install openai), and instantiate the client with base_url="https://api.deepseek.com". Then call client.chat.completions.create with model="deepseek-flash" and a messages array. Example 1 above is a minimal call. Full setup steps live in our DeepSeek API getting started tutorial.
What is the difference between deepseek-v4-flash and deepseek-v4-pro?
deepseek-v4-flash is now a legacy name: requests that use it are served by DeepSeek-V4.1-Flash-1017 and billed at the deepseek-flash price, so use deepseek-flash in new code. deepseek-flash costs $0.30 cache-miss input / $1.20 output per million tokens at peak ($0.15 / $0.60 off-peak; cache hits $0.006 / $0.003) and is the only current model with image input. deepseek-v4-pro (DeepSeek-V4-Pro-0813) costs $1.32 / $3.96 at peak ($0.66 / $1.98 off-peak; cache hits $0.044 / $0.022). Both share the 1M-token context, 384K maximum output, thinking modes, JSON mode, tool calling and streaming. Start with Flash and move a workload to Pro only if your evals show it pays off. Compare in detail at the DeepSeek models hub.
Does the DeepSeek API remember previous messages?
No. The API is stateless: every POST /chat/completions request must include the full conversation history in messages. The web chat and mobile app keep session history, but the developer API does not. Repeated prefixes are billed at the cheaper cache-hit rate automatically once they have been persisted. See DeepSeek context caching for how to structure prompts so the cache fires.
Can I use the OpenAI Python SDK with DeepSeek?
Yes. DeepSeek’s API matches the OpenAI Chat Completions wire format. Change base_url to https://api.deepseek.com, supply your DeepSeek API key and use a DeepSeek model name — existing call sites keep working, and DeepSeek-specific fields such as thinking go in extra_body. DeepSeek also supports the Responses API on the same base URL and an Anthropic-compatible surface at https://api.deepseek.com/anthropic. The compatibility caveats are catalogued in our DeepSeek OpenAI SDK compatibility notes.
Why does DeepSeek return reasoning_content in some responses?
Thinking mode is on by default, and whenever it is on — by default or with reasoning_effort="high" and extra_body={"thinking": {"type": "enabled"}} — the model returns reasoning_content alongside the final content. The reasoning field holds the chain-of-thought the model produced before answering; the content field is the user-facing answer. Pass extra_body={"thinking": {"type": "disabled"}} if you don’t want it. Legacy deepseek-reasoner produced the same shape; it was scheduled for retirement on 2026-07-24 at 15:59 UTC. More on prompt design in our DeepSeek prompt engineering guide.
Sources & Methodology
Primary sources
- Official documentationDeepSeek API — Your First API CallCanonical /chat/completions request, base URLs, current model names (fetched 25 Oct 2026)Last checked: October 25, 2026
- Official documentationDeepSeek API — Chat Completions API referenceDocumented request fields used in every example; max_tokens range/defaults; finish_reason values; tool_choice limits; usage fieldsLast checked: October 25, 2026
- Official documentationDeepSeek API — Thinking Mode, Multi-round, JSON Output, Tool Calls, FIM and Chat Prefix Completion guidesExample patterns: thinking default/effort, reasoning_content pass-back, json keyword and empty content, Beta base URL, FIM 4K max, prefix: trueLast checked: October 25, 2026
- Official documentationDeepSeek API — Error Codes400/401/402/422/429/500/503 meaningsLast checked: October 25, 2026
- Official documentationDeepSeek Models & Pricing pagePeak/off-peak rates and hours for the cost helper; concurrency limits; vision on Flash onlyLast checked: October 25, 2026
Methodology
Pricing figures were checked against the official DeepSeek pricing page and normalised into estimated monthly costs using sample token usage scenarios. Actual costs may vary depending on caching, input/output ratio, regional availability, and provider updates.
Data confidence
High — figures checked directly against the official pricing page on the review date.
Editorial note
The site's pricing dataset is fetched daily from DeepSeek's official pricing page; this article reflects the prices on the date shown above.
