SDKs

Official SDKs for Python, TypeScript, and Go. All SDKs share the same behavior: automatic retry on 5xx with exponential backoff, UUIDv7 event ID generation, and no client-side cost calculation.

Python SDK

pip install tokage

Install

shell
pip install tokage

Requires Python 3.9+ and httpx ≥0.27

Sync client

python
from tokage import TokageClient, TokenUsageEvent

# Sync client — use in regular Python apps and scripts
client = TokageClient(api_key="tok_live_...")

event_id = client.track(
    TokenUsageEvent(
        model_provider="anthropic",
        model_id="claude-sonnet-4-6",
        input_tokens=512,
        output_tokens=128,
        total_tokens=640,
        application_id="my-app",
        user_id="alice@example.com",
        environment="production",
    )
)
print(f"Tracked: {event_id}")

Async client

python
import asyncio
from tokage import AsyncTokageClient, TokenUsageEvent

async def main():
    async with AsyncTokageClient(api_key="tok_live_...") as client:
        event_id = await client.track(
            TokenUsageEvent(
                model_provider="openai",
                model_id="gpt-4o",
                input_tokens=1024,
                output_tokens=256,
                total_tokens=1280,
            )
        )
        print(f"Tracked: {event_id}")

asyncio.run(main())

Batch ingestion

python
with TokageClient(api_key="tok_live_...") as client:
    response = client.track_batch([
        TokenUsageEvent(
            model_provider="openai", model_id="gpt-4o",
            input_tokens=100, output_tokens=50, total_tokens=150,
        ),
        TokenUsageEvent(
            model_provider="anthropic", model_id="claude-haiku-4-5",
            input_tokens=200, output_tokens=80, total_tokens=280,
        ),
    ])
    print(f"Accepted {response.accepted} events: {response.event_ids}")

Error handling

python
from tokage import TokageClient, TokenUsageEvent
from tokage import AuthenticationError, RateLimitError, ServerError, ValidationError
import time

client = TokageClient(api_key="tok_live_...")

try:
    client.track(event)
except AuthenticationError:
    print("Check your API key")
except ValidationError as e:
    print(f"Bad payload: {e.errors}")
except RateLimitError as e:
    if e.retry_after:
        time.sleep(e.retry_after)
except ServerError:
    # SDK already retried 3 times with exponential backoff
    print("Tokage is experiencing issues")

TypeScript / Node.js SDK

npm install @tokage/sdk

Install

shell
npm install @tokage/sdk
# or: yarn add @tokage/sdk  /  pnpm add @tokage/sdk

Requires Node.js 18+ (uses native fetch and ES modules)

Track events

typescript
import { TokageClient } from '@tokage/sdk';

const client = new TokageClient({ apiKey: process.env.TOKAGE_API_KEY! });

// Single event
const eventId = await client.track({
  modelProvider: 'anthropic',
  modelId: 'claude-sonnet-4-6',
  inputTokens: 512,
  outputTokens: 128,
  totalTokens: 640,
  applicationId: 'my-app',
  userId: 'alice@example.com',
  environment: 'production',
});

// Batch (up to 1000 events)
const result = await client.trackBatch([
  { modelProvider: 'openai', modelId: 'gpt-4o', inputTokens: 100, outputTokens: 50, totalTokens: 150 },
  { modelProvider: 'anthropic', modelId: 'claude-haiku-4-5', inputTokens: 200, outputTokens: 80, totalTokens: 280 },
]);
console.log(`Accepted ${result.accepted} events`);

Error handling

typescript
import { TokageClient, AuthenticationError, RateLimitError, ServerError } from '@tokage/sdk';

const client = new TokageClient({ apiKey: process.env.TOKAGE_API_KEY! });

try {
  await client.track(event);
} catch (err) {
  if (err instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (err instanceof RateLimitError) {
    console.error(`Rate limited, retry after ${err.retryAfter}s`);
  } else if (err instanceof ServerError) {
    // Already retried 3× with exponential backoff + jitter
    console.error('Tokage server error');
  }
}

Go SDK

go get github.com/tokage-io/tokage/sdks/go/tokage

Install

shell
go get github.com/tokage-io/tokage/sdks/go/tokage

Requires Go 1.22+

Track a single event

go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tokage-io/tokage/sdks/go/tokage"
)

func main() {
    client := tokage.NewClient(os.Getenv("TOKAGE_API_KEY"))

    // Single event — fluent builder
    event := tokage.NewEvent("anthropic", "claude-sonnet-4-6", 512, 128).
        WithApplicationID("my-app").
        WithUserID("alice@example.com").
        WithEnvironment("production").
        WithMetadata(map[string]string{"session": "abc123"})

    eventID, err := client.Track(context.Background(), event)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Tracked:", eventID)
}

Batch ingestion

go
// Batch ingestion
events := []*tokage.Event{
    tokage.NewEvent("openai", "gpt-4o", 1024, 256),
    tokage.NewEvent("anthropic", "claude-haiku-4-5", 200, 80),
}

result, err := client.TrackBatch(context.Background(), events)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Accepted %d events\n", result.Accepted)

Error handling

go
import "github.com/tokage-io/tokage/sdks/go/tokage"

eventID, err := client.Track(ctx, event)
if err != nil {
    var authErr *tokage.AuthenticationError
    var rateLimitErr *tokage.RateLimitError
    switch {
    case errors.As(err, &authErr):
        log.Fatal("invalid API key")
    case errors.As(err, &rateLimitErr):
        log.Printf("rate limited, retry after %ds", rateLimitErr.RetryAfter)
        time.Sleep(time.Duration(rateLimitErr.RetryAfter) * time.Second)
    default:
        // 5xx errors already retried 3× with exponential backoff
        log.Printf("track failed: %v", err)
    }
}

Common SDK Behavior

  • Automatic retry: 5xx errors are retried up to 3 times with exponential backoff (500ms, 1s, 2s) and ±20% jitter.
  • No retry on 4xx: Authentication, validation, and rate-limit errors are returned immediately.
  • UUIDv7 event IDs: Auto-generated if not provided. Monotonically increasing, time-prefixed, used for deduplication.
  • No cost fields: Never provide input_cost_usd, output_cost_usd, or total_cost_usd. Cost is stamped server-side.
  • Thread-safe: All SDK clients are safe for concurrent use across goroutines, threads, and async contexts.