## Global IP lists (`global-ip-lists`)

Platform-wide IP blacklist and whitelist with optional expiry, reason and source per entry, plus bulk import and export; admin only.

Authentication: Admin only · Docs: https://www-demo.kuxitong.com/en/docs/api/global-ip-lists

### GET `/api/v2/global-ip-lists`

Get global IP blacklist and whitelist · Authentication: Admin only

```sh
curl "https://panel.example.com/api/v2/global-ip-lists" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PUT `/api/v2/global-ip-lists`

Set global IP blacklist and whitelist · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `black` | string[] |  | IP/CIDR of the unexpired blacklist entries. |
| `black_items` | IpListItem[] |  | Blacklist entries with expiry, reason and source. |
| `expected_updated_at` | string |  | Optimistic lock - the updated_at as the caller read it (use 1970-01-01T00:00:00Z when it was null). If it differs from the stored one, 409 stale_version is returned and nothing is saved; omit to skip the check. |
| `white` | string[] |  | IP/CIDR of the unexpired whitelist entries. |
| `white_items` | IpListItem[] |  | Whitelist entries with expiry, reason and source. |

```sh
curl -X PUT "https://panel.example.com/api/v2/global-ip-lists" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"black_items":[{"expires_at":"2030-01-01T00:00:00Z","ip":"198.51.100.0/24","reason":"scanner"}]}'
```

### GET `/api/v2/global-ip-lists/export`

Export global IP list entries · Authentication: Admin only

Query parameters:

| Field | Type | Required | Description |
|---|---|---|---|
| `list` | string | Yes | Which list to export. Values: ["black","white"] |
| `source` | IpListSource |  | Only export entries from this source; omit for all. Values: ["manual","import","ip_detail","api"] |
| `format` | string |  | txt (default, one entry per line) or csv (with header, a source column and a UTF-8 BOM). Values: ["txt","csv"] Default: "txt" |

```sh
curl "https://panel.example.com/api/v2/global-ip-lists/export" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/global-ip-lists/import`

Bulk import global IP list entries · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `dry_run` | boolean |  | true only checks the file and saves nothing. Default: false |
| `expected_updated_at` | string |  | Optimistic lock - the updated_at as the caller read it (use 1970-01-01T00:00:00Z when it was null). If it differs from the stored one, 409 stale_version is returned and nothing is saved; omit to skip the check. |
| `list` | string | Yes | Which list to import into. Values: ["black","white"] |
| `mode` | string |  | merge adds to the current list (the imported row wins for the same IP); replace swaps the whole list for the imported rows. Values: ["merge","replace"] Default: "merge" |
| `text` | string | Yes | File content (txt/csv), one entry per line: IP/CIDR[,expiry][,reason]. |

```sh
curl -X POST "https://panel.example.com/api/v2/global-ip-lists/import" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dry_run":true,"list":"black","mode":"merge","text":"198.51.100.0/24,2030-01-01T00:00:00Z,scanner\n"}'
```

Global IP lists object:

| Field | Type | Required | Description |
|---|---|---|---|
| `added` | integer |  | Entries added. |
| `applied` | boolean |  | Whether the import was saved (false for dry_run or when blocking issues exist). |
| `black` | string[] |  | IP/CIDR of the unexpired blacklist entries. |
| `black_items` | IpListItem[] |  | Blacklist entries with expiry, reason and source. |
| `dry_run` | boolean |  | true only checks the file and saves nothing. Default: false |
| `expected_updated_at` | string |  | Optimistic lock - the updated_at as the caller read it (use 1970-01-01T00:00:00Z when it was null). If it differs from the stored one, 409 stale_version is returned and nothing is saved; omit to skip the check. |
| `issues` | IpListImportIssue[] |  | Per-line issues (at most 1000, ascending by line). |
| `lines` | integer |  | Number of valid entries (after de-duplication). |
| `list` | string | Yes | Which list to import into. Values: ["black","white"] |
| `mode` | string |  | merge adds to the current list (the imported row wins for the same IP); replace swaps the whole list for the imported rows. Values: ["merge","replace"] Default: "merge" |
| `removed` | integer |  | In replace mode, existing entries that are not in the new list (entries with the same IP count as updated, not removed). |
| `text` | string | Yes | File content (txt/csv), one entry per line: IP/CIDR[,expiry][,reason]. |
| `updated` | integer |  | Entries already in the list that were updated by the import. |
| `updated_at` | string |  | Updated at (read-only) |
| `white` | string[] |  | IP/CIDR of the unexpired whitelist entries. |
| `white_items` | IpListItem[] |  | Whitelist entries with expiry, reason and source. |
