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

# API 密钥

> 创建并安全使用具有细粒度权限和账户范围限制的 API 密钥

API 密钥用于认证私有账户和交易请求。每个密钥由公开密钥和私密密钥组成，并设有账户访问范围及一组权限。

## 创建 API 密钥

1. 登录 [qfex.com](https://qfex.com)，选择右下角的个人资料。

   ![](https://mintcdn.com/qfex/LD0EtLtcrjzAI_0J/images/api_key/1.png?fit=max\&auto=format\&n=LD0EtLtcrjzAI_0J\&q=85\&s=33b5ace9fa054bfb6270adb08a37a0e1)

2. 通过轮播菜单进入 **Developer Settings（开发者设置）**。

   ![](https://mintcdn.com/qfex/LD0EtLtcrjzAI_0J/images/api_key/2.png?fit=max\&auto=format\&n=LD0EtLtcrjzAI_0J\&q=85\&s=8d6618d0c17a0bf5b5dd78f1985b660f)

3. 点击 **Generate public and secret API Keys（生成公开和私密 API 密钥）**。

   ![](https://mintcdn.com/qfex/LD0EtLtcrjzAI_0J/images/api_key/3.png?fit=max\&auto=format\&n=LD0EtLtcrjzAI_0J\&q=85\&s=1b7b5ab90e72d02f9bcfa133c03695db)

4. 确认已启用双因素认证（2FA）。

   ![](https://mintcdn.com/qfex/LD0EtLtcrjzAI_0J/images/api_key/4.png?fit=max\&auto=format\&n=LD0EtLtcrjzAI_0J\&q=85\&s=a8f712aee7ef85e4d78fd1abcbf14246)

5. 输入便于识别的名称，选择需要的账户访问范围和权限，然后确认。

   ![](https://mintcdn.com/qfex/LD0EtLtcrjzAI_0J/images/api_key/5.png?fit=max\&auto=format\&n=LD0EtLtcrjzAI_0J\&q=85\&s=be500c5f1c214ca058bc919521272a23)

6. **复制**生成的密钥并安全保存；它只会显示一次。

   ![](https://mintcdn.com/qfex/LD0EtLtcrjzAI_0J/images/api_key/6.png?fit=max\&auto=format\&n=LD0EtLtcrjzAI_0J\&q=85\&s=cca987090f4920ab4953b408c9d2392f)

## 账户访问范围与权限

每个 API 密钥同时受**账户访问范围**和**权限**限制。请求必须同时满足两项设置。

账户访问范围可选择：

* **指定账户**：密钥只能用于选中的主账户或子账户。
* **所有账户**：密钥可以用于您拥有的任何账户。仅当集成确实需要跨账户访问时使用。

权限决定密钥能够执行的操作：

| 权限 | 允许的操作 |
| - | - |
| 执行订单 | 提交、修改、取消订单及相关交易操作。 |
| 查看订单 | 读取订单、成交及交易历史。 |
| 查看持仓 | 读取未平仓头寸。 |
| 查看余额（`view_balance`） | 读取余额、权益、手续费，通过 `GET /address` 读取充值地址，通过 `GET /withdrawal-addresses` 读取已登记提现地址。 |
| 入金与提现（`deposit_withdraw`） | 使用支持的出入金操作、轮换充值地址及管理银行账户。加密资产提现要求目的地址已登记。此权限仅适用于访问范围为“所有账户”的密钥。 |

只授予用途所必需的权限。例如，报表软件可能需要查看权限，但不应需要下单或提现权限。

## 向第三方授权使用 API 密钥

若您授权受信任的第三方应用通过 API 密钥访问 QFEX：

1. 为该应用创建专用密钥，不要复用个人集成密钥。
2. 限定必要的账户范围，只启用应用所需权限。
3. 通过安全渠道提供公开密钥和私密密钥。应用不需要您的 QFEX 密码或 MFA 验证码。
4. 应用必须在安全服务器上保存私密密钥，并用其签署认证请求。绝不能在浏览器代码、移动应用、日志、URL 或源码仓库中暴露私密密钥。
5. 不再需要集成，或任一凭据可能泄露时，在开发者设置中撤销密钥。

私密密钥只显示一次，创建后 QFEX 无法再次展示；丢失时请创建替代密钥。

直接集成的交易签名流程见 [WebSocket 身份认证](https://docs.qfex.com/cn/websocket/channels/trade/authenticate.md)，出入金 REST 请求见[程序化出入金](https://docs.qfex.com/cn/api-reference/programmatic-funding.md)。第三方应用也可以通过 [QFEX OAuth](https://docs.qfex.com/cn/api-reference/builder-integration.md)或[钱包签名的 Builder 注册](https://docs.qfex.com/cn/api-reference/builder-wallet-registration.md)连接用户账户。

> [!WARNING]
>
> 请像保护密码一样保护私密密钥。任何同时持有两个密钥值的人，都可以在您所授予的账户范围及权限内执行操作。

## Builder 签发的 API 密钥

[Builder 钱包注册](https://docs.qfex.com/cn/api-reference/builder-wallet-registration.md)允许已获启用的开发者，在用户签署钱包消息后创建用户交易密钥。开发者使用自己的 API 密钥和 `register_user` 权限认证注册请求。

返回的用户密钥仅限主账户，授予交易、账户读取、充值地址读取，以及向已登记地址提取加密资产的权限。其 `view_balance` 权限允许 `GET /address` 和 `GET /withdrawal-addresses`。通过 `POST /withdraw` 向已登记地址提取加密资产的权限，由 Builder 密钥签发及替换流程启用，不能在开发者设置中选择。该密钥的 `deposit_withdraw` 为关闭状态，因此不能轮换充值地址、管理银行账户或提取美元。相关请求见[程序化出入金](https://docs.qfex.com/cn/api-reference/programmatic-funding.md)。

密钥标签为 `builder-` 加开发者用户名。为同一用户和同一 Builder 标签再创建密钥，会替换原有密钥。以 `builder-` 或 `managed` 开头的标签不会出现在普通 API 密钥列表中。

## 通过程序创建 API 密钥

标准程序化密钥创建使用 QFEX 用户会话，而不是现有 API 密钥。先通过[钱包认证](https://docs.qfex.com/cn/api-reference/wallet-authentication.md)或其他支持的登录方式建立会话，再完成 MFA，获取最近经过权限提升的访问令牌。

向密钥生成接口发送该令牌。请显式提供每项权限，以免默认值变化导致密钥意外获得额外权限：

```javascript theme={null}
const QFEX_AUTH_URL = "https://verify.qfex.com";
const QFEX_AUTH_CLIENT_KEY = "YOUR_QFEX_AUTH_CLIENT_KEY";

export async function createQfexApiKey({
  accessToken,
  name,
  accountId = "*",
  permissions = {},
}) {
  const response = await fetch(
    `${QFEX_AUTH_URL}/rest/v1/rpc/generate_api_key_v3`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        apikey: QFEX_AUTH_CLIENT_KEY,
        Authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify({
        p_name: name,
        p_account_id: accountId,
        p_execute_orders: permissions.executeOrders === true,
        p_view_orders: permissions.viewOrders === true,
        p_view_positions: permissions.viewPositions === true,
        p_view_balance: permissions.viewBalance === true,
        p_deposit_withdraw:
          accountId === "*" && permissions.depositWithdraw === true,
      }),
    },
  );

  const result = await response.json();
  if (!response.ok) {
    throw new Error(result.message ?? "API key creation failed");
  }

  return {
    publicKey: result.public_key,
    secretKey: result.secret_key,
  };
}
```

用户选定账户范围和权限后创建密钥：

```javascript theme={null}
const apiKey = await createQfexApiKey({
  accessToken: elevatedSession.access_token,
  name: "order-service",
  accountId: "11111111-1111-4111-8111-111111111111",
  permissions: {
    executeOrders: true,
    viewOrders: true,
    viewPositions: true,
    viewBalance: true,
    depositWithdraw: false,
  },
});

await saveToEncryptedCredentialStore(apiKey);
```

`accountId` 必须为以下之一：

* `*`：用户拥有的所有主账户和子账户。
* 用户的主账户 ID。
* 用户拥有的子账户 ID。

只有 `accountId` 为 `*` 时，才能授予入金与提现权限。对于限定单个账户的密钥，QFEX 会强制将该权限设为 `false`。

> [!WARNING]
>
> 不要将生成的私密密钥写入日志、分析系统、浏览器存储，或返回给不受信任的调用方。该响应是 QFEX 唯一一次返回明文私密密钥。

### 使用 TOTP 提升会话权限

创建 API 密钥要求近期完成 MFA 验证。如果用户已有经验证的身份验证器应用因素，请在创建密钥前对该因素发起挑战并验证：

```javascript theme={null}
async function qfexAuthRequest(path, { accessToken, body }) {
  const response = await fetch(`${QFEX_AUTH_URL}${path}`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      apikey: QFEX_AUTH_CLIENT_KEY,
      Authorization: `Bearer ${accessToken}`,
    },
    body: JSON.stringify(body),
  });

  const result = await response.json();
  if (!response.ok) {
    throw new Error(result.msg ?? result.message ?? "MFA request failed");
  }
  return result;
}

export async function elevateQfexSessionWithTotp({
  accessToken,
  factorId,
  code,
}) {
  const challenge = await qfexAuthRequest(
    `/auth/v1/factors/${encodeURIComponent(factorId)}/challenge`,
    { accessToken, body: { factorId } },
  );

  return qfexAuthRequest(
    `/auth/v1/factors/${encodeURIComponent(factorId)}/verify`,
    {
      accessToken,
      body: {
        challenge_id: challenge.id,
        code,
      },
    },
  );
}
```

使用验证响应中的 `access_token` 创建密钥。`factorId` 应取自已登录用户的已验证因素。用户必须提供当前身份验证器验证码；不要替用户保存或尝试生成验证码。

### HTTP 请求

原始密钥生成请求如下：

```http theme={null}
POST /rest/v1/rpc/generate_api_key_v3
Host: verify.qfex.com
Content-Type: application/json
apikey: <QFEX_AUTH_CLIENT_KEY>
Authorization: Bearer <MFA_ELEVATED_ACCESS_TOKEN>

{
  "p_name": "order-service",
  "p_account_id": "*",
  "p_execute_orders": true,
  "p_view_orders": true,
  "p_view_positions": true,
  "p_view_balance": true,
  "p_deposit_withdraw": false
}
```

成功响应包含 `public_key` 和 `secret_key`。丢弃响应前务必保存密钥对；私密密钥之后无法再次获取。

### 常见错误

| 错误 | 处理方式 |
| - | - |
| `no_recent_mfa_auth` | 完成新的 MFA 挑战，并使用权限提升后的访问令牌重试。 |
| `api_key_name_required` | 提供非空的 `p_name`。 |
| 账户范围无效 | 使用 `*`、用户主账户 ID 或其拥有的子账户 ID。 |
| 密钥名称重复 | 为该用户选择另一个名称。 |
| `401` | 重新登录或刷新用户会话。 |


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