Open-source LLM FinOps proxy — track OpenAI, Anthropic (Claude), and Google Gemini API costs by feature, team, and customer. Zero code changes.
Project description
BurnLens — See exactly what your LLM API calls cost
pip install burnlens — open-source LLM FinOps proxy for OpenAI, Anthropic (Claude), and Google Gemini. Track real token costs, attribute spend to features, teams, and customers, and detect waste. Zero code changes. Everything runs locally.
Zero code changes. Every dollar tracked. Works with the official OpenAI, Anthropic, and Google AI SDKs out of the box.
Install
pip install burnlens
burnlens start
# Dashboard → http://127.0.0.1:8420/ui
Point your SDK at the proxy
# OpenAI — note the /v1 suffix
export OPENAI_BASE_URL=http://127.0.0.1:8420/proxy/openai/v1
# Anthropic (Claude)
export ANTHROPIC_BASE_URL=http://127.0.0.1:8420/proxy/anthropic
# Google Gemini — one-line patch
import burnlens.patch; burnlens.patch.patch_google()
Your existing SDK code works unchanged. BurnLens intercepts, logs, and forwards — nothing else.
Tag any request for attribution
X-BurnLens-Tag-Feature: chat
X-BurnLens-Tag-Team: backend
X-BurnLens-Tag-Customer: acme-corp
Tags are stripped before reaching the AI provider. They never leave your machine.
Why BurnLens
- OpenAI and Anthropic bill by model, not by feature. You find out at month end which feature cost the most.
- Reasoning tokens on o1 / o3 / Claude thinking models cost 10× more than expected. One prompt change can balloon your bill.
- One bad deploy can burn $47K before anyone notices. Budget alerts catch it in minutes.
BurnLens fixes this at the proxy layer — no instrumentation, no SDK wrapping, no vendor lock-in.
What you get
- Cost timeline — daily spend trend across all providers
- Attribution — cost by model, feature, team, customer
- Waste detection — context bloat, duplicate requests, model overkill
- Per-request detail — tokens, cost, and latency for every call
- Budget alerts — Slack + terminal notifications when you hit spend limits
Supported providers
| Provider | Models |
|---|---|
| OpenAI | gpt-4o, gpt-4o-mini, o1, o3, o1-mini, gpt-4-turbo |
| Anthropic (Claude) | claude-opus-4, claude-sonnet-4, claude-3-5-sonnet, claude-3-haiku |
| Google Gemini | gemini-2.0-flash, gemini-1.5-pro, gemini-1.5-flash |
Reasoning tokens, cached tokens, and vision tokens are all tracked separately.
CLI
burnlens start # proxy + dashboard on :8420
burnlens top # live cost by model (htop-style)
burnlens report # weekly cost summary
burnlens analyze # waste detection report
burnlens export # CSV of last 7 days
burnlens run -- python app.py # auto-tag a process with repo / dev / pr / branch
burnlens key register <name> # label an API key + set a daily cap
burnlens key list # list registered keys with caps
burnlens keys # today's spend per registered key
burnlens scan claude # import Claude Code session costs from disk
burnlens scan cursor # import Cursor IDE session costs from disk
burnlens scan codex # import OpenAI Codex session costs from disk
burnlens scan gemini # import Gemini CLI session costs from disk
Per-API-key daily kill-switch
Stop a leaked or runaway API key before it burns the month's budget.
# Register your provider key with a label and a $25/day hard cap
burnlens key register prod-openai --provider openai --cap 25.00
# Use the key normally — the proxy resolves it to its label, tracks
# today's spend, fires 50/80/100% alerts, and returns HTTP 429 at 100%
export OPENAI_API_KEY=sk-...
export OPENAI_BASE_URL=http://127.0.0.1:8420/proxy/openai/v1
# Inspect today's per-key roll-up
burnlens keys
- Keys are stored as SHA-256 hashes — never in plaintext.
- TZ-aware daily reset (UTC midnight by default, configurable).
- 100% breach returns
429 {"error": "burnlens_daily_cap_exceeded"}until reset. - Dashboard panel "API keys today" shows live status at
:8420/ui.
Offline scan — coding agent sessions
Already spent money in Claude Code, Cursor, Codex, or Gemini CLI? Import those session logs into the same dashboard without replaying any traffic:
burnlens scan claude # ~/.claude/projects/ — JSONL session files
burnlens scan cursor # ~/.cursor/ — SQLite bubble DB
burnlens scan codex # ~/.codex/sessions/ — JSONL session files
burnlens scan gemini # ~/.gemini/tmp/<project>/chats/ — JSON/JSONL
All four commands are idempotent — re-running them won't create duplicate rows. Imported records appear alongside live-proxy traffic in burnlens top, the dashboard, and exports.
Configuration
Zero config required — sensible defaults out of the box. Optional burnlens.yaml:
budget_limit_usd: 500.00
budgets:
teams:
backend: 200.00
research: 100.00
alerts:
slack_webhook: https://hooks.slack.com/...
How it works
App → SDK → BurnLens proxy (localhost:8420) → AI provider
↓
SQLite: logs request, calculates cost, extracts tags
↓
Dashboard (localhost:8420/ui) + CLI (burnlens top/report)
- Local-first. Everything runs on localhost. No cloud account needed.
- Privacy-preserving. Prompts and completions never leave your machine. API keys pass through, never stored remotely.
- Streaming passthrough. SSE chunks forwarded immediately. < 20 ms proxy overhead.
- Fail-open. If BurnLens can't log, it still forwards the request. Never breaks your app.
Cloud (optional)
Need team-wide dashboards and multi-workspace cost tracking? BurnLens Cloud offers:
- Free — local proxy only (this repo)
- Cloud — $29/mo — personal cloud dashboard, 7-day trial
- Teams — $99/mo — multi-user workspaces, shared budgets
The CLI is free forever. Cloud is opt-in and only syncs anonymised cost records (tokens + cost — never prompts, completions, or API keys).
Contributing
Issues and PRs welcome. See CONTRIBUTING.md.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file burnlens-1.1.0.tar.gz.
File metadata
- Download URL: burnlens-1.1.0.tar.gz
- Upload date:
- Size: 137.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e84d7dcbf31af0266b8dd7c437025174d29c37f96a3d876c71df38c482d480e6
|
|
| MD5 |
47d1abb81ee1e90a0095cda57813fd07
|
|
| BLAKE2b-256 |
384a28f65260d9342993074d73f72f5389ef87e20b5efaeb4d280b0fb2eaa5ce
|
Provenance
The following attestation bundles were made for burnlens-1.1.0.tar.gz:
Publisher:
publish.yml on sairintechnologycom/burnlens
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
burnlens-1.1.0.tar.gz -
Subject digest:
e84d7dcbf31af0266b8dd7c437025174d29c37f96a3d876c71df38c482d480e6 - Sigstore transparency entry: 1432036023
- Sigstore integration time:
-
Permalink:
sairintechnologycom/burnlens@c65efb320bd25b6dedd30e3993ea1fd9417f96f2 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/sairintechnologycom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c65efb320bd25b6dedd30e3993ea1fd9417f96f2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file burnlens-1.1.0-py3-none-any.whl.
File metadata
- Download URL: burnlens-1.1.0-py3-none-any.whl
- Upload date:
- Size: 163.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41b8bcc85bdf7c7ab00226a3210b7c5fa3632b28d7ce592c663af64a6bebc5b3
|
|
| MD5 |
b2fed81acdc689f07c96adfcf643494e
|
|
| BLAKE2b-256 |
f1104630cb4b21efd53b6c239ab6e6a43f996f7086f5fcc9375a418c188f3384
|
Provenance
The following attestation bundles were made for burnlens-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on sairintechnologycom/burnlens
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
burnlens-1.1.0-py3-none-any.whl -
Subject digest:
41b8bcc85bdf7c7ab00226a3210b7c5fa3632b28d7ce592c663af64a6bebc5b3 - Sigstore transparency entry: 1432036291
- Sigstore integration time:
-
Permalink:
sairintechnologycom/burnlens@c65efb320bd25b6dedd30e3993ea1fd9417f96f2 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/sairintechnologycom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c65efb320bd25b6dedd30e3993ea1fd9417f96f2 -
Trigger Event:
push
-
Statement type: