余额与用量查询

生产环境如何健壮地监控余额、API Key 限速和请求成本。

查询接口概览

  • GET /v1/wallet — 当前余额、冻结额、可用额(Console JWT)
  • GET /v1/keys — API Key 限速、预算、Token 上限、过期时间与备注(Console JWT)
  • GET /v1/wallet/transactions — 交易流水分页(Console JWT)
  • GET /v1/monitoring/usage/summary — 用量汇总(Console JWT)
注意这些是**平台 API**,用 JWT 认证,不是 sk-swx-*。用 SDK 客户端不能直接用。 登录后通过 Console → 设置可以生成长期 personal access token 调用这些接口。

推荐的监控模式

1. 定时低频查询(每分钟)

python
import httpx
import time

def get_wallet_balance(jwt):
    r = httpx.get(
        "http://api.swarmixtoken.com/v1/wallet",
        headers={"Authorization": f"Bearer {jwt}"},
    )
    r.raise_for_status()
    return r.json()

while True:
    w = get_wallet_balance(JWT)
    print(f"余额 ¥{w['balance']:.2f}, 冻结 ¥{w['frozen']:.2f}")
    if w["available"] < 10:
        send_alert("低余额")
    time.sleep(60)

2. 请求前预检(高 QPS 慎用)

如果你做 SaaS 转卖,需要在每次用户下单时检查余额:

python
def forward_request(user_request):
    # 不要在每次都查 /v1/wallet — 太慢,加缓存
    if not has_budget_cached(user_id):
        return 402, "Insufficient budget"
    # 转发到 Swarmix
    return swarmix_client.chat.completions.create(**user_request)
Swarmix 本身在余额不足时会直接返回 402 给客户端,你不需要自己预检查 — 除非你做了一层业务逻辑,想自己决定何时报错。

3. Webhook 订阅事件(最可靠)

Swarmix 在余额低于阈值、扣款或告警产生时推 webhook:

  • billing.low_balance — 余额低于预警线
  • billing.deduction — 每次扣款(高频,谨慎订阅)
  • alert.created — 新告警产生

订阅方式:Console → Webhooks 添加订阅。Swarmix 会向你的 URL POST JSON:

http
POST https://your-app.com/hook
Content-Type: application/json
X-Swarmix-Event: billing.low_balance
X-Swarmix-Signature: sha256=<hmac>
X-Swarmix-Delivery: evt_xxxxx

{
  "event": "billing.low_balance",
  "tenant_id": 13,
  "data": {
    "balance": 8.52,
    "threshold": 10.0,
    "currency": "CNY"
  },
  "timestamp": 1776996123
}
请校验 X-Swarmix-Signature:HMAC-SHA256,密钥为 webhook 创建时分配的 secret。避免伪造的回调。

用量分析 SQL

企业私有部署时你可以直接查 ClickHouse:

sql
-- 本月每个模型的消费
SELECT
  model,
  count() AS requests,
  sum(total_tokens) AS tokens,
  sum(cost_cny) AS cost_cny
FROM ygj_logs.request_logs
WHERE tenant_id = 13
  AND created_at >= toDate('2026-04-01')
GROUP BY model
ORDER BY cost_cny DESC;

-- 今日各时段 QPS 曲线
SELECT
  toStartOfMinute(created_at) AS minute,
  count() AS rps
FROM ygj_logs.request_logs
WHERE tenant_id = 13
  AND created_at >= toStartOfDay(now())
GROUP BY minute
ORDER BY minute;