> ## 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.

# API密钥管理

> 用户 API Token 的完整管理系统，支持创建、更新、删除、批量操作及配额与权限控制

<Info>
  接口前缀统一为 `https://api.gravitex.ai`。生产环境应使用 HTTPS 以保证认证令牌，HTTP 仅建议用于开发环境。

  用户 API Token 的完整管理系统，支持创建、更新、删除、批量操作及配额与权限控制。
</Info>

<Note>
  注意：API 密钥为您在「个人中心 - 访问令牌」中生成的、用于 `/api` 路由访问的令牌。
</Note>

## 用户鉴权

以下接口均需要用户登录鉴权，请在请求头中携带 `Authorization`。

<ParamField header="Authorization" type="string" required>
  用户登录令牌，格式：`Bearer your_user_token`
</ParamField>

### 通用响应结构

所有接口均返回统一的 JSON 信封结构：

| 字段        | 类型               | 说明                    |
| --------- | ---------------- | --------------------- |
| `success` | 布尔               | 请求是否成功                |
| `message` | 字符串              | 提示信息，成功时通常为空字符串       |
| `data`    | 对象 / 数组 / 数字 / 空 | 业务数据，部分接口（如创建、删除）无此字段 |

### Token 对象字段

列表、搜索、详情、更新等接口返回的 Token 对象包含以下字段（`key` 在列表/详情/更新响应中为脱敏值）：

| 字段                     | 类型  | 说明                                                                     |
| ---------------------- | --- | ---------------------------------------------------------------------- |
| `id`                   | 整数  | Token ID                                                               |
| `user_id`              | 整数  | 所属用户 ID                                                                |
| `name`                 | 字符串 | Token 名称                                                               |
| `key`                  | 字符串 | API Key；列表/详情/更新接口返回脱敏值（如 `abcd**********efgh`），完整密钥需调用「获取 Token 密钥」接口 |
| `status`               | 整数  | 状态：`1` 启用、`2` 禁用、`3` 已过期、`4` 额度耗尽                                      |
| `remain_quota`         | 整数  | 剩余额度（内部单位，500,000 = \$1 USD）                                           |
| `used_quota`           | 整数  | 已使用额度（内部单位）                                                            |
| `unlimited_quota`      | 布尔  | 是否无限额度                                                                 |
| `model_limits_enabled` | 布尔  | 是否启用模型限制                                                               |
| `model_limits`         | 字符串 | 允许使用的模型列表，逗号分隔                                                         |
| `allow_ips`            | 字符串 | 允许的 IP 白名单，换行或逗号分隔，支持 CIDR                                             |
| `group`                | 字符串 | 计费分组，`auto` 表示智能熔断                                                     |
| `cross_group_retry`    | 布尔  | 跨分组重试，仅 `group` 为 `auto` 时有效                                           |
| `expired_time`         | 整数  | 过期时间 Unix 秒时间戳，`-1` 表示永不过期                                             |
| `created_time`         | 整数  | 创建时间 Unix 秒时间戳                                                         |
| `accessed_time`        | 整数  | 最近访问时间 Unix 秒时间戳                                                       |

***

### 获取全部 Token

* **HTTP 方法**：GET
* **路径**：`/api/token/`
* **功能简介**：分页获取当前用户的所有 Token 列表

**查询参数**

<ParamField query="p" type="integer" default="1">
  页码
</ParamField>

<ParamField query="size" type="integer" default="20">
  每页数量
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/?p=1&size=20', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  }
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": "",
  "data": {
    "items": [
      {
        "id": 1,
        "user_id": 1001,
        "name": "API Token",
        "key": "abcd**********efgh",
        "status": 1,
        "remain_quota": 1000000,
        "used_quota": 500000,
        "unlimited_quota": false,
        "model_limits_enabled": true,
        "model_limits": "gpt-3.5-turbo,gpt-4",
        "allow_ips": "192.168.1.1\n10.0.0.1",
        "group": "default",
        "cross_group_retry": false,
        "expired_time": 1640995200,
        "created_time": 1640908800,
        "accessed_time": 1640995000
      }
    ],
    "total": 5,
    "page": 1,
    "page_size": 20
  }
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "获取Token列表失败"
}
```

**响应字段**

| 字段               | 类型 | 说明                           |
| ---------------- | -- | ---------------------------- |
| `data`           | 对象 | 分页数据                         |
| `data.items`     | 数组 | Token 对象列表，字段见上文「Token 对象字段」 |
| `data.total`     | 整数 | Token 总数                     |
| `data.page`      | 整数 | 当前页码                         |
| `data.page_size` | 整数 | 每页数量                         |

***

### 搜索 Token

* **HTTP 方法**：GET
* **路径**：`/api/token/search`
* **功能简介**：根据关键词和 Token 值搜索用户的 Token

**查询参数**

<ParamField query="keyword" type="string">
  搜索关键词，匹配 Token 名称
</ParamField>

<ParamField query="token" type="string">
  Token 值搜索，支持部分匹配（可省略 `sk-` 前缀）；支持 `%` 通配符，最多 2 个
</ParamField>

<ParamField query="p" type="integer" default="1">
  页码
</ParamField>

<ParamField query="size" type="integer" default="20">
  每页数量，最大 100
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/search?keyword=api&token=sk-123', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  }
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": "",
  "data": {
    "items": [
      {
        "id": 1,
        "user_id": 1001,
        "name": "API Token",
        "key": "abcd**********efgh",
        "status": 1,
        "remain_quota": 1000000,
        "used_quota": 0,
        "unlimited_quota": false,
        "model_limits_enabled": false,
        "model_limits": "",
        "allow_ips": "",
        "group": "default",
        "cross_group_retry": false,
        "expired_time": -1,
        "created_time": 1640908800,
        "accessed_time": 1640995000
      }
    ],
    "total": 1,
    "page": 1,
    "page_size": 20
  }
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "搜索Token失败"
}
```

**响应字段**

| 字段               | 类型 | 说明                     |
| ---------------- | -- | ---------------------- |
| `data`           | 对象 | 分页数据，结构与「获取全部 Token」相同 |
| `data.items`     | 数组 | 匹配的 Token 对象列表         |
| `data.total`     | 整数 | 匹配结果总数                 |
| `data.page`      | 整数 | 当前页码                   |
| `data.page_size` | 整数 | 每页数量                   |

***

### 获取单个 Token

* **HTTP 方法**：GET
* **路径**：`/api/token/:id`
* **功能简介**：获取指定 Token 的详细信息

**路径参数**

<ParamField path="id" type="integer" required>
  Token ID
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/123', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  }
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": "",
  "data": {
    "id": 123,
    "user_id": 1001,
    "name": "API Token",
    "key": "abcd**********efgh",
    "status": 1,
    "remain_quota": 1000000,
    "used_quota": 200000,
    "unlimited_quota": false,
    "model_limits_enabled": true,
    "model_limits": "gpt-3.5-turbo,gpt-4",
    "allow_ips": "192.168.1.1,10.0.0.1",
    "group": "default",
    "cross_group_retry": false,
    "expired_time": 1640995200,
    "created_time": 1640908800,
    "accessed_time": 1640995000
  }
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "Token不存在"
}
```

**响应字段**

| 字段     | 类型 | 说明                          |
| ------ | -- | --------------------------- |
| `data` | 对象 | 单个 Token 对象，字段见「Token 对象字段」 |

***

### 创建 Token

* **HTTP 方法**：POST
* **路径**：`/api/token/`
* **功能简介**：创建新的 API Token，支持批量创建

**请求体**

<ParamField body="name" type="string" required>
  Token 名称，最大长度 30 个字符
</ParamField>

<ParamField body="expired_time" type="integer">
  过期时间戳，-1 表示永不过期
</ParamField>

<ParamField body="remain_quota" type="integer">
  剩余配额
</ParamField>

<ParamField body="unlimited_quota" type="boolean">
  是否无限配额
</ParamField>

<ParamField body="model_limits_enabled" type="boolean">
  是否启用模型限制
</ParamField>

<ParamField body="model_limits" type="array">
  允许使用的模型列表
</ParamField>

<ParamField body="allow_ips" type="string">
  允许的 IP 地址，逗号分隔
</ParamField>

<ParamField body="group" type="string">
  所属分组
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  },
  body: JSON.stringify({
    name: "My API Token",
    expired_time: 1640995200,
    remain_quota: 1000000,
    unlimited_quota: false,
    model_limits_enabled: true,
    model_limits: ["gpt-3.5-turbo", "gpt-4"],
    allow_ips: "192.168.1.1,10.0.0.1",
    group: "default"
  })
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": ""
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "令牌名称过长"
}
```

**响应字段**

| 字段        | 类型  | 说明            |
| --------- | --- | ------------- |
| `success` | 布尔  | 是否创建成功        |
| `message` | 字符串 | 错误信息；成功时为空字符串 |

<Note>
  创建成功后响应体不包含 `data` 字段，也不返回完整 `key`。请通过「获取 Token 密钥」接口按需获取完整密钥。
</Note>

***

### 更新 Token

* **HTTP 方法**：PUT
* **路径**：`/api/token/`
* **功能简介**：更新 Token 配置，支持状态切换和完整更新

**请求体**

<ParamField body="id" type="integer" required>
  Token ID
</ParamField>

<ParamField query="status_only" type="boolean">
  是否仅更新状态
</ParamField>

其他字段与创建 Token 接口相同，均为可选。

**请求示例（完整更新）**

```javascript theme={null}
const response = await fetch('/api/token/', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  },
  body: JSON.stringify({
    id: 123,
    name: "Updated Token",
    expired_time: 1640995200,
    remain_quota: 2000000,
    unlimited_quota: false,
    model_limits_enabled: true,
    model_limits: ["gpt-3.5-turbo", "gpt-4"],
    allow_ips: "192.168.1.1",
    group: "vip"
  })
});
const data = await response.json();
```

**请求示例（仅更新状态）**

```javascript theme={null}
const response = await fetch('/api/token/?status_only=true', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  },
  body: JSON.stringify({
    id: 123,
    status: 1
  })
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": "",
  "data": {
    "id": 123,
    "user_id": 1001,
    "name": "Updated Token",
    "key": "abcd**********efgh",
    "status": 1,
    "remain_quota": 2000000,
    "used_quota": 100000,
    "unlimited_quota": false,
    "model_limits_enabled": true,
    "model_limits": "gpt-3.5-turbo,gpt-4",
    "allow_ips": "192.168.1.1",
    "group": "vip",
    "cross_group_retry": false,
    "expired_time": 1640995200,
    "created_time": 1640908800,
    "accessed_time": 1640995000
  }
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "令牌已过期，无法启用，请先修改令牌过期时间，或者设置为永不过期"
}
```

**响应字段**

| 字段     | 类型 | 说明                            |
| ------ | -- | ----------------------------- |
| `data` | 对象 | 更新后的 Token 对象，字段见「Token 对象字段」 |

***

### 删除 Token

* **HTTP 方法**：DELETE
* **路径**：`/api/token/:id`
* **功能简介**：删除指定的 Token

**路径参数**

<ParamField path="id" type="integer" required>
  Token ID
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/123', {
  method: 'DELETE',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  }
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": ""
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "Token不存在"
}
```

**响应字段**

| 字段        | 类型  | 说明            |
| --------- | --- | ------------- |
| `success` | 布尔  | 是否删除成功        |
| `message` | 字符串 | 错误信息；成功时为空字符串 |

***

### 批量删除 Token

* **HTTP 方法**：POST
* **路径**：`/api/token/batch`
* **功能简介**：批量删除多个 Token

**请求体**

<ParamField body="ids" type="array" required>
  要删除的 Token ID 列表，必填且不能为空
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/batch', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  },
  body: JSON.stringify({
    ids: [1, 2, 3, 4, 5]
  })
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": "",
  "data": 5
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "参数错误"
}
```

**响应字段**

| 字段        | 类型  | 说明             |
| --------- | --- | -------------- |
| `success` | 布尔  | 是否删除成功         |
| `message` | 字符串 | 错误信息；成功时为空字符串  |
| `data`    | 整数  | 成功删除的 Token 数量 |

***

### 获取 Token 密钥

* **HTTP 方法**：POST
* **路径**：`/api/token/:id/key`
* **功能简介**：按需获取指定 Token 的完整密钥（未脱敏），受频率限制保护

**路径参数**

<ParamField path="id" type="integer" required>
  Token ID
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/123/key', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  }
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": "",
  "data": {
    "key": "XyLy1234567890abcdefghijklmnop"
  }
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "Token不存在"
}
```

**响应字段**

| 字段         | 类型  | 说明                                           |
| ---------- | --- | -------------------------------------------- |
| `data`     | 对象  | 密钥数据                                         |
| `data.key` | 字符串 | 完整 API Key（不含 `sk-` 前缀，使用时需自行拼接为 `sk-{key}`） |

<Note>
  该接口返回完整密钥，请妥善保管，避免在日志或前端页面中明文展示。
</Note>

***

### 批量获取 Token 密钥

* **HTTP 方法**：POST
* **路径**：`/api/token/batch/keys`
* **功能简介**：批量获取多个 Token 的完整密钥，单次最多 100 个

**请求体**

<ParamField body="ids" type="array" required>
  要获取密钥的 Token ID 列表，必填且不能为空，最多 100 个
</ParamField>

**请求示例**

```javascript theme={null}
const response = await fetch('/api/token/batch/keys', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_user_token'
  },
  body: JSON.stringify({
    ids: [1, 2, 3]
  })
});
const data = await response.json();
```

**成功响应**

```json theme={null}
{
  "success": true,
  "message": "",
  "data": {
    "keys": {
      "1": "abcd1234efgh5678ijkl9012mnop3456",
      "2": "qrst1234uvwx5678yzab9012cdef3456",
      "3": "hijk1234lmno5678pqrs9012tuvw3456"
    }
  }
}
```

**失败响应**

```json theme={null}
{
  "success": false,
  "message": "参数错误"
}
```

**响应字段**

| 字段          | 类型 | 说明                                                         |
| ----------- | -- | ---------------------------------------------------------- |
| `data`      | 对象 | 批量密钥数据                                                     |
| `data.keys` | 对象 | Token ID 到完整密钥的映射，键为 Token ID（字符串），值为完整 `key`（不含 `sk-` 前缀） |
