Password Reset
UrsaMU does not have a self-service “forgot password” email flow — the server
has no email sending built in. Instead, password resets are a two-step process:
an admin generates a short-lived token in-game, then the player uses that token
to set a new password via the REST API.
Overview
Admin (in-game) Player (out of band)
───────────────────────────── ─────────────────────────────────
@resettoken PlayerName Receives token from admin
→ token printed in-game ───▶ POST /api/v1/auth/reset-password
{ token, newPassword }
← 200 OK — password updated
The token is a UUID, stored on the player object, and expires 1 hour after
generation. It is single-use — it is deleted immediately on successful reset.
Admin Steps
Any admin or wizard can generate a reset token for any player character.
In-game command
@resettoken <player>
Example:
@resettoken Talia
Reset token for Talia: 3f8a9b2c-1e4d-4f7a-8b6e-2a9c0d1e3f5a (expires in 1 hour)
The token is printed directly in your in-game session. You then pass it to the
player through any out-of-band channel — Discord, email, direct message, etc.
Security note: The token grants the ability to set a new password for that
account. Treat it like a temporary password and communicate it securely.
If the token is compromised before use, run@resettokenagain — the new
token replaces the old one.
Player Steps
The player calls the REST endpoint with the token they received.
POST /api/v1/auth/reset-password
No authentication header required.
Request body:
{
"token": "3f8a9b2c-1e4d-4f7a-8b6e-2a9c0d1e3f5a",
"newPassword": "my-new-secure-password"
}
Example with curl:
curl -X POST https://yourgame.example.com/api/v1/auth/reset-password \
-H "Content-Type: application/json" \
-d '{"token":"3f8a9b2c-1e4d-4f7a-8b6e-2a9c0d1e3f5a","newPassword":"my-new-secure-password"}'
Success response (200 OK):
{ "message": "Password updated successfully." }
After a successful reset the player can log in with their new password using the
normal POST /api/v1/auth/login endpoint.
API Reference
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | Yes | UUID generated by @resettoken |
newPassword |
string | Yes | Max 512 characters |
| Outcome | Status | Body |
|---|---|---|
| Success | 200 |
{ "message": "Password updated successfully." } |
| Missing fields | 400 |
{ "error": "token and newPassword are required." } |
| Password too long | 400 |
{ "error": "Password must be 512 characters or fewer." } |
| Bad or expired token | 400 |
{ "error": "Invalid or expired reset token." } |
Error Responses
Invalid or expired token
The token is invalid if:
- It was never generated (or the player name was wrong)
- More than 1 hour has passed since
@resettokenwas run - It was already used successfully
{ "error": "Invalid or expired reset token." }
Run @resettoken <player> again to generate a fresh token.
Password too long
Passwords are limited to 512 characters.
{ "error": "Password must be 512 characters or fewer." }
Security Notes
- Tokens are stored as plain UUIDs on the player object and are single-use.
- Both generation (
ADMIN_RESETTOKEN) and consumption (PASSWORD_RESET) are
written tologs/security.logwith the actor ID and client IP. - Admins can reset their own token at any time by running
@resettokenagain —
the new token overwrites the old one. - The
@newpassword <player>=<pass>command is an alternative for admins who
want to set the password directly without involving the player.