Skip to main content

Automatic LLM cost tracking for OpenAI, Anthropic, and more

Project description

Tokenr Python SDK

Automatic LLM cost tracking in one line of code.

Track costs from OpenAI, Anthropic, and other LLM providers with zero code changes. Get real-time visibility into spending by agent, feature, team, or any dimension you need.

Features

  • One-line setup — Add tokenr.init() and you're done
  • Zero code changes — Use OpenAI/Anthropic SDK as normal
  • Automatic tracking — Token counts and costs tracked automatically
  • Async by default — Never slows down your app
  • Multi-provider — OpenAI, Anthropic (more coming)
  • Rich attribution — Track by agent, feature, team, or custom tags
  • Production-ready — Handles errors gracefully, never crashes your app

Installation

pip install tokenr

Quickstart

OpenAI

import tokenr
import openai

# One line to enable tracking
tokenr.init(token="your-tokenr-token")

# Use OpenAI exactly as you normally would
response = openai.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello!"}]
)

# That's it — costs are automatically tracked to Tokenr

Anthropic

import tokenr
from anthropic import Anthropic

tokenr.init(token="your-tokenr-token")

client = Anthropic(api_key="your-anthropic-key")
response = client.messages.create(
    model="claude-opus-4-5",
    messages=[{"role": "user", "content": "Hello!"}]
)

# Automatically tracked!

Configuration

Environment Variables

export TOKENR_TOKEN="your-token"
import tokenr
tokenr.init()  # Reads from TOKENR_TOKEN

All Options

tokenr.init(
    token="your-token",           # API token (or TOKENR_TOKEN env var)
    url="https://tokenr.co/...",  # Override API URL (optional)
    agent_id="my-app",            # Default agent ID for all requests
    tags={"environment": "prod"}, # Default tags applied to every request
    enabled=True,                 # Set False to disable tracking entirely
    debug=False,                  # Print tracking info to console
)

Disable in Development

import os
tokenr.init(
    token=os.getenv("TOKENR_TOKEN"),
    enabled=os.getenv("ENV") == "production"
)

Advanced Usage

Track by Agent

# Option 1: Set a default agent ID at init
tokenr.init(token="...", agent_id="customer-support-bot")

# Option 2: Override per request
response = openai.chat.completions.create(
    model="gpt-4",
    messages=[...],
    tokenr_agent_id="sales-assistant"
)

Track by Feature

response = openai.chat.completions.create(
    model="gpt-4",
    messages=[...],
    tokenr_feature="chat",
    tokenr_agent_id="support-bot"
)

Multi-Tenant Tracking

response = openai.chat.completions.create(
    model="gpt-4",
    messages=[...],
    tokenr_team_id="team-123",
    tokenr_agent_id="shared-bot"
)

Custom Tags

response = openai.chat.completions.create(
    model="gpt-4",
    messages=[...],
    tokenr_tags={
        "customer_id": "cust_123",
        "conversation_id": "conv_456",
        "language": "en",
        "priority": "high"
    }
)

Manual Tracking

For providers not yet auto-patched, or when you need full control:

import tokenr

tokenr.track(
    provider="custom-provider",
    model="custom-model-v1",
    input_tokens=1000,
    output_tokens=500,
    agent_id="my-agent",
    feature_name="translation",
    tags={"language": "es"}
)

Per-Request Parameters

Add any of these to OpenAI or Anthropic calls:

Parameter Type Description
tokenr_agent_id str Agent identifier
tokenr_feature str Feature name
tokenr_team_id str Team or customer ID
tokenr_tags dict Arbitrary metadata

tokenr.track() Reference

tokenr.track(
    provider="openai",        # required
    model="gpt-4",            # required
    input_tokens=100,         # required
    output_tokens=50,         # required
    cache_read_tokens=0,      # tokens served from prompt cache
    cache_write_tokens=0,     # tokens written to prompt cache
    agent_id=None,
    feature_name=None,
    team_id=None,
    status="success",         # "success" or "error"
    latency_ms=None,
    tags=None,
    requested_at=None,        # ISO 8601 timestamp; defaults to now
)

Supported Providers

Provider Auto-Tracking Manual Tracking
OpenAI Yes Yes
Anthropic Yes Yes
Google AI Coming soon Yes
Cohere Coming soon Yes
Custom Yes

Prompt Caching

Both OpenAI and Anthropic support prompt caching, and the SDK handles it automatically. You don't need to do anything special.

OpenAI includes cached tokens inside prompt_tokens. The SDK reads prompt_tokens_details.cached_tokens and separates them so Tokenr can price each category at the correct rate.

Anthropic reports cache tokens as separate fields (cache_creation_input_tokens and cache_read_input_tokens). The SDK passes these through directly.

In both cases, the Tokenr server applies the right per-token rate for input, output, cache reads, and cache writes.

For manual tracking, you can pass cache tokens explicitly:

tokenr.track(
    provider="anthropic",
    model="claude-sonnet-4-20250514",
    input_tokens=500,
    output_tokens=200,
    cache_read_tokens=8000,
    cache_write_tokens=2000,
)

How It Works

  1. tokenr.init() wraps the create method on OpenAI and Anthropic clients
  2. After each call, token counts are read from the response usage field
  3. A background daemon thread sends the data to Tokenr asynchronously
  4. If tracking fails for any reason, your app is completely unaffected

Examples

See the examples/ directory:

Getting Your API Token

  1. Sign up at tokenr.co
  2. Go to API Tokens and create a token
  3. Copy it — it's shown only once
export TOKENR_TOKEN="your-token-here"

Troubleshooting

No data showing up?

tokenr.init(token="your-token", debug=True)
# Prints: [Tokenr] Tracked: gpt-4 - $0.0012
  1. Verify echo $TOKENR_TOKEN returns your token
  2. Confirm you're making actual LLM API calls
  3. Check network access to tokenr.co

Errors? The SDK never raises — it always fails silently. Use debug=True to see what's happening.

Running Tests

# Unit and mock tests (no API keys needed)
python -m unittest discover tests -v

# Live integration tests (makes real API calls, costs fractions of a cent)
OPENAI_API_KEY=sk-... ANTHROPIC_API_KEY=sk-ant-... python -m unittest tests.test_live_integration -v

The live tests make a real call to each provider, then verify that the token counts in the Tokenr payload match what the provider actually returned. This includes a test that triggers Anthropic prompt caching and confirms cache tokens are extracted correctly.

Security

This SDK is open source so you can audit exactly what data is sent and when. The short version:

  • Only token counts, model names, and your attribution metadata are transmitted
  • No prompt content or response content ever leaves your application
  • All requests use HTTPS
  • The tracker runs in a daemon thread and cannot block your process

License

MIT — see LICENSE

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tokenr-0.1.3.tar.gz (18.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tokenr-0.1.3-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file tokenr-0.1.3.tar.gz.

File metadata

  • Download URL: tokenr-0.1.3.tar.gz
  • Upload date:
  • Size: 18.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for tokenr-0.1.3.tar.gz
Algorithm Hash digest
SHA256 9d0c7b62ddba8acd84f5348327b954350ec47f4d3405820795847bf2212aa334
MD5 1a229ad40f5aeaf643d4bb7fa7714077
BLAKE2b-256 4db05eeb68c6b02c9c1a568217957f4efdd096ba9de6fdfc198b9e16fa481182

See more details on using hashes here.

File details

Details for the file tokenr-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: tokenr-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 8.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for tokenr-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 2c12b309ace9cdb51e7671a3650846089a438f178ce978216925263b1d22a2e9
MD5 cf23e26a993cfb384fd8b066125e0524
BLAKE2b-256 768d042e889c1ad4c314dc65907e549db131dcff9611edb4b65aeb608f8a8b72

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page