API Documentation
Track and query LLM costs programmatically using the tokenr API.
Authentication
All API requests require a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_TOKEN
Generate tokens from the API Tokens page.
Endpoints
POST /api/v1/track
Track a single LLM request. Requires write scope.
Request Body
{
"model": "gpt-4o",
"provider": "openai",
"agent_id": "customer-support-agent",
"feature_name": "ticket-classification",
"team_id": "engineering",
"input_tokens": 500,
"output_tokens": 150,
"total_cost": 0.0195, // optional, calculated if omitted
"latency_ms": 1250,
"status": "success",
"external_id": "req_abc123", // optional, for deduplication
"requested_at": "2024-01-15T10:30:00Z",
"tags": { "env": "production" },
"metrics": { "temperature": 0.7 }
}
Response
{
"id": 12345,
"cost": 0.0195
}
POST /api/v1/track/batch
Track multiple LLM requests at once. Requires write scope.
Request Body
{
"requests": [
{ "model": "gpt-4o", "input_tokens": 100, "output_tokens": 50, "agent_id": "agent-1" },
{ "model": "gpt-4o-mini", "input_tokens": 200, "output_tokens": 100, "agent_id": "agent-2" }
]
}
Response
{
"accepted": 2,
"rejected": 0,
"errors": []
}
GET /api/v1/costs
Query cost data with filters. Requires read scope.
Query Parameters
| Parameter | Description |
|---|---|
start_date | Start date (ISO 8601). Default: 30 days ago |
end_date | End date (ISO 8601). Default: now |
agent_id | Filter by agent ID |
model | Filter by model name |
team_id | Filter by team ID |
feature | Filter by feature name |
group_by | Group results: agent_id, feature_name, team_id |
Response
{
"total_cost": 1250.45,
"total_requests": 45230,
"total_tokens": 12500000,
"input_tokens": 10000000,
"output_tokens": 2500000,
"period": {
"start": "2024-01-01T00:00:00Z",
"end": "2024-01-31T23:59:59Z"
}
}
GET /api/v1/costs/agents
Get costs grouped by agent. Requires read scope.
Query Parameters
| Parameter | Description |
|---|---|
limit | Number of agents to return. Default: 50 |
start_date | Start date filter |
end_date | End date filter |
Response
{
"agents": [
{
"agent_id": "customer-support-agent",
"total_cost": 450.25,
"input_tokens": 5000000,
"output_tokens": 1200000,
"request_count": 12500
}
]
}
GET /api/v1/costs/models
Get costs grouped by model. Requires read scope.
Response
{
"models": [
{
"model": "gpt-4o",
"display_name": "GPT-4o",
"total_cost": 800.50,
"input_tokens": 8000000,
"output_tokens": 2000000,
"request_count": 25000
}
]
}
GET /api/v1/costs/timeseries
Get time series cost data. Requires read scope.
Query Parameters
| Parameter | Description |
|---|---|
interval | hour, day, week, or month. Default: day |
start_date | Start date filter |
end_date | End date filter |
Response
{
"interval": "day",
"data": [
{ "time": "2024-01-15T00:00:00Z", "cost": 45.25, "tokens": 500000, "requests": 1250 },
{ "time": "2024-01-16T00:00:00Z", "cost": 52.10, "tokens": 580000, "requests": 1400 }
]
}
GET /api/v1/tokens/me
Get information about the current API token.
Response
{
"token": {
"prefix": "ac_prod_",
"name": "Production SDK",
"scopes": ["read", "write"],
"created_at": "2024-01-01T00:00:00Z",
"expires_at": null,
"usage_count": 12500,
"last_used_at": "2024-01-15T10:30:00Z"
},
"organization": {
"id": 1,
"name": "Acme Corp",
"slug": "acme-corp"
}
}
Rate Limits
- General API: 100 requests/minute per token
- Tracking endpoints: 500 requests/minute per token
Rate limit headers are included in responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
Retry-After: 60
Error Responses
// 401 Unauthorized
{ "error": "Invalid API token" }
// 403 Forbidden
{ "error": "Token missing required scope: write" }
// 429 Too Many Requests
{ "error": "Rate limit exceeded. Retry in 45 seconds." }
// 422 Unprocessable Entity
{ "error": "Model can't be blank" }
Ruby SDK
Install the SDK for automatic tracking:
# Gemfile
gem 'tokenr_sdk'
# Configuration
tokenrSdk.configure do |c|
c.api_key = ENV['AGENT_COST_API_KEY']
c.agent_id = 'my-agent'
end
# Track manually
tokenrSdk.track(model: 'gpt-4o', input_tokens: 500, output_tokens: 100)
# Or wrap your OpenAI client
client = OpenAI::Client.new(access_token: ENV['OPENAI_KEY'])
tracked = tokenrSdk::Integrations::OpenAI.wrap(client, agent_id: 'my-agent')
tracked.chat(parameters: { model: 'gpt-4o', messages: [...] })