BurnGuard is built on a proxy-first philosophy: the only reliable place to enforce a budget is on the wire, before a request reaches the provider. API-level monitoring — billing dashboards, cost anomaly detectors, usage alerts from the provider itself — all operate on data that is hours old by the time you see it. A local reverse proxy sees every byte of every request and response in real time, in process, with no network round-trip to a monitoring service. That is why BurnGuard is a binary on your machine rather than a SaaS product you integrate with.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Verifieddanny/BurnGuard/llms.txt
Use this file to discover all available pages before exploring further.
Request Flow
Every AI call from your application passes through the following pipeline:Reverse Proxy Routing
BurnGuard uses Go’s standardnet/http/httputil.ReverseProxy with a custom Rewrite function. When a request arrives, the proxy splits the URL path on the first two segments to extract the provider name and the remaining path:
| Incoming (local) | Forwarded (upstream) |
|---|---|
http://localhost:8080/anthropic/v1/messages | https://api.anthropic.com/v1/messages |
http://localhost:8080/openai/v1/chat/completions | https://api.openai.com/v1/chat/completions |
Authorization or x-api-key header — are forwarded to the upstream provider as-is. BurnGuard never reads, stores, or modifies your API key.
Token Counting and Cost Calculation
Non-Streaming Responses
For standard JSON responses the proxy reads the complete response body inside theModifyResponse hook, parses the provider-specific usage fields, calculates cost, writes a record to SQLite, and then restores the body so it continues to your application unmodified:
Streaming Responses (SSE)
When the upstream response hasContent-Type: text/event-stream, buffering the entire body would defeat the purpose of streaming. Instead, BurnGuard wraps the response body in a StreamReader that passes bytes through to the client unchanged while accumulating them in an internal buffer:
Close method scans the buffer for SSE data: lines, strips the prefix, filters out [DONE] markers, and passes all data payloads to the provider-specific parser:
Pricing Models
Pricing tables are built into the binary and updated with each release. Both providers have non-uniform token pricing that BurnGuard handles correctly. Anthropic cache-aware pricing:| Token type | Rate multiplier |
|---|---|
| Standard input | 1.00× |
| Cache creation input | 1.25× (25% premium) |
| Cache read input | 0.10× (90% discount) |
| Output | Standard output rate |
| Token type | Rate multiplier |
|---|---|
| Standard prompt | 1.00× |
| Cached prompt (older models) | 0.50× (50% discount) |
| Cached prompt (GPT-5.4+) | 0.10× (90% discount) |
| Completion | Standard completion rate |
Budget Enforcement
TheBudgetGuard middleware wraps the entire proxy and runs before every request is forwarded:
Tracker maintains total spend in memory, protected by a mutex so concurrent requests never race:
main.go seeds the tracker with the cumulative spend already stored in SQLite, so the budget limit is enforced correctly across proxy restarts:
Alert Delivery
After every request, the proxy callsalerter.Check(spent, budget). The Alerter iterates through the configured thresholds and fires a notification the first time each one is crossed:
triggered map ensures each threshold fires exactly once per proxy session. Notifications are sent concurrently in a goroutine so they never block the response path. If both Slack and Discord webhooks are configured they are posted simultaneously:
Cloud Sync
Whensync.enabled is true, a background goroutine starts alongside the proxy and ticks on the configured interval (default 60 seconds):
syncOnce fetches up to 100 unsynced records from SQLite, marshals them to JSON, and POSTs to POST /v1/usage on the BurnGuard API with a Bearer token:
201 Created response the records are marked as synced in SQLite so they are never re-sent. Sync failures are logged but do not affect the proxy — requests continue to be forwarded and recorded locally regardless of cloud reachability.
Full Architecture
The proxy is completely stateless with respect to the upstream provider. It adds no extra network hop — requests are forwarded directly from your machine to
api.anthropic.com or api.openai.com. The only overhead is the in-process token parsing that happens inside ModifyResponse or StreamReader.Close, both of which run after the provider has already sent its response.