API documentation

TokenKiln speaks the OpenAI API shape. Anything that works with the OpenAI SDKs works here — change the base URL and key, keep your code.

Quickstart

Your base URL is your deployment origin plus /api/v1. Create an API key from the dashboard, then:

curl https://your-gateway.up.railway.app/api/v1/chat/completions \
  -H "Authorization: Bearer tk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "tokenkiln/default",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

Python (openai ≥ 1.0):

from openai import OpenAI

client = OpenAI(
    base_url="https://your-gateway.up.railway.app/api/v1",
    api_key="tk_...",
)

response = client.chat.completions.create(
    model="tokenkiln/default",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)

JavaScript / TypeScript:

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://your-gateway.up.railway.app/api/v1",
  apiKey: "tk_...",
});

const stream = await client.chat.completions.create({
  model: "tokenkiln/default",
  messages: [{ role: "user", content: "Hello!" }],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Authentication

Pass your key as a bearer token: Authorization: Bearer tk_…. Keys are shown once at creation and stored only as SHA-256 hashes. Revoke a key at any time from the dashboard; revocation is immediate.

Streaming

Set "stream": truefor server-sent events, token by token, identical to OpenAI's format (terminated by data: [DONE]). Usage is metered from the engine's own token counts. If you also want the usage summary chunk in your stream, pass "stream_options": {"include_usage": true}.

Embeddings

POST /embeddingsis proxied to the same backend and billed at the model's input-token rate.

curl https://your-gateway.up.railway.app/api/v1/embeddings \
  -H "Authorization: Bearer tk_..." \
  -H "Content-Type: application/json" \
  -d '{"model": "your/embedding-model", "input": "The quick brown fox"}'

Models

GET /models lists available models. Catalog models carry a pricing extension field (USD per million tokens). See the models page for the human-readable version.

Billing model

  • Credits are prepaid; balances are tracked in micro-dollars.
  • Before dispatch, the gateway checks your balance against a worst-case estimate (request size + max_tokens).
  • After the response, you're charged for actual engine-reported usage — never the estimate.
  • Failed upstream requests are never billed.
  • Each response carries an x-request-id header that matches your dashboard activity log.

Errors

StatusCodeMeaning
401invalid_api_keyMissing, malformed, or revoked API key.
402insufficient_quotaPrepaid balance can't cover the request's worst-case cost. Top up.
404model_not_foundThe model isn't in the catalog.
429rate_limit_errorToo many requests per minute for this key. Honor Retry-After.
429monthly_key_limit_exceededThe key's monthly spend cap is exhausted.
502/504server_errorThe GPU backend failed or timed out. You are not charged.

Error bodies follow the OpenAI shape: { "error": { "message", "type", "code" } }