## Authentication (`auth`)

Login, token refresh, logout, password change, TOTP, password reset, captcha and admin SSO. Login endpoints need no authentication.

Authentication: No auth · Docs: https://www-demo.kuxitong.com/en/docs/api/auth

### GET `/api/v2/auth/captcha`

Get captcha · Authentication: No auth

```sh
curl "https://panel.example.com/api/v2/auth/captcha"
```

### POST `/api/v2/auth/login`

Log in · Authentication: No auth

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `captcha_code` | string |  | Characters shown in the captcha image |
| `captcha_id` | string |  | Captcha id from GET /auth/captcha; required after repeated failed logins |
| `password` | string | Yes | Login password |
| `totp_code` | string |  | Current 6-digit TOTP code, or an unused recovery code (XXXXX-XXXXX, consumed on use); required when the account has TOTP enabled |
| `username` | string | Yes | Username |
| `verify_code` | string |  | Second-factor login code. Required when the account has email/SMS code login (login_verify) enabled; obtain it first via POST /verify-codes (purpose=login) |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/login"
```

### POST `/api/v2/auth/logout`

Log out · Authentication: User

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

### PUT `/api/v2/auth/password`

Change password · Authentication: User

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `new_password` | string | Yes | New password, 8 to 128 characters |
| `old_password` | string | Yes | Current password |

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

### POST `/api/v2/auth/password-reset`

Reset password · Authentication: No auth

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `channel` | string | Yes | Recover by email or by phone number Values: ["email","sms"] |
| `code` | string | Yes | Verification code sent to target (POST /verify-codes, purpose=reset_password) |
| `new_password` | string | Yes | New password, 8 to 128 characters |
| `target` | string | Yes | Email or phone number bound to the account |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/password-reset" \
  -H "Content-Type: application/json" \
  -d '{"channel":"email","code":"123456","new_password":"${NEW_PASSWORD}","target":"user@example.com"}'
```

### POST `/api/v2/auth/refresh`

Refresh token · Authentication: No auth

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `refresh_token` | string | Yes | Refresh token, exchanged for a new token pair |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/refresh"
```

### POST `/api/v2/auth/sso`

Admin SSO login · Authentication: No auth

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `sso_ticket` | string | Yes | Login ticket issued by the super admin: base64url (no padding) bytes of a licwire envelope (kind sso_ticket) |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/sso" \
  -H "Content-Type: application/json" \
  -d '{"sso_ticket":"eyJib2R5Ijp7fX0"}'
```

### POST `/api/v2/auth/switch`

Switch admin to user · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `user_id` | integer | Yes | User ID |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/switch" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id":2}'
```

### POST `/api/v2/auth/switch-login`

Log in with a switch ticket · Authentication: No auth

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `switch_ticket` | string | Yes | One-time switch ticket obtained by an administrator. |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/switch-login"
```

### POST `/api/v2/auth/switch-ticket`

Create a one-time switch ticket · Authentication: Admin only

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `user_id` | integer | Yes | User ID |

```sh
curl -X POST "https://panel.example.com/api/v2/auth/switch-ticket" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id":2}'
```

### POST `/api/v2/auth/totp`

Generate TOTP secret · Authentication: User

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

### PUT `/api/v2/auth/totp`

Enable TOTP · Authentication: User

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `code` | string | Yes | Verification code sent to target (POST /verify-codes, purpose=reset_password) |

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

### DELETE `/api/v2/auth/totp`

Disable TOTP · Authentication: User

Request body:

| Field | Type | Required | Description |
|---|---|---|---|
| `code` | string | Yes | Verification code sent to target (POST /verify-codes, purpose=reset_password) |

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

Authentication object:

| Field | Type | Required | Description |
|---|---|---|---|
| `access_token` | string |  | Access token, sent as Authorization: Bearer |
| `captcha_code` | string |  | Characters shown in the captcha image |
| `captcha_id` | string |  | Captcha id from GET /auth/captcha; required after repeated failed logins |
| `channel` | string | Yes | Recover by email or by phone number Values: ["email","sms"] |
| `code` | string | Yes | Verification code sent to target (POST /verify-codes, purpose=reset_password) |
| `expires_in` | integer |  | Access token lifetime in seconds |
| `id` | string |  | Pass back as captcha_id when logging in; single use, invalidated after one check whether right or wrong |
| `image` | string |  | PNG data URI |
| `key` | string |  | Base32 secret (returned only once, here) |
| `must_change_password` | boolean |  | Login response only; true means the account still uses the installer-generated initial password and must change it first. |
| `new_password` | string | Yes | New password, 8 to 128 characters |
| `old_password` | string | Yes | Current password |
| `otpauth_uri` | string |  | otpauth:// URI to add to an authenticator app by scanning |
| `password` | string | Yes | Login password |
| `recovery_codes` | string[] |  | Eight one-time recovery codes (XXXXX-XXXXX), returned only once, when TOTP is enabled |
| `refresh_token` | string |  | Refresh token, exchanged for a new token pair |
| `sso_ticket` | string | Yes | Login ticket issued by the super admin: base64url (no padding) bytes of a licwire envelope (kind sso_ticket) |
| `switch_ticket` | string | Yes | One-time switch ticket obtained by an administrator. |
| `target` | string | Yes | Email or phone number bound to the account |
| `token_type` | string |  | Token type, always Bearer |
| `totp_code` | string |  | Current 6-digit TOTP code, or an unused recovery code (XXXXX-XXXXX, consumed on use); required when the account has TOTP enabled |
| `user_id` | integer | Yes | User ID |
| `username` | string | Yes | Username |
| `verify_code` | string |  | Second-factor login code. Required when the account has email/SMS code login (login_verify) enabled; obtain it first via POST /verify-codes (purpose=login) |
