一个接口打通 DeepSeek、通义千问、豆包、智谱、Kimi 等六家厂商。
不用注册多家大模型、不用一家家充值——一个账号、一个钱包用遍所有模型,用多少付多少,没有月费、没有最低消费。
不用写注册登录页、不用管 API Key、不用逐家对接、不用垫付 token 成本——用户自己付自己的。
分岔点只有一个:这些 AI 调用,谁付钱?
面向 C 端、有很多最终用户:每个用户用自己的 Tokin 钱包付自己的量,你一分钱不垫、也不用管 Key。桌面应用、网页服务、App 都适用。
① 不用注册:标识自己起一个 dev_你的应用名 写进代码即可跑通全流程(开发联调、或长期只做中转,都可以一直这么用)
② 接 OAuth 授权(托管登录页,用户点一次授权,之后自动续期永久免登录)
③ 用拿到的 access_token 调 /v1 —— 用量自动归属你的 app_id
④ 要不要注册,看你需不需要这些:独占标识、用量统计归属、上架商店。需要就到控制台注册,把 dev_xxx 换成签发的 app_xxx,其余代码不动。
⚠ dev_ 标识不保证唯一:任何人都能用同一个字符串,用量统计会与之混在一起。要独占标识与干净的统计,请注册取得 app_(该号段只由平台签发,无法被他人占用)。切换到 app_ 后,此前记在 dev_ 名下的历史用量不会自动合并——在意统计连续性就一开始直接注册。
⑤ 上架应用商店 / 查看应用用量统计 —— 这两项需注册并完成实名认证(面向公众分发的合规要求)
内部工具、自研服务、原型验证:用你自己账号的余额跑,不必实名、不必注册应用、不必上架。
① 注册 Tokin 账号并充值(建议给项目单开一个账号当"公户",账目清爽、便于交接)
② 控制台 → API Keys → 新建子 Key,设额度上限 / 模型白名单 / 预算告警
③ 代码里用该子 Key 调 /v1(Key 只放服务端)
④ 想分开看用量:请求加 X-App-Id: 你起的标签,无需注册即可分组统计
日后要转成"用户各自付费",只需补认证 + 换授权那段代码,模型调用部分不动。
注册登录页由 Tokin 托管(含短信验证码 + 滑动验证)。你的应用一行代码都不用写。
丢进项目 libs/,加进 classpath 即可(零第三方依赖)。Maven 中央仓库即将上线。
# 装进本地 Maven 仓库后即可引用:
mvn install:install-file \
-Dfile=tokin-sdk-0.2.0.jar \
-DgroupId=ai.tokin -DartifactId=tokin-sdk \
-Dversion=0.2.0 -Dpackaging=jar
import ai.tokin.TokinClient;
TokinClient tokin = new TokinClient("app_abax_jz");
String reply = tokin.chat("tokin-balanced", "帮我记一笔:午餐 35 元");
// 没绑定?自动弹浏览器让用户注册授权
// 绑定后自动续期,永久免登录
tokin.chatStream(model, msgs,
delta -> print(delta)); // 流式:打字机效果,强烈推荐
tokin.balance(); // 余额(元)
tokin.topupUrl(); // 充值页,放个按钮打开它
tokin.auth().switchAccount(); // 换用户
tokin.auth().setApiKey("sk-tokin-…"); // 手动绑定(备用)
提交新版本不会影响线上:新包进审核队列期间,商店照常展示当前版本、用户下载与 /latest 自动更新拿到的仍是当前版本;审核通过才整体顶替,驳回则只丢弃新包、线上不受影响。
控制台 →「上传应用」,选安装包(exe/apk)、填版本号(如 1.3.0)+ 更新说明。平台自动做安全检查,通过即上架应用商店供下载;下载地址固定不变:
https://tokincloud.com/store/download/<appId>
发新版就是「传个更新版本号的新包」——下载地址不变,老用户下次查更新即可拿到。
机制:平台当"更新源",你的 App 启动时查一下、有新版就下载安装(只有 App 自己能装自己)。
// Java:SDK 一行查更新
var u = TokinClient.checkUpdate(
"https://api.tokincloud.com", "app_abax_jz", "1.2.0");
if (u != null && u.hasUpdate()) {
// 下载 u.downloadUrl(),SHA-256 校验 u.hash(),再拉起安装
Desktop.getDesktop().browse(URI.create(u.downloadUrl()));
}
任意语言:直接 GET /store/apps/<appId>/latest → 返回 {version, downloadUrl, releaseNotes, hash},版本不同就下载安装。
接法 A · 零界面工作(推荐):「反馈」按钮直接打开平台托管反馈页,界面我们出(建议/投诉单选、留言、联系方式、截图):
// Java:一行打开托管反馈页
Desktop.getDesktop().browse(URI.create(
tokin.feedbackUrl("1.3.0")));
// 或任意语言直接拼 URL:
https://tokincloud.com/feedback.html?app_id=...&version=...
接法 B · 应用内自绘:自己画表单,一个 POST 发平台:
POST https://api.tokincloud.com/feedback
{ "appId": "...", "version": "1.3.0",
"kind": "suggestion", // suggestion=建议 | complaint=投诉
"message": "...", // 必填 ≤2000字
"contact": "微信/手机/邮箱", // 选填
"imageBase64": "..." } // 选填 ≤2MB PNG/JPEG/WebP
反馈界面请让用户自选「建议 / 投诉」。建议类你可在控制台开发者中心只读查看(联系方式脱敏);投诉类仅平台可见、由平台跟进。
// Java:SDK 一行
TokinClient.sendFeedback(
"https://api.tokincloud.com", appId,
"1.3.0", 留言, 联系方式, 截图路径或null);
⚠️ 红线:截图必须由用户主动粘贴或选择,发送前让用户看到发的是什么——绝不自动抓屏(用户屏幕上可能是敏感数据)。自动附带的只允许版本号等系统信息。
发送失败(断网等)请兜底提示改发邮件,别让用户的话丢了。
npm i @tokincloud/sdk
const c = TokinClient.withApiKey(baseUrl, apiKey);
await c.chat({ model, messages });
await c.panel({ messages, judge: true }); // 多 agent
pip install tokincloud
from tokincloud import TokinClient
c = TokinClient.with_api_key(base_url, api_key)
c.chat(model=..., messages=[...])
c.panel(messages=[...], judge=True)
用你熟悉的 OpenAI SDK,只改 base_url:
client = OpenAI(
api_key="sk-tokin-…",
base_url="https://api.tokincloud.com/v1")
移动端 / 其它栈想做「一键连接」?流程是标准 OAuth 2.0 授权码 + PKCE: 桌面用 loopback 回调,iOS/安卓用自定义 scheme 深链 —— 每种语言都有现成 OAuth 库,照标准接即可。细节见下方「OAuth 接入细节」。
tools / tool_choice 全量透传上游,响应 tool_calls 原样返回,流式同理。在售文本模型(DeepSeek / 通义 / 智谱 / Kimi / 豆包 / MiniMax)基本都支持。
{ "model": "deepseek-chat",
"messages": [...],
"tools": [{ "type":"function",
"function": { "name":"add_expense", ... } }],
"tool_choice": "auto" }
tool 消耗计入正常 usage 计费,无额外费用。
messages 放 OpenAI 标准 image_url,http(s) 地址或 data:image/…;base64, 均可。推荐:qwen3-vl-flash(便宜) / qwen3-vl-plus / qwen-vl-max / glm-5v-turbo。
{ "role": "user", "content": [
{ "type":"text", "text":"识别这张发票" },
{ "type":"image_url", "image_url":
{ "url":"data:image/png;base64,..." } } ] }
图片 token 计入输入价计费。注意:图片别太小(几像素会被上游拒);base64 带完整前缀。
· 授权页:tokincloud.com/authorize.html?app_id=…&redirect_uri=…&code_challenge=…&state=…(PKCE S256)
· 换码/刷新:POST api.tokincloud.com/oauth/token(grant_type = authorization_code / refresh_token)
· 回调地址:loopback 免登记;自定义回调用主 Key 自助登记(精确匹配,至多 5 条):PUT /v1/apps/<app_id>/redirects {"uris":["https://…/oauth/callback"]}
· 有效期:access 900 秒;refresh 无固定过期、每次刷新即轮换(重放触发吊销);用户可在控制台随时吊销。
· scope:无细分——凭证代表「该用户在你的 app 下」的数据面权限,计费落用户钱包、用量归属你的 app_id。
· 裸 REST 接入(不用 SDK):启动时发一次 POST /attest {"appId":"…"}(免鉴权,点亮后台"运行时握手")。
· X-App-Id 什么时候要加:用 OAuth access_token 调用时不需要(凭证里已含 app_id,加了会被忽略);只有用主 Key / 子 Key 直调且想区分应用时才加。
· 授权页可带 &phone=1xxxxxxxxxx 预填手机号(减少用户输入;验证码/密码仍只在我方页面输入,应用永远碰不到凭证)。
让模型查实时信息,并拿到搜索引擎返回的真实链接——可入库、可点开核验,适合尽调 / 教学笔记 / 任何要留痕的场景。无需额外 Key,按 token 计费(搜索结果算输入)。
POST /v1/chat/completions
{ "model": "qwen-plus",
"messages": [{"role":"user","content":"今天上海天气?"}],
"enable_search": true,
"search_options": { "forced_search": true } # 可选,默认已强制联网
}
# 响应在标准结构上多一个 search_info:
{ "choices":[…], "usage":{…},
"search_info": { "search_results": [
{ "title": "…", "url": "https://…" }, … ] } }
响应头 X-Tokin-Web-Search: native 表示本次真的联网了。
· 仅通义千问系模型支持(qwen-plus / qwen-max / qwen3.7-max 等)。其它厂商会返回 X-Tokin-Web-Search: unsupported,我们不假装成功。
· 正文里的链接不可信,只信 search_info。正文的 [1] 角标与 URL 是模型自己写的、可能是编的;search_info.search_results 才是搜索引擎返回的真实标题与 URL。要留痕就存这个。
· 流式暂不带来源:stream: true 时走的是兼容模式,能搜但没有 search_info。要来源请用非流式。
搜索结果作为输入 token 计费:天气类问题约 2000 输入 token(≈¥0.002),人物/新闻类约 5000(≈¥0.004)。比独立搜索接口便宜。
防幻觉建议:在 prompt 里明确「只依据检索结果作答,未覆盖的写『未检索到』,绝不编造链接/日期/数字」。
OpenAI 兼容的 /v1/audio/transcriptions。返回句级 + 字级时间戳,可直接做字幕、或建立「第几分几秒讲了什么」的时间轴索引。按音频秒数计费,输出不计费。
curl https://api.tokincloud.com/v1/audio/transcriptions -H "Authorization: Bearer sk-tokin-…" -F file=@lecture.mp3 -F response_format=verbose_json -F prompt="吉布斯抽样,卡尔曼滤波" # 领域词表,显著降错字
# → { text, duration, segments:[
# { start: 0.48, end: 3.43, text: "…",
# speaker: 0, words:[{word,start,end}] } ] }
response_format:json(默认) / verbose_json(带时间戳) / text / srt / vtt。后两个直接就是字幕文件。
# 长录音:流式上传 + 异步(参数走 query)
curl -X POST "…/v1/audio/transcriptions?async=true&response_format=srt" -H "Content-Type: audio/mpeg" --data-binary @lecture.mp3
# → 202 { task_id, poll: "/v1/audio/transcriptions/{id}" }
GET /v1/audio/transcriptions/{task_id}?response_format=srt
# → 202 处理中 / 200 结果
· 同步模式等待超过 90 秒会自动转异步并返回 task_id,不会白等一场。
· 结果可在 24 小时内重复取回(换 response_format 再取一次也行)——取结果时网络断了不必重转,同一任务只计费一次。
· 长录音请走流式上传:multipart 会把整个文件读进服务端内存,因此限 25MB;把音频直接作为请求体(Content-Type: audio/*,参数放 query)则边收边写盘,可到 200MB。
· 一节课 90 分钟约 90MB → 用流式上传或 file_url;超限返回 413 upstream_rejected。
· diarization=true 开说话人分离,段里带 speaker。
· 已有公网音频地址可用 file_url 替代上传,省一次中转。
按音频时长计费,转出多少字都不加钱。响应头 X-Tokin-Audio-Seconds / X-Tokin-Billing 回显本次秒数与金额。90 分钟的课约 ¥0.44。
WebSocket 双向流:麦克风音频往上送,识别结果边说边回。约 1 秒出首字,中间稿持续刷新,句末给带时间戳的终稿。适合课堂字幕、会议纪要、直播实时字幕。
// 凭证走 query:浏览器无法给 WS 设 Authorization 头
const ws = new WebSocket(
"wss://api.tokincloud.com/v1/realtime/transcriptions"
+ "?token=sk-tokin-…&sample_rate=16000&format=pcm");
ws.onmessage = (e) => {
const m = JSON.parse(e.data);
// session.started → transcript(多次) → billing
if (m.type === "transcript")
render(m.text, m.is_final, m.begin_time, m.end_time);
};
// 上行:二进制帧 = 音频块;说完发 {"type":"finish"}
ws.send(pcmChunk);
ws.send(JSON.stringify({ type: "finish" }));
音频建议 16kHz 单声道 PCM,每 100ms 一块(3200 字节)。也支持 opus/mp3/aac 等,用 format 指定。
{"type":"session.started", model, sample_rate}
{"type":"transcript", text, is_final,
begin_time, end_time} // 毫秒
{"type":"billing", seconds, amount,
final} // 每结算一次一条
{"type":"error", message, code}
· is_final=false 是中间稿(会被后续覆盖),true 才是定稿——入库只存终稿。
· 单账号同时最多 5 路;单会话最长 2 小时,超时服务端主动断。
· 每满 60 秒音频结算一次并推一条 billing 消息(seconds 是累计值,不是增量),不是断开才算——余额花光会被中断,不会欠账。
· 会话结束时若还有不满 60 秒的零头,补结一次并推 final:true 的 billing——以这条为最终账单。一节 90 分钟的课共 90 条左右。
· 课上到一半余额用尽会当场断开并给 insufficient_quota;因为是「先扣款再发现」,最多透支一个计费周期(约 ¥0.015),不会持续欠账。长课建议课前确认余额。
· 断线(网络抖动/客户端崩溃)已转写部分照常计费,重连请重新建立会话。
按音频秒数,¥0.00024/秒 × 加价倍率 → 一节 90 分钟的课约 ¥1.3。比课后文件转写(约 ¥0.44)贵,换来的是实时。
模型之外的能力,同一个 Key、同一个钱包:调用成功按次扣费(价格见 GET /v1/services),支持代付、X-Usage-Tag 分组、子 Key 预算——口径与模型调用完全一致。上游失败不收费。
POST /v1/search
{ "query": "2026 世界杯 举办地", "count": 10,
"freshness": "noLimit" } # 可选 oneDay/oneWeek/oneMonth/oneYear
# → { results:[{title,url,snippet,publishedTime?,siteName?}],
# billing:{service:"web-search",amount} }
给模型喂实时信息的标配:搜索 → 把 results 拼进 prompt → 再调 /v1/chat/completions。query ≤200 字符,count 1–20;snippet 已是长摘要,可直接入 prompt。
# 简易:按关键词查企业(自动走「实体识别」)
POST /v1/company
{ "keyword": "阿里巴巴" }
# 进阶:先看工具目录,再精确调任一工具
GET /v1/company/tools?server=risk # 目录免费
POST /v1/company
{ "server":"risk", "tool":"工具名", "arguments":{…} }
# → { result:…, billing:{service:"company-search",amount} }
数据源为企查查智能体数据平台,共 185 个原子工具。服务可选:company / risk / ipr / operation / history / executive / regulation / case / tender / document。「客户尽调 / 合同相对方核验 / 供应商体检」直接搭。
按工具计价:不同工具单价不同(约 ¥0.1~¥2 / 次),GET /v1/company/tools 的每个工具都带 price 字段,调用前即可知价;实际扣费以响应里的 billing.amount 为准。查无结果不收费。
授权页在主域,API 在 api 子域——这是最常见的接错点。
| 用途 | 端点 | 鉴权 |
|---|---|---|
| 授权页(浏览器打开) | https://tokincloud.com/authorize.html | 用户登录 |
| 换码 / 刷新令牌 | POST https://api.tokincloud.com/oauth/token | 无(PKCE) |
| 模型推理 | POST https://api.tokincloud.com/v1/chat/completions | Bearer access_token 或 sk-tokin-* |
| 多 agent 面板 | POST https://api.tokincloud.com/v1/panel | 同上 |
| 实时转写(WebSocket) | wss://api.tokincloud.com/v1/realtime/transcriptions?token=… | token 走 query |
| 音频转写 | POST https://api.tokincloud.com/v1/audio/transcriptions | 同上(按秒计费) |
| 联网搜索 / 企业查询 | POST https://api.tokincloud.com/v1/search · /v1/company | 同上(按次计费) |
| 余额 / 用量 | GET https://api.tokincloud.com/v1/balance · /v1/usage | 同上 |
| 启动握手(可选) | POST https://api.tokincloud.com/attest | 无 |
| 回调地址登记 | PUT https://api.tokincloud.com/v1/apps/<app_id>/redirects | 开发者本人的 sk-tokin-* |
桌面应用用 SDK 的 connect()(拉起浏览器 + loopback 收码)。Web 后端要为 N 个用户分别保管凭证——Python 有官方封装,其它语言按下方协议自己实现(就三步)。
pip install tokincloud
from tokincloud import TokinWebAuth, SqliteTokenStore
auth = TokinWebAuth(
base_url="https://api.tokincloud.com",
app_id="app_xxxxxxxxxxxxxxxx", # 线上域名回调须用平台签发的 app_
redirect_uri="https://你的域名/oauth/callback",
store=SqliteTokenStore("tokens.db"), # 换成你自己的库:实现 save/load/delete 三个方法
)
url = auth.start(user_id="本站用户ID") # ① 302 跳过去(PKCE + state 内部生成)
uid = auth.callback(code=code, state=state) # ② 回调换凭证并落库,从 state 还原本站用户
auth.client_for(uid).chat(model=..., messages=...) # ③ 之后随时用,过期自动续、轮换自动回存
可跑示例:FastAPI · Django。本地调试用 http://127.0.0.1:8000/oauth/callback 配 dev_ 前缀即可,免注册;多进程部署(gunicorn -w 4)把 pending 换成 Redis 实现,示例文件末尾有现成的。
# 服务端生成并暂存(按 state 索引本站用户)
verifier = base64url(random(32))
challenge = base64url(sha256(verifier))
state = random()
store[state] = { user_id, verifier } # 5~10 分钟过期
# 302 跳转用户浏览器到:
https://tokincloud.com/authorize.html
?app_id=dev_yourapp
&redirect_uri=https://你的域名/oauth/callback
&code_challenge={challenge}&state={state}
非 loopback 回调需先登记:PUT /v1/apps/<app_id>/redirects(用开发者本人的 sk-tokin-* 主 Key,不是终端用户的)。
# GET /oauth/callback?code=..&state=..
{ user_id, verifier } = store.pop(state) # state 不匹配即拒绝
POST https://api.tokincloud.com/oauth/token
{ "grant_type":"authorization_code",
"code": code, "code_verifier": verifier }
# → { access_token, refresh_token, expires_in, token_type }
db.save(user_id, refresh_token, access_token,
expires_at = now + expires_in)
if now >= expires_at - 60:
POST /oauth/token
{ "grant_type":"refresh_token",
"refresh_token": db.get(user_id) }
# refresh_token 每次刷新都会轮换 → 必须回写覆盖
刷新是自研最容易出错的部分。官方 SDK(TokinWebAuth / TokenManager)已内置下面全部行为;自己实现请逐条对照:
· 并发单飞:同一用户多个线程/请求同时发现过期时,只应发出一次刷新(拿锁后先复查凭证是否已被别人换新)。否则并发刷新互相作废对方的 refresh_token。
· 轮换必回存:每次刷新返回新的 refresh_token,必须覆盖保存后再放行业务请求。先用后存的窗口里进程崩溃 = 该用户凭证永久失效。
· 30 秒宽限期:多副本用同一个旧值重复刷新,30 秒内会回放同一结果(不误判盗用);超过 30 秒的重放按泄露处理、整条授权吊销。宽限期是兜底,不是许可——仍应以单飞为目标。
· 失败要分类,不能一律清凭证重授权:401 invalid_grant = 授权确实失效 → 清凭证、引导重新授权;503 temporarily_unavailable = 瞬时故障 → 重试,别清凭证;403 access_revoked(业务调用时)= 用户主动吊销 → 清凭证。
· 401 兜底重试一次:业务请求撞上刚好过期的 access → 强制刷新后重放一次即可,不要循环。
// 请求(二选一)
{ "grant_type":"authorization_code",
"code":"...", "code_verifier":"..." }
{ "grant_type":"refresh_token",
"refresh_token":"..." }
// 响应 200
{ "access_token": "...", // Bearer 用它调 /v1
"refresh_token": "...", // 每次刷新都轮换,务必覆盖保存
"expires_in": 900, // 秒(access 有效期)
"token_type": "Bearer" }
// 失败 401
{ "error":"invalid_grant", "message":"..." }
refresh_token 无固定过期。支持轮换宽限期:多副本服务并发刷新时,30 秒内用同一个旧值重复刷新会回放上次结果(返回同一个新 refresh_token),不会误判为盗用;超过 30 秒的重放仍按泄露处理、吊销整条授权,所以务必以最新值覆盖保存。
{ "object":"list", "data":[
{ "id":"tokin-balanced", "object":"model-mode",
"description":"速度效果均衡(默认)" },
{ "id":"deepseek-v4-flash", "object":"model",
"owned_by":"deepseek" } ] }
按 object 区分:model-mode=语义模式,model=具体模型。只列当前已上架可调用的,可直接用于选择器与可用性校验。
// GET /v1/balance
{ "balance": 12.3456 } // 单位:元(人民币),可为小数
// GET /v1/usage
{ "count": 42, "totalSpent": 1.234,
"records": [ { "ts":…, "provider":"deepseek",
"model":"deepseek-chat", "promptTokens":…,
"completionTokens":…, "spent":0.0021 } ] }
401 invalid_token — access 过期/无效 → 用 refresh_token 刷新后重试一次
403 access_revoked — 用户已吊销授权 → 刷新无用,引导用户重新授权
402 insufficient_quota — 用户余额不足 → 提示去充值
429 rate_limit_exceeded — 超过 RPM(默认 60/分钟)→ 退避重试
429 app_quota_exceeded — 单应用窗口花费上限 → 退避 / 联系我们调额
400 model_not_found — 模型名错或未开放 → 对照 /v1/models
400 upstream_rejected — 上游拒绝了请求本身(如输入超长)→ 不会故障转移,按 message 修请求
502 upstream_error — 上游全失败(已自动故障转移过)→ 可稍后重试
503 temporarily_unavailable — 刷新令牌时的瞬时冲突 → 退避重试即可,勿清除凭证
所有端点(含 /oauth/token)错误体统一为 {"error":{"message","type","code"}},只写一套解析即可;OAuth 端点额外在顶层保留 code 字段兼容旧客户端。
标准 OpenAI SSE 协议,裸 REST 即可用。强烈建议开启——首字通常几百毫秒返回,体感比等全文快得多。
POST /v1/chat/completions
{ "model":"deepseek-v4-flash",
"messages":[…], "stream": true }
# 响应 Content-Type: text/event-stream
data: {"choices":[{"delta":{"content":"你"}}]}
data: {"choices":[{"delta":{"content":"好"}}]}
data: {"choices":[…],"usage":{…}} # 见右
data: [DONE]
按行读,取 data: 后的 JSON;遇 [DONE] 结束。非 JSON 帧(心跳等)忽略即可。
· usage 在最后一个数据帧([DONE] 之前那帧)。我们已自动向上游注入 stream_options.include_usage,你不必自己传。计费以该帧为准。
· 中途出错:HTTP 已 200,无法再改状态码,因此以一个错误帧表达,随后关闭流:
data: {"error":{"message":"…","type":"upstream_error"}}
所以每帧都要检查有没有 error 字段。
· 已扣费的部分以收到的 usage 帧为准;未产生 usage 帧则不计费。
· rate_limit_exceeded:每「用户 × 应用」60 次/分钟(滑动窗口)。不是按 app 汇总——一个班几十人同时用互不挤占。
· app_quota_exceeded:同样按「用户 × 应用」计,默认 ¥10/窗口,防单用户异常烧钱。
· 两者都返回 429 + Retry-After(秒),响应体也带 error.retryAfter,照它退避即可。
量确实不够用时联系我们按 app 调高,不必自建排队层。
· 我们绝不静默截断——请求原样透传给上游,不做任何裁剪。
· 超出模型上下文时,上游会拒绝,我们原样回传原因:400 {"error":{"code":"upstream_rejected","message":"…"}}
· 这类「请求本身的问题」不会触发故障转移(换厂商也一样失败),会立即返回,不浪费时间。
长文(如整节课转写)建议选长上下文模型,或自行分段后合并。
· 非流式:建议客户端超时 120 秒(长文本+推理模型可能跑到 1 分钟以上)。
· 流式:建议按「首字超时 30 秒 + 帧间超时 60 秒」,别用总时长卡。
· 我们侧不主动截断长生成;上游各家自身有其超时策略。
X-Usage-Tag按班级 / 课程 / 项目分组对账。平台不解释标签含义,只做聚合(≤64 字符)。多维标签的约定:一个字符串装多层、用 . 分隔,报表用 prefix 过滤任一层。
POST /v1/chat/completions
X-Usage-Tag: course_abc.feature_note # 第一层=班级,第二层=功能
# 查询聚合(含调用次数与 token 数——判断"变多"还是"变贵")
GET /v1/usage/by-tag?days=30
# → { tags:[{tag,calls,tokensIn,tokensOut,spent,lastUsedAt}] }
# 前缀过滤:course_abc. 开头 = 这个班的全部功能
GET /v1/usage/by-tag?days=30&prefix=course_abc.
# 按天分桶(做周报/月报客户端按天汇总即可)
GET /v1/usage/by-tag?days=30&bucket=day
# → { tags:[{tag,day:"2026-08-13",calls,…}] }(标签×天,Asia/Shanghai)
# 机构视角(看自己代付的成员,按标签分),同样支持 prefix/bucket
GET /v1/sponsor/usage/by-tag?days=30
# → { tags:[{tag,calls,members,tokensIn,tokensOut,spent}] }
标签会不会被别人"污染"?不会——以上报表都按「你的账号 / 你代付的成员」聚合,从不按 app 汇总;即使有人用了与你相同的 dev_ 标识和标签,也进不了你的报表(app 维度的平台统计才会混,这是尽早注册 app_ 的又一理由)。
用语义模式(tokin-balanced 等)时,响应头会明示真实模型,便于留痕与复现:
X-Tokin-Served-Model: deepseek-v4-flash # 实际模型
X-Tokin-Served-By: deepseek # 实际厂商
X-Tokin-Mode: tokin-balanced # 你传的模式(仅模式调用时)
X-Tokin-Failover: true # 发生了故障转移(仅转移时)
直接指定具体模型时,返回体 model 字段即为实际模型。流式同样带这些响应头(胜出候选在首帧确定后才开流),流式与非流式可共用一套"读响应头"代码。
# 带 redirect_uri 时 → 原样回跳并带上:
{redirect_uri}?error=access_denied&state={state}
# 无 redirect_uri(桌面手动复制场景)
# → 停在我们页面显示"已取消授权",不回跳
回调里请同时处理 code 与 error 两种参数;state 一律原样带回。
· 主机名 127.0.0.1 / localhost / ::1 等价,均免登记。
· 端口任意(遵循 RFC 8252,桌面应用可用随机端口)。
· loopback 允许 http;其它主机必须登记,登记后按完整字符串精确匹配(含路径与端口)。
授权页向用户明示:该应用仅可代其发起模型调用并从钱包扣费;拿不到账户密码或主密钥,不能提现、不能改账户、不能读取其它数据;凭证可随时在控制台一键吊销。
面向学校 / 家长解释时可直接引用这段。
可填具体模型名,也可填语义模式——由平台按你的意图自动选最优模型并故障转移:
tokin-fasttokin-balancedtokin-qualitytokin-cheapesttokin-reasoning
会自适应,而你什么都不用做——只要把 model 填成语义模式(如 tokin-balanced):
平台按意图自动选当前最优模型,某家故障时自动切换下一家。
新模型上线、厂商降价、接口变更,都由我们在服务端跟进,你的应用零改动自动受益。
想锁死某个模型?把 model 填具体名(如 deepseek-chat),我们就不替你选。
具体模型名与实时价格见 定价页,或调用 GET /v1/models。