deepseek-v4-pro answers with a different model on Monday, and your input cost drops 77% when it does
Two DeepSeek model IDs already return something other than what you asked for. A third joins them at 04:00 UTC on 14 September. The substitution is cheaper than the model it replaces, which means spend alerting cannot see it: input falls from $0.66 to $0.15 per million tokens and the graph reads as a saving. Here are the three strings to grep for, the check to run before Monday, and the two windows each weekday where the same request costs double.
Three strings, if they appear anywhere in your code, config, or a model= field in a notebook you have not opened since August:
deepseek-v4-flash
deepseek-v4-flash-vision-exp
deepseek-v4-pro
The first two stopped pointing at the models they name yesterday. The third stops on Monday. All three keep working, keep returning 200, and keep producing plausible output, which is the part worth slowing down for.
DeepSeek released V4.1-Flash on 10 September and published the retirement in the same change log entry. The wording for the first two is that the previous-generation models "have been retired; for compatibility, the model names deepseek-v4-flash and deepseek-v4-flash-vision-exp are temporarily routed to V4.1 Flash." For the third:
After 12:00 Beijing Time on September 14, 2026, and until the future release of V4.1 Pro, all requests to
deepseek-v4-prowill be routed to V4.1 Flash and billed at the V4.1 Flash price.
Beijing is UTC+8, so that is 04:00 UTC on Monday 14 September. If you deploy on a Monday morning European time, the cutover happens before you sit down.
The bill moves the wrong way
Here is the part that makes this different from an ordinary deprecation, and the reason spend monitoring will not catch it.
The replacement is cheaper than the model it replaces, and DeepSeek is explicit that requests to the old ID will be "billed at the V4.1 Flash price". These are the two rows from the pricing page as they read on 11 September, per million tokens, off-peak rate first:
| cache-hit input | cache-miss input | output | |
|---|---|---|---|
deepseek-v4-pro (V4-Pro-0813) | $0.022 / $0.044 | $0.66 / $1.32 | $1.98 / $3.96 |
deepseek-flash (V4.1-Flash) | $0.003 / $0.006 | $0.15 / $0.30 | $0.60 / $1.20 |
Cache-miss input falls 77 percent. Output falls 70 percent. Cache-hit input falls 86 percent.
So consider what your dashboards do on Monday afternoon. A cost-anomaly alert fires on spend going up. A weekly spend review looks for the line that grew. A budget guard trips at a ceiling. Every one of those instruments is pointed in the opposite direction from the event. What they will show is a large, sudden, unexplained reduction in DeepSeek spend, arriving on a Monday, with no deploy of yours attached to it.
That is not a hypothetical failure of attention. A 77 percent cost reduction with no corresponding change on your side is exactly the kind of graph that gets screenshotted approvingly and not investigated. The substitution is invisible to the only automated instrument most teams have pointed at their model provider.
The second-order version is worse if you route through a gateway. If you run LiteLLM or a similar proxy with per-model budgets and fallbacks, a model that suddenly costs a quarter as much reorders whatever cost-based routing you configured. The cheap tier just got cheaper, and the router does not know the weights behind the label changed.
What to run before Monday
Start with the strings, because the list of places a model ID hides is longer than the list of places you remember putting it:
grep -rn --include='*.py' --include='*.ts' --include='*.js' --include='*.go' \
--include='*.rs' --include='*.rb' --include='*.java' --include='*.yaml' \
--include='*.yml' --include='*.toml' --include='*.json' --include='*.env*' \
--include='*.ipynb' \
-e 'deepseek-v4-pro' -e 'deepseek-v4-flash' \
. 2>/dev/null
Then check the places that are not in the repository. Environment variables in your deployment platform, a model column in a database of saved configurations, a LiteLLM config.yaml, an OpenRouter route, a Zapier or n8n step, and the default in whatever internal tool a colleague built in March. The .env* and .ipynb patterns above exist because those two account for most of the hits people are surprised by.
Next, establish what you are comparing against. If you have an eval set, run it now, against deepseek-v4-pro, and keep the output. After Monday that same command measures a different model, and you will have no baseline to diff against unless you capture one in the next three days. This is the whole reason to act before the date rather than after it: the old behaviour becomes unobservable at 04:00 UTC, and a regression you cannot reproduce is a regression you cannot report.
If you do not have an eval set, a crude version is still worth more than nothing. Take twenty real requests out of your logs, run them, and save the responses to a file with today's date on it. Twenty saved pairs are enough to notice a tone shift, a format change, or a tool call that stopped being emitted.
Then decide which of two things you actually want:
Pin to the new model deliberately. Change the ID to deepseek-flash. You get the same weights you would have been given anyway, but the name in your config now matches what answers it, and the next person to read the file is not misled.
Move off the ID entirely. If V4-Pro was chosen because something about it suited your workload, note that V4.1-Flash is a different shape, not just a newer one: a 552B mixture-of-experts model on a new causal encoder-decoder architecture, activating 8B parameters on input and 16B on output. DeepSeek's own benchmark numbers put it ahead of V4-Pro, and its concurrency limit is 2,500 against V4-Pro's 500. Those are the vendor's figures, published by the vendor, and they are a reason to test rather than a reason to skip testing.
There is one more difference worth knowing before you re-baseline: V4.1-Flash accepts images and V4-Pro does not. If you are migrating in the other direction, or comparing outputs, the modality difference will show up in your results before anything else does.
The two windows that double the same request
While you are in the pricing page, there is a second thing in it that is not a deprecation and costs some people money every week. Quoting it directly:
Off-peak rates are half of the peak rates. Peak hours are 01:00 - 04:00 and 06:00 - 10:00 UTC, Monday through Friday (all other hours are off-peak).
Seven hours per weekday are charged at double. That is 35 of the week's 168 hours; the remaining 133 are off-peak, including all of Saturday and Sunday.
Now think about where scheduled work tends to land. Nightly batch jobs, nightly evals, index rebuilds, and document-processing runs get cron expressions written by someone thinking in their own timezone, and a great many of them land between 01:00 and 10:00 UTC because that is the middle of the night in Europe and the end of the day in the Americas. A job at 0 2 * * 1-5 is inside the first peak window. A job at 0 7 * * 1-5 is inside the second. Either one is paying twice the rate for work that, by its nature, nobody is waiting on.
Check what you have scheduled:
crontab -l 2>/dev/null | grep -v '^#'
and the equivalent in whatever actually runs your jobs: GitHub Actions schedule.cron, a Kubernetes CronJob schedule, an Airflow DAG interval, a Cloud Scheduler entry. The cron fields to read are minute and hour, and the question is only whether the hour falls in 01-03 or 06-09.
Moving a nightly job from 02:00 to 04:30 UTC, or from 07:00 to 11:00, halves its input and output rate for an identical workload. Nothing else about the job changes. For batch work with no human waiting on the result, that is close to a free adjustment, and it is the kind of thing that is obvious once stated and invisible until someone states it.
Two honest caveats. First, whether this peak and off-peak split is newly introduced is not something I could verify from a primary source: DeepSeek says only that "API prices have been reduced accordingly" with the V4.1-Flash release and does not publish a before-and-after table, and the archived copies of that page do not render the price grid. The table above is what the page says today, checked today. Second, halving the rate is not halving the bill if your job is dominated by cache hits, where the absolute numbers are small enough that the scheduling change may not be worth the disruption.
If you point Claude Code at DeepSeek
DeepSeek publishes an Anthropic-format base URL, https://api.deepseek.com/anthropic, and recommends it for exactly this: running Claude Code, Copilot, or OpenCode against DeepSeek models without code changes. If that is your setup, this window contained a second, unrelated thing worth knowing about.
Claude Code 2.1.265 shipped on 8 September and introduced a regression that the 2.1.268 changelog describes as "every turn failing with HTTP 400 on third-party Anthropic-compatible endpoints (ANTHROPIC_BASE_URL)", caused by a regex in the Artifact tool's input schema that those endpoints reject. Every turn, not some turns. From npm publish times, 2.1.265 went out at 19:05 UTC on 8 September and 2.1.268 landed at 18:41 UTC on 10 September: 47 hours and 36 minutes on the latest tag, with 2.1.266 and 2.1.267 both carrying the fault forward.
The reason to mention it is not the bug, which is fixed. It is that the stable dist-tag sat on 2.1.236 throughout, where it has been since 19 August, and saw none of it. You can read both tags without installing anything:
npm view @anthropic-ai/claude-code dist-tags
If you run an agent CLI against a third-party endpoint, latest is a channel where a schema detail that Anthropic's own API tolerates and a proxy does not can fail every request for two days. That is an argument for choosing your tag deliberately rather than an argument that either tag is correct.
A model ID is a routing label
A model ID at a hosted provider is a routing label. It is a promise about the request shape, the response shape, and the endpoint, and it is not a promise about the weights on the other end. DeepSeek documented this cleanly and gave notice, which is better practice than the alternative, and the underlying property is the same at every provider that serves inference: the string is stable, the thing behind it is a business decision.
The operational consequence is narrow and worth adopting generally. Treat every model ID in your configuration as a value that needs a recorded baseline and a periodic re-check, in the same way you would treat a dependency without a lockfile. Capture eval output with a date attached. When a provider's cost per request moves sharply and you did not deploy anything, that is a signal to investigate rather than a result to celebrate. And when you read a release note that describes a substitution as a compatibility convenience, the convenience is that your code keeps running, which is not the same as your code still doing what you tested.
For the calendar: deepseek-v4-flash and deepseek-v4-flash-vision-exp are already redirected. deepseek-v4-pro follows at 04:00 UTC on Monday 14 September. Three days to capture a baseline you cannot capture afterwards.
Get the next post when it ships
One email on Sunday with the new post and a short list of what shipped that week — new guides, tool updates, and a couple of links worth reading.