令牌申请
需要使用 API 控制令牌,需要先向经销商或者管理员提出申请,待管理员开通之后,才能使用。
联系邮箱: support@bsf.ai
请附上您开通缘由和需要开通的账号。
所有令牌管理接口需要用户认证(UserAuth 中间件),支持两种方式:
- Session Cookie(浏览器登录后自动携带)
- Access Token(通过
Authorization请求头传递,适合 curl / 程序调用)
使用 Access Token 方式时,需要提供以下请求头:
| 请求头 | 必填 | 说明 |
|---|---|---|
Authorization | 是 | 用户 Access Token |
以下 curl 示例均使用 Access Token 方式,请替换:
https://api.bsf.ai/— 你的服务地址{ACCESS_TOKEN}— 你的用户 Access Token
基础路径:/api/token
数据结构
Token 对象
| 字段 | 类型 | 说明 |
|---|---|---|
id | int | 令牌 ID(主键) |
user_id | int | 所属用户 ID |
key | string | API Key(48 位,自动生成,前缀 sk-) |
status | int | 状态:1 启用 / 2 禁用 / 3 已过期 / 4 额度耗尽 |
name | string | 令牌名称(最长 50 字符) |
created_time | int64 | 创建时间(Unix 时间戳) |
accessed_time | int64 | 最后访问时间(Unix 时间戳) |
expired_time | int64 | 过期时间(Unix 时间戳),-1 表示永不过期 |
remain_quota | int | 剩余额度 |
unlimited_quota | bool | 是否无限额度 |
used_quota | int | 已消耗额度 |
model_limits_enabled | bool | 是否启用模型限制 |
model_limits | string | 允许使用的模型列表(逗号分隔,如 gpt-4,claude-3-opus) |
allow_ips | string | IP 白名单(换行 \n 分隔,支持 CIDR 格式) |
group | string | 渠道分组 |
cross_group_retry | bool | 跨分组重试(仅 auto 分组有效) |
接口列表
1. 获取令牌列表
GET /api/token/?p={page}&size={pageSize}Query 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
p | int | 否 | 页码,从 0 开始 |
size | int | 否 | 每页数量 |
响应示例:
json
{
"success": true,
"message": "",
"data": {
"page": 0,
"page_size": 10,
"total": 2,
"items": [
{
"id": 1,
"name": "my-token",
"status": 1,
"key": "",
"created_time": 1710000000,
"expired_time": -1,
"remain_quota": 500000,
"unlimited_quota": false,
"used_quota": 12000,
"model_limits_enabled": false,
"model_limits": "",
"allow_ips": "",
"group": "",
"cross_group_retry": false
}
]
}
}注意:列表接口中
key字段会被清空,不会返回实际的 API Key。
curl 示例:
bash
curl -X GET 'https://api.bsf.ai/api/token/?p=0&size=10' \
-H 'Authorization: {ACCESS_TOKEN}'2. 搜索令牌
GET /api/token/search?keyword={keyword}&token={tokenKey}&p={page}&size={pageSize}Query 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
keyword | string | 否 | 按名称模糊搜索 |
token | string | 否 | 按 Key 搜索 |
p | int | 否 | 页码 |
size | int | 否 | 每页数量 |
搜索有频率限制(
SearchRateLimit中间件)。模糊搜索最少 2 个字符,最多 2 个通配符。
curl 示例:
bash
# 按名称搜索
curl -X GET 'https://api.bsf.ai/api/token/search?keyword=production&p=0&size=10' \
-H 'Authorization: {ACCESS_TOKEN}'
# 按 Key 搜索
curl -X GET 'https://api.bsf.ai/api/token/search?token=abc123&p=0&size=10' \
-H 'Authorization: {ACCESS_TOKEN}'3. 获取单个令牌
GET /api/token/{id}Path 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | int | 是 | 令牌 ID |
响应示例:
json
{
"success": true,
"message": "",
"data": {
"id": 1,
"name": "my-token",
"key": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"status": 1,
"remain_quota": 500000,
"..."
}
}curl 示例:
bash
curl -X GET 'https://api.bsf.ai/api/token/1' \
-H 'Authorization: {ACCESS_TOKEN}'4. 创建令牌
POST /api/token/
Content-Type: application/json请求 Body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 令牌名称,最长 50 字符 |
expired_time | int64 | 否 | 过期时间(Unix 时间戳),-1 永不过期 |
remain_quota | int | 否 | 剩余额度(非无限额度时,范围 0 ~ 1,000,000,000 × QuotaPerUnit) |
unlimited_quota | bool | 否 | 是否无限额度 |
model_limits_enabled | bool | 否 | 是否启用模型限制 |
model_limits | string | 否 | 允许的模型列表(逗号分隔) |
allow_ips | string | 否 | IP 白名单(换行分隔,支持 CIDR) |
group | string | 否 | 渠道分组 |
cross_group_retry | bool | 否 | 跨分组重试 |
请求示例:
json
{
"name": "production-key",
"expired_time": 1735689600,
"remain_quota": 1000000,
"unlimited_quota": false,
"model_limits_enabled": true,
"model_limits": "gpt-4,gpt-4o,claude-3-opus",
"allow_ips": "192.168.1.0/24\n10.0.0.1",
"group": "default"
}响应:
json
{
"success": true,
"message": ""
}每个用户有最大令牌数量限制,超出后无法创建。
curl 示例:
bash
# 创建一个有额度限制和模型限制的令牌
curl -X POST 'https://api.bsf.ai/api/token/' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"name": "production-key",
"expired_time": 1735689600,
"remain_quota": 1000000,
"unlimited_quota": false,
"model_limits_enabled": true,
"model_limits": "gpt-4,gpt-4o,claude-3-opus",
"allow_ips": "192.168.1.0/24\n10.0.0.1",
"group": "default"
}'
# 创建一个无限额度、永不过期的令牌
curl -X POST 'https://api.bsf.ai/api/token/' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"name": "unlimited-key",
"expired_time": -1,
"unlimited_quota": true
}'5. 更新令牌
5a. 更新全部可修改字段
PUT /api/token/
Content-Type: application/json请求 Body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | int | 是 | 要更新的令牌 ID |
name | string | 否 | 令牌名称 |
expired_time | int64 | 否 | 过期时间 |
remain_quota | int | 否 | 剩余额度 |
unlimited_quota | bool | 否 | 是否无限额度 |
model_limits_enabled | bool | 否 | 是否启用模型限制 |
model_limits | string | 否 | 允许的模型列表 |
allow_ips | string | 否 | IP 白名单 |
group | string | 否 | 渠道分组 |
cross_group_retry | bool | 否 | 跨分组重试 |
curl 示例:
bash
# 更新令牌名称、额度和模型限制
curl -X PUT 'https://api.bsf.ai/api/token/' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"id": 1,
"name": "renamed-key",
"remain_quota": 2000000,
"unlimited_quota": false,
"model_limits_enabled": true,
"model_limits": "gpt-4o,claude-3-5-sonnet",
"expired_time": 1767225600
}'5b. 仅更新状态
PUT /api/token/?status_only=1
Content-Type: application/json请求 Body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | int | 是 | 令牌 ID |
status | int | 是 | 1 启用 / 2 禁用 |
限制:
- 已过期且过期时间未修改的令牌无法启用
- 额度耗尽且非无限额度的令牌无法启用
curl 示例:
bash
# 禁用令牌
curl -X PUT 'https://api.bsf.ai/api/token/?status_only=1' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"id": 1, "status": 2}'
# 启用令牌
curl -X PUT 'https://api.bsf.ai/api/token/?status_only=1' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"id": 1, "status": 1}'响应:
json
{
"success": true,
"message": "",
"data": { "...更新后的令牌对象..." }
}6. 删除令牌
DELETE /api/token/{id}Path 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | int | 是 | 令牌 ID |
curl 示例:
bash
curl -X DELETE 'https://api.bsf.ai/api/token/1' \
-H 'Authorization: {ACCESS_TOKEN}'响应:
json
{
"success": true,
"message": ""
}删除为软删除,数据不会立即清除。
7. 批量删除令牌
POST /api/token/batch
Content-Type: application/json请求 Body:
json
{
"ids": [1, 2, 3]
}响应:
json
{
"success": true,
"message": "",
"data": 3
}data 为实际删除的数量。
curl 示例:
bash
curl -X POST 'https://api.bsf.ai/api/token/batch' \
-H 'Authorization: {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"ids": [1, 2, 3]}'令牌用量查询
此接口使用 Bearer Token 认证(即用 API Key 本身查询自己的用量),不需要用户登录。
GET /api/usage/token/
Authorization: Bearer sk-xxxxxxxxcurl 示例:
bash
curl -X GET 'https://api.bsf.ai/api/usage/token/' \
-H 'Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'响应示例:
json
{
"code": true,
"message": "ok",
"data": {
"object": "token_usage",
"name": "my-token",
"total_usd_granted": 2.024,
"total_usd_used": 0.024,
"total_usd_available": 2.0,
"unlimited_quota": false,
"model_limits": {
"gpt-4": true,
"claude-3-opus": true
},
"model_limits_enabled": true,
"expires_at": 1735689600,
"user_usd_available": 88.5
}
}| 字段 | 说明 |
|---|---|
total_usd_granted | 令牌总授予额度(USD),等于 total_usd_available + total_usd_used |
total_usd_used | 令牌已使用额度(USD) |
total_usd_available | 令牌剩余可用额度(USD) |
unlimited_quota | 是否无限额度 |
model_limits | 模型限制映射 |
expires_at | 过期时间,0 表示永不过期 |
user_usd_available | 用户账户剩余额度(USD)。无限额度时,此字段表示实际可用上限 |
令牌每日消费统计
GET /api/token/{id}/usage?start_date={start}&end_date={end}需要用户登录认证(同令牌管理接口)。
Path 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | int | 是 | 令牌 ID |
Query 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
start_date | string | 否 | 开始日期,格式 YYYY-MM-DD |
end_date | string | 否 | 结束日期,格式 YYYY-MM-DD |
限制:
- 不传参数默认查询最近 1 天
- 最多查询 7 天,超出自动截断到
start_date + 7天 - 结果缓存 10 分钟,高频调用不会增加数据库压力
响应示例:
json
{
"success": true,
"data": {
"token_id": 1,
"token_name": "my-token",
"start_date": "2026-03-20",
"end_date": "2026-03-26",
"daily": [
{
"date": "2026-03-20",
"usd": 0.35,
"requests": 12,
"prompt_tokens": 5000,
"completion_tokens": 2000
}
]
}
}daily 字段说明:
| 字段 | 说明 |
|---|---|
date | 日期(YYYY-MM-DD) |
usd | 当日消费金额(USD) |
requests | 当日请求次数 |
prompt_tokens | 当日输入 token 数 |
completion_tokens | 当日输出 token 数 |
curl 示例:
bash
# 查询最近 1 天(默认)
curl -X GET 'https://api.bsf.ai/api/token/1/usage' \
-H 'Authorization: {ACCESS_TOKEN}'
# 查询指定日期范围(最多 7 天)
curl -X GET 'https://api.bsf.ai/api/token/1/usage?start_date=2026-03-20&end_date=2026-03-26' \
-H 'Authorization: {ACCESS_TOKEN}'