认证

JoyToken 的 OpenAI-compatible API 使用 API Key 认证。模型调用入口是 POST /openai/v1/chat/completions,网关会先校验 Key,再执行策略检查、路由、钱包预冻结、provider 调用、用量记录和账单归因。

API Key 代表真实的钱包额度和策略权限。不要把明文 Key 放进浏览器、移动端包、公开仓库、日志或 issue 截图里。生产请求应从你的服务端发起。

使用 API Key

新接入推荐使用 Authorization: Bearer

cURL
$curl https://api-dev.joytokens.ai/openai/v1/chat/completions \
> -H "Authorization: Bearer $JOY_TOKEN_API_KEY" \
> -H "Content-Type: application/json" \
> -H "X-Request-ID: auth-example-001" \
> -d '{
> "model": "auto",
> "tier": "standard",
> "messages": [
> { "role": "user", "content": "ping" }
> ],
> "stream": false
> }'

如果你已经在使用 OpenAI SDK,只需要替换 apiKeybaseURL

1import OpenAI from "openai";
2
3const client = new OpenAI({
4 apiKey: process.env.JOY_TOKEN_API_KEY,
5 baseURL: "https://api-dev.joytokens.ai/openai/v1",
6});
7
8const response = await client.chat.completions.create({
9 model: "auto",
10 messages: [{ role: "user", content: "Say hello from JoyToken." }],
11});
12
13console.log(response.choices[0]?.message?.content);

请求头

Header必填当前行为
Authorization推荐写法:Bearer $JOY_TOKEN_API_KEY
X-API-Key可选兼容写法。若同时存在,网关优先读取 X-API-Key
Content-TypeJSON 请求使用 application/json
X-Request-ID可选用于网关日志、provider 调用、账单记录和排障关联;未提供时网关会生成 req-*

X-API-Key 是兼容入口,不建议新项目作为默认写法。团队接入统一使用 Bearer token,能减少代理层和 SDK 中的特殊处理。

网关校验流程

api-gateway 会从请求头提取明文 Key,并通过 apikey-serviceValidateApiKey 校验。校验通过后,网关才会继续构造 policy、调用 router 和 provider。

Client
-> api-gateway
-> apikey-service ValidateApiKey
-> policy check
-> wallet precheck / freeze
-> router-service
-> provider-adapter-service
-> upstream model

校验结果会被网关用于路由和计费:

字段用途
valid / status判断 Key 是否可用。当前要求 valid = truestatus = ACTIVE
api_key_id用量记录、账单归因、钱包额度同步
owner_id / tenant_id个人或组织归属
billing_type / billing_id决定扣个人钱包还是组织账户
tierAPI Key 绑定的可用档位
fixed_model限定这个 Key 只能使用指定模型
limit_total / limit_daily / limit_weekly网关和账单侧的额度检查输入
policy_snapshot_jsonKey 创建时绑定的策略快照,包括 IP、模型黑名单、路由策略和可用 tier

策略与钱包检查

认证成功不代表请求一定会被执行。网关还会继续检查:

检查失败时常见响应
请求体解析、messages 是否为空、body 是否超过 8 MiB400 invalid_request_error
Key 是否 active403 invalid_api_key
IP 白名单/黑名单、模型黑名单、fixed model、tier 策略403 policy_rejected
钱包余额、预算、预冻结额度402 insufficient_quota
路由服务或 provider 调用失败502 routing_errorupstream_error

错误响应保持 OpenAI-compatible 的形态:

Error response
1{
2 "error": {
3 "type": "missing_api_key",
4 "message": "missing api key"
5 }
6}

响应中的认证和治理信号

成功响应保留 OpenAI-compatible 的 choicesusage 结构。JoyToken 会额外写入响应头和 metadata

信号位置含义
X-DAOE-Used-Modelresponse header实际命中的模型
X-DAOE-Used-Providerresponse header实际命中的 provider
X-DAOE-Failoverresponse headerstreaming provider failover 时为 1
metadata.modelresponse body / stream metadata最终模型
metadata.tierresponse body / stream metadata本次路由和计费 tier
metadata.scoreresponse body / stream metadatarouter 对所选模型的评分
metadata.billingresponse body / stream metadatacredits、input/output tokens、cache tokens
metadata.latencyresponse body / stream metadatarouting_msfirst_token_msstream_ms

非流式响应会把 metadata 合并进 JSON body;流式响应会在最后的 [DONE] 前追加一条 metadata event:

Streaming tail
data: {"metadata":{"model":"GLM-5","tier":"standard","billing":{"credits_used":"0.2288","input_tokens":24,"output_tokens":14}}}
data: [DONE]

服务端代理

浏览器和移动端不应该直接持有 JoyToken API Key。推荐把请求发到你的后端,由后端注入 Key:

Browser -> Your backend -> JoyToken /openai/v1/chat/completions
Next.js route handler
1export async function POST(req: Request) {
2 const body = await req.json();
3
4 const response = await fetch("https://api-dev.joytokens.ai/openai/v1/chat/completions", {
5 method: "POST",
6 headers: {
7 "Content-Type": "application/json",
8 Authorization: `Bearer ${process.env.JOY_TOKEN_API_KEY}`,
9 "X-Request-ID": crypto.randomUUID(),
10 },
11 body: JSON.stringify(body),
12 });
13
14 return new Response(response.body, {
15 status: response.status,
16 headers: response.headers,
17 });
18}

生产环境不要让客户端传入任意 apiKey。如果需要多租户计费,应该在你的服务端根据用户、团队或项目选择对应的 JoyToken Key。

轮换 API Key

  1. 创建新 Key,并绑定同样或更严格的 policy。
  2. 把新 Key 写入服务端 secret manager 或环境变量。
  3. 用新的 X-Request-ID 发起一条验证请求。
  4. 在 JoyToken Logs / Usage 中确认新 Key 已经产生流量。
  5. 禁用或 revoke 旧 Key。
  6. 检查一段时间内是否还有旧 Key 的请求失败日志。

安全建议

  • 一个应用、环境、agent workflow 使用独立 Key。
  • 生产 Key 必须绑定预算、tier、model policy,必要时加 IP 白名单。
  • 不要把 Key 放在前端 .env、浏览器 localStorage、移动端包或日志中。
  • 对高风险 agent 请求传 X-Request-ID,并把 workflow ID / step ID 放进去。
  • 泄露后不要尝试“隐藏历史记录”,直接 revoke 旧 Key、创建新 Key、检查 Usage 和 Billing。