Meter LLM costs per tenant —
and enforce limits automatically
Usage metering and cost enforcement for LLM calls, built for multi-tenant B2B apps. One call instruments every OpenAI, Anthropic, Google AI, DeepSeek, and OpenRouter request — no changes to your LLM code.
Instrument once. Track and enforce everything.
TokenLimit patches provider SDKs at startup. Every call your application makes — including calls from libraries — is automatically captured, attributed, and checked against spend limits.
Patch at startup
Call meter.patch("provider_name") once when your app starts. All five provider SDKs are wrapped automatically — including calls made by libraries.
Tag by tenant
Use meter.for_tenant() as a context manager. Thread-safe and async-safe via Python ContextVars. Works with sync and async code identically.
Enforce spend limits
Set a monthly or daily USD cap with meter.set_limit(). When a tenant hits the limit, LimitExceededException is raised — trigger your upgrade flow.
Background flush
Events queue in memory and batch POST to your ingest_url every 5 seconds. Your LLM calls are never blocked or slowed down.
Full event schema
Every event carries provider, model, input/output/cached tokens, audio & image-specific fields, duration, request ID, and your custom tags.
Just a few lines to full coverage
Initialize at startup, call meter.patch("provider_name"), set per-tenant limits with set_limit(), and wrap handlers with for_tenant(). Catch LimitExceededException to trigger your upgrade flow.
# Initialize once at startup meter = Meter(MeterConfig( api_key="your-api-key", )) meter.patch("openai") # anthropic, google, deepseek, openrouter
# Set a monthly spend cap per tenant meter.set_limit("acme-corp", limit_usd=50.00, frequency="per_day")# or default is per month
# Tag + enforce per request with meter.for_tenant("acme-corp"): try: response = client.chat.completions.create(...) except LimitExceededException: show_upgrade_message()
Works with every major LLM API
OpenAI
chat, responses, embeddings, audio STT/TTS, image gen — sync & async, streaming & non-streaming
Anthropic
messages.create — sync & async, streaming & non-streaming, prompt cache (read + write) tracking
Google AI
generate_content + generate_content_stream — sync & async via google.genai client
DeepSeek
chat, FIM, and beta chat — sync & async, streaming; covers first-party SDK and openai client
OpenRouter
Instance-level patch on registered clients — sync & async, streaming, real USD cost capture
Any provider
BasePatch extension for any LLM API, or meter.track_manually() for one-off calls