## Packages (`packages`)

Base packages for sale, defining quotas such as traffic, bandwidth and domains, and prices.

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

### GET `/api/v2/packages`

List packages · Authentication: Admin only

Query parameters:

| Field | Type | Required | Description |
|---|---|---|---|
| `page` | integer |  | Page number, starting from 1 Default: 1 |
| `page_size` | integer |  | Items per page Default: 20 |
| `sort` | string |  | Sort fields, comma-separated; prefix `-` for descending, e.g. `-created_at,id` |

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

### POST `/api/v2/packages`

Create package · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `backup_group_id` | integer |  | Backup node group; null = none. |
| `bandwidth_mbps` | integer |  | Bandwidth in Mbps, -1 = unlimited. |
| `buy_limit` | integer |  | Maximum copies a tenant may hold, -1 = unlimited. |
| `cname_domain_id` | integer |  | CNAME root domain; null = the package binds no lines. |
| `cname_host_suffix` | string |  | Suffix for newly generated host records; empty = only the 8-character random name. |
| `cname_mode` | PackageCnameMode |  | CNAME mode. site = one access name per site or stream; package = sites and streams of a purchased package share one access name. Values: ["site","package"] |
| `connections` | integer |  | Concurrent connections, -1 = unlimited. |
| `custom_cc_rule` | boolean |  | Allows custom CC rules. |
| `des` | string |  | Description |
| `domains` | integer |  | Number of domains (each IP site counts as 1), -1 = unlimited. |
| `enabled` | boolean |  | Whether enabled |
| `group_ids` | integer[] |  | Package groups it belongs to. |
| `http_ports` | integer |  | Number of non-standard HTTP/HTTPS ports (other than 80/443), -1 = unlimited. |
| `ip_num` | integer |  | Number of selectable IPs ("My IPs"), -1 = unlimited. |
| `ip_pool_id` | integer |  | IP pool used to provision IP sites (IP product line); null = not provisioned. |
| `ip_site_port` | integer |  | IP-site ports: distinct ports across all IP sites of the package (80/443 included), -1 = unlimited; IP-site ports do not count toward non-standard ports. |
| `l2` | boolean |  | Includes tiered origin (tenant switch of the paid feature l2): tenants can turn on tiered origin for sites, and nodes use it, only while the master license l2 is active; existing packages are false (on upgrade, purchased packages of tenants already using tiered origin are set to true). |
| `name` | string | Yes | Name |
| `node_group_id` | integer |  | Primary node group; null = the package binds no lines. |
| `origin_ip_limit` | string[] |  | Allowed origin IPs or CIDR ranges; empty = any. When set, origins of sites under the package must fall inside them and domain origins are rejected. |
| `owners` | integer[] |  | Tenant ids allowed to buy; empty = no restriction. |
| `price_month_cents` | integer | Yes | Monthly price in cents. |
| `price_quarter_cents` | integer | Yes | Quarterly price in cents. |
| `price_year_cents` | integer | Yes | Yearly price in cents. |
| `region_id` | integer |  | Region; null = the package binds no lines. |
| `renew_before_days` | integer |  | Renewal is only allowed within this many days before expiry, -1 = unlimited. |
| `require_verified` | boolean |  | Real-name verification is required to purchase. |
| `sale_until` | string |  | Not sold after this time; omitted/null = no limit. |
| `sort` | integer |  | Display order (smaller first). |
| `stream_ports` | integer |  | Number of TCP/UDP forwarding ports, -1 = unlimited. |
| `traffic_gb` | integer |  | Traffic in GB per billing cycle, -1 = unlimited. |
| `waf_enhanced` | boolean |  | Includes WAF Enhanced (tenant switch of the paid feature waf_enhanced): tenants can use standard/strict levels, big screen, deep Bot, anti-tamper and so on only while the master license WAF Enhanced is not degraded; existing packages are false. |
| `websocket` | boolean |  | Allows WebSocket. |

```sh
curl -X POST "https://panel.example.com/api/v2/packages" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domains":10,"group_ids":[],"http_ports":2,"name":"基础版","price_month_cents":3000,"price_quarter_cents":8000,"price_year_cents":30000}'
```

### POST `/api/v2/packages/batch-enable`

Batch enable or disable packages · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `enabled` | boolean | Yes | Whether enabled |
| `ids` | integer[] | Yes | IDs of the objects to change, at most 100. |

```sh
curl -X POST "https://panel.example.com/api/v2/packages/batch-enable" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled":false,"ids":[1,2]}'
```

### GET `/api/v2/packages/{id}`

Get package · Authentication: Admin only

```sh
curl "https://panel.example.com/api/v2/packages/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PUT `/api/v2/packages/{id}`

Update package · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `backup_group_id` | integer |  | Backup node group; null = none. |
| `bandwidth_mbps` | integer |  | Bandwidth in Mbps, -1 = unlimited. |
| `buy_limit` | integer |  | Maximum copies a tenant may hold, -1 = unlimited. |
| `cname_domain_id` | integer |  | CNAME root domain; null = the package binds no lines. |
| `cname_host_suffix` | string |  | Suffix for newly generated host records; empty = only the 8-character random name. |
| `cname_mode` | PackageCnameMode |  | CNAME mode. site = one access name per site or stream; package = sites and streams of a purchased package share one access name. Values: ["site","package"] |
| `connections` | integer |  | Concurrent connections, -1 = unlimited. |
| `custom_cc_rule` | boolean |  | Allows custom CC rules. |
| `des` | string |  | Description |
| `domains` | integer |  | Number of domains (each IP site counts as 1), -1 = unlimited. |
| `enabled` | boolean |  | Whether enabled |
| `group_ids` | integer[] |  | Package groups it belongs to. |
| `http_ports` | integer |  | Number of non-standard HTTP/HTTPS ports (other than 80/443), -1 = unlimited. |
| `ip_num` | integer |  | Number of selectable IPs ("My IPs"), -1 = unlimited. |
| `ip_pool_id` | integer |  | IP pool used to provision IP sites (IP product line); null = not provisioned. |
| `ip_site_port` | integer |  | IP-site ports: distinct ports across all IP sites of the package (80/443 included), -1 = unlimited; IP-site ports do not count toward non-standard ports. |
| `l2` | boolean |  | Includes tiered origin (tenant switch of the paid feature l2): tenants can turn on tiered origin for sites, and nodes use it, only while the master license l2 is active; existing packages are false (on upgrade, purchased packages of tenants already using tiered origin are set to true). |
| `name` | string | Yes | Name |
| `node_group_id` | integer |  | Primary node group; null = the package binds no lines. |
| `origin_ip_limit` | string[] |  | Allowed origin IPs or CIDR ranges; empty = any. When set, origins of sites under the package must fall inside them and domain origins are rejected. |
| `owners` | integer[] |  | Tenant ids allowed to buy; empty = no restriction. |
| `price_month_cents` | integer | Yes | Monthly price in cents. |
| `price_quarter_cents` | integer | Yes | Quarterly price in cents. |
| `price_year_cents` | integer | Yes | Yearly price in cents. |
| `region_id` | integer |  | Region; null = the package binds no lines. |
| `renew_before_days` | integer |  | Renewal is only allowed within this many days before expiry, -1 = unlimited. |
| `require_verified` | boolean |  | Real-name verification is required to purchase. |
| `sale_until` | string |  | Not sold after this time; omitted/null = no limit. |
| `sort` | integer |  | Display order (smaller first). |
| `stream_ports` | integer |  | Number of TCP/UDP forwarding ports, -1 = unlimited. |
| `traffic_gb` | integer |  | Traffic in GB per billing cycle, -1 = unlimited. |
| `waf_enhanced` | boolean |  | Includes WAF Enhanced (tenant switch of the paid feature waf_enhanced): tenants can use standard/strict levels, big screen, deep Bot, anti-tamper and so on only while the master license WAF Enhanced is not degraded; existing packages are false. |
| `websocket` | boolean |  | Allows WebSocket. |

```sh
curl -X PUT "https://panel.example.com/api/v2/packages/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domains":10,"group_ids":[],"http_ports":2,"name":"基础版","price_month_cents":3000,"price_quarter_cents":8000,"price_year_cents":30000}'
```

### DELETE `/api/v2/packages/{id}`

Delete package · Authentication: Admin only

```sh
curl -X DELETE "https://panel.example.com/api/v2/packages/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/packages/{id}/syncs`

Sync base package to purchased packages · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `items` | PackageSyncField[] | Yes | Fields to sync. |

```sh
curl -X POST "https://panel.example.com/api/v2/packages/{id}/syncs" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items":["traffic_gb","price_month_cents"]}'
```

Packages object:

| Field | Type | Required | Description |
|---|---|---|---|
| `backup_group_id` | integer |  | Backup node group; null = none. |
| `bandwidth_mbps` | integer |  | Bandwidth in Mbps, -1 = unlimited. |
| `buy_limit` | integer |  | Maximum copies a tenant may hold, -1 = unlimited. |
| `cname_domain_id` | integer |  | CNAME root domain; null = the package binds no lines. |
| `cname_host_suffix` | string |  | Suffix for newly generated host records; empty = only the 8-character random name. |
| `cname_mode` | PackageCnameMode |  | CNAME mode. site = one access name per site or stream; package = sites and streams of a purchased package share one access name. Values: ["site","package"] |
| `connections` | integer |  | Concurrent connections, -1 = unlimited. |
| `created_at` | string |  | Created at (read-only) |
| `custom_cc_rule` | boolean |  | Allows custom CC rules. |
| `des` | string |  | Description |
| `domains` | integer |  | Number of domains (each IP site counts as 1), -1 = unlimited. |
| `enabled` | boolean |  | Whether enabled |
| `errors` | FieldError[] |  | Why each remaining item was not changed; field is /ids/<index>, code as in the single-item update (not_found, readonly and so on). |
| `group_ids` | integer[] |  | Package groups it belongs to. |
| `http_ports` | integer |  | Number of non-standard HTTP/HTTPS ports (other than 80/443), -1 = unlimited. |
| `id` | integer |  | Record ID (read-only) |
| `ids` | integer[] | Yes | IDs of the objects to change, at most 100. |
| `ip_num` | integer |  | Number of selectable IPs ("My IPs"), -1 = unlimited. |
| `ip_pool_id` | integer |  | IP pool used to provision IP sites (IP product line); null = not provisioned. |
| `ip_site_port` | integer |  | IP-site ports: distinct ports across all IP sites of the package (80/443 included), -1 = unlimited; IP-site ports do not count toward non-standard ports. |
| `items` | PackageSyncField[] | Yes | Fields to sync. |
| `l2` | boolean |  | Includes tiered origin (tenant switch of the paid feature l2): tenants can turn on tiered origin for sites, and nodes use it, only while the master license l2 is active; existing packages are false (on upgrade, purchased packages of tenants already using tiered origin are set to true). |
| `name` | string |  | Name |
| `node_group_id` | integer |  | Primary node group; null = the package binds no lines. |
| `origin_ip_limit` | string[] |  | Allowed origin IPs or CIDR ranges; empty = any. When set, origins of sites under the package must fall inside them and domain origins are rejected. |
| `owners` | integer[] |  | Tenant ids allowed to buy; empty = no restriction. |
| `price_month_cents` | integer |  | Monthly price in cents. |
| `price_quarter_cents` | integer |  | Quarterly price in cents. |
| `price_year_cents` | integer |  | Yearly price in cents. |
| `region_id` | integer |  | Region; null = the package binds no lines. |
| `renew_before_days` | integer |  | Renewal is only allowed within this many days before expiry, -1 = unlimited. |
| `require_verified` | boolean |  | Real-name verification is required to purchase. |
| `sale_until` | string |  | Not sold after this time; omitted/null = no limit. |
| `skipped` | integer |  | Number skipped because they do not follow the base package or individually edited at least one changed field (other fields are still synced). |
| `skipped_ids` | integer[] |  | Ids of the skipped purchased packages. |
| `sort` | integer |  | Display order (smaller first). |
| `stream_ports` | integer |  | Number of TCP/UDP forwarding ports, -1 = unlimited. |
| `sync` | PackageSyncResult |  | Sync result. |
| `synced` | integer |  | Number of purchased packages synced (for automatic sync, those where every changed field was synced). |
| `traffic_gb` | integer |  | Traffic in GB per billing cycle, -1 = unlimited. |
| `updated` | integer[] |  | IDs that were set (including those already in the target state), in request order. |
| `updated_at` | string |  | Updated at (read-only) |
| `waf_enhanced` | boolean |  | Includes WAF Enhanced (tenant switch of the paid feature waf_enhanced): tenants can use standard/strict levels, big screen, deep Bot, anti-tamper and so on only while the master license WAF Enhanced is not degraded; existing packages are false. |
| `websocket` | boolean |  | Allows WebSocket. |
