Skip to content

积分与计费 ​

网页型智能体可以在用户确认一次业务消费后,由开发者服务端调用小雅开放 API 扣积分;业务最终失败且原扣费已经成功时,再按原订单退积分。MCP 工具如果已经声明 xiaoya/pricePoints,由平台自动确认、扣费和退款,开发者不得重复调用 /charge。

调用前准备 ​

  • Personal 余额需要 balance Scope;扣费和退款需要 charge;用量汇总需要 usage。
  • Team 操作需要绑定 URL 中精确 team_id 的 Team Token 和对应 Scope。
  • Access Token 只能保存在可信服务端,通过 Authorization: Bearer <token> 发送。
  • points 是 1–1,000,000,000,000 的整数;幂等键长度为 8–64。

查询 Personal 余额 ​

bash
curl 'https://claw.zhenhuiai.com/api/v1/open/balance' \
  --header 'Authorization: Bearer <personal-access-token>' \
  --header 'Accept: application/json'
json
{
  "success": true,
  "data": {
    "subscription": 80,
    "gift_card": 20,
    "recharge": 100,
    "total": 200
  },
  "request_id": "req_balance_01"
}

subscription、gift_card、recharge 分别是套餐、礼品卡和充值积分,total 是当前总和。余额只用于展示;并发情况下只有 /charge 的原子结果有效。

扣除 Personal 积分 ​

先在开发者数据库创建 pending 订单并保存稳定幂等键:

bash
curl --request POST 'https://claw.zhenhuiai.com/api/v1/open/charge' \
  --header 'Authorization: Bearer <personal-access-token>' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
    "points": 20,
    "reason": "生成单图落地页",
    "idempotencyKey": "order_20260830_000001"
  }'
json
{
  "success": true,
  "data": {
    "chargedPoints": 20,
    "balance": {
      "subscription": 60,
      "gift_card": 20,
      "recharge": 100,
      "total": 180
    }
  },
  "request_id": "req_charge_01"
}
请求字段规则
points可信服务端按商品或订单生成的整数积分
reason1–100 字符的稳定业务说明,不放个人敏感信息
idempotencyKey8–64 字符的稳定订单键;同一业务重试必须完全相同

相同键、积分和原因重试会返回相同业务结果;相同键配不同参数会返回 BALANCE_IDEMPOTENCY_CONFLICT。

退回 Personal 积分 ​

退款必须引用原扣费键,并为退款本身生成另一个稳定键:

bash
curl --request POST 'https://claw.zhenhuiai.com/api/v1/open/refund' \
  --header 'Authorization: Bearer <personal-access-token>' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
    "points": 20,
    "reason": "生成失败退款",
    "chargeIdempotencyKey": "order_20260830_000001",
    "idempotencyKey": "refund_20260830_000001"
  }'
json
{
  "success": true,
  "data": {
    "refundedPoints": 20,
    "balance": {
      "subscription": 80,
      "gift_card": 20,
      "recharge": 100,
      "total": 200
    }
  },
  "request_id": "req_refund_01"
}

不得跨用户、跨智能体或跨原订单退款,累计退款不得超过原扣费。只有确认原扣费成功且业务最终失败时才退款。

查询 Personal 用量 ​

bash
curl 'https://claw.zhenhuiai.com/api/v1/open/usage' \
  --header 'Authorization: Bearer <personal-access-token>'
json
{
  "success": true,
  "data": {
    "chargedPoints": 100,
    "refundedPoints": 20,
    "netPoints": 80,
    "modelUsage": {
      "requestCount": 3,
      "inputTokens": 1200,
      "outputTokens": 360,
      "cacheReadTokens": 0,
      "cacheWriteTokens": 0,
      "imageCount": 0,
      "chargedPoints": 12
    }
  },
  "request_id": "req_usage_01"
}

/usage 仅接受 Personal Token;Team 概览不是相同粒度的替代接口。

创建者赞助的公开会话 ​

已发布智能体的创建者可以使用带 model Scope 的 Personal-bound Token 创建最多一小时有效的短期赞助会话;Team-bound Token 不得静默转为个人扣费:

bash
curl --request POST 'https://claw.zhenhuiai.com/api/v1/open/public-billing-sessions' \
  --header 'Authorization: Bearer <personal-creator-access-token>' \
  --header 'Content-Type: application/json' \
  --data '{"expires_in_seconds":900,"max_points":1000,"max_calls":100}'

返回的短期 accessToken 只能保存在业务服务端会话中,用于调用模型或 TTS 网关,不得发给浏览器。max_points 与 max_calls 由两类网关共享并在调用供应商前原子预留;过期、撤销或任一预算用尽后都拒绝新调用。结束时调用 DELETE /api/v1/open/public-billing-sessions/{id} 撤销。创建者长期 Token、短期赞助 Token 和完整输入都不得写入日志或模型上下文。

Team 余额、扣费与退款 ​

bash
curl 'https://claw.zhenhuiai.com/api/v1/open/teams/team_01/balance' \
  --header 'Authorization: Bearer <team-access-token>'
json
{
  "success": true,
  "data": {
    "teamId": "team_01",
    "memberId": "member_01",
    "role": "member",
    "balancePoints": 860,
    "balancePointsDecimal": "860",
    "walletBalancePoints": 12500,
    "quotaLimit": 1000,
    "quotaUsed": 140,
    "quotaRemaining": 860
  },
  "request_id": "req_team_balance_01"
}

Team 扣费请求没有 reason 字段:

bash
curl --request POST 'https://claw.zhenhuiai.com/api/v1/open/teams/team_01/charge' \
  --header 'Authorization: Bearer <team-access-token>' \
  --header 'Content-Type: application/json' \
  --data '{"points":20,"idempotencyKey":"team_order_20260830_0001"}'
json
{
  "success": true,
  "data": {
    "teamId": "team_01",
    "chargeLedgerId": "ledger_01",
    "chargedPoints": 20,
    "chargedPointsDecimal": "20",
    "balancePoints": 840,
    "balancePointsDecimal": "840",
    "walletBalancePoints": 12480,
    "quotaUsed": 160
  },
  "request_id": "req_team_charge_01"
}
bash
curl --request POST 'https://claw.zhenhuiai.com/api/v1/open/teams/team_01/refund' \
  --header 'Authorization: Bearer <team-access-token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "points":20,
    "chargeIdempotencyKey":"team_order_20260830_0001",
    "idempotencyKey":"team_refund_20260830_0001"
  }'
json
{
  "success": true,
  "data": {
    "teamId": "team_01",
    "refundLedgerId": "ledger_02",
    "requestedPoints": 20,
    "requestedPointsDecimal": "20",
    "refundedPoints": 20,
    "refundedPointsDecimal": "20",
    "unrecoveredPoints": 0,
    "unrecoveredPointsDecimal": "0",
    "balancePoints": 860,
    "balancePointsDecimal": "860",
    "walletBalancePoints": 12500,
    "quotaUsed": 140
  },
  "request_id": "req_team_refund_01"
}

业务层应以 refundedPoints 判断实际退款数量;unrecoveredPoints 表示因原积分来源状态等原因未恢复的积分。

Node.js 服务端示例 ​

下载 Skill 后可复用 assets/example-mcp/src/xiaoya-open-api.mjs:

js
import { XiaoyaOpenApiClient } from './xiaoya-open-api.mjs';

const client = new XiaoyaOpenApiClient({
  platformBaseUrl: process.env.XIAOYA_BASE_URL,
  accessToken: process.env.XIAOYA_ACCESS_TOKEN
});

await client.balance();
await client.charge({
  points: 20,
  reason: '生成单图落地页',
  idempotencyKey: 'order_20260830_000001'
});
await client.refund({
  points: 20,
  reason: '生成失败退款',
  chargeIdempotencyKey: 'order_20260830_000001',
  idempotencyKey: 'refund_20260830_000001'
});
await client.teamBalance('team_01');
await client.teamCharge('team_01', { points: 20, idempotencyKey: 'team_order_20260830_0001' });
await client.teamRefund('team_01', {
  points: 20,
  chargeIdempotencyKey: 'team_order_20260830_0001',
  idempotencyKey: 'team_refund_20260830_0001'
});

客户端默认使用 10 秒超时、拒绝重定向并校验统一响应 envelope。浏览器不要直接实例化该客户端。

错误与重试 ​

json
{
  "success": false,
  "code": "INSUFFICIENT_POINTS",
  "message": "The account does not have enough points",
  "request_id": "req_error_01"
}
HTTP错误码处理
402INSUFFICIENT_POINTS余额不足,不继续业务写入
403OPEN_AGENT_SCOPE_REQUIRED重新授权所需 Scope
403TEAM_CONTEXT_MISMATCH不得混用 Personal/Team 或不同 Team
404OPEN_AGENT_CHARGE_NOT_FOUNDPersonal 原扣费不存在或不属于当前上下文
404OPEN_AGENT_TEAM_CHARGE_NOT_FOUNDTeam 原扣费不存在或不属于当前上下文
409BALANCE_IDEMPOTENCY_CONFLICT同一键参数不一致,停止自动重试并检查订单
409TEAM_CREDIT_IDEMPOTENCY_CONFLICTTeam 幂等参数冲突,停止自动重试
422OPEN_AGENT_CHARGE_LIMIT_EXCEEDED超过当前智能体单笔上限
422OPEN_AGENT_REFUND_EXCEEDS_CHARGEPersonal 累计退款超过原扣费
422TEAM_CREDIT_REFUND_EXCEEDS_CHARGETeam 累计退款超过原扣费

网络超时或 5xx 时结果可能未知:扣费重试继续使用原扣费键,退款重试继续使用原退款键;不要生成新键,也不要在外部 HTTP 请求期间持有数据库事务。日志只保留错误码和 request_id。

字段的权威 Schema 见完整 API 参考。

OAuth credentials and model-provider secrets must remain on trusted servers.