## CNAME access domains (`cname-domains`)

Admin only. Root domains used to build CNAME access names, each owned by a DNS provider account; supports migrating everything to a new root domain and checking whether customers have switched their records.

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

### GET `/api/v2/cname-domains`

List CNAME access domains · 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` |
| `domain` | string |  | Only list root domains containing this text (partial match, case-insensitive; surrounding spaces and a trailing dot are ignored). |
| `type` | string |  | Only list domains belonging to this provider type (such as aliyun). |
| `dns_provider_id` | integer |  | Only list domains belonging to this account. |
| `status` | CnameDomainStatus |  | Only list domains in this status. Values: ["active","retiring"] |

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

### POST `/api/v2/cname-domains`

Create CNAME access domain · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `dns_provider_id` | integer | Yes | ID of the provider account hosting this root domain. |
| `domain` | string | Yes | Lowercase root domain, such as cdn.example.com. |
| `expected_updated_at` | string |  | Optimistic lock (used on update) - the updated_at of the resource as the caller read it. If it differs from the stored one, 409 stale_version is returned and nothing is saved; omit to skip the check; ignored on create. |
| `expire_at` | string |  | Expiry date entered by the admin, YYYY-MM-DD; the admin is reminded 30, 7 and 1 days before expiry and once after it. |
| `remark` | string |  | Remark |
| `status` | CnameDomainStatus |  | active: in use; retiring: being retired (migrated away, no longer offered when choosing a package domain). Values: ["active","retiring"] |

```sh
curl -X POST "https://panel.example.com/api/v2/cname-domains" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dns_provider_id":1,"domain":"cdn.example.com","expire_at":"2027-01-31","remark":"主接入域名"}'
```

### PUT `/api/v2/cname-domains/status`

Batch set CNAME access domain status · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `ids` | integer[] | Yes | IDs of the access domains to update. |
| `status` | CnameDomainStatus | Yes | active: in use; retiring: being retired (migrated away, no longer offered when choosing a package domain). Values: ["active","retiring"] |

```sh
curl -X PUT "https://panel.example.com/api/v2/cname-domains/status" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ids":[1],"status":"retiring"}'
```

### GET `/api/v2/cname-domains/{id}`

Get CNAME access domain · Authentication: Admin only

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

### PUT `/api/v2/cname-domains/{id}`

Update CNAME access domain · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `dns_provider_id` | integer | Yes | ID of the provider account hosting this root domain. |
| `domain` | string | Yes | Lowercase root domain, such as cdn.example.com. |
| `expected_updated_at` | string |  | Optimistic lock (used on update) - the updated_at of the resource as the caller read it. If it differs from the stored one, 409 stale_version is returned and nothing is saved; omit to skip the check; ignored on create. |
| `expire_at` | string |  | Expiry date entered by the admin, YYYY-MM-DD; the admin is reminded 30, 7 and 1 days before expiry and once after it. |
| `remark` | string |  | Remark |
| `status` | CnameDomainStatus |  | active: in use; retiring: being retired (migrated away, no longer offered when choosing a package domain). Values: ["active","retiring"] |

```sh
curl -X PUT "https://panel.example.com/api/v2/cname-domains/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dns_provider_id":1,"domain":"cdn.example.com","expire_at":"2027-01-31","remark":"主接入域名"}'
```

### DELETE `/api/v2/cname-domains/{id}`

Delete CNAME access domain · Authentication: Admin only

Query parameters:

| Field | Type | Required | Description |
|---|---|---|---|
| `local_only` | boolean |  | When true, delete only the local record and do not clean up provider-side records under this root domain. |

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

### POST `/api/v2/cname-domains/{id}/migrate`

Migrate CNAME access domain · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `notify` | boolean |  | Whether to send in-app messages to the affected customers. Default: true |
| `retire` | boolean |  | Whether to set the old domain to retiring. Default: true |
| `target_id` | integer | Yes | ID of the target root domain. |

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

### GET `/api/v2/cname-domains/{id}/refs`

Get CNAME access domain references · Authentication: Admin only

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

### GET `/api/v2/cname-domains/{id}/switch-check`

Check switch status after migration · 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 |
| `state` | CnameSwitchState |  | Only list rows in this check state. Values: ["changed","unchanged","not_cname","failed","pending"] |
| `q` | string |  | Fuzzy match on customer name, site domain or actual resolution. |

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

### GET `/api/v2/cname-domains/{id}/switch-check/export`

Export switch check table · Authentication: Admin only

Query parameters:

| Field | Type | Required | Description |
|---|---|---|---|
| `state` | CnameSwitchState |  | Only list rows in this check state. Values: ["changed","unchanged","not_cname","failed","pending"] |
| `q` | string |  | Fuzzy match on customer name, site domain or actual resolution. |

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

### POST `/api/v2/cname-domains/{id}/switch-check/remind`

Remind customers who have not switched · Authentication: Admin only

```sh
curl -X POST "https://panel.example.com/api/v2/cname-domains/{id}/switch-check/remind" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/cname-domains/{id}/switch-check/run`

Run switch check now · Authentication: Admin only

```sh
curl -X POST "https://panel.example.com/api/v2/cname-domains/{id}/switch-check/run" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

CNAME access domains object:

| Field | Type | Required | Description |
|---|---|---|---|
| `actual` | string |  | What it actually resolves to (CNAME target or IP); on lookup failure, the reason (NXDOMAIN, Timeout, ...). |
| `changed` | integer |  | Number of rows now switched. |
| `check_rows` | integer |  | Number of check rows created (one per site domain). |
| `checked` | integer |  | Number of rows rechecked. |
| `checked_at` | string |  | Time of the last resolution check. |
| `created_at` | string |  | Created at (read-only) |
| `dns_provider_id` | integer |  | ID of the provider account hosting this root domain. |
| `domain` | string |  | Lowercase root domain, such as cdn.example.com. |
| `example_hostname` | string |  | An existing access name (without the root domain), used by the wizard to build old and new access address examples. |
| `expected_updated_at` | string |  | Optimistic lock (used on update) - the updated_at of the resource as the caller read it. If it differs from the stored one, 409 stale_version is returned and nothing is saved; omit to skip the check; ignored on create. |
| `expire_at` | string |  | Expiry date entered by the admin, YYYY-MM-DD; the admin is reminded 30, 7 and 1 days before expiry and once after it. |
| `failed` | integer |  | Number of rows whose lookup failed. |
| `from` | string |  | Source root domain. |
| `id` | integer |  | Record ID (read-only) |
| `ids` | integer[] | Yes | IDs of the access domains to update. |
| `messaged` | integer |  | Number of customers who received an in-app message. |
| `new_target` | string |  | CNAME target after the switch. |
| `not_cname` | integer |  | Number of rows not using a CNAME. |
| `notified_at` | string |  | Time the customer was notified. |
| `notify` | boolean |  | Whether to send in-app messages to the affected customers. Default: true |
| `old_target` | string |  | CNAME target before the switch. |
| `package` | integer |  | Number of package access names switched. |
| `package_list` | string[] |  | First 20 purchased packages referencing this root domain. |
| `provider_name` | string |  | Name of the owning account. |
| `provider_type` | string |  | Provider type of the owning account. |
| `remark` | string |  | Remark |
| `retire` | boolean |  | Whether to set the old domain to retiring. Default: true |
| `site` | integer |  | Number of site access names switched. |
| `site_id` | integer |  | Site ID |
| `site_list` | string[] |  | List of site access names switched. |
| `skipped` | object[] |  | Skipped access domains with reasons. |
| `state` | CnameSwitchState |  | changed: already switched; unchanged: not switched yet; not_cname: not a CNAME access (points elsewhere or only has an A record); failed: lookup failed; pending: waiting to be checked. Values: ["changed","unchanged","not_cname","failed","pending"] |
| `status` | CnameDomainStatus |  | active: in use; retiring: being retired (migrated away, no longer offered when choosing a package domain). Values: ["active","retiring"] |
| `stream` | integer |  | Number of TCP/UDP forwarding access names switched. |
| `stream_list` | string[] |  | First 20 TCP/UDP forwardings (id:<id> <access name>). |
| `switched_at` | string |  | Time of the migration; empty if not migrated. |
| `switched_to` | integer |  | ID of the root domain it was migrated to. |
| `switched_to_domain` | string |  | Name of the root domain it was migrated to; empty if not migrated. |
| `target_id` | integer | Yes | ID of the target root domain. |
| `tenant_id` | integer |  | Owner tenant (user) ID |
| `to` | string |  | Target root domain. |
| `unchanged` | integer |  | Number of rows still not switched. |
| `updated` | integer |  | Number of domains actually updated. |
| `updated_at` | string |  | Updated at (read-only) |
| `user_list` | string[] |  | List of affected customers. |
| `user_name` | string |  | Customer (tenant) name; empty if the tenant was deleted. |
| `users` | integer |  | Number of affected customers (distinct tenants owning the sites). |
