Auth endpoints (Client API: account)
31 FeatherPanel Client API: account endpoints from user/auth.php: methods, paths, auth, permissions, rate limits, parameters and responses.
Last synced from FeatherPanel 15b94e9 on .
On this page
Defined in backend/app/routes/user/auth.php. Authentication used here: Public, Signed-in user. Read Authentication for how to send credentials and Rate limits and errors for the response envelope.
Paths, methods, permissions and rate limits come from the route file. Summaries, parameters and response codes come from the OpenAPI annotations on the controllers; endpoints without annotations show only what the route file declares.
Endpoints
PUT/api/user/auth/register
Register new user Create a new user account with email verification and welcome email. User is automatically logged in after successful registration. Includes CloudFlare Turnstile validation if enabled.
Request body: RegisterRequest (application/json) · Response data: RegisterResponse
| Body field | Type | Required | Description |
|---|---|---|---|
username | string | yes | Username (alphanumeric and underscores only) |
email | string (email) | yes | User email address |
password | string | yes | User password |
first_name | string | yes | User first name |
last_name | string | yes | User last name |
turnstile_token | string | no | CloudFlare Turnstile token (required if Turnstile is enabled) |
Response data field | Type | Description |
|---|---|---|
user | object | User information |
preferences | object | User preferences |
message | string | Success message |
curl -X PUT "$PANEL_URL/api/user/auth/register" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"username":"","email":"","password":"","first_name":"","last_name":"","turnstile_token":""}'Plugin events: featherpanel:auth:login:success, featherpanel:auth:register:success, featherpanel:auth:registration:failed
Responses: 200 User registered successfully and automatically logged in · 400 Bad request - Missing required fields, invalid data format, Turnstile validation failed, or Turnstile keys not set · 403 Forbidden - Registration is not enabled · 409 Conflict - Username or email already exists · 500 Internal server error - Failed to create user
PUT/api/user/auth/login
Login user Authenticate user with username or email and password. Includes CloudFlare Turnstile validation if enabled. Returns 2FA requirement if enabled.
Request body: LoginRequest (application/json)
| Body field | Type | Required | Description |
|---|---|---|---|
username_or_email | string | yes | User email address or username |
password | string | yes | User password |
turnstile_token | string | no | CloudFlare Turnstile token (required if Turnstile is enabled) |
curl -X PUT "$PANEL_URL/api/user/auth/login" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"username_or_email":"","password":"","turnstile_token":""}'Plugin events: featherpanel:auth:login:failed
Responses: 200 User logged in successfully or two-factor authentication required · 400 Bad request - Missing required fields, invalid username or email format, Turnstile validation failed, or Turnstile keys not set · 401 Unauthorized - Invalid credentials, user is banned, or authentication otherwise rejected · 500 Internal server error - Remember token not set
PUT/api/user/auth/forgot-password
Request password reset Send a password reset email to the user. Includes CloudFlare Turnstile validation if enabled.
Request body: ForgotPasswordRequest (application/json) · Response data: ForgotPasswordResponse
| Body field | Type | Required | Description |
|---|---|---|---|
email | string (email) | yes | User email address |
turnstile_token | string | no | CloudFlare Turnstile token (required if Turnstile is enabled) |
Response data field | Type | Description |
|---|---|---|
message | string | Success message |
curl -X PUT "$PANEL_URL/api/user/auth/forgot-password" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"email":"","turnstile_token":""}'Plugin events: featherpanel:auth:forgot:password, featherpanel:auth:forgot:password:failed
Responses: 200 Generic success whether or not the email belongs to an account, including when User::updateUser() fails (anti-enumeration). Reset email is queued asynchronously when an account exists. · 400 Bad request - Missing required fields, invalid email format, Turnstile validation failed, or Turnstile keys not set
GET/api/user/auth/reset-password
Validate reset token Validate a password reset token to check if it is valid before allowing password reset.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
token | query | string | yes | Password reset token from email |
Response data: TokenValidationResponse
Response data field | Type | Description |
|---|---|---|
message | string | Token validation message |
token | string | Validated token |
curl -X GET "$PANEL_URL/api/user/auth/reset-password?token=$TOKEN" \
-H "Accept: application/json"Responses: 200 Token is valid · 400 Bad request - Missing token or invalid token · 500 Internal server error - Failed to validate token
GET/api/user/auth/verify-email
curl -X GET "$PANEL_URL/api/user/auth/verify-email" \
-H "Accept: application/json"POST/api/user/auth/verify-email/resend
curl -X POST "$PANEL_URL/api/user/auth/verify-email/resend" \
-H "Accept: application/json"PUT/api/user/auth/reset-password
Reset password Reset user password using token from forgot password email. Includes CloudFlare Turnstile validation if enabled.
Request body: ResetPasswordRequest (application/json) · Response data: ResetPasswordResponse
| Body field | Type | Required | Description |
|---|---|---|---|
token | string | yes | Password reset token from email |
password | string | yes | New password |
turnstile_token | string | no | CloudFlare Turnstile token (required if Turnstile is enabled) |
Response data field | Type | Description |
|---|---|---|
message | string | Success message |
curl -X PUT "$PANEL_URL/api/user/auth/reset-password" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"token":"","password":"","turnstile_token":""}'Plugin events: featherpanel:auth:password:reset:failed, featherpanel:auth:reset:password:success
Responses: 200 Password reset successfully · 400 Bad request - Missing required fields, Turnstile validation failed, or Turnstile keys not set · 404 Not found - Invalid token · 500 Internal server error - Failed to reset password
PUT/api/user/auth/two-factor
Enable two-factor authentication Enable two-factor authentication for the authenticated user using TOTP code verification. Includes CloudFlare Turnstile validation if enabled.
Request body: TwoFactorEnableRequest (application/json) · Response data: TwoFactorEnableResponse
| Body field | Type | Required | Description |
|---|---|---|---|
code | string | yes | 6-digit TOTP code |
secret | string | yes | 16-character secret key |
turnstile_token | string | no | CloudFlare Turnstile token (required if Turnstile is enabled) |
Response data field | Type | Description |
|---|---|---|
user | object | User information |
message | string | Success message |
curl -X PUT "$PANEL_URL/api/user/auth/two-factor" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"code":"","secret":"","turnstile_token":""}'Plugin events: featherpanel:auth:2fa:enabled
Responses: 200 Two-factor authentication enabled successfully · 400 Bad request - Missing required fields, invalid code length, Turnstile validation failed, or Turnstile keys not set · 401 Unauthorized - Invalid TOTP code or user is banned · 500 Internal server error - Failed to enable 2FA
GET/api/user/auth/two-factor
Get two-factor setup Get QR code URL and secret key for setting up two-factor authentication with an authenticator app.
Response data: TwoFactorSetupResponse
Response data field | Type | Description |
|---|---|---|
qr_code_url | string | QR code URL for authenticator app |
secret | string | Secret key for manual entry |
message | string | Success message |
curl -X GET "$PANEL_URL/api/user/auth/two-factor" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"Plugin events: featherpanel:auth:2fa:setup
Responses: 200 Two-factor setup information retrieved successfully · 400 Bad request - Two-factor authentication already enabled · 401 Unauthorized - User not authenticated · 500 Internal server error - Failed to generate setup information
GET/api/user/auth/logout
Logout user Logout the authenticated user by clearing remember token cookie and updating user session. Blocks 2FA if enabled.
Response data: LogoutResponse
Response data field | Type | Description |
|---|---|---|
message | string | Logout success message |
curl -X GET "$PANEL_URL/api/user/auth/logout" \
-H "Accept: application/json"Plugin events: featherpanel:auth:logout
Responses: 200 User logged out successfully · 500 Internal server error - Failed to logout user
DELETE/api/user/auth/logout
Logout user Logout the authenticated user by clearing remember token cookie and updating user session. Blocks 2FA if enabled.
Response data: LogoutResponse
Response data field | Type | Description |
|---|---|---|
message | string | Logout success message |
curl -X DELETE "$PANEL_URL/api/user/auth/logout" \
-H "Accept: application/json"Plugin events: featherpanel:auth:logout
Responses: 200 User logged out successfully · 500 Internal server error - Failed to logout user
POST/api/user/auth/two-factor
Verify two-factor code Verify two-factor authentication code during login process to complete authentication.
Request body: TwoFactorVerifyRequest (application/json) · Response data: TwoFactorVerifyResponse
| Body field | Type | Required | Description |
|---|---|---|---|
email | string (email) | yes | User email address |
code | string | yes | 6-digit TOTP code |
challenge | string | yes | Challenge token from the password authentication step (TWO_FACTOR_REQUIRED) |
Response data field | Type | Description |
|---|---|---|
user | object | User information |
message | string | Success message |
curl -X POST "$PANEL_URL/api/user/auth/two-factor" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"email":"","code":"","challenge":""}'Plugin events: featherpanel:auth:2fa:failed, featherpanel:auth:2fa:verified, featherpanel:auth:login:success
Responses: 200 Two-factor authentication verified successfully · 400 Bad request - Missing email, code, or challenge · 401 Unauthorized - 2FA not enabled, invalid code, or missing/invalid challenge · 429 Too many failed 2FA attempts for this account · 500 Internal server error - Failed to verify 2FA
GET/api/user/auth/discord/login
curl -X GET "$PANEL_URL/api/user/auth/discord/login" \
-H "Accept: application/json"GET/api/user/auth/discord/callback
curl -X GET "$PANEL_URL/api/user/auth/discord/callback" \
-H "Accept: application/json"GET/api/user/auth/discord/link
curl -X GET "$PANEL_URL/api/user/auth/discord/link" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"PUT/api/user/auth/discord/link
curl -X PUT "$PANEL_URL/api/user/auth/discord/link" \
-H "Accept: application/json"PUT/api/user/auth/discord/register
curl -X PUT "$PANEL_URL/api/user/auth/discord/register" \
-H "Accept: application/json"DELETE/api/user/auth/discord/unlink
curl -X DELETE "$PANEL_URL/api/user/auth/discord/unlink" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"GET/api/user/auth/oidc/login
Initiate OIDC login Redirects the user to the configured OpenID Connect (OIDC) provider.
curl -X GET "$PANEL_URL/api/user/auth/oidc/login" \
-H "Accept: application/json"GET/api/user/auth/oidc/callback
OIDC callback Handles the OpenID Connect (OIDC) callback and logs the user in.
curl -X GET "$PANEL_URL/api/user/auth/oidc/callback" \
-H "Accept: application/json"GET/api/user/auth/oidc/link
curl -X GET "$PANEL_URL/api/user/auth/oidc/link" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"DELETE/api/user/auth/oidc/unlink
curl -X DELETE "$PANEL_URL/api/user/auth/oidc/unlink" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"POST/api/user/auth/email-login/request
Request email login code Send a 6-digit login code to the user's email address for passwordless authentication.
Request body: EmailLoginRequest (application/json) · Response data: EmailLoginCodeSentResponse
| Body field | Type | Required | Description |
|---|---|---|---|
email | string (email) | yes | User email address |
turnstile_token | string | no | CloudFlare Turnstile token (required if Turnstile is enabled) |
Response data field | Type | Description |
|---|---|---|
message | string | Success message |
email | string | Email address where code was sent |
curl -X POST "$PANEL_URL/api/user/auth/email-login/request" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"email":"","turnstile_token":""}'Plugin events: featherpanel:auth:email:login:code:requested, featherpanel:auth:login:failed
Responses: 200 Login code sent successfully · 400 Bad request - Missing email, invalid format, or Turnstile validation failed · 401 Unauthorized - Email not found or user is banned · 403 Forbidden - Email login is disabled · 429 Too many requests - Rate limited
POST/api/user/auth/email-login/verify
Verify email login code Verify the 6-digit login code and authenticate the user.
Request body: EmailLoginVerifyRequest (application/json) · Response data: LoginResponse
| Body field | Type | Required | Description |
|---|---|---|---|
email | string (email) | yes | User email address |
code | string | yes | 6-digit login code sent to email |
Response data field | Type | Description |
|---|---|---|
user | object | User information |
preferences | object | User preferences |
message | string | Success message |
curl -X POST "$PANEL_URL/api/user/auth/email-login/verify" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"email":"","code":""}'Plugin events: featherpanel:auth:login:failed
Responses: 200 User logged in successfully · 400 Bad request - Missing fields or invalid code format · 401 Unauthorized - Invalid or expired code · 403 Forbidden - Email login is disabled
POST/api/user/auth/qr/start
Start QR login challenge Creates a short-lived QR login challenge for Discord-style sign-in from a phone that is already logged in.
curl -X POST "$PANEL_URL/api/user/auth/qr/start" \
-H "Accept: application/json"Responses: 200 Challenge created · 429 Rate limited
POST/api/user/auth/qr/poll
Poll QR login challenge Desktop polls challenge status. When approved, returns a one-time exchange_token.
curl -X POST "$PANEL_URL/api/user/auth/qr/poll" \
-H "Accept: application/json"Responses: 200 Challenge status · 400 Invalid challenge or secret · 429 Polling too fast
POST/api/user/auth/qr/exchange
Exchange QR login token for session Desktop redeems the one-time exchange_token and receives the remember_token cookie via completeLogin.
curl -X POST "$PANEL_URL/api/user/auth/qr/exchange" \
-H "Accept: application/json"Responses: 200 Logged in · 400 Invalid or expired token · 403 User banned or deleted
GET/api/user/auth/qr/code/{user_code}
Look up QR login challenge by user code Authenticated user enters the short code shown on another device to load and mark the challenge as scanned.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user_code | path | - | yes |
curl -X GET "$PANEL_URL/api/user/auth/qr/code/$USER_CODE" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"Responses: 200 Challenge details · 400 Invalid or expired code · 401 Unauthorized
GET/api/user/auth/qr/{challenge_id}
Get QR login challenge for approval Authenticated phone loads challenge details and marks it as scanned.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
challenge_id | path | - | yes |
curl -X GET "$PANEL_URL/api/user/auth/qr/$CHALLENGE_ID" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"Responses: 200 Challenge details · 400 Invalid or expired challenge · 401 Unauthorized
POST/api/user/auth/qr/{challenge_id}/approve
Approve QR login challenge Authenticated phone approves the desktop login. Does not set a cookie on the phone; mints an exchange token for the desktop.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
challenge_id | path | - | yes |
curl -X POST "$PANEL_URL/api/user/auth/qr/$CHALLENGE_ID/approve" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"Responses: 200 Approved · 400 Invalid challenge · 401 Unauthorized · 403 User banned or deleted
POST/api/user/auth/qr/{challenge_id}/deny
Deny QR login challenge
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
challenge_id | path | - | yes |
curl -X POST "$PANEL_URL/api/user/auth/qr/$CHALLENGE_ID/deny" \
-H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
-H "Accept: application/json"Responses: 200 Denied · 400 Invalid challenge · 401 Unauthorized