文档

一个 OpenAI 兼容的接口,
和一份你能自己算一遍的账

把现有 SDK 的 base URL 指过来、换个 key 就行。这一页写的就是约定本身: 同样的价格、同样的系数、同样的 usage 字段——我们按它开账单。

各部分的真实状态

api.tokentoken.ai内测中
app.tokentoken.ai 控制台内测中
公开价格与 rate已上线
Skill 文件已上线

这是如实状态,不是路线图承诺。细节见下面那条提示。

动手接之前先读这一段

推理 API 还没有开放自助注册。现在 https://api.tokentoken.ai 对所有路径都返回 503 和一段说明用的 JSON——这个域名是预留的, 不是在跑。下面的接口是我们正在按着做的约定,提前公开,方便你审一遍、估成本、 并告诉我们缺什么。

如果你是现有的中转客户(New API 那套服务),你的 base URL 是 https://tokenindex.ai/v1,手里的 sk- key 不变。那是另一套服务:账号、余额、上游都和这里不共享。

想在开放时拿到名额?sales@cflabs.ai——告诉我们要哪些模型、 大概的月用量。

1 · 接入地址与鉴权

每个请求带一个 bearer token。Key 只在创建时显示一次,我们只存哈希, 所以丢了没法帮你找回——只能轮换。

POST https://api.tokentoken.ai/v1/chat/completions
Authorization: Bearer tt-...
Content-Type: application/json

Key 前缀

所有 key 以 tt- 开头。控制台显示前缀和创建时间,不显示密文。

一把 key 上挂什么

模型白名单、消费上限、RPM/TPM、并发上限、有效期,以及可选的 IP 白名单。全部在服务端强制。

归属

Key 属于组织而不是个人。吊销一把 key 不影响余额,也不影响其他 key。

2 · 第一个请求

线上协议就是 OpenAI 那套。任何能改 base URL 的客户端都能直接用——官方 openai SDK、LangChain、LlamaIndex、Codex CLI、Cline、Aider。

curl

curl https://api.tokentoken.ai/v1/chat/completions \
  -H "Authorization: Bearer $TOKENTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "tt/kimi-k3.1-pro",
    "messages": [{"role": "user", "content": "用五个字打个招呼"}],
    "max_tokens": 64
  }'

Python

from openai import OpenAI

client = OpenAI(
    base_url="https://api.tokentoken.ai/v1",
    api_key=os.environ["TOKENTOKEN_API_KEY"],
)

resp = client.chat.completions.create(
    model="tt/kimi-k3.1-pro",
    messages=[{"role": "user", "content": "用五个字打个招呼"}],
    max_tokens=64,
)
print(resp.choices[0].message.content)
print(resp.id)            # 留着:这就是账单那一行的 id

Node

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.tokentoken.ai/v1",
  apiKey: process.env.TOKENTOKEN_API_KEY,
});

const resp = await client.chat.completions.create({
  model: "tt/kimi-k3.1-pro",
  messages: [{ role: "user", content: "用五个字打个招呼" }],
  max_tokens: 64,
});

流式:传 stream: true。 不需要为了计费去传 stream_options——usage 由我们自己向上游取, 计费不依赖客户端配合。

3 · 模型 id

自部署线路一律以 tt/ 开头。一个 id 钉住的是同一份权重、 同一种量化、同一个上下文长度——我们不会悄悄把 id 背后的东西换成新版本。 换了 revision 就是一个新 id。

字段含义
id你在 model 里填的那个值。
source_label它跑在哪:own_gpu / official / cloud / licensed_third_party。每个响应里都带,不只在目录里。
context最大上下文长度(token)。
quantization实际在服务的权重格式。

完整目录与价格 llms.txt(机器可读)

4 · 这笔钱是怎么算出来的

价格按每百万 token 公开。单次调用的金额是一次精确的整数运算—— 计费链路上任何一处都不用浮点,也不用网关自己给出的成本估算, 因为它不算缓存折扣。

charge = 四舍五入(
    ( 未命中缓存的输入 × 输入价
    + 命中缓存的 token × 缓存读取价
    + 输出 token       × 输出价 ) × rate
)

缓存命中是打折的

prompt_tokens 里包含缓存命中部分。我们把 cached_tokens 减出来按缓存价算,命中的 token 绝不按全价收。

一次调用只收一次

上游重试或切换线路,你只为成功那一次付钱。失败的尝试是我们的成本,不进你的账。

rate 是一个公开数字

现在是 1.00。GET /v1/pricing 会带版本号返回它, 每条账单记录它结算时用的版本。改 rate 不会重算历史。

把用量读回来

GET /v1/pricing                  → { rate, rate_version, currency, models: [...] }
GET /v1/usage?from=&to=          → 一次调用一行:request_id、模型、token 数、金额、rate 版本
GET /v1/credits                  → { balance, currency, as_of }

每一行都带 API 当时返回的 request_id, 所以账单上任何一行都能追回到产生它的那次调用。

5 · 错误

错误体是 OpenAI 的形状:{"error":{"type","code","message"}}。 下面的 code 是我们自己的,且保持稳定。

状态码code什么意思、该怎么办
401invalid_api_keykey 不存在、已吊销或已过期。不要重试。
402insufficient_credits余额低于这次调用的估算成本。没有预扣、也没有扣款。充值后重试。
403model_not_allowed该模型不在这把 key 的白名单里。
403ip_not_allowed来源 IP 不在这把 key 的 IP 白名单里。
400parameter_out_of_range某个会放大费用的参数超了上限——max_tokens、图片张数 n、视频秒数、批量数。设上限是为了让一个写错的值不能造成失控的账单。
429rate_limited撞到这把 key 的 RPM / TPM / 并发上限。按 Retry-After 退避。
502upstream_failed该模型所有线路都失败了。预扣已释放,没有计费。
503not_launched这是今天 API 实际返回的东西。见本页顶部那条提示。

如果你的客户端在流式过程中断开,上游已经产出的 token 是真实成本,会计费;这条记录会标成 client_disconnected, 方便你找到它。

给 Agent 用

机器可读的模型目录、可直接装的 skill 文件,以及按 key 的限额—— agent 讲不通道理,因为限额在服务端强制。

Skills 与 Agent 接入 llms.txt

这页没回答的问题

接入问题找 support@cflabs.ai, 要名额和谈量找 sales@cflabs.ai, 安全相关找 security@cflabs.ai。 数据处理、留存期与可信推理在 可信与合规 页。