Usage
Returns quota, subscription, or wallet-balance information for the current API key, plus recent usage statistics. The endpoint is intended for client integrations like CC Switch that display "how much is left".
About the unit: "USD" response field
For backward compatibility, the unit field always returns the string "USD". One numeric unit = ¥1 — the values match the ¥ prices shown in the Console and documentation 1:1, with no FX conversion. Treat any number labeled (USD) below as if it were (¥).
Endpoint
GET https://api.sakrylle.com/v1/usageHeaders
| Name | Required | Description |
|---|---|---|
Authorization | Yes | Bearer sk-xxxxxxxxxxxxxxxx |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | No | YYYY-MM-DD, start of the model statistics window, defaults to 30 days ago |
end_date | string | No | YYYY-MM-DD, end of the window, defaults to today |
days | integer | No | Daily-aggregation window, 1–90, default per internal rules |
timezone | string | No | IANA timezone (e.g. Asia/Shanghai); affects daily aggregation cutover |
Response modes
The endpoint returns one of two modes depending on the API key configuration:
mode | Trigger | Meaning |
|---|---|---|
quota_limited | The API key has a total quota (Quota > 0) or rate limits | Returns key-level quota / rate-limit data |
unrestricted | No key-level limits | Returns subscription or wallet balance |
quota_limited fields
| Field | Type | Description |
|---|---|---|
mode | string | Always quota_limited |
isValid | boolean | Whether the key is still usable |
status | string | Key status enum |
quota.limit | number | Total quota (USD) |
quota.used | number | Used (USD) |
quota.remaining | number | Remaining (USD) |
quota.unit | string | USD |
remaining | number | Same as quota.remaining (legacy clients) |
unit | string | USD (legacy clients) |
rate_limits[] | array | 5h / 1d / 7d window limits (only configured windows are returned) |
rate_limits[].window | string | 5h / 1d / 7d |
rate_limits[].limit | number | Window limit (USD) |
rate_limits[].used | number | Used in the window |
rate_limits[].remaining | number | Remaining in the window |
rate_limits[].window_start | string | Window start time |
rate_limits[].reset_at | string | Window end time (only while the window has not expired) |
expires_at | string | Key expiration time |
days_until_expiry | integer | Days until expiration |
usage | object | Today / cumulative usage summary (see below) |
daily_usage | array | Daily-aggregated usage |
model_stats | array | Per-model usage stats (only when there is data in the date range) |
unrestricted mode fields
Subscription-style group:
| Field | Type | Description |
|---|---|---|
mode | string | Always unrestricted |
isValid | boolean | Always true |
planName | string | Group name |
unit | string | USD |
remaining | number | Minimum remaining quota across configured periods; 0 if any configured period is exhausted; -1 if no period is configured |
subscription.daily_usage_usd | number | Used today |
subscription.weekly_usage_usd | number | Used this week |
subscription.monthly_usage_usd | number | Used this month |
subscription.daily_limit_usd | number | null | Daily limit |
subscription.weekly_limit_usd | number | null | Weekly limit |
subscription.monthly_limit_usd | number | null | Monthly limit |
subscription.expires_at | string | Subscription expiration time |
Wallet-balance group:
| Field | Type | Description |
|---|---|---|
mode | string | Always unrestricted |
isValid | boolean | Always true |
planName | string | Literal Chinese string 钱包余额 (hardcoded by the gateway, not localized) |
remaining | number | Balance |
balance | number | Balance (same value as remaining) |
unit | string | USD |
usage block
usage.today and usage.total share the same shape:
| Field | Type | Description |
|---|---|---|
requests | integer | Number of requests |
input_tokens | integer | Input tokens |
output_tokens | integer | Output tokens |
cache_creation_tokens | integer | Cache creation tokens |
cache_read_tokens | integer | Cache read tokens |
total_tokens | integer | All tokens |
cost | number | Upstream official price (USD) |
actual_cost | number | Actual charge after applying rate_multiplier (USD) |
usage also carries three live metrics: average_duration_ms, rpm, and tpm.
Wallet balance mode
{
"mode": "unrestricted",
"isValid": true,
"planName": "Wallet Balance",
"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 mode
{
"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"
}
]
}Errors
400 invalid_request_error—daysis outside 1–90401 authentication_error— invalid API key
For the full table, see Errors.
Code samples
curl https://api.sakrylle.com/v1/usage \
-H "Authorization: Bearer sk-xxxxxxxxxxxxxxxx"import httpx
resp = httpx.get(
"https://api.sakrylle.com/v1/usage",
headers={"Authorization": "Bearer sk-xxxxxxxxxxxxxxxx"},
)
print(resp.json())const resp = await fetch("https://api.sakrylle.com/v1/usage", {
headers: { Authorization: "Bearer sk-xxxxxxxxxxxxxxxx" },
});
console.log(await resp.json());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))
}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(())
}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());
}
}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());