baozi API 参考(v1)
2026-09-13 上线:所有三方调用端点都在 /api/v1/* 路径下。/api/*(无版本)保留给 baozi 内部使用(前端页面直接调),不建议三方接入。
1. 鉴权(OAuth 2.0 client_credentials)
1.1 注册 M2M Client
联系 trust@ohoooho.com 申请 client_id + client_secret,附:
- 应用名 + 用途说明
- 需要的 scope(见 §1.3)
- 回调/对账邮箱
⚠️ client_secret 只展示一次,请安全保存。泄露请立刻联系
trust@ohoooho.com轮换。
1.2 拿 access_token
POST https://baozi.ohoooho.com/api/v1/m2m/auth
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "your-client-id",
"client_secret": "your-client-secret"
}
响应 200:
{
"success": true,
"api_version": "v1",
"data": {
"access_token": "1f4c7febd196ffe4c5a1...",
"token_type": "Bearer",
"expires_in": 7200,
"expires_at": 1789265900000,
"scope": "[\"packages:read\",\"tokens:read\",\"tokens:write\",\"orders:read\",\"orders:write\"]",
"client_id": "your-client-id",
"client_name": "Your App"
}
}
access_token 有效期 2 小时。过期前重新调此端点拿新的。
错误码:
| HTTP | code | 含义 |
|---|---|---|
| 400 | unsupported_grant_type | grant_type 不是 client_credentials |
| 400 | invalid_request | client_id 或 client_secret 缺失 |
| 401 | invalid_client | client_id 不存在 |
| 401 | invalid_client_secret | client_secret 错误 |
| 403 | client_disabled | client 已被停用 |
1.3 Scope 列表
| scope | 端点 | 说明 |
|---|---|---|
packages:read | GET /api/v1/packages GET /api/v1/packages/:id | 套餐列表 + 详情 |
tokens:read | GET /api/v1/tokens | 列 end_user 的 keys |
tokens:write | POST /api/v1/tokens DELETE /api/v1/tokens/:id | 创建 / 撤销 key |
orders:read | GET /api/v1/orders/:id | 查订单 |
orders:write | POST /api/v1/orders | 创建订单 |
admin | 所有端点 | 超管通杀(仅内部分配) |
1.4 后续调用
每个请求 Header 带:
Authorization: Bearer <access_token>
2. 套餐
2.1 套餐列表(公开)
GET https://baozi.ohoooho.com/api/v1/packages
响应 200(实测 2026-09-13):
{
"success": true,
"api_version": "v1",
"data": [
{
"id": "bz-chat",
"name": "日常套餐",
"scene": "chat",
"tiers": [
{ "id": "lite", "name": "Lite", "price_yuan": 18, "quota": 2000, "period": "月" },
{ "id": "standard", "name": "Standard", "price_yuan": 28, "quota": 5000, "period": "月" },
{ "id": "pro", "name": "Pro", "price_yuan": 99, "quota": 20000, "period": "月" }
]
}
],
"total": 1
}
2.2 单套餐详情
GET https://baozi.ohoooho.com/api/v1/packages/:id
响应 200:同单条 data
响应 404:code: "not_found" —— 套餐不存在或未启用
3. 订单
3.1 创建订单(需要 orders:write)
POST https://baozi.ohoooho.com/api/v1/orders
Authorization: Bearer <access_token>
Content-Type: application/json
{
"package_id": "bz-chat",
"tier_id": "lite",
"period": "月",
"external_order_id": "my-order-2026-09-13-001"
}
响应 201(实测):
{
"success": true,
"api_version": "v1",
"data": {
"id": "m2m-bz-2-1757771234567-97ti6t",
"package_id": "bz-chat",
"tier_id": "lite",
"period": "月",
"amount_cents": 1800,
"amount_yuan": 18,
"status": "pending",
"external_order_id": "my-order-2026-09-13-001",
"created_at": 1757771234567
}
}
💡 完整流程:第三方下单 → baozi 内部 fulfillment → 调
POST /api/v1/tokens创 key。这两步分开(SaaS 标准对账/履约分离),不在创订单时自动创 key。
3.2 查订单(需要 orders:read)
GET https://baozi.ohoooho.com/api/v1/orders/:order_id
Authorization: Bearer <access_token>
响应 200(实测):
{
"success": true,
"api_version": "v1",
"data": {
"id": "m2m-bz-2-1757771234567-97ti6t",
"user_id": 2,
"package_id": "bz-chat",
"scene": "chat",
"tier": "lite",
"period": "月",
"action": "new",
"amount_cents": 1800,
"status": "pending",
"payment_provider": "m2m",
"tokens": [
{ "user_token_id": 2, "name": "prod-001", "status": "active", "masked_key": "w3SE***...6MC9" }
],
"created_at": 1757771234567
}
}
3.3 列订单(需要 orders:read)
GET https://baozi.ohoooho.com/api/v1/orders?end_user_email=user@example.com
Authorization: Bearer <access_token>
4. Key(API Token)
4.1 创 key(需要 tokens:write)
POST https://baozi.ohoooho.com/api/v1/tokens
Authorization: Bearer <access_token>
Content-Type: application/json
{
"order_id": "m2m-bz-2-1757771234567-97ti6t",
"name": "prod-key-001"
}
响应 201(实测 2026-09-13):
{
"success": true,
"api_version": "v1",
"data": {
"user_token_id": 2,
"new_api_token_id": 284,
"name": "prod-key-001",
"masked_key": "w3SE***...6MC9",
"package_id": "bz-chat",
"tier_id": "lite",
"quota": 500000,
"expires_at": 1791857235000
}
}
🔑 完整 key 怎么拿到?
当前 baozi v1 出于安全考虑,只返 masked_key。完整 key 由 end_user 在 baozi/dashboard/keys页查看。
如果你必须代 end_user 拿完整 key,请联系trust@ohoooho.com评估特殊授权。
4.2 列 end_user 的 keys(需要 tokens:read)
GET https://baozi.ohoooho.com/api/v1/tokens?end_user_email=user@example.com
Authorization: Bearer <access_token>
响应 200:
{
"success": true,
"api_version": "v1",
"data": [
{
"id": 2,
"package_id": "bz-chat",
"scene": "chat",
"tier": "lite",
"period": "月",
"status": "active",
"new_api_token_id": 284,
"token_name": "prod-key-001",
"quota": 500000,
"used": 0,
"remaining": 500000,
"expires_at": 1791857235000,
"is_expired": false,
"created_at": 1757771234567
}
],
"total": 1
}
4.3 单 key 详情(需要 tokens:read)
GET https://baozi.ohoooho.com/api/v1/tokens/:user_token_id
Authorization: Bearer <access_token>
4.4 撤销 key(需要 tokens:write)
DELETE https://baozi.ohoooho.com/api/v1/tokens/:user_token_id
Authorization: Bearer <access_token>
响应 200(实测):
{
"success": true,
"api_version": "v1",
"data": { "id": 2, "status": "disabled" }
}
幂等:已 disabled 的 user_token 返 already: true。
5. 错误码速查
所有 v1 端点返 { success: false, code, message, ... } 结构。
| code | HTTP | 含义 |
|---|---|---|
unauthorized | 401 | 缺 Authorization 头 |
invalid_token | 401 | access_token 无效 |
token_expired | 401 | access_token 已过期,重新调 /api/v1/m2m/auth |
client_disabled | 403 | M2M client 已被停用 |
insufficient_scope | 403 | 没有该端点需要的 scope |
invalid_request | 400 | 请求参数缺失或格式错 |
not_found | 404 | 资源不存在 |
package_not_found | 404 | package_id 不存在或未启用 |
end_user_not_found | 404 | end_user_email 在 baozi 没记录(让用户先登录) |
end_user_not_linked | 400 | end_user 没关联 new-api(同上) |
self_create_failed | 502 | 后端 new-api 创 token 失败 |
rate_limited | 429 | 触发频率限制(仅 /api/me/token) |
6. 完整流程示例(curl)
# 1. 拿 access_token
TOKEN=$(curl -s -X POST https://baozi.ohoooho.com/api/v1/m2m/auth \
-H "Content-Type: application/json" \
-d '{"grant_type":"client_credentials","client_id":"...","client_secret":"..."}' \
| jq -r .data.access_token)
# 2. 列套餐
curl -s https://baozi.ohoooho.com/api/v1/packages | jq '.data[].id'
# 3. 创订单
curl -s -X POST https://baozi.ohoooho.com/api/v1/orders \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"package_id":"bz-chat","tier_id":"lite","period":"月","external_order_id":"demo-001"}'
# 4. 创 key
curl -s -X POST https://baozi.ohoooho.com/api/v1/tokens \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"order_id":"m2m-bz-2-1757771234567-97ti6t","name":"prod-001"}'
# 5. 列 end_user keys
curl -s "https://baozi.ohoooho.com/api/v1/tokens?end_user_email=user@example.com" \
-H "Authorization: Bearer $TOKEN"
# 6. 撤销 key
curl -s -X DELETE "https://baozi.ohoooho.com/api/v1/tokens/2" \
-H "Authorization: Bearer $TOKEN"
7. URL 自检清单(2026-09-13 实测)
| URL | 状态 | 说明 |
|---|---|---|
POST /api/v1/m2m/auth | ✅ 401 | 已实现(bogus credential 返 401 invalid_client) |
GET /api/v1/packages | ✅ 200 | 已实现 |
GET /api/v1/packages/:id | ✅ 200/404 | 已实现 |
POST /api/v1/orders | ✅ 401/201 | 已实现(需 Bearer) |
GET /api/v1/orders/:id | ✅ 200/404 | 已实现 |
POST /api/v1/tokens | ✅ 401/201 | 已实现(需 Bearer) |
GET /api/v1/tokens | ✅ 401/200 | 已实现 |
GET /api/v1/tokens/:id | ✅ 200/404 | 已实现 |
DELETE /api/v1/tokens/:id | ✅ 200 | 已实现 |
GET /api/v1/admin/users | ✅ 200 | 已实现 |
GET /api/v1/admin/grants | ✅ 200 | 已实现 |
POST /api/v1/admin/grant-quota | ✅ 403/201 | 已实现 |
POST /api/v1/admin/create-user | ✅ 403/201 | 已实现 |
GET /api/v1/admin/user-tokens/:username | ✅ 403/200 | 已实现 |
8. 联系 & 变更
- 申请 M2M client:
trust@ohoooho.com - 报告问题:同上
- API 版本变更会先在 baozi
/changelog公示,至少 30 天兼容期
api_version: v1 · 2026-09-13