API
Base URL: https://main-api.dev.tokencannon.io/v1. Standard endpoints match OpenAI's, with additional utilities for tokenization and request details.
Authentication
Send Authorization: Bearer tc_live_…. Keys are minted in the console and shown once; only a hash is stored server-side.
Endpoints
| Method | Path | Notes |
|---|---|---|
GET | /v1/models | OpenAI shape plus configuration fields for revision, precision, context, engine, and the four prices: `price_in_micros_per_mtok`, `price_out_micros_per_mtok`, `price_cache_read_micros_per_mtok`, `price_cache_write_micros_per_mtok` (all strings, micro-dollars per million tokens). |
POST | /v1/chat/completions | Streaming and non-streaming. `usage` is always present. |
POST | /v1/completions | Legacy text completion. |
POST | /v1/tokenize | Token count and ids under the exact served tokenizer. Non-standard on purpose. |
GET | /v1/receipts/{request_id} | The full metering record for one request. |
Tokenize
Runs the exact tokenizer of the exact revision we serve, so you can recount any prompt yourself.
curl https://main-api.dev.tokencannon.io/v1/tokenize \
-H "Authorization: Bearer $TOKENCANNON_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "tokencannon/qwen3-0.6b", "input": "Say hello in five words."}'Receipts
Every request that reaches a worker gets a receipt: the four billed counts, the prices it was billed at, model revision, engine version, timings, and finish reason. The request id is returned in the response headers.
curl https://main-api.dev.tokencannon.io/v1/receipts/$REQUEST_ID \
-H "Authorization: Bearer $TOKENCANNON_API_KEY"{
"request_id": "req_01M180J9T92B2DFDCCDHWJJ5Q6",
"model": "tokencannon/qwen3-0.6b",
"hf_revision": "c1899de289a04d12100db370d81485cdf75e47ca",
"engine_version": "v0.27.1",
"endpoint": "chat/completions",
"usage": {
"input_tokens": 2415,
"output_tokens": 8,
"cache_read_tokens": 0,
"cache_write_tokens": 2400
},
"prices": {
"input_micros_per_mtok": "50000",
"output_micros_per_mtok": "150000",
"cache_read_micros_per_mtok": "5000",
"cache_write_micros_per_mtok": "0"
},
"cost_micros": "121",
"ttft_ms": 530,
"latency_ms": 1172,
"finish_reason": "length",
"status_code": 200,
"streamed": true,
"created_at": "2026-08-30T00:19:33.644Z"
}usage is { input_tokens, output_tokens, cache_read_tokens, cache_write_tokens }; the cache fields are null when the engine did not report them, and then a noteappears ("engine did not report cached tokens; billed as uncached"). prices are the micro-dollars per million tokens the request was billed at, as strings. Cost is cost_micros = floor((input×in + cache_read×cache_read + cache_write×cache_write + output×out) / 1,000,000).
Errors
Errors use OpenAI's envelope so client SDKs handle them without changes.
{
"error": {
"message": "Insufficient credits.",
"type": "insufficient_credits",
"code": "insufficient_credits"
}
}| Status | Meaning |
|---|---|
401 | Invalid or revoked API key. |
402 | Insufficient credits. |
404 | Unknown model. |
429 | Rate limited. Honor `Retry-After`. |
503 | No capacity, or the upstream worker is unreachable. |
Rate limits
Limits are per key (requests and tokens per minute) plus a per-organization concurrency cap. Current limits are returned in X-RateLimit-* headers on every response.