Two separate things, both in the DeepSeek rows of data/model_data.ts.
1. The prices are from the previous generation
deepseek-v4-pro and deepseek-v4-flash carry a single flat rate each:
{ id: 'deepseek-v4-pro', cost: { input_per_million: 0.435, cached_input_per_million: 0.003625, output_per_million: 0.87 } },
{ id: 'deepseek-v4-flash', cost: { input_per_million: 0.14, cached_input_per_million: 0.0028, output_per_million: 0.28 } },
DeepSeek's page (read 2026-08-23, https://api-docs.deepseek.com/quick_start/pricing/) gives per 1M tokens, USD:
| model |
band |
cache hit |
cache miss |
output |
deepseek-v4-pro |
peak |
0.044 |
1.32 |
3.96 |
deepseek-v4-pro |
off-peak |
0.022 |
0.66 |
1.98 |
deepseek-v4-flash |
peak |
0.014 |
0.44 |
1.32 |
deepseek-v4-flash |
off-peak |
0.007 |
0.22 |
0.66 |
deepseek-v4-flash-vision-exp |
peak |
0.014 |
0.44 |
1.32 |
deepseek-v4-flash-vision-exp |
off-peak |
0.007 |
0.22 |
0.66 |
0.435 is not either band — it looks like a V3-era number that survived the rename. getPrice therefore understates DeepSeek by about 1.5× off-peak and about 3× at peak, and by roughly 6× on cached input for v4-pro.
2. TimeBasedPrice cannot express the schedule even if it were wired up
Nothing in model_data.ts uses peak_price_per_million today, so the branch in cost_tracker.ts never fires for DeepSeek. If you point it at these models, two things block it:
- Two windows, not one. The type holds a single
[peak_utc_start, peak_utc_end); DeepSeek peaks at 01:00–04:00 and 06:00–10:00 UTC. The e.g. 0 for 00:30 comment describes the old V3/R1 discount window, which was a single span.
- Weekdays only. The footnote reads "Peak hours are 01:00 - 04:00 and 06:00 - 10:00 UTC, Monday through Friday (all other hours are off-peak)." The Chinese page pins the timezone: 「高峰时段为北京时间周一至周五 9:00 - 12:00、14:00 - 18:00」. Peak is 35 hours a week, not 49;
cost_tracker.ts:154 reads getUTCHours() with no day.
Both fall out of turning the two fields into a list plus an optional day filter:
export interface TimeBasedPrice {
peak_price_per_million: number;
off_peak_price_per_million: number;
/** [startMinute, endMinute) since UTC midnight; a window crossing midnight is split in two. */
peak_windows_utc: ReadonlyArray<readonly [number, number]>;
/** ISO weekday numbers, Mon = 1 … Sun = 7. Omitted means every day. */
peak_days?: readonly number[];
}
One caveat worth a comment wherever peak_days gets read: the weekday is on the vendor's clock, not UTC. Taking it with getUTCDay() is right for DeepSeek today only because both windows end before 16:00 UTC, which is exactly where a UTC date and a Beijing date start to disagree — so the two readings price identically at all 168 hours and no test against the published windows can tell them apart. If a window ever moves past 16:00 UTC that stops being true with nothing going red.
Happy to send a PR for part 1 on its own if that is easier to take.
Two separate things, both in the DeepSeek rows of
data/model_data.ts.1. The prices are from the previous generation
deepseek-v4-proanddeepseek-v4-flashcarry a single flat rate each:DeepSeek's page (read 2026-08-23, https://api-docs.deepseek.com/quick_start/pricing/) gives per 1M tokens, USD:
deepseek-v4-prodeepseek-v4-prodeepseek-v4-flashdeepseek-v4-flashdeepseek-v4-flash-vision-expdeepseek-v4-flash-vision-exp0.435is not either band — it looks like a V3-era number that survived the rename.getPricetherefore understates DeepSeek by about 1.5× off-peak and about 3× at peak, and by roughly 6× on cached input forv4-pro.2.
TimeBasedPricecannot express the schedule even if it were wired upNothing in
model_data.tsusespeak_price_per_milliontoday, so the branch incost_tracker.tsnever fires for DeepSeek. If you point it at these models, two things block it:[peak_utc_start, peak_utc_end); DeepSeek peaks at 01:00–04:00 and 06:00–10:00 UTC. Thee.g. 0 for 00:30comment describes the old V3/R1 discount window, which was a single span.cost_tracker.ts:154readsgetUTCHours()with no day.Both fall out of turning the two fields into a list plus an optional day filter:
One caveat worth a comment wherever
peak_daysgets read: the weekday is on the vendor's clock, not UTC. Taking it withgetUTCDay()is right for DeepSeek today only because both windows end before 16:00 UTC, which is exactly where a UTC date and a Beijing date start to disagree — so the two readings price identically at all 168 hours and no test against the published windows can tell them apart. If a window ever moves past 16:00 UTC that stops being true with nothing going red.Happy to send a PR for part 1 on its own if that is easier to take.