> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 查询消费用量

>  - 查询指定时间范围内的消费金额与调用统计
- 支持按模型过滤、按模型或自然日分组
- 支持当前 API Key 或整个账号的消费统计
- 返回美元金额、积分、调用次数与 token 用量 

使用 API Key 查询指定时间范围内的消费金额，可按模型过滤，并按模型、自然日或二者组合分组。此接口直接返回聚合结果，不需要创建任务或轮询任务状态。

```bash cURL theme={null}
curl --get 'https://api.apimart.ai/v1/usage' \
  --header 'Authorization: Bearer <token>' \
  --data-urlencode 'start=2026-09-01T00:00:00+08:00' \
  --data-urlencode 'end=2026-09-08T00:00:00+08:00' \
  --data-urlencode 'group_by=model'
```

```python Python theme={null}
import requests

response = requests.get(
    "https://api.apimart.ai/v1/usage",
    headers={"Authorization": "Bearer <token>"},
    params={
        "start": "2026-09-01T00:00:00+08:00",
        "end": "2026-09-08T00:00:00+08:00",
        "group_by": "model",
    },
    timeout=30,
)

payload = response.json()
if not response.ok or not payload.get("success"):
    message = payload.get("error", {}).get("message", "用量查询失败")
    raise RuntimeError(f"HTTP {response.status_code}: {message}")

print(payload["data"]["total"])
print(payload["data"]["items"])
```

```javascript JavaScript theme={null}
const url = new URL("https://api.apimart.ai/v1/usage");
url.search = new URLSearchParams({
  start: "2026-09-01T00:00:00+08:00",
  end: "2026-09-08T00:00:00+08:00",
  group_by: "model",
}).toString();

const response = await fetch(url, {
  headers: { Authorization: "Bearer <token>" },
});
const payload = await response.json();

if (!response.ok || !payload.success) {
  throw new Error(
    `HTTP ${response.status}: ${payload.error?.message ?? "用量查询失败"}`,
  );
}

console.log(payload.data.total);
console.log(payload.data.items);
```

```json 200 theme={null}
{
  "success": true,
  "data": {
    "scope": "key",
    "start": 1788192000,
    "end": 1788796800,
    "tz": "Asia/Shanghai",
    "group_by": "model",
    "total": {
      "amount_usd": 12.3456,
      "credits": 123.456,
      "requests": 1834,
      "prompt_tokens": 902311,
      "completion_tokens": 215044
    },
    "items": [
      {
        "model": "gpt-5.6-luna",
        "amount_usd": 9.1271,
        "credits": 91.271,
        "requests": 1520,
        "prompt_tokens": 880120,
        "completion_tokens": 201300
      },
      {
        "model": "sora-2",
        "amount_usd": 3.2185,
        "credits": 32.185,
        "requests": 314,
        "prompt_tokens": 22191,
        "completion_tokens": 13744
      }
    ]
  }
}
```

```json 400 theme={null}
{
  "success": false,
  "error": {
    "code": "range_too_large",
    "message": "Time range must not exceed 31 days.",
    "type": "usage_query_error"
  }
}
```

## 认证

**Authorization** `string` *required*

使用与调用模型相同的 API Key，通过 Bearer Token 认证。访问 [API Key 管理页面](https://apimart.ai/keys) 获取密钥。

```
Authorization: Bearer YOUR_API_KEY
```

> [!NOTE]
>
> 余额为 0 时仍可查询。本接口不校验余额，但仍校验 API Key 状态、过期时间、IP 白名单及账号状态。

## 接口端点

```text theme={null}
GET /v1/usage
GET /usage
```

两个端点功能相同，支持 CORS 跨域请求。请妥善保管 API Key，不要将其暴露在公开的前端代码中。

## 请求参数

所有参数均通过 URL Query 传递。

**start** `integer | string`

起始时间，包含该时刻。支持 Unix 秒级时间戳或带时区的 RFC3339 字符串，例如 `2026-09-01T00:00:00+08:00`。

不传时默认为 `end` 前 24 小时。时间戳单位为秒，不是毫秒。

**end** `integer | string`

结束时间，不包含该时刻。格式与 `start` 相同，不传时默认为当前时间。

必须晚于 `start`，且 `end - start` 不得超过 31 天。

**model** `string`

模型名称，不传时统计全部模型。多个模型使用英文逗号分隔，最多 `50` 个。

精确匹配、不区分大小写，不支持通配符。

示例：`gpt-5.6-luna,sora-2`

**group\_by** `string` (default: none)

分组方式：

* `none`：仅返回合计，`items` 为空数组
* `model`：按模型分组
* `date`：按自然日分组
* `model,date`：按模型和自然日组合分组

**tz** `string` (default: Asia/Shanghai)

IANA 时区名称，默认 `Asia/Shanghai`。

仅影响 `group_by` 包含 `date` 时的自然日边界，不改变查询的起止时刻。RFC3339 起止时间仍按其自身携带的时区解析。

**scope** `string` (default: key)

统计范围：

* `key`：仅统计当前 API Key（默认）
* `account`：统计当前 API Key 所属账号的全部 API Key 合计

> [!NOTE]
>
> 查询时间区间为 `[start, end)`：包含起点、不包含终点。相邻查询以相同的时间作为前一次的 `end` 和后一次的 `start`，不会重复计算边界时刻。
>
> 手动拼接 URL 时，RFC3339 中的 `+` 必须编码为 `%2B`。示例中的 cURL `--data-urlencode`、Python `params` 和 JavaScript `URLSearchParams` 会自动处理编码。

## 请求示例

### 当前 API Key 最近 24 小时的消费合计

不传 Query 参数即可使用默认时间范围、默认统计范围和默认分组方式：

```bash theme={null}
curl 'https://api.apimart.ai/v1/usage' \
  --header 'Authorization: Bearer <token>'
```

### 整个账号指定模型的每日消费

查询 2026 年 9 月 11 日至 9 月 18 日（北京时间，不含 9 月 18 日）的消费：

```bash theme={null}
curl --get 'https://api.apimart.ai/v1/usage' \
  --header 'Authorization: Bearer <token>' \
  --data-urlencode 'start=1789056000' \
  --data-urlencode 'end=1789660800' \
  --data-urlencode 'model=gpt-5.6-luna' \
  --data-urlencode 'group_by=date' \
  --data-urlencode 'scope=account' \
  --data-urlencode 'tz=Asia/Shanghai'
```

### 按模型和自然日组合分组

```bash theme={null}
curl --get 'https://api.apimart.ai/v1/usage' \
  --header 'Authorization: Bearer <token>' \
  --data-urlencode 'start=2026-09-01T00:00:00+08:00' \
  --data-urlencode 'end=2026-09-08T00:00:00+08:00' \
  --data-urlencode 'model=gpt-5.6-luna,sora-2' \
  --data-urlencode 'group_by=model,date' \
  --data-urlencode 'tz=Asia/Shanghai'
```

该分组方式下，每个 `items` 元素同时包含 `model` 和 `date`。

## 响应字段

**success** `boolean`

查询是否成功。成功时为 `true`，用量查询错误时为 `false`。

**data** `object`

成功时返回查询范围、合计与分组明细。

**data 属性**

**scope** `string`

本次统计范围：`key` 或 `account`。

**start** `integer`

实际查询起始时间，Unix 秒级时间戳，含起点。

**end** `integer`

实际查询结束时间，Unix 秒级时间戳，不含终点。

**tz** `string`

本次使用的自然日分组时区。

**group\_by** `string`

本次分组方式：`none`、`model`、`date` 或 `model,date`。

**total** `object`

本次查询范围内的合计，统计字段见下表。

**items** `object[]`

分组明细，按 `amount_usd` 降序排列；`group_by=none` 时为空数组。每个元素包含下表中的统计字段。

* `group_by` 包含 `model` 时，元素包含 `model`
* `group_by` 包含 `date` 时，元素包含 `date`，格式为 `YYYY-MM-DD`，按 `tz` 划分自然日

`data.total` 与 `data.items[]` 共用以下统计字段：

| 字段 | 类型 | 说明 |
| - | - | - |
| `amount_usd` | number | 美元金额，保留 6 位小数 |
| `credits` | number | 站内积分，等于 `amount_usd × 10`，与官网展示单位一致 |
| `requests` | integer | 计费成功的调用次数 |
| `prompt_tokens` | integer | 输入 token 数；按次或按秒计费的图片、视频模型通常为 0 |
| `completion_tokens` | integer | 输出 token 数；按次或按秒计费的图片、视频模型通常为 0 |

**error** `object`

用量查询错误时返回，包含 `code`、`message` 和 `type`，其中 `type` 为 `usage_query_error`。401 / 403 鉴权错误由鉴权层返回。

## 限流与缓存

* 每把 API Key 每分钟最多查询 `60` 次，同时受全局 API 限流约束
* 相同参数的查询结果缓存 `60` 秒，响应头 `X-Usage-Cache` 为 `hit` 或 `miss`
* 通常 1 秒内可查到消费记录，但最近 1 分钟的数据可能不完整，且存在缓存延迟
* 建议查询间隔不低于 1 分钟，不要将本接口作为实时扣费通知

## 统计口径

* 数据来自计费成功的调用记录，与官网“数据看板”使用相同数据
* 调用失败或任务失败后退款的记录不计入，无需自行冲抵；组图部分成功时按实际交付张数计费
* 按计费落账时刻归属消费；异步图片、视频任务在完成时落账，不是提交时刻。跨零点任务归入完成当天
* 删除后重建的 API Key 属于新的 Key；使用新 Key 查询 `scope=key` 时，不包含旧 Key 的历史
* 后台人工调整余额不属于调用消费，不在统计范围内
* 可查询 2026 年 4 月 27 日之后的数据

## 错误处理

| HTTP 状态码 | `error.code` | 说明 |
| - | - | - |
| 400 | `invalid_start` / `invalid_end` | 起止时间格式无效 |
| 400 | `invalid_range` | `end` 不大于 `start` |
| 400 | `range_too_large` | 时间跨度超过 31 天，请拆分为多个查询区间 |
| 400 | `invalid_tz` | 未知的 IANA 时区 |
| 400 | `invalid_group_by` | 分组方式无效 |
| 400 | `invalid_scope` | 统计范围无效 |
| 400 | `too_many_models` | 模型数量超过 50 个 |
| 401 / 403 | — | API Key 无效、过期、IP 不在白名单或账号被停用 |
| 429 | — | 超过每 Key 每分钟 60 次的限制，或触发全局 API 限流 |
| 503 | `usage_unavailable` | 用量数据暂时不可用，请稍后重试 |

> [!WARNING]
>
> 收到 `503 usage_unavailable` 时，不会返回任何金额。这表示查询不可用，不表示消费为 0；不要将失败响应转换为零金额或覆盖此前成功查询的结果。

## 与其他接口的区别

| 接口 | 能力 |
| - | - |
| `GET /v1/dashboard/billing/usage` | 返回累计已用总额，不能按模型或时间筛选 |
| `POST /v1/logs/export` | 异步导出调用明细（CSV / XLSX），需要自行汇总 |
| `GET /v1/usage` | 按指定时间与模型查询，直接返回消费合计及分组明细 |

如需查询剩余额度，请使用 [查询令牌余额](/cn/api-reference/account/token-balance.md) 或 [查询用户余额](/cn/api-reference/account/user-balance.md)。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.