15 KiB
NewAPI sk-key 查询接口文档
基于源码实证调研(QuantumNous/new-api),整理所有可通过
sk-API key 直接访问的查询接口。调研日期:2025-07 月 · 源码版本:main 分支
0. 通用说明
认证方式
所有接口均使用 API key 鉴权,在请求头中携带:
Authorization: Bearer sk-xxxxxxxxxxxx
不需要账号登录态(access token / session)。这是拼车场景能成立的关键前提。
BaseURL
即 NewAPI 站点地址,例如 https://your-friend-domain.com。所有路径前不带多余前缀,直接拼接。
两种鉴权中间件
| 中间件 | 说明 |
|---|---|
TokenAuth() |
标准版:校验 key 有效、未过期、有剩余额度。过期或耗尽的 key 会被拒绝。 |
TokenAuthReadOnly() |
宽松版:只校验 key 存在且用户未封禁。即使 key 已过期、已禁用、额度耗尽也能查询。 |
/api/usage/token和/api/log/token用的是TokenAuthReadOnly(),所以伙伴的 key 即使用完了,仍能查到自己的用量记录。
已确认的换算参数
| 参数 | 值 | 来源 |
|---|---|---|
QuotaPerUnit |
500000 | 实测验证:接口① total_used ÷ 500000 = 接口④ total_usage ÷ 100 |
关键开关:DisplayTokenStatEnabled
| 接口 | 受开关影响? |
|---|---|
| billing 接口(③④⑤⑥) | ✅ 受影响。开启 -> 返回 token 级额度;关闭 -> 回退到账号级额度(暴露整个账号余额) |
/api/usage/token、/api/log/token |
❌ 不受影响,恒返回 token 级数据 |
实测已确认当前平台开关为开启状态(billing 接口返回的 hard_limit_usd 是 token 级占位值,非账号总额)。
开关位于后台:设置 -> 计费设置(Billing)-> "货币与显示"(Currency & Display)-> Display Token Statistics。仅管理员可改。
1. 接口清单总览
| 序号 | 方法 | 路径 | 鉴权 | 用途 |
|---|---|---|---|---|
| ① | GET | /api/usage/token |
TokenAuthReadOnly | 查 token 的累计已用/剩余/总额(原始 quota) |
| ② | GET | /api/log/token |
TokenAuthReadOnly | 查该 key 最近 1000 条调用日志 |
| ③ | GET | /v1/dashboard/billing/subscription |
TokenAuth | 查总额度上限(OpenAI 兼容,美元) |
| ④ | GET | /v1/dashboard/billing/usage |
TokenAuth | 查累计已用(OpenAI 兼容,美分) |
| ⑤ | GET | /dashboard/billing/subscription |
TokenAuth | 同 ③,不带 /v1 前缀 |
| ⑥ | GET | /dashboard/billing/usage |
TokenAuth | 同 ④,不带 /v1 前缀 |
| ⑦ | GET | /v1/models |
TokenAuth | 列出可用模型(OpenAI 格式) |
| ⑧ | GET | /v1/models/:model |
TokenAuth | 查单个模型详情 |
| ⑨ | GET | /v1beta/models |
TokenAuth | 列出可用模型(Gemini 格式) |
| ⑩ | GET | /v1beta/openai/models |
TokenAuth | 列出可用模型(OpenAI 格式) |
③和⑤是同一个接口,④和⑥是同一个接口,只是路径前缀不同(为兼容不同客户端写法)。测一组即可。
⑦~⑩是模型列表接口,与用量统计无关,列出仅为完整覆盖。
2. 用量/额度查询接口详解
① GET /api/usage/token - token 级用量汇总
鉴权:TokenAuthReadOnly()(宽松版,key 过期/耗尽也能查)
请求参数:无
请求示例:
GET /api/usage/token
Authorization: Bearer sk-xxxx
返回结构(源码:controller/token.go -> GetTokenUsage):
{
"code": true,
"message": "ok",
"data": {
"object": "token_usage",
"name": "令牌名称",
"total_granted": 6012,
"total_used": 673419457,
"total_available": -673413445,
"unlimited_quota": true,
"model_limits": {},
"model_limits_enabled": false,
"expires_at": 0
}
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | 令牌名称 |
total_granted |
int | 总额度 = RemainQuota + UsedQuota(原始 quota 单位) |
total_used |
int | 累计已用(原始 quota 单位)。从 key 创建以来累计,非当月。换算美元:total_used ÷ 500000 |
total_available |
int | 剩余 = total_granted − total_used。无限额度时为负数,无实际意义 |
unlimited_quota |
bool | 是否无限额度。true 时 total_granted/total_available 无实际意义 |
model_limits |
object | 模型限制(map) |
model_limits_enabled |
bool | 是否启用模型限制 |
expires_at |
int | 过期时间(Unix 秒),0 = 永不过期 |
注意事项:
total_used是累计值,从 key 创建以来累计,不是当月用量。- 额度单位是原始 quota 整数,需自行除以
QuotaPerUnit(默认 500000)换算美元。 - 禁用再解禁不会重置
total_used(源码验证:Update()的.Select(...)列表不含used_quota)。
② GET /api/log/token - token 级调用日志
鉴权:TokenAuthReadOnly()
请求参数:无(不支持任何 query 参数)
请求示例:
GET /api/log/token
Authorization: Bearer sk-xxxx
返回结构(源码:controller/log.go:62 -> GetLogByKey):
{
"success": true,
"message": "",
"data": [
{
"id": 123456,
"user_id": 12,
"created_at": 1751328000,
"type": 2,
"content": "模型倍率 1.0,分组倍率 1.0",
"username": "用户名",
"token_name": "令牌名",
"model_name": "gpt-4o",
"quota": 2500,
"prompt_tokens": 1500,
"completion_tokens": 500,
"use_time": 2,
"is_stream": true,
"channel": 0,
"channel_name": "",
"token_id": 100,
"group": "default",
"ip": "",
"request_id": "req_xxx",
"upstream_request_id": "",
"other": ""
}
]
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
created_at |
int | 调用时间(Unix 秒)- 客户端可据此筛当月 |
type |
int | 日志类型:2=消费,5=错误,1=充值等 |
model_name |
string | 调用的模型名 |
quota |
int | 本次消耗的 quota(换算美元:quota ÷ 500000) |
prompt_tokens |
int | 输入 token 数 |
completion_tokens |
int | 输出 token 数 |
use_time |
int | 耗时(秒) |
is_stream |
bool | 是否流式 |
channel_name |
string | 渠道名(普通用户会被清空) |
关键限制:
- 硬上限 1000 条:固定返回最近 1000 条日志(
Limit(common.MaxRecentItems),MaxRecentItems = 1000,定义于common/constants.go)。 - 不支持任何请求参数:
GetLogByKey不读任何c.Query(),没有分页(page/limit/offset),没有时间过滤(start_timestamp/end_timestamp)。 - 固定按
id desc排序:即最新 1000 条。 - 超过 1000 条的旧记录无法获取:无法翻页,无法扩大 limit。
- 当月调用超 1000 次时,此接口无法覆盖完整当月数据。
③ GET /v1/dashboard/billing/subscription - 总额度上限
鉴权:TokenAuth()
请求参数:无
请求示例:
GET /v1/dashboard/billing/subscription
Authorization: Bearer sk-xxxx
返回结构(源码:controller/billing.go:13 -> GetSubscription):
{
"object": "billing_subscription",
"has_payment_method": true,
"soft_limit_usd": 100000000,
"hard_limit_usd": 100000000,
"system_hard_limit_usd": 100000000,
"access_until": 0
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
hard_limit_usd |
float | 总额度上限(美元)。无限额度 key 返回 100000000(占位值,无实际意义) |
soft_limit_usd |
float | 软上限(同 hard_limit_usd) |
system_hard_limit_usd |
float | 系统上限(同 hard_limit_usd) |
access_until |
int | token 过期时间(Unix 秒),0 = 永不过期 |
注意事项:
- 受
DisplayTokenStatEnabled开关影响。开启时返回 token 级额度;关闭时返回账号级额度(会暴露整个账号余额)。 - 无限额度 key 返回
100000000(一亿)作为占位值,无参考意义。 - 受
quota_display_type影响:USD 模式直接是美元;CNY 模式会做货币转换;Tokens 模式是原始 token 数。
④ GET /v1/dashboard/billing/usage - 累计已用
鉴权:TokenAuth()
请求参数:无
请求示例:
GET /v1/dashboard/billing/usage
Authorization: Bearer sk-xxxx
返回结构(源码:controller/billing.go:75 -> GetUsage):
{
"object": "list",
"total_usage": 134683.8914
}
字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
total_usage |
float | 累计已用(单位:美分)。换算美元:total_usage ÷ 100 |
实测验证:
total_usage = 134683.8914 美分 ÷ 100 = 1346.84 美元
与接口① total_used(673419457) ÷ 500000 = 1346.84 美元 完全吻合
注意事项:
total_usage是累计值(从 key 创建至今),不是当月用量。- 受
DisplayTokenStatEnabled开关影响(开启时为 token 级)。 - 受
quota_display_type影响(USD 模式才是美元,否则需另行换算)。 hard_limit_usd(接口③)−total_usage ÷ 100(接口④)= 剩余额度(仅有限额 key 有意义)。
3. 模型列表接口(与用量无关)
以下接口 sk-key 可访问,但返回的是模型列表,与用量统计无关。列出仅为完整覆盖。
⑦ GET /v1/models
返回当前 key 可用的模型列表,OpenAI 兼容格式。
{
"object": "list",
"data": [
{
"id": "gpt-4o",
"object": "model",
"created": 1686935000,
"owned_by": "openai"
}
]
}
⑧ GET /v1/models/:model
返回单个模型详情。将 :model 替换为模型名,如 /v1/models/gpt-4o。
已知限制:此接口与
/v1/models数据源不同。/v1/models查数据库abilities表(反映渠道实际配置的模型),而此接口查代码内硬编码的静态模型列表(openAIModelsMap)。当渠道配了新模型或自定义模型名但代码未收录时,会出现"列表里有但单查返回model_not_found"的现象。不影响实际模型调用。
⑨ GET /v1beta/models
返回模型列表(Gemini 兼容格式)。
⑩ GET /v1beta/openai/models
返回模型列表(OpenAI 格式,Gemini 路由下)。
4. 确认不存在的接口(排除清单)
以下接口在源码中不存在或不可用 sk-key 访问,测试时应返回 404 或 401:
4.1 不存在的接口(返回 404)
| 路径 | 状态 |
|---|---|
/v1/usage |
不存在 |
/v1/quota |
不存在 |
/api/token/self |
不存在 |
4.2 存在但需要登录态的接口(sk-key 访问返回 401)
这些接口支持时间范围查询和 token_name 过滤,但必须用账号登录态(access token + New-Api-User header),sk-key 无法访问:
| 路径 | 鉴权 | 能力 |
|---|---|---|
/api/log/self |
UserAuth() |
支持 start_timestamp、end_timestamp、token_name 过滤,返回日志明细 |
/api/log/self/stat |
UserAuth() |
支持时间范围 + token_name,返回 quota 汇总(调 SumUsedQuota) |
/api/data/self |
UserAuth() |
按日聚合的看板数据 |
/api/token/ (GET/POST/PUT/DELETE) |
UserAuth() |
token 的增删改查 |
/api/user/self |
UserAuth() |
用户自身信息 |
特别说明:
/api/log/self/stat是 NewAPI 中最适合算"当月用量"的接口--传当月起止时间 +token_name即可返回该 key 当月消耗的 quota 总和。但它需要登录态,是拼车场景下"当月用量"难以纯客户端实现的核心障碍。
4.3 参数被忽略的情况
| 请求 | 实际行为 |
|---|---|
/api/log/token?p=2 |
参数被忽略,仍返回最近 1000 条 |
/api/log/token?limit=5000 |
参数被忽略,仍返回最近 1000 条 |
/api/log/token?start_timestamp=1751328000 |
参数被忽略,仍返回最近 1000 条 |
/v1/dashboard/billing/usage?start_date=2025-07-01 |
参数被忽略 |
5. 用量换算速查
核心换算公式
原始 quota ÷ 500000 = 美元
实测数据验证
| 来源 | 原始值 | 换算 | 结果 |
|---|---|---|---|
接口① total_used |
673,419,457 quota | ÷ 500000 | 1346.84 美元 |
接口④ total_usage |
134,683.8914 美分 | ÷ 100 | 1346.84 美元 |
两者完全吻合,确认 QuotaPerUnit = 500000。
6. 关键限制总结
6.1 时间维度
- 所有 sk-key 接口返回的用量都是累计值(从 key 创建至今),没有任何接口直接返回"当月用量"。
- 唯一带时间戳的是
/api/log/token,但硬限 1000 条且不支持时间过滤。 - 支持时间范围的接口(
/api/log/self、/api/log/self/stat)需要登录态,sk-key 无法访问。
6.2 日志条数
/api/log/token硬上限 1000 条(MaxRecentItems = 1000,定义于common/constants.go)。- 不支持分页、不支持时间过滤、不支持改变 limit。
- 月调用量超过 1000 次时,此接口无法覆盖完整当月数据。
6.3 写操作
- sk-key 没有任何写接口(没有 POST/PUT/DELETE 能改 token 自身)。
- token 的增删改查(
/api/token/)全部需要登录态UserAuth()。 - 无法通过 sk-key 重置
used_quota(没有"重置用量"接口,Update()的 Select 列表不含used_quota)。
6.4 禁用/解禁行为
- 禁用 token 只改
status字段,不重置used_quota,不清零remain_quota,不丢历史日志。 - 解禁后
used_quota、remain_quota、历史日志全部原封不动。 - 唯一让
used_quota归零的途径是删除 token 后新建(产生全新 Id/Key,旧日志按旧 token_id 关联,新 token 查不到旧日志)。 - 解禁保护:额度耗尽(
Exhausted)且RemainQuota ≤ 0且非无限额度的 token 不能直接解禁,需先充值;已过期的 token 也不能直接解禁,需改过期时间。
7. 源码参考
| 关注点 | 文件路径 | 关键函数/位置 |
|---|---|---|
| 路由注册 | router/api-router.go |
usageRoute、logRoute 组 |
| 路由注册 | router/dashboard.go:14-23 |
billing 路由组 |
| 路由注册 | router/relay-router.go |
models 路由 |
| API key 鉴权 | middleware/auth.go:171 |
TokenAuthReadOnly() |
| API key 鉴权 | middleware/auth.go |
TokenAuth() / SetupContextForToken |
| token 用量查询 | controller/token.go |
GetTokenUsage |
| 日志查询 | controller/log.go:62 |
GetLogByKey |
| 日志查询(model) | model/log.go |
GetLogByTokenId(Limit 1000) |
| billing 查询 | controller/billing.go:13 |
GetSubscription |
| billing 查询 | controller/billing.go:75 |
GetUsage |
| 显示开关 | common/constants.go |
DisplayTokenStatEnabled |
| 日志上限 | common/constants.go |
MaxRecentItems = 1000 |
| 配额单位 | common/constants.go |
QuotaPerUnit(默认 500000) |
| token 更新 | model/token.go |
Update()(Select 不含 used_quota) |
| 额度增减 | model/token.go |
increaseTokenQuota / decreaseTokenQuota |