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,附:

⚠️ 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 小时。过期前重新调此端点拿新的。

错误码

HTTPcode含义
400unsupported_grant_typegrant_type 不是 client_credentials
400invalid_requestclient_id 或 client_secret 缺失
401invalid_clientclient_id 不存在
401invalid_client_secretclient_secret 错误
403client_disabledclient 已被停用

1.3 Scope 列表

scope端点说明
packages:readGET /api/v1/packages GET /api/v1/packages/:id套餐列表 + 详情
tokens:readGET /api/v1/tokens列 end_user 的 keys
tokens:writePOST /api/v1/tokens DELETE /api/v1/tokens/:id创建 / 撤销 key
orders:readGET /api/v1/orders/:id查订单
orders:writePOST /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
响应 404code: "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, ... } 结构。

codeHTTP含义
unauthorized401缺 Authorization 头
invalid_token401access_token 无效
token_expired401access_token 已过期,重新调 /api/v1/m2m/auth
client_disabled403M2M client 已被停用
insufficient_scope403没有该端点需要的 scope
invalid_request400请求参数缺失或格式错
not_found404资源不存在
package_not_found404package_id 不存在或未启用
end_user_not_found404end_user_email 在 baozi 没记录(让用户先登录)
end_user_not_linked400end_user 没关联 new-api(同上)
self_create_failed502后端 new-api 创 token 失败
rate_limited429触发频率限制(仅 /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. 联系 & 变更


api_version: v1 · 2026-09-13