Tokonomics API Documentation
Tokonomics is a drop-in proxy between your app and any LLM provider. Change one URL, get full cost tracking, budget alerts, and analytics — in any language, any framework.
Quick Start
Replace your provider's base URL with the Tokonomics proxy URL. That's it.
# Before: direct to OpenAI
# curl https://api.openai.com/v1/chat/completions
# After: through Tokonomics (one URL change)
curl https://tokonomics.ca/proxy/openai/chat/completions \
-H "Authorization: Bearer mk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello!"}]
}'
from openai import OpenAI
client = OpenAI(
api_key="mk_your_key_here",
base_url="https://tokonomics.ca/proxy/openai" # only change
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'mk_your_key_here',
baseURL: 'https://tokonomics.ca/proxy/openai', // only change
});
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello!' }],
});
console.log(response.choices[0].message.content);
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]any{
"model": "gpt-4o",
"messages": []map[string]string{{"role": "user", "content": "Hello!"}},
})
req, _ := http.NewRequest("POST",
"https://tokonomics.ca/proxy/openai/chat/completions",
bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer mk_your_key_here")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
}
Authentication
All API requests require a Tokonomics API key passed as a Bearer token in the Authorization header.
Authorization: Bearer mk_your_key_here
| Property | Details |
|---|---|
Format |
Prefix mk_ followed by 48 hex characters |
Storage |
Only the SHA-256 hash is stored — the key is shown once at creation |
Scope |
Tied to your tenant — all usage is attributed to your account |
Management |
Dashboard → API Keys |
mk_...) is different from your provider key (sk-...). The Tokonomics key authenticates you to the proxy. Your provider key is stored encrypted in Provider Keys.
Base URL
https://tokonomics.ca
All endpoints are relative to this base URL. The proxy path follows the pattern:
https://tokonomics.ca/proxy/{provider}/{upstream-path}
Proxy Endpoint
POST /proxy/{provider}/{path}
Forwards your request to the upstream LLM provider, records token usage, calculates cost, and checks budget alerts — all transparently.
Path Parameters
| Parameter | Required | Description |
|---|---|---|
provider |
Required | Provider slug: openai, anthropic, deepseek, gemini, mistral, groq, together, xai, cohere |
path |
Required | Upstream API path, e.g. chat/completions or messages |
Headers
| Header | Required | Description |
|---|---|---|
Authorization |
Required | Your Tokonomics key: Bearer mk_... |
Content-Type |
Required | application/json |
X-Metering-Tags |
Optional | JSON object for cost attribution, e.g. {"team":"growth","feature":"chatbot"} |
X-Provider-Key |
Optional | Override the stored provider key for this request only |
Request Body
Pass the exact same body you would send directly to the provider. Tokonomics forwards it unchanged.
Response
The response is streamed back transparently — identical to calling the provider directly. Tokonomics does not buffer or modify the response body.
Supported Providers
Use the provider slug in the proxy path. The upstream path mirrors the provider's own API.
/proxy/openai/chat/completions
/proxy/anthropic/messages
/proxy/deepseek/chat/completions
/proxy/gemini/...
/proxy/mistral/chat/completions
/proxy/groq/chat/completions
/proxy/together/chat/completions
/proxy/xai/chat/completions
/proxy/cohere/chat
openai provider slug — just point your SDK's base_url to https://tokonomics.ca/proxy/openai.
Tagging Calls
Add the X-Metering-Tags header to attribute costs to specific teams, features, users, or environments. Tags are stored with every usage event and queryable via analytics.
curl https://tokonomics.ca/proxy/openai/chat/completions \
-H "Authorization: Bearer mk_your_key_here" \
-H "Content-Type: application/json" \
-H 'X-Metering-Tags: {"team":"growth","feature":"chatbot","env":"production"}' \
-d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hello!"}]}'
Common Tag Patterns
| Pattern | Example | Use case |
|---|---|---|
| By feature | {"feature":"support-bot"} |
Which feature costs the most? |
| By team | {"team":"growth"} |
Per-team budget allocation |
| By tenant | {"tenant":"acme-corp"} |
Multi-tenant SaaS cost isolation |
| By environment | {"env":"staging"} |
Separate dev/prod costs |
| By user | {"user_id":"usr_123"} |
Per-user cost tracking |
Bring Your Own Key (BYOK)
Tokonomics never calls providers on your behalf — you supply your own API keys. There are two ways to provide them:
Option 1: Store in dashboard (recommended)
Go to Provider Keys and save your provider API key once. It is stored encrypted with AES-256. Every proxy request automatically uses it.
Option 2: Per-request header
Pass your provider key directly in the request header. This overrides any stored key for that request only.
curl https://tokonomics.ca/proxy/openai/chat/completions \
-H "Authorization: Bearer mk_your_key_here" \
-H "X-Provider-Key: sk-your-openai-key" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hello!"}]}'
Key resolution priority
| Priority | Source |
|---|---|
| 1 (highest) | X-Provider-Key header (per-request) |
| 2 | Stored key in dashboard (encrypted AES-256) |
| 3 | Error — no key found |
Analytics: Summary
GET /analytics/summary
Returns current month spend, budget utilization percentage, and a breakdown by model.
curl https://tokonomics.ca/analytics/summary \
-H "Authorization: Bearer mk_your_key_here"
{
"current_spend_usd": 12.4831,
"monthly_budget_usd": 100.00,
"budget_used_pct": 12.48,
"by_model": [
{ "model": "gpt-4o", "cost_usd": 9.21, "calls": 142 },
{ "model": "deepseek-chat", "cost_usd": 3.27, "calls": 891 }
]
}
Analytics: Daily Spend
GET /analytics/daily?days=30
Returns daily spend for the last N days. Maximum 90 days.
| Parameter | Type | Default | Description |
|---|---|---|---|
days |
integer | 30 |
Number of days to return. Max 90. |
{
"daily": [
{ "date": "2026-06-01", "cost_usd": 1.2340, "calls": 48 },
{ "date": "2026-06-02", "cost_usd": 0.8821, "calls": 31 }
]
}
Analytics: By Tag
GET /analytics/by-tag?key=team&period=month
Returns spend grouped by a custom tag key. Useful for per-team or per-feature cost reports.
| Parameter | Type | Required | Description |
|---|---|---|---|
key |
string | Required | Tag key to group by, e.g. team, feature, env |
period |
string | Optional | month (default) or all |
{
"tag_key": "team",
"period": "month",
"breakdown": [
{ "value": "growth", "cost_usd": 8.44, "calls": 312 },
{ "value": "support", "cost_usd": 4.00, "calls": 189 }
]
}
Analytics: Events
GET /analytics/events?limit=50&offset=0
Returns paginated raw usage events. Maximum limit of 200 per request.
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 50 |
Number of events to return. Max 200. |
offset |
integer | 0 |
Pagination offset. |
{
"events": [
{
"id": "uuid",
"model": "gpt-4o",
"provider": "openai",
"input_tokens": 512,
"output_tokens": 128,
"cost_usd": 0.00384,
"latency_ms": 342,
"tags": { "team": "growth", "feature": "chatbot" },
"created_at": "2026-06-05T14:32:00Z"
}
],
"total": 1042,
"limit": 50,
"offset": 0
}
Errors
All errors return a JSON body with an error field and an appropriate HTTP status code.
| Status | Code | Cause |
|---|---|---|
401 |
Unauthorized | Missing or invalid API key |
400 |
Bad Request | Malformed request body |
500 |
Proxy Error | Internal proxy failure |
502 |
Provider Error | Upstream provider returned an error |
{ "error": "Invalid or inactive API key" }
Rate Limits
Per-minute rate limits
| Plan | Requests/minute | Monthly cap |
|---|---|---|
| Free | 10 | 100 calls/month |
| Pro | 60 | 1M calls/month (fair use) |
Response headers
Every proxy response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Max requests per minute for your plan |
X-RateLimit-Remaining |
Requests remaining in current window |
X-RateLimit-Reset |
Unix timestamp when the window resets |
Retry-After |
Seconds to wait (only on 429 responses) |
When limits are exceeded
Requests return 429 Too Many Requests with a Retry-After header. Wait until the window resets, then retry.
{
"error": "Rate limit exceeded",
"detail": "You have exceeded 10 requests/minute. Free plan limit.",
"retry_after": 12
}
Health Check
GET /health
No authentication required. Returns server status and current timestamp.
{ "status": "ok", "ts": 1749139200 }