Automatic LLM cost tracking in a few lines of code.
Track costs from OpenAI, Anthropic, and other LLM providers with minimal code changes. Get real-time visibility into spending by agent, feature, team, or any dimension you need.
- Minimal setup — configure once, wrap your client, you're done
- Async by default — batches requests in a background thread; never adds latency
- Multi-provider — OpenAI and Anthropic today; manual tracking for anything else
- Rich attribution — agent, feature, team, and custom tags per request
- Production-ready — tracking failures are silent; your app always runs
# Gemfile
gem "tokenr-ruby"bundle installOr install directly:
gem install tokenr-rubyThe gem is named
tokenr-rubyon RubyGems. Once installed, yourequire "tokenr"as normal.
require "openai"
require "tokenr"
Tokenr.configure do |c|
c.api_key = ENV["TOKENR_TOKEN"]
c.agent_id = "my-app" # optional default
end
client = OpenAI::Client.new(access_token: ENV["OPENAI_API_KEY"])
tracked = Tokenr::Integrations::OpenAI.wrap(client)
response = tracked.chat(parameters: {
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }]
})
# Cost is automatically tracked to Tokenrrequire "anthropic"
require "tokenr"
Tokenr.configure do |c|
c.api_key = ENV["TOKENR_TOKEN"]
end
client = Anthropic::Client.new(api_key: ENV["ANTHROPIC_API_KEY"])
tracked = Tokenr::Integrations::Anthropic.wrap(client)
response = tracked.messages(
model: "claude-opus-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }]
)
# Automatically tracked!export TOKENR_TOKEN="your-token"Tokenr.configure do |c|
c.api_key = ENV["TOKENR_TOKEN"] # or it's read automatically
endTokenr.configure do |c|
c.api_key = ENV["TOKENR_TOKEN"] # required
c.agent_id = "my-app" # default agent ID for all requests
c.team_id = nil # default team ID
c.default_tags = { environment: "prod" } # merged into every request
c.async = true # send in background (recommended)
c.batch_size = 100 # flush after this many queued events
c.flush_interval = 5 # flush every N seconds
endTokenr.configure do |c|
c.api_key = ENV["TOKENR_TOKEN"]
c.async = ENV["RAILS_ENV"] == "production"
end# Option 1: default at configure time
Tokenr.configure { |c| c.agent_id = "support-bot" }
# Option 2: per-wrapper
tracked = Tokenr::Integrations::OpenAI.wrap(client, agent_id: "sales-bot")tracked = Tokenr::Integrations::OpenAI.wrap(client,
agent_id: "support-bot",
feature_name: "ticket-summary"
)# Wrap with a team_id to roll up costs per customer/team
def ai_client_for(team)
Tokenr::Integrations::OpenAI.wrap(
base_client,
agent_id: "shared-bot",
tags: { team_id: team.id, plan: team.plan }
)
endtracked = Tokenr::Integrations::Anthropic.wrap(client,
tags: { customer_id: "cust_123", language: "es" }
)For providers without a built-in integration, or when you want explicit control:
Tokenr.track(
provider: "cohere",
model: "command-r-plus",
input_tokens: 1200,
output_tokens: 400,
agent_id: "research-bot",
feature_name: "summarization",
latency_ms: 320
)# Costs for the last 7 days
Tokenr.costs(start_date: 7.days.ago.iso8601, end_date: Time.now.iso8601)
# Grouped by agent
Tokenr.client.get_costs_by_agent(limit: 20)
# Time-series
Tokenr.client.get_timeseries(interval: "day")Tokenr::Integrations::OpenAI.wrap(client)returns a thin wrapper around your existing client- After each call the wrapper reads token counts from the response
usagefield - Events are pushed onto an in-process queue and flushed to Tokenr in the background
- If tracking fails for any reason, the exception is swallowed — your app is unaffected
- On process exit,
at_exitflushes any remaining queued events
| Provider | Auto-Tracking | Manual Tracking |
|---|---|---|
| OpenAI | Yes | Yes |
| Anthropic | Yes | Yes |
| Cohere | Coming soon | Yes |
| Custom | — | Yes |
- Sign up at tokenr.co
- Go to API Tokens and create a token
- Copy it — shown only once
export TOKENR_TOKEN="your-token-here"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
- Tracking runs on a background thread and cannot block your main thread
MIT — see LICENSE.txt
- Issues: github.com/tokenr-co/tokenr-ruby/issues
- Email: support@tokenr.co