# IP 白名单 API

使用账户 API 令牌查询、批量新增和按 IP 批量删除账户白名单。

白名单 OpenAPI 提供账户级查询、批量新增和批量删除能力。三个接口均使用 [`api_key` 查询参数认证](/developers/authentication/api-token)，每批最多 100 个 IP。

## 查询白名单

`GET /openapi/v1/proxy/whitelist/list`

| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `api_key` | 是 | 账户完整 API 令牌 |
| `page` | 否 | 默认 `1` |
| `page_size` | 否 | 默认 `20`，最大 `100` |
| `status` | 否 | `all`、`active` 或 `disabled`，默认 `all` |
| `ip` | 否 | 精确 IP 筛选 |

```bash
curl --get "$API_BASE_URL/openapi/v1/proxy/whitelist/list" \
  --data-urlencode 'api_key=<API_KEY>' \
  --data-urlencode 'status=all'
```

成功响应中的条目只包含 `whitelist_id`、`ip`、`remark`、数字状态和 `created_at`。软删除、所有权版本、claim 状态和网关内部字段不会对外返回。

## 批量新增

`POST /openapi/v1/proxy/whitelist/add`

```bash
curl -X POST "$API_BASE_URL/openapi/v1/proxy/whitelist/add?api_key=<API_KEY>" \
  -H 'Content-Type: application/json' \
  --data '{"items":[{"ip":"<PUBLIC_IPV4>","remark":"office"}]}'
```

- `items` 必须包含 1–100 项，备注最多 255 个字符。
- 请求拒绝未知字段和尾随 JSON。
- 仅接受中国大陆以外的公网 IPv4；IPv6、私网、回环、CGNAT、文档、组播和其他保留地址会失败。
- 每个条目独立提交。同账号已存在、他人占用或正在释放只影响对应条目，不回滚此前成功项。
- 新增前校验账户状态和实名认证。

## 按 IP 批量删除

`POST /openapi/v1/proxy/whitelist/delete`

```bash
curl -X POST "$API_BASE_URL/openapi/v1/proxy/whitelist/delete?api_key=<API_KEY>" \
  -H 'Content-Type: application/json' \
  --data '{"ips":["<PUBLIC_IPV4>"]}'
```

`ips` 必须包含 1–100 项。接口按 IP 删除，不要求先查询记录 ID；不存在和不属于当前账户统一返回“白名单不存在”，不会暴露其他账户归属。删除既有记录不重新要求实名认证，成功后立即释放全局所有权，已有连接自然结束。

## 批量响应

全部成功时 `code=200`，失败列表为空。任意条目失败时，无论部分成功还是全部失败，顶层业务码都是 `10431`：

```json
{
  "code": 10431,
  "message": "成功添加 1 个IP，失败 1 个IP",
  "requestId": "req_xxx",
  "data": {
    "success_count": 1,
    "failed_count": 1,
    "failed_items": [
      {
        "ip": "<PUBLIC_IPV4>",
        "code": 10425,
        "reason": "该IP已在白名单中"
      }
    ]
  }
}
```

响应不返回成功 IP 列表。收到 `10431` 后，只处理 `failed_items`；不要重放整个批次，否则已经成功的新增可能转为重复错误。

## HTTP 状态与限流

- 普通参数错误和业务结果使用 HTTP `200`。
- 无效令牌、权限拒绝和限流分别使用 HTTP `401`、`403` 和 `429`。
- 系统故障使用 HTTP `500`；生产共享限流存储不可用时返回 HTTP `503`，不会绕过保护。
- 每个令牌的查询限额为 60 次/分钟，新增和删除分别为 10 次/分钟；无效令牌尝试还会按来源 IP 单独限流。

超过 100 项或请求外层结构非法时不会处理任何条目。重试前请结合 `requestId`、HTTP 状态和 [`10431` 明细](/developers/errors/error-codes)判断是否可安全重放。

html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}
