Skip to main content

Burnclock

How much AI budget you have left, and how long it lasts — in one glance.

Burnclock reads each AI provider's own balance/usage endpoint (or your local Hermes usage records), then computes what most consoles don't show you: burn per day, days of paid runway left, and the date your monthly budget runs out — per provider, in one table or one JSON envelope.

Estimates, not billing truth. Every dollar is computed locally from provider responses and usage records. It is not a bill, not a guarantee, and not affiliated with any provider.

Example output (synthesized, not a live account):

┌────────────┬───────┬───────────┬──────────┬───────────────┐
│ Provider   │ State │ Balance   │ Burn/day │ Runway (paid) │
├────────────┼───────┼───────────┼──────────┼───────────────┤
│ DeepSeek   │ OK    │ 20.23 USD │ 2.69     │ 6.0 d         │
│ OpenRouter │ EMPTY │ -0.09 USD │ 8.08     │ —             │
└────────────┴───────┴───────────┴──────────┴───────────────┘

What it answers

  • Do I need to top up today? Balance + days-left at your current burn, per provider.
  • Where is my money going? Burn/day from your actual usage (Hermes state.db, deduped logs), not a guess.
  • When does the month's budget run out? Budget bars and a projected crossing date.
  • Is this key dead or just empty? KEY_REJECTED vs EMPTY vs PERMISSION_DENIED are distinct states.

Providers

Provider Balance source Verification
DeepSeek GET /user/balance live-verified
OpenRouter GET /api/v1/key + /credits (remaining = credits − usage) live-verified
Moonshot GET /v1/users/me/balance doc-unverified, disabled by default
xAI management API prepaid balance (needs team_id) doc-unverified, disabled by default
MiniMax account/query_balance or token_plan/remains (region auto) doc-unverified, disabled by default
fal account/billing (prepaid/postpaid discriminated) doc-unverified, disabled by default

Providers without a balance API still get an honest row: NO_API (spend-only, e.g. priced usage records) or NOT_QUERYABLE (console-only). No state ever fabricates a number.

Install

Not on PyPI yet — the first release is pending. From source:

git clone <repo-url> && cd burnclock
python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/burnclock --version

Once released: pipx install burnclock or uv tool install burnclock.

Requires Python ≥ 3.12. The watch TUI needs the optional extra: pip install 'burnclock[tui]'.

Use

burnclock                          # human status table
burnclock status --json            # envelope v1 + script-safe exit codes
burnclock forecast                 # paid runway, burn/day, budget crossing date
burnclock dashboard                # every known provider (disabled rows included)
burnclock budget show              # resolved monthly budgets
burnclock budget set deepseek 50 --dry-run   # offline preview, never a surprise write
burnclock watch                    # live TUI on a TTY; plain table when piped
burnclock badge                    # prompt-safe one-line balance (cached; never blocks)
burnclock completion bash|zsh|fish # print a static shell completion script
burnclock config show | path       # effective config / config file location

Config lives at ~/.config/burnclock/config.toml on macOS/Linux and %APPDATA%\burnclock\config.toml on Windows (the pre-rename location is still read, with a one-time warning). Keys are never stored in config: a provider entry names an environment variable (e.g. key_env = "DEEPSEEK_API_KEY"); a secret-shaped value in config refuses to load.

Exit codes on machine paths: 0 ok · 1 internal · 2 usage · 3 config · 4 auth (KEY_REJECTED/PERMISSION_DENIED) · 5 threshold crossed · 6 unreachable — worst wins, in the order 1 > 2 > 3 > 4 > 5 > 6 > 0. Human views exit 0 whenever output was produced.

status --min <usd> and status --min-days <n> turn it into an alert (exit 5) for cron and agents.

On an interactive terminal only (never for --json or piped output), burnclock checks PyPI at most once a day and prints a one-line upgrade hint to stderr; set BURNCLOCK_NO_UPGRADE_CHECK=1 to opt out.

Badge

burnclock badge prints one line for a shell prompt, tmux bar, or agent surface: DeepSeek $12.68 · 4.3d. It reads a small cache and never blocks on the network — a stale or missing cache prints the last known line (else burnclock —) and refreshes itself in a detached background process.

burnclock badge                      # cache hit: instant, no network, no config
burnclock badge --refresh            # collect now (same exit codes as status), write the cache
burnclock badge --print-path         # print the cat-able badge.txt path and exit
burnclock badge --provider xai --format plain

--refresh writes badge.json plus a plain-text sibling badge.txt (exactly one line, no ANSI) for prompts that just cat it. Both live in ~/.cache/burnclock/ on macOS/Linux (%LOCALAPPDATA%\burnclock\ on Windows); $BURNCLOCK_BADGE_CACHE moves the cache file. The cache is fresh for 300 s ($BURNCLOCK_BADGE_TTL). --provider picks the row; otherwise [badge].provider from config, then the first provider with a numeric balance. Color is TTY-only and disabled by NO_COLOR or --format plain; --json is always ANSI-free.

In a prompt or status bar

badge.txt is one plain line, so a prompt only has to read the file — no Python startup, no network:

# ~/.zshrc: right prompt, refreshed in the background at most every 4 minutes
_burnclock_precmd() {
  [[ -r ~/.cache/burnclock/badge.txt ]] &&
    RPROMPT="%F{244}$(<~/.cache/burnclock/badge.txt)%f"
  (( EPOCHSECONDS - ${_bc_last:-0} < 240 )) && return
  _bc_last=$EPOCHSECONDS
  ~/.hermes/skills/burnclock/scripts/badge-chip.sh --refresh >/dev/null 2>&1 &!
}
autoload -Uz add-zsh-hook && add-zsh-hook precmd _burnclock_precmd
# ~/.tmux.conf: burnclock paints its own line, tmux refreshes it every 60 s
set -g status-interval 60
set -g status-right '#[fg=colour244]#(~/.hermes/skills/burnclock/scripts/badge-chip.sh)#[default]'

badge-chip.sh is the integration entry point: it routes through the skill shim, so a gateway- or launchd-spawned shell (which never inherited your keys) can still refresh the cache.

The repo also ships a Hermes desktop status-bar chip (desktop-plugin/); bash scripts/install-badge.sh installs it into ~/.hermes/desktop-plugins/burnclock-badge/, where the app hot-loads it. It polls the same cache every 60 s and tones the dot green → amber (<5 days runway) → red (<2 days or a failed provider).

States

OK · LOW · CRITICAL · EMPTY · KEY_REJECTED · PERMISSION_DENIED · NO_API · NOT_QUERYABLE · ERROR · UNREACHABLE

KEY_REJECTED distinguishes a dead/rotated key from a $0 balance; PERMISSION_DENIED means the key is valid but under-scoped. EMPTY means unknown or zero — never "free".

Hermes skill

The repo ships a Hermes skill (hermes-skill/, packaged as dist/burnclock-skill.zip) so an agent session can answer "how many tokens do I have left" with real numbers. Its shim reads only the six provider key variable names from ~/.hermes/.env — it never sources the file and never prints a value. A daily cron suggestion for a runway alert lives in hermes-skill/CRON.md.

Design rules

  • Read-only. No top-ups, no spending, no provider mutations. Spending endpoints are never called.
  • Fail-closed. Missing keys are reported as such; malformed responses are ERROR, never $0.
  • No secrets in files. Config holds env-var names only; the packaged skill is secret-scanned.
  • Offline floor. With zero keys it still reports what your local Hermes usage records know.
  • Estimates, not billing truth. Runway is a range: bursty usage moves it, and providers change prices.

Development

.venv/bin/pytest -q                            # full suite (synthetic fixtures only, no network)
bash hermes-skill/scripts/build-skill-zip.sh   # package + secret-scan the skill

Tests never touch a real provider: transports are faked and every fixture is synthetic. Timing protocol and recorded numbers live in BENCH.md; release history in CHANGELOG.md.

MIT licensed. Built by Jeremy Silbernagel.

Metadata

Release files for burnclock 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for burnclock 0.1.1
File Size Uploaded
burnclock-0.1.1.tar.gz 140.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for burnclock 0.1.1
File Interpreter ABI Platform
burnclock-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 230.0 kB

Release files / burnclock-0.1.1.tar.gz

Download URL burnclock-0.1.1.tar.gz
Size 140.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0e5cc0d90ccb1d7bab9282ebb2b517e35b7355e97bf7d62e4b77528dc25ffaac
BLAKE2b-256 checksum
How to use checksums
97b5444f5e354d6789d425e6b65c05c4231cf027bd7cf0ed51c1884cf4c4039d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / burnclock-0.1.1-py3-none-any.whl

Download URL burnclock-0.1.1-py3-none-any.whl
Size 89.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
524be71af724ca5e9bbc7afc772a5fcf530ddb8f0c2eb4a005b9135cd1722e4d
BLAKE2b-256 checksum
How to use checksums
f79096fc56137bf68bb081b0fee11d5b6dc25e60b2f15979e4ec29347c901ebf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.2

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page