Authentication API
Authentication requests establish an account session or replace the credentials used to obtain one. Signup and authenticator confirmation form an enrollment transaction; password changes, recovery, and authenticator rotation have their own confirmation and session-revocation rules. Enrollment explains the user flow, while SDK authentication documents wrappers for seven common operations.
POST /auth/signup
{"user":"alice@example.com","email":"alice@example.com","password":"a long unique password"}
Optional public_keys is a list of at most two public JWKs. 201 returns user, enrollment_token, expires_in (600), secret, otpauth_uri, and qr_png_base64 when a PNG can be built.
The account is pending and cannot log in. The enrollment token is not a session.
POST /auth/signup/confirm
{"user":"alice@example.com","enrollment_token":"TOKEN","otp":"123456"}
200 returns access_token, token_type (Bearer), expires_in, expires_at, and eight recovery_codes. expires_in is the bearer lifetime in seconds. The default is 86400. {session_ttl, Seconds} sets it, from 60 to 2592000. Show the recovery codes once.
POST /auth/login
{"user":"alice@example.com","password":"a long unique password","otp":"123456"}
200 returns access_token, token_type, expires_in, and expires_at. expires_in is the same configured bearer lifetime as confirm.
POST /auth/logout
Authorization: Bearer TOKEN and an empty body. mesgd revokes that session.
POST /auth/refresh
Authorization: Bearer TOKEN and an empty body. The bearer has to be live. mesgd retires it and returns the next one for the same session: access_token, token_type (Bearer), expires_in, and expires_at. expires_in is session_ttl counted from this call. The session keeps its id, the way the caller signed in, and the time that session began. Sending the retired bearer again, or a bearer that has already expired, is 401. A grant token is not refreshed here.
POST /auth/password/reset
{"user":"alice@example.com","recovery_code":"SAVED","otp":"123456","new_password":"a different long unique password"}
200 returns password_reset: true and eight new recovery_codes. Sessions and old recovery codes are invalidated. No token is returned. The user logs in again.
POST /auth/password/change
Bearer token required.
{"password":"current password","new_password":"a different long unique password","otp":"123456"}
200 returns password_changed: true. Sessions are revoked.
POST /auth/otp/rotate
Bearer token required.
{"password":"current password","otp":"123456"}
200 returns secret, otpauth_uri, enrollment_token, expires_in (600), and qr_png_base64 when a PNG can be built. The previous authenticator remains in use until confirm.
POST /auth/otp/confirm
Bearer token required.
{"enrollment_token":"TOKEN","otp":"123456"}
200 returns otp_rotated: true and eight new recovery_codes. Sessions are revoked.
POST /auth/recovery/enroll
Use this after an administrator, or mesgd user recover, has given the person a handoff code. See Recovery.
{"user":"alice@example.com","recovery_token":"HANDOFF","new_password":"optional when a password is required"}
200 returns an enrollment (enrollment_token, secret, otpauth_uri, optional PNG). It does not return a session. Confirm with /auth/signup/confirm.