- Python:
lago-agent-sdkon PyPI. Python 3.10+. - JavaScript / TypeScript:
lago-agent-sdkon npm. Authored in TypeScript, ships compiled JS with.d.ts.
Pick your provider
Each integration page carries the install command, the wrap call, streaming and async coverage, the per-call override syntax, and the exact fields captured for that provider.OpenAI
Chat Completions and the Responses API. Reasoning tokens on o-series models.
Anthropic
messages.create and the streaming helper. Full prompt-caching breakdown.AWS Bedrock
Converse and InvokeModel, streaming included. Seven InvokeModel shape families.
Google Gemini
google-genai unified SDK. Reasoning tokens on Gemini 2.5, plus audio and image.Mistral
chat.complete and chat.stream, with cache-read tokens when the cache hits.Cloudflare AI Gateway
Any provider behind your gateway. Cache hits skipped, Workers AI priced, logs backfilled.
Databricks AI Gateway
Hosted models and BYOK traffic. Live instrumentation, or backfill from Databricks’ own system tables.
Something missing? The wrapper layer is one file per provider in both repos. Open an issue or a PR on Python or JavaScript.
How it works
- Wraps your existing LLM client in place. Your application code does not change.
- Extracts usage from each response into a normalized shape (
CanonicalUsage, 11 numeric fields). - Buffers events in memory and flushes them in batches to Lago’s
/events/batchendpoint. - Survives provider and Lago outages with exponential backoff and a bounded buffer.
- Never blocks your LLM call on Lago. Recording usage costs microseconds against a call that takes hundreds of milliseconds, and the request to Lago goes out on a background thread.
- Never breaks your LLM call. Instrumentation errors are caught, logged, and optionally forwarded to your observability stack.
Quickstart
1
Install the SDK
Install the core package plus the provider SDK you already use. Python ships provider support as optional extras; in JavaScript you install the provider package yourself.
2
Initialize and wrap your LLM client
Pass your Lago API key and a default
external_subscription_id, then wrap your provider client. The returned object is a drop-in replacement, and wrap() is idempotent: calling it twice on the same client is a no-op.3
Make LLM calls normally
The wrapped client preserves the original signature, return shape, and exceptions. No call-site changes required.
4
Flush events on shutdown
Events flush automatically: every second, or as soon as 100 events are buffered. Call
flush() explicitly at process exit (FastAPI shutdown hook, Express server close, AWS Lambda extension) so in-flight events are not lost.A clean interpreter exit already triggers a 2-second flush. Python registers an
atexit hook, JavaScript a beforeExit handler. An explicit flush() is still the right call in a request-scoped or serverless runtime.5
Wire up on_error
Instrumentation failures are silent by design — the SDK will never break your LLM call to tell you about one. That makes the error hook the only way to find out something is wrong, so set it on day one rather than later.
6
Register billable metrics in Lago
Before events count toward charges, register matching billable metrics in your Lago tenant. The SDK ships with default metric codes — Billing lists all eleven and shows the plan setup that prices them correctly.Follow Create a billable metric to create them, then attach charges in your plan. For a full worked example, see the per-token pricing template.
What the SDK does not cover
wrap() instruments the chat and completion surfaces, not everything a provider client can do. Embeddings, image and video generation, audio endpoints, batch APIs, and — on OpenAI and Anthropic — the parse() structured-output helpers all pass through unmetered.
Each provider page has a “what is and isn’t instrumented” section with the exact list. For anything the wrappers miss, including providers with no wrapper at all, build a CanonicalUsage yourself and pass it to sdk.emit().
Where to go next
Billing
Token mode versus price mode, the metric codes to register, and the plan setup that prices each token type correctly.
Reference
Every configuration option, subscription routing, the error types, and how the SDK behaves under failure.
Verify the integration
Make one call through the wrapped client and callflush(). In the Lago dashboard, open Developers → Events and confirm an event arrives with the expected metric code and properties, then check that the customer’s usage counter moved.
If nothing arrives, look at on_error first — instrumentation failures are silent by design. The usual causes are an unregistered metric code, no resolvable external_subscription_id, and an API key without write access.