Quickstart

From zero to "I can see what every customer costs" in five minutes. KostLens observes your AI calls — it never proxies them — and computes cost server-side from a versioned price catalog.

1 · Get a key

Sign up, create a project, then Settings → API keys → New key. The plaintext (kl_live_…) is shown once — store it as an environment variable.

2 · Wrap your client

TypeScript / JavaScript

npm install @kostlens/track
import OpenAI from "openai";
import { KostLens, wrapOpenAI } from "@kostlens/track";

const kl = new KostLens({ apiKey: process.env.KOSTLENS_KEY! });

const openai = wrapOpenAI(new OpenAI(), kl, {
  tags: { feature: "chat" },
});

// Use `openai` exactly as before. Streaming included.

Also available: wrapAnthropic and wrapGoogleGenAI. Any OpenAI-compatible API (Groq, OpenRouter, DeepSeek, Kimi…) works through wrapOpenAI — just point the OpenAI SDK at their base URL as usual.

Python

pip install kostlens
from openai import OpenAI
from kostlens import KostLens, wrap_openai

kl = KostLens("kl_live_...")
client = wrap_openai(OpenAI(), kl, tags={"feature": "chat"})

# Use `client` exactly as before. Streaming included.

Also available: wrap_anthropic and wrap_google_genai.

Go

go get github.com/kostlens/kostlens/sdk-go
import (
    "os"

    kostlens "github.com/kostlens/kostlens/sdk-go"
)

kl := kostlens.New(kostlens.Options{APIKey: os.Getenv("KOSTLENS_KEY")})
defer kl.Shutdown()

httpc := kostlens.WrapHTTPClient(nil, kl, kostlens.MiddlewareOptions{
    Tags: map[string]string{"feature": "chat"},
})

// Hand `httpc` to the official SDK — e.g. openai-go:
//   openai.NewClient(option.WithHTTPClient(httpc))
// Every call through it is measured. Streaming included.

In Go there is no monkey-patching — the SDK is an http.RoundTripper middleware, the idiomatic design. It detects OpenAI, Anthropic, Gemini and OpenAI-compatible hosts (Groq, DeepSeek, Kimi…) automatically. Per-request tags (like the end user of THIS call) go through context: req = req.WithContext(kostlens.ContextWithTags(ctx, map[string]string{"endUserId": userID}))

The sacred rule: the SDK can never break your app. Network failures, bad keys or KostLens outages degrade to "some events are lost" — never to an exception in your request path. Events are batched, retried on transient failures, and dropped (with a callback) when permanently rejected.

3 · Tag what matters

Two reserved tags unlock the dashboards that providers can't build: endUserId (cost per customer) and feature (cost per feature). Pass them per-wrapper or per-call — everything else in tags is stored too.

const openai = wrapOpenAI(new OpenAI(), kl, {
  tags: { feature: "summarize", endUserId: user.id },
});

No-code alternative: connect an admin key

Settings → Connections → Add connection, paste an OpenAI or Anthropic admin key, hit Sync now. KostLens imports your daily usage (day × model) and prices it with the same catalog. Keys are stored encrypted (AES-256-GCM) and never returned by any API. You get history instantly; add the SDK later for customer/feature granularity.

Deploy markers

One line in your CI/CD pipeline annotates the spend chart with each release:

curl -X POST https://ingest.kostlens.com/v1/deploys \
  -H "Authorization: Bearer $KOSTLENS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sha": "'$GITHUB_SHA'", "label": "v1.4.0"}'

CI cost check

Fail the pipeline when the last 24h of AI spend crosses a ceiling:

npx --package=@kostlens/ci kostlens-ci --max-usd 5 --feature chat
# exit 0 under the ceiling · exit 1 over it · exit 2 config/network error
# key via --key or the KOSTLENS_KEY env var

Ask your costs in Claude (MCP)

Add the KostLens MCP server to Claude Desktop or Claude Code:

{
  "mcpServers": {
    "kostlens": {
      "command": "npx",
      "args": ["--package=@kostlens/mcp", "kostlens-mcp"],
      "env": { "KOSTLENS_KEY": "kl_live_..." }
    }
  }
}

Then just ask: "which customer cost us the most this month?" — Claude calls get_top_customers and answers with your real numbers.

How cost is computed