Skip to main content

llmtrack-sdk (Python)

LLMtrack records server-side LLM token usage, cost, and request context so teams can understand AI usage in one dashboard.

The PyPI distribution is named llmtrack-sdk, while Python imports use llmtrack_sdk: distribution names can contain hyphens, but import identifiers cannot, and the distinct name also avoids the unrelated llmtrack distribution.

Install

pip install llmtrack-sdk

Quickstart

Create an ingestion key in LLMtrack, save it at ~/.config/llmtrack/api-key, and run:

export LLMTRACK_API_KEY="$(cat ~/.config/llmtrack/api-key)"
import os
from llmtrack_sdk import LLMtrack
tracker = LLMtrack(api_key=os.environ["LLMTRACK_API_KEY"])
tracker.track(provider="openai", model="gpt-5.6-sol", prompt_tokens=241,
              completion_tokens=86, reasoning_tokens=32, feature="support-chat")

Exported Node.js event type

When using the companion Node.js package, import its canonical class (with a lowercase t) and exported event type directly:

import { LLMtrack, type TrackOptions } from 'llmtrack';
const event: TrackOptions = { provider: 'openai', model: 'gpt-5.6-sol', promptTokens: 241, completionTokens: 86 };

Common mistakes

  • Class casing: the canonical class is LLMtrack, with a lowercase t. Python also exports LLMTrack as a safety alias, but documentation and examples use LLMtrack.
  • Field casing: Python accepts snake_case event fields only (for example, prompt_tokens); an unknown or wrong-cased key causes an unexpected-keyword TypeError, reported through on_error when using track(). Node.js accepts camelCase only and silently drops unknown runtime properties (while TypeScript normally rejects them).
  • Provider usage: use from_openai_usage() or from_anthropic_usage() rather than manually copying token counts and cache-accounting conventions.
  • Cost: do not supply cost; client-supplied cost is ignored because LLMtrack computes cost server-side.

Provider examples

Both examples call track() immediately after the provider completion and read counts from the official response objects.

OpenAI

import os
from openai import OpenAI
from llmtrack_sdk import LLMtrack, from_openai_usage
openai, tracker = OpenAI(), LLMtrack(api_key=os.environ["LLMTRACK_API_KEY"])
response = openai.chat.completions.create(model="gpt-5.6-sol", messages=[{"role": "user", "content": "Explain why the sky is blue in two sentences."}])
tracker.track(provider="openai", model=response.model, **from_openai_usage(response.usage), feature="science-explainer")

Anthropic

Anthropic includes thinking tokens in output_tokens rather than exposing a separate reasoning-token count, so do not duplicate them in reasoning_tokens.

import os
from anthropic import Anthropic
from llmtrack_sdk import LLMtrack, from_anthropic_usage
anthropic, tracker = Anthropic(), LLMtrack(api_key=os.environ["LLMTRACK_API_KEY"])
response = anthropic.messages.create(model="claude-opus-5", max_tokens=1024, messages=[{"role": "user", "content": "Summarize the benefits of typed APIs."}])
tracker.track(provider="anthropic", model=response.model, **from_anthropic_usage(response.usage), feature="document-summary")

Cache accounting conventions

OpenAI-style usage is inclusive: prompt tokens already include cached input tokens, and completion tokens already include reasoning tokens. Anthropic-style usage is exclusive: input tokens exclude cache reads and writes reported separately. The adapters label these conventions automatically. Set cache_accounting yourself only when the server cannot infer the convention, such as for a gateway or an unrecognised vendor; use exactly inclusive or exclusive.

Fire-and-forget and awaited usage

Method Behavior
track(**event) Synchronous fire-and-forget entry point: starts a daemon delivery thread, returns None immediately, never blocks and never raises. Errors go to on_error.
await track_sync(**event) Async awaited entry point: returns the API dictionary and raises LLMtrackError on failure. Despite its compatibility name, it must be awaited.
result = await tracker.track_sync(provider="openai", model="gpt-5.6-sol", prompt_tokens=241,
                                  completion_tokens=86, reasoning_tokens=32, feature="support-chat")

Set enabled=False in tests and local development to make both methods no-ops:

tracker = LLMtrack(api_key=os.environ["LLMTRACK_API_KEY"], enabled=False)

Constructor options

Name Type Default Description
api_key str required Server-side LLMtrack ingestion key.
base_url str https://llm-track.com API origin; primarily useful with a test server.
environment str production Environment applied when an event does not override it.
on_error Callable[[LLMtrackError], None] | None logs one [llmtrack] warning Receives track() background errors; callback exceptions are contained.
on_warning Callable[[LLMtrackWarning], None] | None logs one [llmtrack] warning Receives pricing warnings, once per distinct warning per process.
enabled bool True When False, both tracking methods do nothing.
timeout_ms int 5000 Timeout in milliseconds for each request attempt.
max_retries int 3 Maximum attempts, including the first request.

Event fields

The wrapper accepts the following snake-case fields from the IngestRequest contract.

Name Type Requirement Description
provider str required Provider name, such as openai or anthropic.
model str required Provider model name, such as gpt-5.6-sol.
prompt_tokens int required Non-negative integer input-token count.
completion_tokens int required Non-negative integer output-token count.
total_tokens int | None optional Optional explicit total; when absent, the server computes it.
reasoning_tokens int | None optional Non-negative reasoning-token count when separately reported.
cached_input_tokens int | None optional Optional cached-input count.
cache_write_tokens int | None optional Optional cache-write count.
input_audio_tokens int | None optional Optional audio input-token count.
output_audio_tokens int | None optional Optional audio output-token count.
cache_accounting str | None optional inclusive or exclusive; overrides the inferred cache-accounting convention.
latency_ms int | None optional End-to-end latency in milliseconds.
status str | None optional One of success, error, timeout, or cancelled.
feature str | None optional Product feature, such as support-chat; defaults server-side to unknown.
customer_id str | None optional Your stable customer identifier.
customer_name str | None optional Your customer display name.
environment str | None optional Overrides the constructor environment for this event.
metadata dict[str, Any] | None optional JSON object containing request context; maximum serialized size is 8 KiB (8192 bytes).
idempotency_key str | None optional SDK-only header option used to deduplicate the call, not an event-body field.

The client validates all token-count fields as non-negative integers, validates cache_accounting, and rejects metadata whose compact UTF-8 JSON serialization exceeds 8192 bytes. The server validates the remaining contract constraints.

Delivery, retries, and idempotency

Each call automatically receives a UUID v4 idempotency key. That key stays stable across retries, preventing double-counting when a stored response is lost. Supply your own stable key to deduplicate separate calls:

tracker.track(provider="openai", model="gpt-5.6-sol", prompt_tokens=241, completion_tokens=86,
              reasoning_tokens=32, feature="support-chat", idempotency_key="9ea0c2ec-7b98-4bc3-9802-20ae6a468a35")

The SDK retries only network failures, timeouts, and HTTP 5xx responses. It never retries HTTP 4xx responses.

Errors

Code Meaning Fix
INVALID_API_KEY The key is missing, unknown, or belongs to a missing workspace. Check LLMTRACK_API_KEY and create or copy a valid ingestion key.
REVOKED_API_KEY The key was revoked. Replace it with an active key.
INACTIVE_API_KEY The key was deactivated. Reactivate it or replace it.
INVALID_PAYLOAD A field failed local or server validation. Correct the named field; check integer token counts and metadata size.
QUOTA_EXCEEDED The event allowance or pay-per-event credits are exhausted. Wait for reset, add credits, or upgrade.
PLAN_INACTIVE Billing status prevents ingestion. Restore billing and reactivate the plan.
NETWORK_ERROR Network/timeout retries were exhausted, or an unclassified HTTP/server failure occurred. Check connectivity, base_url, timeout, and service availability.

track_sync() raises these errors. track() sends them to on_error and never raises.

Warnings

Response Meaning
pricing_status: unknown_model No active pricing matched the provider/model, so cost is 0; token usage is still recorded.

Troubleshooting

Events are not appearing

A short-lived process can exit before the daemon thread finishes; use await track_sync() in scripts and jobs that must confirm delivery, and inspect its returned API dictionary.

Cost shows 0

Check for UNKNOWN_MODEL or pricing_status: unknown_model. Use the exact response.model returned by the provider so active pricing can match it.

The key is rejected

Inspect LLMtrackError.code: replace invalid/revoked keys, reactivate inactive keys, and confirm the environment variable is available to the server process. Use await track_sync() to inspect the complete exception.

Contributing

Async tests use pytest-asyncio (included in the test and dev extras):

pip install -e 'packages/python[test]'
pytest packages/python/tests

More information

Metadata

Release files for llmtrack-sdk 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for llmtrack-sdk 0.2.0
File Size Uploaded
llmtrack_sdk-0.2.0.tar.gz 49.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for llmtrack-sdk 0.2.0
File Interpreter ABI Platform
llmtrack_sdk-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 145.7 kB

Release files / llmtrack_sdk-0.2.0.tar.gz

Download URL llmtrack_sdk-0.2.0.tar.gz
Size 49.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e34feddf2d350a40db26c68cf6738dde8f614a3813bc6f5b8d76d73f69d2aa95
BLAKE2b-256 checksum
How to use checksums
35d02746686435dc990c10bd06b48d39370a09e152648881760f0fc9c1e0184d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / llmtrack_sdk-0.2.0-py3-none-any.whl

Download URL llmtrack_sdk-0.2.0-py3-none-any.whl
Size 96.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc72a574e83d9e4eac5f3299c8cbc45b3859338548b74aba7c02ff86314313de
BLAKE2b-256 checksum
How to use checksums
b1aa9bdd5d985f104bf7c770fdc4eedc67e406f3c30f25d3403b6c90475632fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page