dsh-openrouter-spend
Manifest validDeepSeek Harness plugin: real OpenRouter spend — today's cost under the composer, per-key and per-model analytics and prepaid balance in Settings. Install: dsh plugin add dsh-openrouter-spend
dsh-openrouter-spend
OpenRouter spend inside DeepSeek Harness — billed USD from OpenRouter's own analytics API, not token estimates priced from a local table.
What you get

The chip under the composer: this chat's spend over the day's total, next to the session's token and context stats.

The popover: range and API-key filters, today's spend per model, daily bars, prepaid balance and lifetime spend.
- Chip under the composer —
session/day: what this chat spent today over the whole day's spend, for the selected range and API key (today, 7 days, or 30 days). - Chip popover — range and API-key filters, today's spend per model, a daily bar chart across the window, prepaid balance and lifetime spend.
- Settings → OpenRouter spend — store or clear the management key, pick the display currency (USD, or RUB at the cbr.ru rate), set the refresh interval, filter by API key.
The host half caches the summary for refreshSeconds and coalesces concurrent refreshes, so any number of open tabs cost one OpenRouter query per refresh window. When a refresh fails, the last good figures stay on screen and the reason is shown instead of an empty panel.
Requirements
- DeepSeek Harness web profile. The plugin needs the
credentials,webServer, andconnectionservices and stays inactive in profiles without them (for example, headless). - An OpenRouter Management API key — OpenRouter dashboard → Settings → Management API Keys → Create New Key (OpenRouter docs). A regular inference key is rejected:
403 Only management keys can perform this operation.
Install
From npm (web is the default web-GUI profile; use your own profile name instead if you run one):
dsh plugin --profile web add dsh-openrouter-spend
From GitHub (plain JavaScript, no build step and no build-script permission):
dsh plugin --profile web add github:RyabykinIlya/dsh-openrouter-spend#v0.3.2
Then open Settings → OpenRouter spend and paste the management key.
Configuration
Every field can be overridden in the profile's cordis.patch.yml row; the schema validates the row at activation and names the offending field.
| Field | Default | Bounds | Meaning |
|---|---|---|---|
credentialRef | OPENROUTER_MGMT_API_KEY | non-empty string | Credentials reference holding the management key |
apiBase | https://openrouter.ai/api/v1 | https:// URL | OpenRouter REST API root |
refreshSeconds | 60 | 10–3600, integer | Seconds between OpenRouter refreshes |
historyDays | 30 | 2–366, integer | Days of history the summary window covers, today included |
cbrUrl | https://www.cbr.ru/scripts/XML_daily.asp | https:// URL | CBR daily-rates sheet read for the RUB rate |
rateRefreshSeconds | 3600 | 60–86400, integer | Seconds between cbr.ru rate reads |
timeoutMs | 15000 | 1000–120000, integer | Per-request deadline against OpenRouter and cbr.ru |
Viewing preferences (display currency, per-key filter, refresh interval override) are browser-local (localStorage).
What the numbers are
- Figures are
total_usage— USD OpenRouter actually billed — fromPOST /api/v1/analytics/query, grouped per UTC day by API key and model. - "Today" is the current UTC day.
- Balance is
total_credits − total_usagefromGET /api/v1/credits: what remains of prepaid credits. - The 7-day and 30-day ranges cover at most
historyDaysdays; keephistoryDays ≥ 30for full coverage. - RUB display converts those USD figures at the cbr.ru daily rate, read host-side and cached for
rateRefreshSeconds. When cbr.ru cannot be reached, the figures stay in USD and the panel says so, with the fetch reason and a hint to check the connection. - The chip's session half comes from the same
analytics/query, grouped bysession_id. The harness stamps each request with its Session id (x-session-id), so a chat's cost is its own figure; the chip showssession/day. Thenonebucket (requests sent without a session) is excluded — it belongs to no chat.
Security
- The management key is stored through the Harness credentials service (
credentials.set), not in this package's files, and is never echoed back to the browser. - The summary and credential routes are fenced by the connection trust check. Anyone who passes that check — by default, the browser session on your local Harness port — can read your spend figures. Do not expose the Harness web port publicly without its own authentication.
License
MIT. Unofficial plugin; not affiliated with OpenRouter or DeepSeek.
Comments
Loading…
From the same category
by awesome-dsh-plugin
A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表
★ 18.1k
CC0-1.0
Python
Oct 8, 2026
by 0xsline
DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.
★ 1.1k
CC0-1.0
Python
Sep 30, 2026
by pax-beehive
Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub
★ 458
MIT
TypeScript
Oct 6, 2026
by xiajiajun516
DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.
★ 167
MIT
TypeScript
Oct 8, 2026
dsh plugin --profile web add dsh-config-managerby yjh051108
推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。
★ 164
TypeScript
Sep 18, 2026
dsh plugin --profile web add @dsh-external/dsh-super-injectorby jigjoy-ai
A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.
★ 124
MIT
TypeScript
Oct 2, 2026