The open-source FinOps proxy for AI spend — track cost by feature, team, and customer across OpenAI, Anthropic, Google, Azure, Bedrock, and Groq.
Project description
BurnLens — The open-source FinOps proxy for AI spend
Track every dollar by feature, team, and customer across OpenAI, Anthropic, Google, Azure, AWS Bedrock, and Groq. Hard-cap budgets before the API call — not after the bill arrives.
pip install burnlens
burnlens start
# Dashboard at http://127.0.0.1:8420/ui
The Problem
Bills tell you the model, not the why. Your invoice says gpt-4o: $4,287. It doesn't say which feature, which team, or which customer burned it. By the time you trace the spike, it's already on next month's card.
Alerts arrive after the damage. A bad deploy, a runaway agent, or one abusive customer can trigger thousands of API calls before any dashboard turns red. You find out when you open the bill — or when your CEO does.
Every provider is a different silo. OpenAI's usage page. Anthropic's console. Azure Cost Management. Bedrock CloudWatch. No unified view, no way to ask "which feature is our biggest AI spend across all providers."
How It Works
-
Drop-in proxy. Point your SDK's
BASE_URLatlocalhost:8420. Existing code works unchanged. Less than 20ms overhead. Full streaming passthrough. No changes to your application logic. -
Tag what matters. Three request headers (
X-BurnLens-Tag-Feature,X-BurnLens-Tag-Team,X-BurnLens-Tag-Customer) attribute any call to any dimension. Tags are stripped before reaching the AI provider — they never leave your machine. -
Cap before you call. Register an API key with a daily dollar limit. At 100%, BurnLens returns
429before the upstream request is made — not after the bill arrives. 50% and 80% thresholds fire Slack or email alerts. -
One dashboard, every provider. OpenAI, Anthropic, Google, Azure OpenAI, AWS Bedrock, and Groq spend in one unified view. Model breakdowns, waste detection, and budget tracking — reconciled to the provider bill.
Code Example
import os, openai
os.environ["OPENAI_BASE_URL"] = "http://127.0.0.1:8420/proxy/openai"
client = openai.OpenAI(default_headers={
"X-BurnLens-Tag-Feature": "chat",
"X-BurnLens-Tag-Team": "backend",
"X-BurnLens-Tag-Customer": "acme-corp",
})
Tags are stripped before the request reaches OpenAI. They never appear in any API payload.
Use Cases
Coding agents. Cursor, Claude Code, Cline, Windsurf — attribute cost per PR, repo, or developer. Set a hard daily cap per API key so one runaway agent can't blow the team's monthly budget overnight.
Customer-facing AI. Tag each request with a customer ID. See which customers drive the most cost. Enforce per-customer monthly spend limits with automatic 429 enforcement before the call is forwarded.
RAG and agents. Tag retrieval calls, tool calls, and generation separately. See whether your vector search or synthesis step is the cost driver — and whether it justifies the output quality.
Internal tools. Set per-team monthly budgets, get Slack alerts at 80% and 100%, and export monthly reports that reconcile line-by-line to the actual provider bill.
Supported Providers
| Provider | Status | Notes |
|---|---|---|
| OpenAI | Stable | All models, streaming, reasoning tokens |
| Anthropic | Stable | All models, streaming, prompt caching tokens |
| Stable | Gemini 1.5/2.0, requires patch_google() |
|
| Azure OpenAI | Roadmap v0.3 | |
| AWS Bedrock | Roadmap v0.3 | |
| Groq | Roadmap v0.2 | |
| Together | Roadmap v0.2 | |
| Mistral | Roadmap v0.2 |
Why BurnLens
| BurnLens | Helicone / Langfuse | Vantage / CloudZero | |
|---|---|---|---|
| Open source | ✓ | Partial | ✗ |
| Local-first (prompts stay local) | ✓ | ✗ | ✗ |
| Hard caps before API call | ✓ | ✗ | ✗ |
| Per-customer attribution | ✓ | ✓ | ✗ |
| Multi-cloud (Azure / AWS / GCP) | ✓ | Partial | ✓ |
Dashboard
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
customers:
acme-corp: 50.00
alerts:
slack_webhook: https://hooks.slack.com/...
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
Contributing
Issues and PRs welcome. See CONTRIBUTING.md.
git clone https://github.com/sairintechnologycom/burnlens
cd burnlens
pip install -e ".[dev]"
pytest
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.2.0.tar.gz.
File metadata
- Download URL: burnlens-1.2.0.tar.gz
- Upload date:
- Size: 141.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f2848c01b3bf02222fcf5a31a56a6673729b99e3ef544c9518d494db79cf2d3
|
|
| MD5 |
1458275c56c5f09253c217f02584a5f2
|
|
| BLAKE2b-256 |
ff5def7c92d1a56a048b6b491a89f77881414448100c923bc06287552e7ee497
|
Provenance
The following attestation bundles were made for burnlens-1.2.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.2.0.tar.gz -
Subject digest:
4f2848c01b3bf02222fcf5a31a56a6673729b99e3ef544c9518d494db79cf2d3 - Sigstore transparency entry: 1437299596
- Sigstore integration time:
-
Permalink:
sairintechnologycom/burnlens@9742669aa4a19760990ca5abcb0de89df7dba004 -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/sairintechnologycom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9742669aa4a19760990ca5abcb0de89df7dba004 -
Trigger Event:
push
-
Statement type:
File details
Details for the file burnlens-1.2.0-py3-none-any.whl.
File metadata
- Download URL: burnlens-1.2.0-py3-none-any.whl
- Upload date:
- Size: 169.6 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 |
73cb38c9ac15e3d346b5d33990a71fdc43fdf196770f8a77205f7d00978ff24d
|
|
| MD5 |
99a597f60aecb13e306cd8a5a4d8b156
|
|
| BLAKE2b-256 |
afac263c476fa123f6dddee567ffc0f5a32a7f29fbb9987977c0edaf0eeefad0
|
Provenance
The following attestation bundles were made for burnlens-1.2.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.2.0-py3-none-any.whl -
Subject digest:
73cb38c9ac15e3d346b5d33990a71fdc43fdf196770f8a77205f7d00978ff24d - Sigstore transparency entry: 1437299600
- Sigstore integration time:
-
Permalink:
sairintechnologycom/burnlens@9742669aa4a19760990ca5abcb0de89df7dba004 -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/sairintechnologycom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9742669aa4a19760990ca5abcb0de89df7dba004 -
Trigger Event:
push
-
Statement type: