Skip to main content
All endpoints under /api/auth handle user identity. Most do not require an existing session, but a few require a valid bearer token (indicated below).
The default credentials are email: admin and password: admin. Change them after first login.

POST /api/auth/login

Exchange credentials for a JWT bearer token. Request body
email
string
required
The user’s email address (or username for the default admin account).
password
string
required
The user’s password.
Response
token
string
JWT bearer token. Pass this as Authorization: Bearer <token> on protected endpoints.
user
object
curl -s -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "admin", "password": "admin"}'
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "a1b2c3d4e5f6",
    "email": "admin",
    "name": null,
    "role": "admin",
    "tier": 0,
    "is_active": true,
    "is_verified": false,
    "created_at": 1700000000000,
    "updated_at": 1700000000000
  }
}

POST /api/auth/signup

Register a new user account. A referrer token is required (obtained from an existing user or admin). Request body
referrer
string
required
Referrer token provided by an existing user.
email
string
required
New user’s email address.
password
string
required
New user’s password.
name
string
Optional display name.
Response — same shape as /login: a LoginResponse with token and user.

GET /api/auth/me

Return the currently authenticated user’s details.
Requires a valid bearer token.
curl -s http://localhost:8080/api/auth/me \
  -H "Authorization: Bearer <token>"
Response — a User object (same fields as the user object in the login response).

PUT /api/auth/me/name

Update the display name of the current user.
Requires a valid bearer token.
Request body
name
string
required
New display name.
Responsetrue on success.

PUT /api/auth/me/password

Change the current user’s password.
Requires a valid bearer token.
Request body
old_password
string
required
Current password.
new_password
string
required
New password.
Responsetrue on success.

POST /api/auth/send-password-reset-link

Send a password-reset link to the given email address. Request body
email
string
required
Email address of the account to reset.
Responsetrue on success.

POST /api/auth/reset-password-with-token

Reset a password using the token received in the reset email. Pass the reset token as a bearer token in the Authorization header.
Requires the password-reset bearer token from the reset email.
Request body
password
string
The new password.
Responsetrue on success.

POST /api/auth/me/send-otp

Send a one-time password (OTP) to the current user’s email for verification.
Requires a valid bearer token.
Response
token
string
An OTP session token to be passed to /verify-otp.

POST /api/auth/verify-otp

Verify an OTP code and mark the user’s email as verified. Submit as multipart/form-data. Form fields
otp
string
required
The one-time password received by email.
token
string
required
The OTP session token returned by /me/send-otp.
Responsetrue on success.

POST /api/auth/me/create-token

Generate a long-lived user API token (distinct from the JWT session token).
Requires a valid bearer token.
Response
token
string
The new API token string.

GET /api/auth/verify-token

Check whether a given user API token is valid and the account is active. Query parameters
token
string
required
The user token to verify.
Responsetrue if the token is valid and the account is active, false otherwise.

POST /api/auth/me/tokens

List all API tokens belonging to the current user.
Requires a valid bearer token.
Response — array of UserToken objects.
token
string
The 10-character token string.
user_id
string
ID of the owning user.
expires_at
integer
Expiry time (UNIX ms).

Using the token

Include the JWT from /login in every protected request:
# Store the token
TOKEN=$(curl -s -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "admin", "password": "admin"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")

# Use the token
curl -s http://localhost:8080/api/novels \
  -H "Authorization: Bearer $TOKEN"
You can also use HTTP Basic Auth on any endpoint that accepts a bearer token: curl -u admin:admin http://localhost:8080/api/novels

Build docs developers (and LLMs) love