diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16a573f..d7720f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
# Changelog
+## 0.5.3 - 2026-09-18
+
+### Fixed
+
+- **The V4.1 cutover is 2026-09-10 04:00 UTC, as DeepSeek published it.**
+ The release note says "New pricing takes effect at 04:00 UTC on Sept 10,
+ 2026" (12:00 Beijing). 0.5.0 guessed 00:00 Beijing from a pattern; 0.5.1
+ guessed 11:00 UTC from when our docs mirror first saw the new pricing page,
+ which lagged the bill by hours. Requests between 04:00 and 11:00 UTC that
+ day were billed at the new Flash price and are now metered at it.
+ `stateVersion` 5.
+
## 0.5.2 - 2026-09-18
### Changed
diff --git a/README.md b/README.md
index 318474f..60808ef 100644
--- a/README.md
+++ b/README.md
@@ -167,12 +167,12 @@ by V4.1 Flash and billed at the Flash price, so the meter bills a
echoes back whatever name you sent, so the echo cannot say which model
billed; the dispatch time can.
-DeepSeek published a date, not an instant. The meter cuts over at
-**2026-09-10 11:00 UTC**: our docs mirror saw the old card on the pricing
-page at 04:50 UTC that day and the new one at 11:27 UTC, and this is the
-last whole hour before the new one was seen, so an error can only
-overstate a bill. A probe at 2026-09-11 17:03 UTC settled on the new card
-to the cent.
+The new price took effect at **2026-09-10 04:00 UTC** (12:00 Beijing),
+as DeepSeek's [release note](https://api-docs.deepseek.com/news/news260910)
+states; the meter cuts over at exactly that instant. The pricing page
+itself lagged by hours, so don't date a price change by when its reference
+page moved. A probe at 2026-09-11 17:03 UTC settled on the new card to the
+cent.
**Weekends have been off-peak all day since 2026-08-22 16:00 UTC**
(00:00 Beijing, Sunday 23 August), on the *Beijing* calendar — so the
@@ -204,7 +204,7 @@ cheapest token, which is the one an agent sends most of.
The retired V4 Flash card, kept to reprice history
Billed by `deepseek-v4-flash` and `deepseek-v4-flash-vision-exp` until
-**2026-09-10 11:00 UTC**; both names bill as `deepseek-flash` since.
+**2026-09-10 04:00 UTC**; both names bill as `deepseek-flash` since.
| | cache hit | cache miss | output |
|---|---|---|---|
diff --git a/README.zh.md b/README.zh.md
index 8f677f3..736f60f 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -127,7 +127,7 @@ DeepSeek 公布的是**两张互相独立的价目表**——国际站按美元
**`deepseek-flash` 即 DeepSeek-V4.1-Flash,自 2026-09-10 起。** 它取代了 V4 Flash 和 V4 Flash Vision Exp(视觉能力已内置),Flash 价格随之下调:空闲时段缓存未命中 ¥1.5 -> ¥1,输出 ¥4.5 -> ¥4,缓存命中 ¥0.05 -> ¥0.02。旧模型名仍可调用,由 V4.1 Flash 提供服务并按 Flash 价格计费,所以切换之后发出的 `deepseek-v4-flash` 请求,电表按 `deepseek-flash` 计费;切换之前的仍按旧价。API 返回的模型名只是回显你发出的名字,看不出实际由谁计费;发出时间可以。
-DeepSeek 公布的是日期,不是时刻。电表在 **UTC 2026-09-10 11:00** 切换:我们的文档镜像当天 UTC 04:50 抓到的价格页还是旧价,11:27 抓到新价,这里取看到新价之前最后一个整点,所以误差只会让账单偏高,不会偏低。UTC 2026-09-11 17:03 的账单探测按新价结算,分毫不差。
+新价格于 **北京时间 2026 年 9 月 10 日 12:00**(UTC 04:00)生效,见 DeepSeek 的[发布公告](https://api-docs.deepseek.com/zh-cn/news/news260910),电表就在这一刻切换。价格页本身晚了好几个小时才更新,所以别用参考页面的变动时间去推断调价时刻。UTC 2026-09-11 17:03 的账单探测按新价结算,分毫不差。
已退役的统一价,保留用于回算历史
@@ -146,7 +146,7 @@ DeepSeek 公布的是日期,不是时刻。电表在 **UTC 2026-09-10 11:00**
已退役的 V4 Flash 价目,保留用于回算历史
-`deepseek-v4-flash` 与 `deepseek-v4-flash-vision-exp` 在 **UTC 2026-09-10 11:00** 之前按此计费,之后均按 `deepseek-flash` 计费。
+`deepseek-v4-flash` 与 `deepseek-v4-flash-vision-exp` 在 **UTC 2026-09-10 04:00**(北京时间 12:00)之前按此计费,之后均按 `deepseek-flash` 计费。
| | 缓存命中 | 缓存未命中 | 输出 |
|---|---|---|---|
diff --git a/docs/index.html b/docs/index.html
index efe3d2a..d744f01 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -656,20 +656,18 @@ Saving mode — let the meter talk back
* DeepSeek-V4.1-Flash model and billed at the Flash price" (pricing page,
* footnote 1; changelog 2026-09-10). The same release cut the Flash price.
*
- * The instant is inferred, not published. The changelog gives a date. Our
- * docs mirror (thevibeworks/deepseek-docs) fetched the pricing page with the
- * OLD card at 2026-09-10T04:50Z and the new one at 11:27Z, so the cutover is
- * in that gap; this takes the last whole hour before the new card was seen.
- * An error inside the gap can only overstate a bill, never understate it.
- * The same instant is used by thevibeworks/deepseek-cli, so the two meters
- * agree. A bill probe at 2026-09-11T17:03Z settled on the new card to the
- * cent (¥0.58 billed, ¥0.583 new, ¥0.749 old).
+ * Published, in the release note rather than the changelog: "New pricing
+ * takes effect at 04:00 UTC on Sept 10, 2026" (news260910; "2026 年 9 月 10
+ * 日 12:00 开始生效" in the Chinese one). A bill probe at 2026-09-11T17:03Z
+ * settled on the new card to the cent (¥0.58 billed, ¥0.583 new, ¥0.749 old).
*
- * 0.5.0 shipped 2026-09-09T16:00Z on the pattern that DeepSeek's price
- * changes land at 00:00 Beijing. The page itself says otherwise: it still
- * carried the old card thirteen hours later.
+ * Two earlier guesses, both wrong and both kept here as the lesson: 0.5.0
+ * took 00:00 Beijing from the pattern of earlier price changes, and 0.5.1
+ * took 11:00 UTC from when our docs mirror first SAW the new pricing page.
+ * The page lagged the bill by hours. Read the vendor's announcement before
+ * inferring anything from its reference pages.
*/
-const V41_FLASH_FROM = Date.UTC(2026, 8, 10, 11, 0, 0)
+const V41_FLASH_FROM = Date.UTC(2026, 8, 10, 4, 0, 0)
/**
* Retired model ids: the rates they billed at while they existed, and the
diff --git a/docs/pricing.json b/docs/pricing.json
index aa982eb..2bb2cbe 100644
--- a/docs/pricing.json
+++ b/docs/pricing.json
@@ -1,6 +1,6 @@
{
"schema": "dsh-meter/pricing@2",
- "generator": "@dshworks/dsh-meter@0.5.2",
+ "generator": "@dshworks/dsh-meter@0.5.3",
"homepage": "https://dsh.works/dsh-meter/",
"source": {
"usd": "https://api-docs.deepseek.com/quick_start/pricing",
@@ -372,8 +372,8 @@
"retiredModels": {
"deepseek-v4-flash": {
"servedBy": "deepseek-flash",
- "since": "2026-09-10T11:00:00.000Z",
- "sinceEpochMs": 1789038000000,
+ "since": "2026-09-10T04:00:00.000Z",
+ "sinceEpochMs": 1789012800000,
"note": "Requests under this name are served by deepseek-flash and billed at its rates from `since`. The rates below are what the name billed before that, for repricing history only.",
"ratesBefore": {
"flat": {
@@ -416,8 +416,8 @@
},
"deepseek-v4-flash-vision-exp": {
"servedBy": "deepseek-flash",
- "since": "2026-09-10T11:00:00.000Z",
- "sinceEpochMs": 1789038000000,
+ "since": "2026-09-10T04:00:00.000Z",
+ "sinceEpochMs": 1789012800000,
"note": "Requests under this name are served by deepseek-flash and billed at its rates from `since`. The rates below are what the name billed before that, for repricing history only.",
"ratesBefore": {
"offpeak": {
diff --git a/lib/client.js b/lib/client.js
index 497c5ec..3f06094 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -111,20 +111,18 @@ const RATES = {
* DeepSeek-V4.1-Flash model and billed at the Flash price" (pricing page,
* footnote 1; changelog 2026-09-10). The same release cut the Flash price.
*
- * The instant is inferred, not published. The changelog gives a date. Our
- * docs mirror (thevibeworks/deepseek-docs) fetched the pricing page with the
- * OLD card at 2026-09-10T04:50Z and the new one at 11:27Z, so the cutover is
- * in that gap; this takes the last whole hour before the new card was seen.
- * An error inside the gap can only overstate a bill, never understate it.
- * The same instant is used by thevibeworks/deepseek-cli, so the two meters
- * agree. A bill probe at 2026-09-11T17:03Z settled on the new card to the
- * cent (¥0.58 billed, ¥0.583 new, ¥0.749 old).
+ * Published, in the release note rather than the changelog: "New pricing
+ * takes effect at 04:00 UTC on Sept 10, 2026" (news260910; "2026 年 9 月 10
+ * 日 12:00 开始生效" in the Chinese one). A bill probe at 2026-09-11T17:03Z
+ * settled on the new card to the cent (¥0.58 billed, ¥0.583 new, ¥0.749 old).
*
- * 0.5.0 shipped 2026-09-09T16:00Z on the pattern that DeepSeek's price
- * changes land at 00:00 Beijing. The page itself says otherwise: it still
- * carried the old card thirteen hours later.
+ * Two earlier guesses, both wrong and both kept here as the lesson: 0.5.0
+ * took 00:00 Beijing from the pattern of earlier price changes, and 0.5.1
+ * took 11:00 UTC from when our docs mirror first SAW the new pricing page.
+ * The page lagged the bill by hours. Read the vendor's announcement before
+ * inferring anything from its reference pages.
*/
-const V41_FLASH_FROM = Date.UTC(2026, 8, 10, 11, 0, 0)
+const V41_FLASH_FROM = Date.UTC(2026, 8, 10, 4, 0, 0)
/**
* Retired model ids: the rates they billed at while they existed, and the
diff --git a/lib/core.js b/lib/core.js
index d190dd7..4a89853 100644
--- a/lib/core.js
+++ b/lib/core.js
@@ -102,20 +102,18 @@ export const RATES = {
* DeepSeek-V4.1-Flash model and billed at the Flash price" (pricing page,
* footnote 1; changelog 2026-09-10). The same release cut the Flash price.
*
- * The instant is inferred, not published. The changelog gives a date. Our
- * docs mirror (thevibeworks/deepseek-docs) fetched the pricing page with the
- * OLD card at 2026-09-10T04:50Z and the new one at 11:27Z, so the cutover is
- * in that gap; this takes the last whole hour before the new card was seen.
- * An error inside the gap can only overstate a bill, never understate it.
- * The same instant is used by thevibeworks/deepseek-cli, so the two meters
- * agree. A bill probe at 2026-09-11T17:03Z settled on the new card to the
- * cent (¥0.58 billed, ¥0.583 new, ¥0.749 old).
+ * Published, in the release note rather than the changelog: "New pricing
+ * takes effect at 04:00 UTC on Sept 10, 2026" (news260910; "2026 年 9 月 10
+ * 日 12:00 开始生效" in the Chinese one). A bill probe at 2026-09-11T17:03Z
+ * settled on the new card to the cent (¥0.58 billed, ¥0.583 new, ¥0.749 old).
*
- * 0.5.0 shipped 2026-09-09T16:00Z on the pattern that DeepSeek's price
- * changes land at 00:00 Beijing. The page itself says otherwise: it still
- * carried the old card thirteen hours later.
+ * Two earlier guesses, both wrong and both kept here as the lesson: 0.5.0
+ * took 00:00 Beijing from the pattern of earlier price changes, and 0.5.1
+ * took 11:00 UTC from when our docs mirror first SAW the new pricing page.
+ * The page lagged the bill by hours. Read the vendor's announcement before
+ * inferring anything from its reference pages.
*/
-export const V41_FLASH_FROM = Date.UTC(2026, 8, 10, 11, 0, 0)
+export const V41_FLASH_FROM = Date.UTC(2026, 8, 10, 4, 0, 0)
/**
* Retired model ids: the rates they billed at while they existed, and the
diff --git a/lib/index.js b/lib/index.js
index c9eaa18..7a379e3 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -73,10 +73,10 @@ export function apply(ctx, config) {
init,
apply: foldEvent,
// 3: 0.5.0 re-attributes retired Flash ids to `deepseek-flash` after the
- // V4.1 cutover and bills `assistant/attempt`. 4: 0.5.1 moved that
+ // V4.1 cutover and bills `assistant/attempt`. 4, 5: 0.5.1 and 0.5.3 moved that
// cutover. A fold cached under an older version would keep pricing
// those requests by the old rule forever.
- stateVersion: 4,
+ stateVersion: 5,
// Two spellings of one contract. `@deepseek-ai/dsh-session-projection`
// 0.1.1-rc.1 split the single `schema`/`view` pair into a host-side
diff --git a/package.json b/package.json
index 3ce9cad..b1b12db 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "@dshworks/dsh-meter",
"description": "The DeepSeek time-of-use meter for dsh: what this session cost, which tariff is running, when it flips, and the account balance behind it — one line under the composer.",
- "version": "0.5.2",
+ "version": "0.5.3",
"license": "MIT",
"homepage": "https://dsh.works/dsh-meter/",
"publishConfig": {
diff --git a/tests/ledger.spec.mjs b/tests/ledger.spec.mjs
index 943253a..d6719c0 100644
--- a/tests/ledger.spec.mjs
+++ b/tests/ledger.spec.mjs
@@ -132,11 +132,12 @@ describe('the fold', () => {
})
describe('the V4.1 Flash retirement', () => {
- /* Weekday off-peak on both sides of the cutover: 2026-09-10 is a
- * Thursday, and 04:50 (the mirror's last old-card read) and 11:30 UTC
- * are outside both peak windows. */
- const oldDays = utc(2026, 9, 10, 4, 50)
- const newDays = utc(2026, 9, 10, 11, 30)
+ /* Weekday off-peak on both sides of the cutover (2026-09-10 04:00 UTC,
+ * a Thursday): 2026-09-09 12:00 and 2026-09-10 04:50 UTC are outside
+ * both peak windows. 04:50 is when the pricing page still showed the old
+ * card — the bill had already moved. */
+ const oldDays = utc(2026, 9, 9, 12)
+ const newDays = utc(2026, 9, 10, 4, 50)
const flashSession = at => fold([
stepStart(at),
header(at, 'deepseek-v4-flash'),