Auth

Authentication for the SpeyBooks API. Credentials are exchanged for a short-lived JSON Web Token (the access token), with optional TOTP two-factor. These endpoints run before any organisation context exists, so they are not tenant-scoped.

Login flow

  1. POST /auth/login with a username (or email) and password.
  2. If TOTP is enabled, the response carries a short-lived temporary token instead of a session; exchange it at POST /auth/totp/verify with the six-digit code.
  3. On success the response carries an access token (its lifetime is returned as expiresIn, in seconds) and a longer-lived refresh token.
  4. Call POST /auth/refresh with the refresh token to obtain a new access token before the current one expires.

Token model

The access token is a bearer credential: send it as Authorization: Bearer <accessToken> on authenticated requests. The refresh token is held by the client and sent only to /auth/refresh. Refresh returns a new access token and does not rotate the refresh token. Changing the password invalidates every outstanding refresh token, so other sessions must log in again; access tokens already issued expire on their own short lifetime. Logout records the event and is a client-side discard: it does not revoke tokens server-side.

Security posture

Passwords are hashed with Argon2id and never stored or returned in any form. TOTP follows RFC 6238 and works with standard authenticator apps. Public auth endpoints are rate limited, and repeated failed logins progressively limit and then temporarily lock the account. The login response does not reveal whether an account exists: an unknown username and a wrong password return the same error.

Endpoints