SpendLens AILens on AI spend

Quickstart

Choose the integration that fits your code.

Add one decorator to an existing application, or use the tracked client when you want precise control over every model call.

1. Install and configure SpendLens

pip install spendlensai

Create a test key under Dashboard → API keys, then set these environment variables. Your application or runtime should load local .env files.

SPENDLENS_API_KEY=sli_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SPENDLENS_PROJECT=production
SPENDLENS_API_BASE_URL=https://spendlensai.dev/backend
SPENDLENS_PROMPT_SAMPLING=template_only
SPENDLENS_DISABLE=0

Option A — Existing application: add one decorator

Lowest-friction integration

Keep your existing OpenAI or Anthropic client unchanged. Add @spendlensai.observe to the business workflow that makes the model call.

OpenAI

import spendlensai
from openai import OpenAI

client = OpenAI()  # Reads OPENAI_API_KEY

@spendlensai.observe(workload="customer-support-reply")
def generate_reply(message: str):
    return client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "Give concise, accurate billing help."},
            {"role": "user", "content": message},
        ],
    )

Anthropic / Claude

import spendlensai
from anthropic import Anthropic

client = Anthropic()  # Reads ANTHROPIC_API_KEY

@spendlensai.observe(workload="customer-support-reply")
def generate_reply(message: str):
    return client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=300,
        system="Give concise, accurate billing help.",
        messages=[{"role": "user", "content": message}],
    )

Use the bare @spendlensai.observe form to derive the workload from the module and function name, or provide workload="..." for a stable business label.

Option B — New or complex application: track the client

Use track() and client.tag() when one function makes multiple model calls, or when you need exact endpoint, task, experiment, region, or feature attribution.

OpenAI

from openai import OpenAI
from spendlensai import track

client = track(OpenAI())

with client.tag(
    endpoint="customer-support-reply",
    task="generation",
    metadata={"feature": "support"},
):
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "Give concise, accurate billing help."},
            {"role": "user", "content": "Why was I charged twice?"},
        ],
    )

Anthropic / Claude

from anthropic import Anthropic
from spendlensai import track

client = track(Anthropic())

with client.tag(endpoint="customer-support-reply", task="generation"):
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=300,
        system="Give concise, accurate billing help.",
        messages=[{"role": "user", "content": "Why was I charged twice?"}],
    )

# Recommended for short scripts, jobs, tests, and notebooks.
client.flush()

When both modes are used, attribution follows client.tag() → @spendlensai.observe → inferred callsite. SpendLens records the call only once.

View your first workload

Run the example once, allow a few seconds for the background queue to flush, then open the dashboard. SpendLens groups supported calls by project, workload, model, provider, and cost.

Privacy and prompt context

template_only sends reusable system/developer instructions to improve categorisation. It does not send user prompts or model responses. Set SPENDLENS_PROMPT_SAMPLING=off when no prompt text should leave the application.

Supported automatic coverage

Decorator mode supports official Python OpenAI chat.completions.create and responses.create calls and Anthropic messages.create calls. Direct REST calls and arbitrary HTTP traffic are not automatically captured. SpendLens does not proxy model traffic.

See the Python SDK guide for detailed configuration, metadata, cache reporting, and failure behavior.

Node.js SDK — Coming soon

The SpendLens Node.js SDK will be available soon. Contact [email protected] for more information.