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

# 日志查询

> 分页查询调用日志、消费日志、充值日志等

<Info>
  分页查询当前凭证所属范围内的调用、消费、充值、管理、错误、退款和测试金日志。
</Info>

## 接口信息

* **HTTP 方法**：`GET`
* **请求地址**：`https://maas.gravitex.ai/prod-api/api/logs/v2/page`
* **鉴权请求头**：`Authorization`
* **语言请求头**：`Accept-Language`，支持 `zh-CN`、`en-US`
* **时间格式**：`yyyy-MM-dd HH:mm:ss`
* **时间范围上限**：31 天
* **默认分页**：`page=1`、`pageSize=30`
* **每页数量上限**：1000

## 用户鉴权

以下格式均支持：

```http theme={null}
Authorization: Bearer sk-your_api_key
Authorization: sk-your_api_key
```

| 凭证                                                     | 查询范围                 | `tokenName` 行为                             |
| ------------------------------------------------------ | -------------------- | ------------------------------------------ |
| [系统访问令牌](https://maas.gravitex.ai/#/profile?tab=token) | 该用户的日志               | 使用请求传入的 `tokenName`，按模糊匹配                  |
| [API Key](/cn/interface-module/token-management)       | 该用户且属于当前 API Key 的日志 | 服务端强制精确匹配当前 API Key 名称，忽略请求传入的 `tokenName` |

<Warning>
  不要在 URL、前端代码、日志或工单中明文记录完整 Key。
</Warning>

## 查询参数

<ParamField query="page" type="integer" default="1">
  页码；小于或等于 0 时按 1 处理
</ParamField>

<ParamField query="pageSize" type="integer" default="30">
  每页数量；小于或等于 0 时按 30 处理，最大 1000
</ParamField>

<ParamField query="tokenName" type="string">
  APIkey名称, 鉴权方式为[系统访问令牌](https://maas.gravitex.ai/#/profile?tab=token)时模糊查询; 为[APIkey](/cn/interface-module/token-management)时不可用,强制查询当前APIkey的日志
</ParamField>

<ParamField query="modelName" type="string">
  模型名称，精确匹配；多个模型用英文逗号分隔
</ParamField>

<ParamField query="requestId" type="string">
  请求 ID，精确匹配
</ParamField>

<ParamField query="ip" type="string">
  请求 IP，精确匹配
</ParamField>

<ParamField query="useTimeMin" type="integer">
  最小用时，单位秒，包含边界
</ParamField>

<ParamField query="useTimeMax" type="integer">
  最大用时，单位秒，包含边界
</ParamField>

<ParamField query="startTime" type="string">
  开始时间，格式 `yyyy-MM-dd HH:mm:ss`，包含边界
</ParamField>

<ParamField query="endTime" type="string">
  结束时间，格式 `yyyy-MM-dd HH:mm:ss`，包含边界
</ParamField>

<ParamField query="types" type="string">
  日志类型，多个值用英文逗号分隔；允许值为 `1,2,3,5,6,8`
</ParamField>

### 日志类型

|   值 | 类型  |
| --: | --- |
| `1` | 充值  |
| `2` | 消费  |
| `3` | 管理  |
| `5` | 错误  |
| `6` | 退款  |
| `8` | 测试金 |

## Accept-Language

只影响 `billingProcessText`：

| 请求头                      | 返回语言 |
| ------------------------ | ---- |
| `Accept-Language: zh-CN` | 中文   |
| `Accept-Language: en-US` | 英文   |
| 未传或其他值                   | 中文   |

## 请求示例

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl --get 'https://maas.gravitex.ai/prod-api/api/logs/v2/page' \
      --header 'Authorization: Bearer your_api_key' \
      --header 'Accept-Language: zh-CN' \
      --data-urlencode 'page=1' \
      --data-urlencode 'pageSize=30' \
      --data-urlencode 'startTime=2026-07-01 00:00:00' \
      --data-urlencode 'endTime=2026-07-21 23:59:59' \
      --data-urlencode 'types=2,5'
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const params = new URLSearchParams({
      page: '1',
      pageSize: '30',
      startTime: '2026-07-01 00:00:00',
      endTime: '2026-07-21 23:59:59',
      types: '2,5',
    });

    const response = await fetch(
      `https://maas.gravitex.ai/prod-api/api/logs/v2/page?${params}`,
      {
        method: 'GET',
        headers: {
          Authorization: 'Bearer your_api_key',
          'Accept-Language': 'zh-CN',
        },
      },
    );

    const result = await response.json();
    if (result.code !== 200) {
      throw new Error(result.msg);
    }

    console.log(result.data.total, result.data.rows);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    url = "https://maas.gravitex.ai/prod-api/api/logs/v2/page"
    headers = {
        "Authorization": "Bearer your_api_key",
        "Accept-Language": "zh-CN",
    }
    params = {
        "page": 1,
        "pageSize": 30,
        "startTime": "2026-07-01 00:00:00",
        "endTime": "2026-07-21 23:59:59",
        "types": "2,5",
    }

    response = requests.get(url, headers=headers, params=params, timeout=30)
    response.raise_for_status()
    result = response.json()

    if result.get("code") != 200:
        raise RuntimeError(result.get("msg"))

    print("总记录数：", result["data"]["total"])
    for item in result["data"]["rows"]:
        print(item["requestId"], item["modelName"], item["quotaDollar"])
    ```
  </Tab>
</Tabs>

## 响应结构

```json theme={null}
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "total": 1,
    "rows": [
      {
        "id": "7485162150730129409",
        "createdAt": 1784601721,
        "createTime": "2026-07-21 10:42:01",
        "type": 2,
        "requestId": "request_example_001",
        "ip": "203.0.113.10",
        "requestPath": "/v1/messages",
        "isStream": 1,
        "streamStatus": "正常 (eof)",
        "useTime": 2,
        "firstTokenTime": 1043,
        "modelName": "claude-sonnet-5",
        "tokenName": "default",
        "quotaDollar": "0.006098",
        "billingType": "token_ratio",
        "billingCountMode": "上游返回",
        "requestConversion": "Claude Messages",
        "textInputTokens": 2804,
        "textOutputTokens": 49,
        "cacheCreationTokens5m": null,
        "cacheCreationTokens1h": null,
        "cacheTokens": 0,
        "audioInput": null,
        "audioOutput": null,
        "imageInputTokens": null,
        "imageOutputTokens": null,
        "videoOutputTokens": null,
        "requestedSeconds": null,
        "imageCount": null,
        "videoResolution": null,
        "videoAudio": null,
        "videoHasInputVideo": null,
        "toolCallBilling": null,
        "billingProcessText": "输入价格：...，最终费用：$0.006098"
      }
    ]
  }
}
```

<Note>
  金额字段 `quotaDollar` 使用十进制字符串返回，调用方应使用 Decimal/BigDecimal 处理，不建议转换为二进制浮点数。
</Note>

## 响应字段

| 字段                      | 类型           | 说明                          |
| ----------------------- | ------------ | --------------------------- |
| `code`                  | integer      | `200` 表示成功，`401` 表示鉴权失败     |
| `msg`                   | string       | 响应说明                        |
| `data.total`            | integer      | 符合条件的总记录数，不是总页数             |
| `data.rows`             | array        | 当前页数据                       |
| `id`                    | string/long  | 日志 ID，客户端建议按字符串处理           |
| `createdAt`             | integer      | Unix 秒级时间戳                  |
| `createTime`            | string       | 格式化创建时间                     |
| `type`                  | integer      | 日志类型                        |
| `requestId`             | string/null  | 请求 ID                       |
| `ip`                    | string/null  | 请求 IP                       |
| `requestPath`           | string/null  | 请求路径                        |
| `isStream`              | integer/null | 是否流式                        |
| `streamStatus`          | string/null  | 流式状态                        |
| `useTime`               | integer/null | 总用时，单位秒                     |
| `firstTokenTime`        | integer/null | 首字时间，单位毫秒                   |
| `modelName`             | string/null  | 模型名称                        |
| `tokenName`             | string/null  | Token 名称                    |
| `quotaDollar`           | decimal/null | 客户花费，单位美元                   |
| `billingType`           | string/null  | 计费类型                        |
| `billingCountMode`      | string/null  | 计费统计方式                      |
| `requestConversion`     | string/null  | 请求协议转换类型                    |
| `textInputTokens`       | integer/null | 文本输入 Token                  |
| `textOutputTokens`      | integer/null | 文本输出 Token                  |
| `cacheCreationTokens5m` | integer/null | 5分钟缓存创建 Token               |
| `cacheCreationTokens1h` | integer/null | 1小时缓存创建 Token               |
| `cacheTokens`           | integer/null | 缓存命中 Token                  |
| `audioInput`            | integer/null | 音频输入计量                      |
| `audioOutput`           | integer/null | 音频输出计量                      |
| `imageInputTokens`      | integer/null | 图片输入 Token                  |
| `imageOutputTokens`     | integer/null | 图片输出 Token                  |
| `videoOutputTokens`     | integer/null | 视频输出 Token                  |
| `requestedSeconds`      | integer/null | 请求时长，单位秒                    |
| `imageCount`            | integer/null | 图片数量                        |
| `videoResolution`       | string/null  | 视频分辨率                       |
| `videoAudio`            | boolean/null | 是否输出音频                      |
| `videoHasInputVideo`    | boolean/null | 是否包含输入视频                    |
| `toolCallBilling`       | array/null   | 工具调用计费明细                    |
| `billingProcessText`    | string/null  | 按 `Accept-Language` 返回的计费过程 |

## 失败响应

<Tabs>
  <Tab title="缺少或无效 Authorization">
    ```json theme={null}
    {
      "code": 401,
      "msg": "Authorization header missing or invalid",
      "data": null
    }
    ```
  </Tab>

  <Tab title="Key 为空">
    ```json theme={null}
    {
      "code": 401,
      "msg": "Authorization key is empty",
      "data": null
    }
    ```
  </Tab>

  <Tab title="Key 无效或已禁用">
    ```json theme={null}
    {
      "code": 401,
      "msg": "无效或已禁用的密钥",
      "data": null
    }
    ```
  </Tab>

  <Tab title="时间格式错误">
    ```json theme={null}
    {
      "code": 500,
      "msg": "startTime 格式错误，请使用 yyyy-MM-dd HH:mm:ss",
      "data": null
    }
    ```
  </Tab>

  <Tab title="时间范围超过31天">
    ```json theme={null}
    {
      "code": 500,
      "msg": "时间范围不能超过1个月",
      "data": null
    }
    ```
  </Tab>
</Tabs>

## 调用建议

1. 服务端安全保存访问令牌或 API Key，不要把完整 Key 写入日志。
2. 推荐传入不超过 31 天的时间范围。
3. 翻页时读取 `data.total`，但不要把它当作页数。
4. 检查响应体 `code`，不要只依据 HTTP 200 判断业务成功。
5. 金额使用 Decimal/BigDecimal 处理，不要用二进制浮点数重新计算。
