Developers
Call models with a customer key. Partners use a separate management key to read their price book, take payment into their own checkout, and issue keys.
Code samples on this page stay in English.
Try a model
Paste a key, load the models on that key, and send a short message. This is a test. The chat is cleared when you press Clear chat or leave this page, and nothing is kept overnight.
Keys and base URL
A customer key starts with sk-tr-. It is emailed after a shop purchase, or issued by a partner. Send it as Authorization: Bearer. The OpenAI-compatible base URL is https://tokenrail.ai/v1.
A partner management key starts with trk_. It manages that partner’s own customers and cannot call the model routes. Create it in the partner portal under API keys.
Chat completions
POST /v1/chat/completions
curl https://tokenrail.ai/v1/chat/completions \
-H "Authorization: Bearer sk-tr-YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Hello"}]
}'
import requests
r = requests.post(
"https://tokenrail.ai/v1/chat/completions",
headers={"Authorization": "Bearer sk-tr-YOUR-KEY"},
json={"model": "gpt-6-sol", "messages": [{"role": "user", "content": "Hello"}]},
)
print(r.json())
const res = await fetch("https://tokenrail.ai/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer sk-tr-YOUR-KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gemini-3.6-flash",
messages: [{ role: "user", content: "Hello" }],
}),
});
<?php
$ch = curl_init("https://tokenrail.ai/v1/chat/completions");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk-tr-YOUR-KEY",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"model" => "grok-4.5",
"messages" => [["role" => "user", "content" => "Hello"]],
]),
CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch);
Responses API
Codex and other Responses clients use POST /v1/responses with the same bearer key. The provider base URL is https://tokenrail.ai/v1.
curl https://tokenrail.ai/v1/responses \
-H "Authorization: Bearer sk-tr-YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-sol",
"input": "Hello"
}'
Claude Desktop and Claude Code
Point the client at https://tokenrail.ai with no /v1 on the end. The client calls /v1/messages itself. Use a bearer token, the same sk-tr- key.
curl https://tokenrail.ai/v1/messages \
-H "Authorization: Bearer sk-tr-YOUR-KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 256,
"messages": [{"role": "user", "content": "Hello"}]
}'
Images
POST /v1/images/generations. The key must include an image model, such as a Creator Studio key. size is width x height.
curl https://tokenrail.ai/v1/images/generations \
-H "Authorization: Bearer sk-tr-YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A red gift card on a blue desk",
"size": "1024x1024",
"n": 1
}'
Video
POST /v1/video/generations. duration is seconds. If the response includes a task id and a status of queued or processing, poll GET /v1/video/generations/{id} until it finishes.
curl https://tokenrail.ai/v1/video/generations \
-H "Authorization: Bearer sk-tr-YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan-3.0",
"prompt": "A train crossing a blue bridge at dusk",
"duration": 6,
"size": "1280x720"
}'
Errors
| Status | Meaning |
|---|---|
| 401 | The key is missing or unknown. |
| 403 | The key is frozen. |
| 503 | The key is not live yet, or the request could not be completed. |
The model on the request must be one of the models on that key. A chat model is not on an image-and-video key, and the reverse is also true.
Partner API
Send Authorization: Bearer trk_YOUR-KEY. These routes bill the partner wallet and return customer keys. They do not accept the customer sk-tr- key. A package is hidden until TokenRail publishes it on that partner’s price book.
Price book
GET /api/v1/price-book
curl https://tokenrail.ai/api/v1/price-book \ -H "Authorization: Bearer trk_YOUR-KEY"
Each package lists tiers (what the partner pays TokenRail, and the credit loaded on the customer key) and models with priceIn and priceOut. baseUrl is https://tokenrail.ai/v1.
Wallet
GET /api/v1/wallet returns balanceUsd and recent entries.
POST /api/partner/wallet/checkout with {"amountUsd": 100} opens a card payment from $10 to $5,000 and returns {"url"}. The paid amount is added to the wallet once.
POST /api/partner/wallet/charge with {"amountUsd": 100, "paymentMethodId": "pm_..."} charges a card already saved on the partner account.
Customers
GET /api/v1/customers
POST /api/v1/customers
curl https://tokenrail.ai/api/v1/customers \
-H "Authorization: Bearer trk_YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Ada", "email": "ada@example.com"}'
PATCH /api/v1/customers/{id} accepts name and status of active or frozen.
Issue a key
POST /api/v1/keys. payUsd is the package amount. The wallet is charged the partner price for that amount. The customer key is loaded with the package amount plus the same bonus ladder as the shop. The response includes key, chargeUsd, creditUsd, balanceUsd, models, and baseUrl.
curl https://tokenrail.ai/api/v1/keys \
-H "Authorization: Bearer trk_YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{
"bundle": "claude",
"payUsd": 100,
"customer": {"name": "Ada", "email": "ada@example.com"}
}'
Give customer.id instead of name and email to issue for a customer already on the account. A low wallet returns 400 and does not create a key.
List, top up, and freeze
GET /api/v1/keys
POST /api/v1/keys/{id}/topup with {"payUsd": 50} adds credit to that key and charges the wallet.
POST /api/v1/keys/{id}/status with {"status": "frozen"} or {"status": "active"}.
GET /api/v1/report returns wallet totals, customer count, key count, usage, and recent wallet entries.
curl https://tokenrail.ai/api/v1/keys/42/topup \
-H "Authorization: Bearer trk_YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{"payUsd": 50}'