Usage
返回当前 API Key 的额度、订阅或钱包余额信息,以及最近的用量统计。该接口主要服务于像 CC Switch 这样的客户端集成,用于显示「还能用多久」。
关于响应字段中的 unit: "USD"
为兼容现有客户端,本接口的 unit 字段固定返回字符串 "USD"。数值层面 1 单位 = ¥1,与控制台和文档中的 ¥ 价格 1:1 一致,不做任何汇率换算。把响应里所有标 (USD) 的数字直接当 (¥) 读即可。
Endpoint
GET https://api.sakrylle.com/v1/usage请求头
| 名称 | 必填 | 说明 |
|---|---|---|
Authorization | 是 | Bearer sk-xxxxxxxxxxxxxxxx |
Query 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
start_date | string | 否 | YYYY-MM-DD,模型统计起点,默认 30 天前 |
end_date | string | 否 | YYYY-MM-DD,模型统计终点,默认今天 |
days | integer | 否 | 日聚合天数,1–90,默认按内部规则 |
timezone | string | 否 | IANA 时区名称(例如 Asia/Shanghai),影响日聚合切日 |
响应模式
接口根据 API Key 配置返回两种模式:
mode | 触发条件 | 含义 |
|---|---|---|
quota_limited | API Key 设了总额度 (Quota > 0) 或速率限制 | 返回 key 级额度/速率信息 |
unrestricted | 无 key 级限制 | 返回订阅或钱包余额 |
quota_limited 字段
| 字段 | 类型 | 说明 |
|---|---|---|
mode | string | 固定 quota_limited |
isValid | boolean | Key 是否仍可用 |
status | string | Key 状态枚举 |
quota.limit | number | 总额度(USD) |
quota.used | number | 已用(USD) |
quota.remaining | number | 剩余(USD) |
quota.unit | string | USD |
remaining | number | 同 quota.remaining(兼容旧客户端) |
unit | string | USD(兼容旧客户端) |
rate_limits[] | array | 5h / 1d / 7d 三个窗口的限额(仅返回已配置项) |
rate_limits[].window | string | 5h / 1d / 7d |
rate_limits[].limit | number | 该窗口限额(USD) |
rate_limits[].used | number | 该窗口已用 |
rate_limits[].remaining | number | 该窗口剩余 |
rate_limits[].window_start | string | 窗口起点 |
rate_limits[].reset_at | string | 窗口结束时间(仅在窗口未过期时返回) |
expires_at | string | Key 过期时间 |
days_until_expiry | integer | 距离过期天数 |
usage | object | 今日 / 累计用量摘要(见下) |
daily_usage | array | 按日聚合的用量 |
model_stats | array | 按模型聚合的用量统计(指定日期范围内有数据时返回) |
unrestricted 字段
订阅类分组:
| 字段 | 类型 | 说明 |
|---|---|---|
mode | string | 固定 unrestricted |
isValid | boolean | 固定 true |
planName | string | 分组名称 |
unit | string | USD |
remaining | number | 取已配置周期中剩余额度的最小值;任一周期已用尽则返回 0;未配置任何周期时返回 -1 |
subscription.daily_usage_usd | number | 当日已用 |
subscription.weekly_usage_usd | number | 本周已用 |
subscription.monthly_usage_usd | number | 本月已用 |
subscription.daily_limit_usd | number | null | 日限额 |
subscription.weekly_limit_usd | number | null | 周限额 |
subscription.monthly_limit_usd | number | null | 月限额 |
subscription.expires_at | string | 订阅到期时间 |
钱包余额类分组:
| 字段 | 类型 | 说明 |
|---|---|---|
mode | string | 固定 unrestricted |
isValid | boolean | 固定 true |
planName | string | 固定 钱包余额 |
remaining | number | 余额 |
balance | number | 余额(与 remaining 相同) |
unit | string | USD |
usage 块结构
usage.today 与 usage.total 同构:
| 字段 | 类型 | 说明 |
|---|---|---|
requests | integer | 请求次数 |
input_tokens | integer | 输入 token |
output_tokens | integer | 输出 token |
cache_creation_tokens | integer | 缓存创建 token |
cache_read_tokens | integer | 缓存读取 token |
total_tokens | integer | 全部 token |
cost | number | 上游官方价(USD) |
actual_cost | number | 应用 rate_multiplier 后的实际计费(USD) |
usage 还含 average_duration_ms、rpm、tpm 三项即时指标。
钱包余额模式
json
{
"mode": "unrestricted",
"isValid": true,
"planName": "钱包余额",
"remaining": 23.71,
"balance": 23.71,
"unit": "USD",
"usage": {
"today": {
"requests": 12,
"input_tokens": 8421,
"output_tokens": 1532,
"cache_creation_tokens": 0,
"cache_read_tokens": 0,
"total_tokens": 9953,
"cost": 0.0461,
"actual_cost": 0.00922
},
"total": {
"requests": 358,
"input_tokens": 312044,
"output_tokens": 64217,
"cache_creation_tokens": 0,
"cache_read_tokens": 0,
"total_tokens": 376261,
"cost": 1.872,
"actual_cost": 0.3744
},
"average_duration_ms": 842,
"rpm": 4,
"tpm": 2103
}
}quota_limited 模式
json
{
"mode": "quota_limited",
"isValid": true,
"status": "active",
"quota": {
"limit": 50,
"used": 12.4,
"remaining": 37.6,
"unit": "USD"
},
"remaining": 37.6,
"unit": "USD",
"rate_limits": [
{
"window": "1d",
"limit": 5,
"used": 1.2,
"remaining": 3.8,
"window_start": "2026-05-22T00:00:00Z",
"reset_at": "2026-05-23T00:00:00Z"
}
]
}错误
400 invalid_request_error—days不在 1–90 区间401 authentication_error— API Key 无效
更多错误码见 错误处理。
代码示例
bash
curl https://api.sakrylle.com/v1/usage \
-H "Authorization: Bearer sk-xxxxxxxxxxxxxxxx"python
import httpx
resp = httpx.get(
"https://api.sakrylle.com/v1/usage",
headers={"Authorization": "Bearer sk-xxxxxxxxxxxxxxxx"},
)
print(resp.json())javascript
const resp = await fetch("https://api.sakrylle.com/v1/usage", {
headers: { Authorization: "Bearer sk-xxxxxxxxxxxxxxxx" },
});
console.log(await resp.json());go
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET",
"https://api.sakrylle.com/v1/usage", nil)
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxxxxxxxx")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}rust
use reqwest::Client;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = Client::new();
let resp: serde_json::Value = client
.get("https://api.sakrylle.com/v1/usage")
.bearer_auth("sk-xxxxxxxxxxxxxxxx")
.send()
.await?
.json()
.await?;
println!("{resp:#}");
Ok(())
}java
import java.net.URI;
import java.net.http.*;
public class Usage {
public static void main(String[] args) throws Exception {
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.sakrylle.com/v1/usage"))
.header("Authorization", "Bearer sk-xxxxxxxxxxxxxxxx")
.GET()
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
}
}csharp
using System.Net.Http.Headers;
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "sk-xxxxxxxxxxxxxxxx");
var resp = await http.GetAsync("https://api.sakrylle.com/v1/usage");
Console.WriteLine(await resp.Content.ReadAsStringAsync());