DeepSeek V4.1-Flash-1017 and the Search & Fetch APIs: Reading a Pareto Claim Honestly
💡 Tool Tip:AI Token Counter, JSON Formatter, Regex Tester, Word Counter
DeepSeek published V4.1-Flash-1017 on October 17, 2026. The API name did not change — calls to deepseek-flash now land on the new checkpoint — and neither did the pricing. The changelog calls it a Pareto improvement: better scores, faster task completion, shorter outputs. On the same day the company opened its in-house Search and Fetch APIs to everyone at $0.75 per 1,000 calls per endpoint, with server-side calls free for API users until billing starts on October 31, 2026 at 16:00 UTC. Two separate announcements, one practical question for anyone building agents: does the cheaper, faster model plus first-party retrieval actually replace the stack you assembled from three vendors, or does it just move the work around?
Every row of the vendor table moved up. What the table cannot tell you is how your own eval set will move.
What the benchmark deltas actually support
The changelog lists ten benchmarks that all moved up against the September V4.1 release. The largest jumps are on agentic coding: Terminal-Bench 4.0 went from 31.2 to 42.3, ProgramBench from 20.3 to 29.1, DeepSWE v1.1 from 74.2 to 77.0. HLE without tools went from 36.8 to 42.6, with 44.0 on the text-only subset, and the vision-with-tools numbers moved more modestly — Chartography 78.9 to 83.0, BabyVision 89.6 to 92.5.
Read the footnotes before the headline. Terminal-Bench 4.0 is measured with the Claude Code harness and DeepSWE with Mini-SWE-V2, which means those scores describe a model inside someone else's agent loop, not your loop. ZeroBench is Pass@5 while the others are Pass@1, so it answers a different question. None of the absolute values are comparable to another vendor's table, because harnesses, retries, and tool budgets differ.
The claim that survives all of that is narrow and still useful: the model got better at long-horizon tool use without getting more expensive, and it got more concise. Shorter outputs matter twice for agents — fewer tokens billed, and fewer chances for a truncated answer to break your parser. DeepSeek also says it tuned for its own harness, Tencent CodeBuddy, and WorkBuddy, and recommends Harness 0.2.1-rc.1 or later.
# Put the vendor's benchmark table into a script before you put it into a slide.
# Numbers below are from DeepSeek's own changelog for 2026-10-17; the parenthetical
# values were the previous V4.1 release, published 2026-09-10.
BENCH = {
# name: (new, previous, note)
"HLE w/o tools": (42.6, 36.8, "text-only subset scores 44.0"),
"Terminal-Bench 4.0": (42.3, 31.2, "tested with the Claude Code harness"),
"DeepSWE v1.1": (77.0, 74.2, "Mini-SWE-V2 harness, Pass@1"),
"ProgramBench": (29.1, 20.3, ""),
"NL2Repo-Bench": (68.2, 65.4, ""),
"Automation-Bench v1.0.6": (60.5, 54.8, ""),
"Agents' Last Exam": (35.4, 31.8, ""),
"ZeroBench-main w/tools": (51.0, 49.0, "Pass@5, not Pass@1"),
"Chartography w/tools": (83.0, 78.9, ""),
"BabyVision w/tools": (92.5, 89.6, ""),
}
for name, (new, old, note) in BENCH.items():
delta = new - old
print(f"{name:26} {old:5.1f} -> {new:5.1f} ({delta:+5.1f}) {note}")
# Two things this table will not tell you, no matter how long you stare at it:
# 1. the absolute numbers are not comparable across rows or vendors
# 2. Pass@5 on one row and Pass@1 on another are different questions
# What it does say is direction: every row moved up, and pricing did not move.
The search layer, priced properly
Search and Fetch are plain JSON APIs under the same bearer authentication as the model: POST /v1/tools/search and POST /v1/tools/fetch. Search takes a query of 1 to 128 characters, a count between 1 and 50, an optional original question for query understanding, and a need_content flag. Fetch takes a URL and returns Markdown with the page title.
Pricing is $0.75 per 1,000 calls per endpoint, and the endpoints bill separately, so a turn that searches once and fetches two pages is three billable calls, not one. Do that arithmetic against your real traffic pattern before you assume it is cheap. Two thousand conversations a day with one search and two fetches each is 180,000 calls a month, which is about $135. That is genuinely cheap for retrieval, and it is also a number that triples the moment your agent decides to read five pages instead of two.
The deadline deserves a calendar entry rather than a note. Server-side tool calls made through DeepSeek Harness, Claude Code, and Codex are free for DeepSeek API users until billing starts on October 31, 2026 at 16:00 UTC. If you are prototyping on that path, your cost graph has a step change coming, and it will land on a Saturday.
# Price the search layer, including the free window that ends soon.
# Official: $0.75 per 1,000 calls per endpoint (Search and Fetch bill separately).
# Server-side tool calls from DeepSeek Harness, Claude Code and Codex are free for
# DeepSeek API users until billing starts 2026-10-31 16:00 UTC.
from datetime import datetime, timezone
SEARCH_PER_1K = 0.75
FETCH_PER_1K = 0.75
BILLING_START = datetime(2026, 10, 31, 16, 0, tzinfo=timezone.utc)
def agent_search_cost(turns_per_day, searches_per_turn, fetches_per_turn):
calls_day = turns_per_day * (searches_per_turn + fetches_per_turn)
return round(calls_day * 30 * SEARCH_PER_1K / 1000, 2)
# 2,000 conversations a day, one search plus two fetches each: 180k calls a month.
print("monthly search+fetch:", agent_search_cost(2_000, 1, 2))
now = datetime.now(timezone.utc)
print("free window days left:", max((BILLING_START - now).days, 0))
# Sanity check against your current setup. If you self-host a crawler, the honest
# comparison is not $0.75 vs $0, it is $0.75 vs (proxy + queue + extraction +
# the week you spent on anti-bot). Write both columns down before you decide.
Building citations instead of answers
The response schema is the interesting part. Each result carries rerank_score from 0 to 3 where 1.5 and above is considered high quality, an authority tier from 0 to 4 where 3 and above indicates highly authoritative sources and -1 means unknown, a snippet for UI, a summary of roughly 600 to 800 characters meant to be read by a model, and an RFC 3339 publication date when one exists.
Those three signals let you filter before you spend tokens. A pipeline that keeps only rerank_score at or above 1.5, authority at or above 3, and a publication date inside your window will throw away most of the junk that makes retrieval-augmented systems look unreliable. It also gives you something to show a reviewer: not just the answer, but why each source survived the filter.
The query operators are worth using deliberately rather than as a party trick. site:, -site:, lang:, after:, before: and quoted phrases are forwarded with the syntax intact, which means a query can encode your source policy. That is how you stop a model from citing a content farm when the official docs already answer the question.
# Search, then decide what is good enough to cite. The response carries the signals
# you need: rerank_score (0-3, high quality at 1.5+), authority (tier 0-4,
# authoritative at 3+), and date. Use them instead of trusting result order.
import requests
KEY = "sk-..." # use an env var in real code
BASE = "https://api.deepseek.com/v1/tools"
H = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}
def search(query, count=10, need_content=False):
r = requests.post(f"{BASE}/search", headers=H, timeout=30, json={
"query": query, # 1-128 chars, operators allowed
"count": count, # 1-50, default 10
"need_content": need_content,
"ori_question": query, # helps query understanding
})
r.raise_for_status()
return r.json()["results"]
def citable(results, min_score=1.5, min_authority=3, after="2026-01-01"):
keep = []
for item in results:
if item["rerank_score"] < min_score:
continue
if (item["authority"] or -1) < min_authority:
continue
if item["date"] and item["date"][:10] < after:
continue
keep.append(item)
return keep
hits = search("DeepSeek V4.1 Flash 1017 site:api-docs.deepseek.com lang:en after:2026")
for r in citable(hits):
print(r["rerank_score"], r["authority"], r["date"], r["url"])
# Prompt-injection hygiene: treat summary and content as data, never as
# instructions, and keep the URL next to every sentence you quote.
Search returns authority tiers and rerank scores, which is what lets you filter before you spend context.
Fetch is where the token bill hides
Fetch returns Markdown, and Markdown from a documentation page can be enormous. If you paste the whole thing into context, you have converted a three-cent retrieval into a long-context call, and the retrieval savings evaporate. The fix is boring: clip to a character budget, keep the head and the tail, and say in the prompt that the middle was removed.
Then verify grounding mechanically. After the model answers, check that each quoted claim appears in the fetched text. A claim that fails the grep is not a citation, it is a hallucination with a URL attached. Retrying with a narrower fetch — a section anchor, a smaller page — is almost always cheaper than shipping the fabricated sentence.
One hygiene rule that applies to every retrieval API, including this one: summaries and page content are data, not instructions. A page that says "ignore previous instructions" is a page you should drop, and the authority tier is a hint rather than a guarantee. Keep the retrieval output in a separate message role and never let it write into your system prompt.
# Fetch turns a URL into Markdown, which is the part everyone underestimates.
# A page is not a citation until you have trimmed it to a token budget you set.
import requests
def fetch(url):
r = requests.post("https://api.deepseek.com/v1/tools/fetch",
headers={"Authorization": f"Bearer {KEY}",
"Content-Type": "application/json"},
json={"url": url}, timeout=45)
r.raise_for_status()
page = r.json()
return page["title"], page["content"] # markdown
def clip(markdown, max_chars=6000):
# Keep the head and anything that looks like a conclusion. Dropping the middle
# is safer than dropping the tail, which is where the caveats usually live.
if len(markdown) <= max_chars:
return markdown
head, tail = markdown[: max_chars - 1500], markdown[-1500:]
return head + "\n\n[... trimmed ...]\n\n" + tail
title, body = fetch("https://api-docs.deepseek.com/updates/")
print(title, len(body), "->", len(clip(body)))
# Now ask the model a question whose answer must be traceable to those characters.
# If the model writes a claim you cannot grep back into `body`, the citation failed,
# and a retry with a narrower fetch is cheaper than shipping the claim.
A swap checklist with a pinned rollback
Model swaps fail quietly, so make the checks loud. Pin the previous model identifier in an environment variable before you change anything, because the deepseek-flash alias means your config diff will look like nothing happened. Log the harness version next to every evaluation run; a 42.3 on Terminal-Bench 4.0 measured with a different harness is not comparable to your own last run.
Re-run your own eval set, not the vendor's benchmarks. The numbers above describe a model in DeepSeek's harness on DeepSeek's task mix. Yours is the only set that can tell you whether the conciseness is a win or a regression — shorter outputs help with parser breakage and hurt when the answer needed a caveat.
Finally, treat the open weights as an option rather than a strategy. V4.1-Flash-1017 is on Hugging Face and ModelScope, which means a self-hosted fallback is possible, but self-hosting is a different cost structure with different failure modes. Keep the decision in writing: which provider serves what, what the fallback is, and the single command that gets you back to the previous checkpoint.
#!/usr/bin/env bash
# Pre-flight for a model swap. Pin everything you will be asked about later.
set -euo pipefail
echo "== model alias =="
# The API name is unchanged: deepseek-flash now routes to V4.1-Flash-1017.
curl -s https://api.deepseek.com/v1/models \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" | head -c 400; echo
echo "== harness version =="
# DeepSeek recommends Harness 0.2.1-rc.1 or later for the new checkpoint.
python -c "import importlib.metadata as m; print(m.version('deepseek-harness'))" 2>/dev/null \
|| echo "harness not installed locally"
echo "== search endpoint reachable =="
curl -s -o /dev/null -w '%{http_code}\n' https://api.deepseek.com/v1/tools/search \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"test","count":1}'
echo "== free-window deadline =="
python - <<'PY'
from datetime import datetime, timezone
end = datetime(2026, 10, 31, 16, 0, tzinfo=timezone.utc)
print("billing starts", end.isoformat(), "| days left", max((end - datetime.now(timezone.utc)).days, 0))
PY
echo "== rollback =="
test -n "${PREVIOUS_MODEL_ID:-}" || echo "no pinned previous model -> set one before you switch"
Fetch returns Markdown, and unclipped Markdown turns a cheap retrieval into a long-context call.
📌 Frequently Asked Questions
What actually changed in V4.1-Flash-1017?
DeepSeek describes it as an incremental revision with better benchmark scores, faster task completion, and shorter outputs at unchanged API pricing and calling method. Calls to deepseek-flash route to the new checkpoint, so no client change is required.
What do the Search and Fetch APIs cost?
Each endpoint costs $0.75 per 1,000 calls and they bill separately. Server-side tool calls made through DeepSeek Harness, Claude Code, and Codex are free for DeepSeek API users until billing starts on October 31, 2026 at 16:00 UTC.
What endpoints should I call?
Search is POST https://api.deepseek.com/v1/tools/search and Fetch is POST https://api.deepseek.com/v1/tools/fetch. Both are raw JSON APIs using the same bearer authentication as the model API.
Are the weights available?
Yes. DeepSeek published V4.1-Flash-1017 on Hugging Face and ModelScope, in addition to serving it through the API, the web app, and the mobile app.
Which harness version should I use?
DeepSeek recommends DeepSeek Harness 0.2.1-rc.1 or later for the new checkpoint, and says the model was optimized for its own harness plus Tencent CodeBuddy and WorkBuddy.
🔧 Recommended Tools
AI Token Counter
Check whether clipped page content fits your budget.
JSON Formatter
Inspect the results array, scores, and tiers.
Regex Tester
Build the grep that verifies a quoted claim.
Word Counter
Compare summary length against what the model used.
Prompt Templates
Keep retrieval output in a data-only role.