Public API 账单查询
Public API 默认查询当前 API Key 的消费,组织管理员账号下的 Key 还可查询所属组织的消费。单次请求返回指定日期范围、每日和每日各模型的折前及折后消费金额,以及分类 Token 用量。
接口地址
GET https://console.exchangetoken.ai/api/public/v1/billing响应格式为 application/json。查询结果按日期升序排列,同一日期内按模型标识升序排列。接口仅返回聚合结果,不提供单次请求明细。
认证
使用调用模型时的 API Key,通过 Authorization 请求头传入:
Authorization: Bearer sk-YOUR_API_KEY不传 scope 或传入 scope=key 时,仅查询当前 API Key 的消费数据,包括组织管理员账号下的 Key。传入 scope=org 时,仅组织管理员(admin/root)账号下的 Key 可以查询该账号所属组织的全部 Key 的消费数据;普通账号的 Key 返回 403 forbidden。
权限以 Key 所属账号当前的角色为准,组织范围由服务端根据该账号确定。接口不接受 token_id、user_id 或 org_id 等指定查询对象的参数,不要求控制台登录态。API Key 不得通过 URL 查询参数传递。
额度耗尽不影响账单查询。API Key 过期、禁用、删除,账户被禁用,或请求来源不符合 Key 的 IP 限制时,无法查询。
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
from | string | 是 | 起始日期,格式为 YYYY-MM-DD,包含当天。 |
to | string | 是 | 结束日期,格式为 YYYY-MM-DD,不包含当天。 |
timezone | string | 否 | 日期边界与每日聚合使用的 IANA 时区标识,默认为 UTC,例如 Asia/Shanghai、America/New_York。 |
scope | string | 否 | 查询范围:key 查询当前 Key,org 查询所属组织。省略时默认为 key;org 仅限组织管理员账号下的 Key。 |
日期范围采用 [from, to),必须满足 from < to,且最多包含 31 个自然日。日期支持范围为 1970 年至 2299 年。参数不得重复,不支持的参数、无效时区或无效 scope(包括空值)将返回 400。
例如,from=2026-09-01&to=2026-09-08 查询指定时区下 9 月 1 日至 9 月 7 日的消费;查询单日时,应将 to 设置为次日。跨度按自然日计算,夏令时引起的每日小时数变化不影响 31 天限制。查询超过 31 天的数据时,应拆分为多个相邻且不重叠的区间。
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
from | string | 查询起始日期。 |
to | string | 查询结束日期,不包含当天。 |
timezone | string | 本次查询使用的时区。 |
currency | string | 金额币种,固定为 USD。 |
total_amount | string | 查询区间折前消费总金额,保留 9 位小数。 |
total_discounted_amount | string | 查询区间折后消费总金额,保留 9 位小数。 |
data | array | 每日汇总列表。 |
data[].date | string | 消费日期,格式为 YYYY-MM-DD。 |
data[].total_amount | string | 当日折前消费总金额,保留 9 位小数。 |
data[].total_discounted_amount | string | 当日折后消费总金额,保留 9 位小数。 |
data[].models | array | 当日各模型的聚合结果。 |
data[].models[].model | string | 模型标识,与控制台账单中心一致。 |
data[].models[].amount | string | 当日该模型的折前消费金额,保留 9 位小数。 |
data[].models[].discounted_amount | string | 当日该模型的折后消费金额,保留 9 位小数。 |
data[].models[].usage | object | 当日该模型的分类 Token 用量。 |
usage 包含以下字段,类型为非负整数:
| 字段 | 说明 |
|---|---|
input_tokens | 按普通输入类别计费的 Token,不包含已归入缓存读取或缓存写入的部分。 |
cache_read_tokens | 按缓存读取类别计费的 Token。 |
cache_write_tokens | 按缓存写入类别计费的 Token 总量,不区分缓存时长。 |
output_tokens | 按输出类别计费的 Token。 |
reasoning_tokens | 单独按推理类别计费的 Token。 |
amount 和 total_amount 按折扣前的原始计费金额统计。discounted_amount 和 total_discounted_amount 汇总账单中已记录的下游折后费用,不按当前折扣配置重新计算历史金额。没有折扣时,折后金额与折前金额相同;完全免收费时,折后金额为 0.000000000。
Token 用量按计费类别统计,已计入输出类别的推理 Token 不会再次计入 reasoning_tokens;该字段为 0 不表示模型未执行推理。未产生的类别返回 0。
usage 按计费类别汇总,不按计价单位筛选。对于非 Token 计价模型,返回值可能采用该模型的计量口径。客户端应使用十进制数处理金额。
折前、折后金额分别满足:区间总金额等于每日总金额之和,每日总金额等于当天各模型金额之和。无消费的日期返回零金额和空 models 数组。
响应示例
以下数据仅用于说明响应结构:
{
"from": "2026-09-01",
"to": "2026-09-03",
"timezone": "UTC",
"currency": "USD",
"total_amount": "1.200000000",
"total_discounted_amount": "0.960000000",
"data": [
{
"date": "2026-09-01",
"total_amount": "1.200000000",
"total_discounted_amount": "0.960000000",
"models": [
{
"model": "example-model",
"amount": "1.200000000",
"discounted_amount": "0.960000000",
"usage": {
"input_tokens": 100000,
"cache_read_tokens": 20000,
"cache_write_tokens": 10000,
"output_tokens": 30000,
"reasoning_tokens": 0
}
}
]
},
{
"date": "2026-09-02",
"total_amount": "0.000000000",
"total_discounted_amount": "0.000000000",
"models": []
}
]
}调用示例
cURL
通过环境变量提供 API Key,并使用 --data-urlencode 编码查询参数:
export EXCHANGE_TOKEN_API_KEY='sk-YOUR_API_KEY'
curl --fail-with-body --get \
'https://console.exchangetoken.ai/api/public/v1/billing' \
--header "Authorization: Bearer ${EXCHANGE_TOKEN_API_KEY}" \
--data-urlencode 'from=2026-09-01' \
--data-urlencode 'to=2026-09-08' \
--data-urlencode 'timezone=Asia/Shanghai'以上示例默认查询当前 Key。使用组织管理员账号下的 Key 查询组织账单时,增加 --data-urlencode 'scope=org',返回字段和金额口径相同。
Python
以下示例使用 Python 标准库发送请求,并使用 Decimal 读取金额:
import json
import os
from decimal import Decimal
from urllib.parse import urlencode
from urllib.request import Request, urlopen
params = urlencode({
"from": "2026-09-01",
"to": "2026-09-08",
"timezone": "UTC",
})
request = Request(
"https://console.exchangetoken.ai/api/public/v1/billing?" + params,
headers={"Authorization": "Bearer " + os.environ["EXCHANGE_TOKEN_API_KEY"]},
)
with urlopen(request, timeout=90) as response:
bill = json.load(response)
print(Decimal(bill["total_amount"]), bill["currency"])
print(Decimal(bill["total_discounted_amount"]), bill["currency"])
for day in bill["data"]:
for item in day["models"]:
print(day["date"], item["model"], Decimal(item["amount"]),
Decimal(item["discounted_amount"]), item["usage"])错误响应
错误统一使用以下 JSON 结构:
{
"error": {
"type": "invalid_request",
"message": "date range must contain between 1 and 31 calendar days; to is exclusive"
}
}| HTTP 状态码 | error.type | 说明 |
|---|---|---|
400 | invalid_request | 缺少日期、日期格式或范围无效、时区或 scope 无效、参数重复或包含不支持的参数。 |
401 | unauthorized | 未提供有效的 Bearer API Key。 |
403 | forbidden | Key 或账户状态不允许访问、不满足 IP 限制,或 Key 所属账号无组织账单查询权限。 |
404 | not_found | 接口路径不存在。 |
405 | method_not_allowed | 请求方法不受支持;本接口仅支持 GET。 |
429 | rate_limit_exceeded | 请求暂时受限,请稍后重试。 |
500 | internal_error | 服务处理异常。 |
503 | service_unavailable / billing_unavailable | 服务繁忙,或认证、账单数据暂不可用。 |
504 | query_timeout | 查询超时,可缩短日期范围后重试。 |
数据更新与重试
收到 429 时,应遵循响应中的 Retry-After 秒数后重试。
消费数据更新存在短暂延迟,不建议查询当日数据。
