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

MethodPathNotes
GET/v1/modelsOpenAI 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/completionsStreaming and non-streaming. `usage` is always present.
POST/v1/completionsLegacy text completion.
POST/v1/tokenizeToken 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.

shell
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.

shell
curl https://main-api.dev.tokencannon.io/v1/receipts/$REQUEST_ID \
  -H "Authorization: Bearer $TOKENCANNON_API_KEY"
application/json
{
  "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.

application/json
{
  "error": {
    "message": "Insufficient credits.",
    "type": "insufficient_credits",
    "code": "insufficient_credits"
  }
}
StatusMeaning
401Invalid or revoked API key.
402Insufficient credits.
404Unknown model.
429Rate limited. Honor `Retry-After`.
503No 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.