# 调用记录 & 账户流水查询 API

## 概述

提供两个对外查询接口，用于拉取当前账户的**调用记录**（每次生成任务的明细）与**账户流水**（余额变动明细）。

两个接口均采用**游标分页**（基于记录 ID 倒序翻页），相比传统页码分页，可避免深度翻页带来的性能下降，单次查询返回不超过 100 条。

| 接口 | 用途 | 路径 |
|------|------|------|
| 调用记录查询 | 查询生成任务的调用明细 | `GET /api/v2/open/records` |
| 账户流水查询 | 查询账户余额变动明细 | `GET /api/v2/open/transactions` |

## 通用说明

### 认证方式

所有接口均使用 Bearer Token (API Key) 认证。

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| Authorization | string | 是 | `Bearer {API_KEY}` |

### 游标分页机制

- 首页请求**不传** `lastId`，从最新记录开始返回。
- 响应返回 `nextLastId` 和 `hasMore`：
  - `hasMore = true` 时，将 `nextLastId` 作为下一次请求的 `lastId` 参数，即可获取下一页。
  - `hasMore = false` 时，`nextLastId` 为 `0`，表示已无更多数据。
- 记录按创建时间（ID）**倒序**返回，即最新的在最前。

通用分页参数：

| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| lastId | int | 否 | 0 | 游标：上一页响应返回的 `nextLastId`；首页不传 |
| limit | int | 否 | 20 | 每页数量，最大 100，超过自动按 100 处理 |

### 通用响应信封

```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "list": [],
    "nextLastId": 0,
    "hasMore": false
  }
}
```

| 字段名 | 类型 | 说明 |
|--------|------|------|
| list | array | 数据列表，元素结构见各接口 |
| nextLastId | int | 下一页游标；作为下次请求的 `lastId`。为 `0` 表示无更多数据 |
| hasMore | bool | 是否还有下一页 |

---

## 一、调用记录查询

### 接口信息

- **接口路径**: `/api/v2/open/records`
- **请求方法**: `GET`
- **认证方式**: Bearer Token (API Key)

### 请求参数（Query）

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| lastId | int | 否 | 游标，见「游标分页机制」 |
| limit | int | 否 | 每页数量，默认 20，最大 100 |
| status | string | 否 | 状态筛选：`success` / `processing` / `failed` |
| model | string | 否 | 按模型名模糊筛选 |
| startDate | string | 否 | 开始日期，格式 `YYYY-MM-DD` |
| endDate | string | 否 | 结束日期，格式 `YYYY-MM-DD`（含当天） |

### 成功响应

```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "list": [
      {
        "taskId": "task_20260601_abc123",
        "modelType": "video",
        "modelName": "Seedance 2.0",
        "modelVersion": "2.0",
        "genType": "t2v",
        "resolution": "1080p",
        "duration": 5,
        "amount": "0.500000",
        "status": "success",
        "createdTime": "2026-06-01T12:30:45+08:00"
      }
    ],
    "nextLastId": 884512,
    "hasMore": true
  }
}
```

### 列表字段说明

| 字段名 | 类型 | 说明 |
|--------|------|------|
| taskId | string | 任务 ID |
| modelType | string | 任务类型：`image`（图片）/ `video`（视频）/ `audio`（音频） |
| modelName | string | 模型名称 |
| modelVersion | string | 模型版本 |
| genType | string | 生成类型，如 `t2i`（文生图）/ `t2v`（文生视频）/ `i2v`（图生视频） |
| resolution | string | 分辨率，如 `1080p` |
| duration | int | 时长（秒），图片类任务为 0 |
| amount | string | 本次任务实际消费金额，失败任务为 `0.000000` |
| status | string | 任务状态：`success` / `processing` / `failed` |
| createdTime | string | 创建时间（RFC3339 格式） |

### 请求示例

```bash
# 首页，每页 50 条，仅看成功的任务
curl -X GET "https://api.apiverse.ai/api/v2/open/records?limit=50&status=success" \
  -H "Authorization: Bearer your_api_key_here"

# 下一页：使用上一次响应返回的 nextLastId
curl -X GET "https://api.apiverse.ai/api/v2/open/records?limit=50&status=success&lastId=884512" \
  -H "Authorization: Bearer your_api_key_here"
```

---

## 二、账户流水查询

### 接口信息

- **接口路径**: `/api/v2/open/transactions`
- **请求方法**: `GET`
- **认证方式**: Bearer Token (API Key)

### 请求参数（Query）

| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| lastId | int | 否 | 游标，见「游标分页机制」 |
| limit | int | 否 | 每页数量，默认 20，最大 100 |
| type | string | 否 | 类型筛选：`recharge`（充值）/ `freeze`（冻结）/ `unfreeze`（解冻）/ `charge`（扣费） |
| startDate | string | 否 | 开始日期，格式 `YYYY-MM-DD` |
| endDate | string | 否 | 结束日期，格式 `YYYY-MM-DD`（含当天） |

### 成功响应

```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "list": [
      {
        "txId": "tx_20260601_xyz789",
        "type": "charge",
        "amount": "0.500000",
        "beforeBalance": "1000.500000",
        "afterBalance": "1000.000000",
        "relatedId": "task_20260601_abc123",
        "model": "Seedance 2.0",
        "remark": "任务扣费",
        "createdTime": "2026-06-01T12:30:50+08:00"
      }
    ],
    "nextLastId": 552301,
    "hasMore": true
  }
}
```

### 列表字段说明

| 字段名 | 类型 | 说明 |
|--------|------|------|
| txId | string | 交易 ID |
| type | string | 交易类型：`recharge` / `freeze` / `unfreeze` / `charge` |
| amount | string | 交易金额 |
| beforeBalance | string | 变动前余额 |
| afterBalance | string | 变动后余额 |
| relatedId | string | 关联 ID（任务扣费类为任务 ID，充值类为充值单号） |
| model | string | 关联任务的模型名称；无关联任务（如充值）时为空字符串 |
| remark | string | 备注 |
| createdTime | string | 交易时间（RFC3339 格式） |

### 请求示例

```bash
# 首页，仅看扣费记录
curl -X GET "https://api.apiverse.ai/api/v2/open/transactions?limit=50&type=charge" \
  -H "Authorization: Bearer your_api_key_here"

# 下一页
curl -X GET "https://api.apiverse.ai/api/v2/open/transactions?limit=50&type=charge&lastId=552301" \
  -H "Authorization: Bearer your_api_key_here"
```

---

## 完整翻页示例

### Python

```python
import requests

BASE = "https://api.apiverse.ai/api/v2/open/records"
HEADERS = {"Authorization": "Bearer your_api_key_here"}

last_id = 0
all_records = []
while True:
    params = {"limit": 100}
    if last_id:
        params["lastId"] = last_id
    resp = requests.get(BASE, headers=HEADERS, params=params).json()
    data = resp["data"]
    all_records.extend(data["list"])
    if not data["hasMore"]:
        break
    last_id = data["nextLastId"]

print(f"共拉取 {len(all_records)} 条调用记录")
```

### JavaScript

```javascript
async function fetchAllRecords() {
  const base = 'https://api.apiverse.ai/api/v2/open/records';
  const headers = { Authorization: 'Bearer your_api_key_here' };
  let lastId = 0;
  const all = [];

  while (true) {
    const params = new URLSearchParams({ limit: '100' });
    if (lastId) params.set('lastId', String(lastId));
    const resp = await fetch(`${base}?${params}`, { headers }).then((r) => r.json());
    const data = resp.data;
    all.push(...data.list);
    if (!data.hasMore) break;
    lastId = data.nextLastId;
  }
  console.log(`共拉取 ${all.length} 条调用记录`);
  return all;
}
```

---

## 注意事项

1. **游标翻页**：请始终使用响应返回的 `nextLastId` 作为下一页的 `lastId`，不要自行构造或递增该值。
2. **单次上限**：`limit` 最大为 100，传入更大值时按 100 处理。
3. **数据范围**：接口返回当前 API Key 所属账户的全部记录。
4. **金额格式**：所有金额字段均为字符串，保留 6 位小数，避免浮点精度问题。
5. **时间筛选**：`startDate` / `endDate` 按自然日筛选，`endDate` 含当天全天。
6. **稳定排序**：记录按 ID 倒序返回；翻页期间若有新记录写入，不会影响已翻页数据的连续性（新数据只会出现在首页）。

## 关于大模型（LLM）用量

- 本组接口（调用记录 / 账户流水）覆盖的是网关本站的生成任务与钱包流水。
- **大模型（LLM）的用量与消费不在本接口返回范围内**：LLM 按 token 聚合计量，消费在账户余额中结算，不会以逐条记录/逐笔流水的形式出现在这里。
- 大模型的用量与消费汇总请前往控制台「用量」/「账单」页面查看。

## 错误码说明

| 错误码 | 说明 | 解决方案 |
|--------|------|----------|
| 10005 | 未授权 / API Key 无效 | 检查 `Authorization` 头与 API Key 是否正确 |
| 90003 | 系统内部异常 | 稍后重试或联系技术支持 |

### 错误响应示例

```json
{
  "code": 10005,
  "msg": "未授权",
  "data": null
}
```